aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-11-24 01:27:16 -0800
committerDavid Brownell <dbrownell@users.sourceforge.net>2009-11-24 01:27:16 -0800
commit5eb893ec41c8c6cf6499558b6fed826b65e18a16 (patch)
tree25b0c1c532fdbb77b0147e17718bcb414101df1c
parent6ff33a4ee8db483e29bc78b8c35e50342ca60850 (diff)
downloadriscv-openocd-5eb893ec41c8c6cf6499558b6fed826b65e18a16.zip
riscv-openocd-5eb893ec41c8c6cf6499558b6fed826b65e18a16.tar.gz
riscv-openocd-5eb893ec41c8c6cf6499558b6fed826b65e18a16.tar.bz2
ARM11: partial support for standard ARM register interfaces.
This provides "standard" ARM register support -- with twenty or more shadow registers on top of what this code now handles, but properly associated with the various core modes -- parallel to the current register code. That is, the current code is stilil managing the "current" registers; the new code shadows them. You can see all the registers with "arm reg", modify the shadows like "r8_fiq" or "sp_abt" with "reg", and see them get properly written back when you step. (Just don't do that with any of the registers managed by the "old" code ...) It also switches to using more standard code, relying on those standard registers, in two places: (a) the poll status display, which now shows core state (ARM/Thumb/...) and mode (Supervisor, IRQ, etc); and (b) GDB register access. So it's not a full migration, there are warts -- every place that touches the old register cache is a potential bug -- but it's a small more-or-less-comprehensible step that's even somewhat useful. Later patches complete the migration. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-rw-r--r--src/target/arm11.c66
1 files changed, 31 insertions, 35 deletions
diff --git a/src/target/arm11.c b/src/target/arm11.c
index 3c841bb..4e6326d 100644
--- a/src/target/arm11.c
+++ b/src/target/arm11.c
@@ -144,9 +144,6 @@ enum arm11_regcache_ids
ARM11_RC_MAX,
};
-/* GDB expects ARMs to give R0..R15, CPSR, and 7 FPA dummies */
-#define ARM11_GDB_REGISTER_COUNT 26
-
static int arm11_on_enter_debug_state(struct arm11_common *arm11);
static int arm11_step(struct target *target, int current,
uint32_t address, int handle_breakpoints);
@@ -223,6 +220,9 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
{
int retval;
+ /* REVISIT entire cache should already be invalid !!! */
+ register_cache_invalidate(arm11->arm.core_cache);
+
for (size_t i = 0; i < ARRAY_SIZE(arm11->reg_values); i++)
{
arm11->reg_list[i].valid = 1;
@@ -297,6 +297,10 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
}
#endif
+ retval = arm_dpm_read_current_registers(&arm11->dpm);
+ if (retval != ERROR_OK)
+ LOG_ERROR("DPM REG READ -- fail %d", retval);
+
retval = arm11_run_instr_data_prepare(arm11);
if (retval != ERROR_OK)
return retval;
@@ -434,6 +438,9 @@ static int arm11_leave_debug_state(struct arm11_common *arm11)
}
}
+/* DEBUG for now, trust "new" code only for shadowed registers */
+retval = arm_dpm_write_dirty_registers(&arm11->dpm);
+
retval = arm11_run_instr_data_prepare(arm11);
if (retval != ERROR_OK)
return retval;
@@ -473,6 +480,11 @@ static int arm11_leave_debug_state(struct arm11_common *arm11)
if (retval != ERROR_OK)
return retval;
+/* DEBUG use this when "new" code is really managing core registers */
+// retval = arm_dpm_write_dirty_registers(&arm11->dpm);
+
+ register_cache_invalidate(arm11->arm.core_cache);
+
/* restore DSCR */
arm11_write_DSCR(arm11, R(DSCR));
@@ -545,14 +557,13 @@ static int arm11_poll(struct target *target)
/* architecture specific status reply */
static int arm11_arch_state(struct target *target)
{
- struct arm11_common *arm11 = target_to_arm11(target);
+ int retval;
- LOG_USER("target halted due to %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
- Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
- R(CPSR),
- R(PC));
+ retval = armv4_5_arch_state(target);
- return ERROR_OK;
+ /* REVISIT also display ARM11-specific MMU and cache status ... */
+
+ return retval;
}
/* target request support */
@@ -1067,31 +1078,6 @@ static int arm11_soft_reset_halt(struct target *target)
return ERROR_FAIL;
}
-/* target register access for gdb */
-static int arm11_get_gdb_reg_list(struct target *target,
- struct reg **reg_list[], int *reg_list_size)
-{
- struct arm11_common *arm11 = target_to_arm11(target);
-
- *reg_list_size = ARM11_GDB_REGISTER_COUNT;
- *reg_list = malloc(sizeof(struct reg*) * ARM11_GDB_REGISTER_COUNT);
-
- /* nine unused legacy FPA registers are expected by GDB */
- for (size_t i = 16; i < 24; i++)
- (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
- (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
-
- for (size_t i = 0; i < ARM11_REGCACHE_COUNT; i++)
- {
- if (arm11_reg_defs[i].gdb_num == -1)
- continue;
-
- (*reg_list)[arm11_reg_defs[i].gdb_num] = arm11->reg_list + i;
- }
-
- return ERROR_OK;
-}
-
/* target memory access
* size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
* count: number of items of <size>
@@ -1633,6 +1619,8 @@ static int arm11_examine(struct target *target)
uint32_t didr, device_id;
uint8_t implementor;
+ /* FIXME split into do-first-time and do-every-time logic ... */
+
/* check IDCODE */
arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);
@@ -1705,6 +1693,14 @@ static int arm11_examine(struct target *target)
if (retval != ERROR_OK)
return retval;
+ /* Build register cache "late", after target_init(), since we
+ * want to know if this core supports Secure Monitor mode.
+ */
+ if (!target_was_examined(target)) {
+ arm11_dpm_init(arm11, didr);
+ retval = arm_dpm_setup(&arm11->dpm);
+ }
+
/* ETM on ARM11 still uses original scanchain 6 access mode */
if (arm11->arm.etm && !target_was_examined(target)) {
*register_get_last_cache_p(&target->reg_cache) =
@@ -1980,7 +1976,7 @@ struct target_type arm11_target = {
.deassert_reset = arm11_deassert_reset,
.soft_reset_halt = arm11_soft_reset_halt,
- .get_gdb_reg_list = arm11_get_gdb_reg_list,
+ .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
.read_memory = arm11_read_memory,
.write_memory = arm11_write_memory,