gerrit
2017-05-22 18:20:24 UTC
This is an automated email from Gerrit.
Salvador Arroyo (***@yahoo.es) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4146
-- gerrit
commit f81af9626bea22297a7b7d6e5f7da30d77a3fe20
Author: Salvador Arroyo <***@yahoo.es>
Date: Mon May 22 20:14:18 2017 +0200
mips32: restore working regs after execption
If an exception is taken, execution does not complete
and registers are not restored. Added a new function
for restoring registers.
Change-Id: Idf7f848777d6adf18dc43ec323ea1a8577aa8cd4
Signed-off-by: Salvador Arroyo <***@yahoo.es>
diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index da2a906..0255063 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -155,7 +155,7 @@ int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info)
return ERROR_OK;
}
-static void pracc_log_debug_mode_exception_info(struct mips_ejtag *ejtag_info)
+static void pracc_log_debug_mode_exception_info(struct mips_ejtag *ejtag_info, bool restore_regs)
{
if (ejtag_info->exception_check) /* avoid recursive calls */
return;
@@ -168,11 +168,14 @@ static void pracc_log_debug_mode_exception_info(struct mips_ejtag *ejtag_info)
if (retval == ERROR_OK)
retval = mips32_cp0_read(ejtag_info, &exc_addr, 24, 0); /* read Cp0 DEPC register */
- ejtag_info->exception_check = 0;
-
if (retval == ERROR_OK && (val & EJTAG_DEBUG_CAUSE_MASK) == 0)
LOG_WARNING("Debug mode exception, code: %s, triggered at address: %"PRIx32,
excep_code[(val & EJTAG_DEBUG_EXCEPCODE_MASK) >> EJTAG_DEBUG_EXCEPCODE_SHIFT], exc_addr);
+
+ if (restore_regs) /* current pracc functions only take 3 registers at most */
+ mips32_pracc_restore_working_regs(ejtag_info, 8, 9); /* restore $8, $9 and $15 */
+
+ ejtag_info->exception_check = 0;
}
int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
@@ -379,7 +382,7 @@ inline void pracc_queue_free(struct pracc_queue_info *ctx)
if (ctx->retval == ERROR_PRACC_TEXT_JUMP) {
ctx->retval = ERROR_JTAG_DEVICE_ERROR; /* change to standard error code */
- pracc_log_debug_mode_exception_info(ctx->ejtag_info);
+ pracc_log_debug_mode_exception_info(ctx->ejtag_info, 1);
}
}
@@ -486,6 +489,30 @@ exit:
return retval;
}
+int mips32_pracc_restore_working_regs(struct mips_ejtag *ejtag_info, unsigned first, unsigned last)
+{
+ if (last > 15 || first > last)
+ return ERROR_FAIL;
+
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
+ pracc_queue_init(&ctx);
+
+ for (unsigned i = first; i <= last; i++)
+ pracc_add_li32(&ctx, i, ejtag_info->regs[i], 1);
+
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));
+ /* restore reg 15 from DeSave except if last == 15 */
+ last == 15 ? pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0)) : /* load $15 in DeSave */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* restore $15 from DeSave */
+
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
+ pracc_queue_free(&ctx);
+
+ if (ctx.retval != ERROR_OK)
+ LOG_ERROR("Failed to restore working registers");
+ return ctx.retval;
+}
+
int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
{
struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
diff --git a/src/target/mips32_pracc.h b/src/target/mips32_pracc.h
index 8181c9b..e4fe04d 100644
--- a/src/target/mips32_pracc.h
+++ b/src/target/mips32_pracc.h
@@ -117,7 +117,7 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);
int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
uint32_t *param_out, bool check_last);
-
+int mips32_pracc_restore_working_regs(struct mips_ejtag *ejtag_info, unsigned first, unsigned last);
/**
* \b mips32_cp0_read
*
--
Salvador Arroyo (***@yahoo.es) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4146
-- gerrit
commit f81af9626bea22297a7b7d6e5f7da30d77a3fe20
Author: Salvador Arroyo <***@yahoo.es>
Date: Mon May 22 20:14:18 2017 +0200
mips32: restore working regs after execption
If an exception is taken, execution does not complete
and registers are not restored. Added a new function
for restoring registers.
Change-Id: Idf7f848777d6adf18dc43ec323ea1a8577aa8cd4
Signed-off-by: Salvador Arroyo <***@yahoo.es>
diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index da2a906..0255063 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -155,7 +155,7 @@ int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info)
return ERROR_OK;
}
-static void pracc_log_debug_mode_exception_info(struct mips_ejtag *ejtag_info)
+static void pracc_log_debug_mode_exception_info(struct mips_ejtag *ejtag_info, bool restore_regs)
{
if (ejtag_info->exception_check) /* avoid recursive calls */
return;
@@ -168,11 +168,14 @@ static void pracc_log_debug_mode_exception_info(struct mips_ejtag *ejtag_info)
if (retval == ERROR_OK)
retval = mips32_cp0_read(ejtag_info, &exc_addr, 24, 0); /* read Cp0 DEPC register */
- ejtag_info->exception_check = 0;
-
if (retval == ERROR_OK && (val & EJTAG_DEBUG_CAUSE_MASK) == 0)
LOG_WARNING("Debug mode exception, code: %s, triggered at address: %"PRIx32,
excep_code[(val & EJTAG_DEBUG_EXCEPCODE_MASK) >> EJTAG_DEBUG_EXCEPCODE_SHIFT], exc_addr);
+
+ if (restore_regs) /* current pracc functions only take 3 registers at most */
+ mips32_pracc_restore_working_regs(ejtag_info, 8, 9); /* restore $8, $9 and $15 */
+
+ ejtag_info->exception_check = 0;
}
int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
@@ -379,7 +382,7 @@ inline void pracc_queue_free(struct pracc_queue_info *ctx)
if (ctx->retval == ERROR_PRACC_TEXT_JUMP) {
ctx->retval = ERROR_JTAG_DEVICE_ERROR; /* change to standard error code */
- pracc_log_debug_mode_exception_info(ctx->ejtag_info);
+ pracc_log_debug_mode_exception_info(ctx->ejtag_info, 1);
}
}
@@ -486,6 +489,30 @@ exit:
return retval;
}
+int mips32_pracc_restore_working_regs(struct mips_ejtag *ejtag_info, unsigned first, unsigned last)
+{
+ if (last > 15 || first > last)
+ return ERROR_FAIL;
+
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
+ pracc_queue_init(&ctx);
+
+ for (unsigned i = first; i <= last; i++)
+ pracc_add_li32(&ctx, i, ejtag_info->regs[i], 1);
+
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));
+ /* restore reg 15 from DeSave except if last == 15 */
+ last == 15 ? pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0)) : /* load $15 in DeSave */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* restore $15 from DeSave */
+
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
+ pracc_queue_free(&ctx);
+
+ if (ctx.retval != ERROR_OK)
+ LOG_ERROR("Failed to restore working registers");
+ return ctx.retval;
+}
+
int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
{
struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
diff --git a/src/target/mips32_pracc.h b/src/target/mips32_pracc.h
index 8181c9b..e4fe04d 100644
--- a/src/target/mips32_pracc.h
+++ b/src/target/mips32_pracc.h
@@ -117,7 +117,7 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);
int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
uint32_t *param_out, bool check_last);
-
+int mips32_pracc_restore_working_regs(struct mips_ejtag *ejtag_info, unsigned first, unsigned last);
/**
* \b mips32_cp0_read
*
--