summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/target/arm720t.c1
-rw-r--r--src/target/arm7_9_common.c32
-rw-r--r--src/target/arm920t.c1
-rw-r--r--src/target/arm926ejs.c1
-rw-r--r--src/target/armv4_5.c67
-rw-r--r--src/target/cortex_a8.c23
-rw-r--r--src/target/xscale.c6
7 files changed, 52 insertions, 79 deletions
diff --git a/src/target/arm720t.c b/src/target/arm720t.c
index ac7e4888..3aa77ea4 100644
--- a/src/target/arm720t.c
+++ b/src/target/arm720t.c
@@ -354,7 +354,6 @@ static int arm720t_soft_reset_halt(struct target *target)
cpsr |= 0xd3;
arm_set_cpsr(armv4_5, cpsr);
armv4_5->cpsr->dirty = 1;
- armv4_5->core_state = ARMV4_5_STATE_ARM;
/* start fetching from 0x0 */
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index 9580f62e..19fe98d8 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -1223,6 +1223,8 @@ int arm7_9_soft_reset_halt(struct target *target)
arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
}
+ /* REVISIT likewise for bit 5 -- switch Jazelle-to-ARM */
+
/* all register content is now invalid */
register_cache_invalidate(armv4_5->core_cache);
@@ -1234,7 +1236,6 @@ int arm7_9_soft_reset_halt(struct target *target)
cpsr |= 0xd3;
arm_set_cpsr(armv4_5, cpsr);
armv4_5->cpsr->dirty = 1;
- armv4_5->core_state = ARMV4_5_STATE_ARM;
/* start fetching from 0x0 */
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
@@ -1334,7 +1335,7 @@ static int arm7_9_debug_entry(struct target *target)
uint32_t context[16];
uint32_t* context_p[16];
uint32_t r0_thumb, pc_thumb;
- uint32_t cpsr;
+ uint32_t cpsr, cpsr_mask = 0;
int retval;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
@@ -1379,11 +1380,21 @@ static int arm7_9_debug_entry(struct target *target)
LOG_DEBUG("target entered debug from Thumb state");
/* Entered debug from Thumb mode */
armv4_5->core_state = ARMV4_5_STATE_THUMB;
+ cpsr_mask = 1 << 5;
arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
- LOG_DEBUG("r0_thumb: 0x%8.8" PRIx32 ", pc_thumb: 0x%8.8" PRIx32 "", r0_thumb, pc_thumb);
- }
- else
- {
+ LOG_DEBUG("r0_thumb: 0x%8.8" PRIx32
+ ", pc_thumb: 0x%8.8" PRIx32, r0_thumb, pc_thumb);
+ } else if (buf_get_u32(dbg_stat->value, 5, 1)) {
+ /* \todo Get some vaguely correct handling of Jazelle, if
+ * anyone ever uses it and full info becomes available.
+ * See ARM9EJS TRM B.7.1 for how to switch J->ARM; and
+ * B.7.3 for the reverse. That'd be the bare minimum...
+ */
+ LOG_DEBUG("target entered debug from Jazelle state");
+ armv4_5->core_state = ARMV4_5_STATE_JAZELLE;
+ cpsr_mask = 1 << 24;
+ LOG_ERROR("Jazelle debug entry -- BROKEN!");
+ } else {
LOG_DEBUG("target entered debug from ARM state");
/* Entered debug from ARM mode */
armv4_5->core_state = ARMV4_5_STATE_ARM;
@@ -1399,11 +1410,10 @@ static int arm7_9_debug_entry(struct target *target)
if ((retval = jtag_execute_queue()) != ERROR_OK)
return retval;
- /* if the core has been executing in Thumb state, set the T bit */
- if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
- cpsr |= 0x20;
-
- arm_set_cpsr(armv4_5, cpsr);
+ /* Sync our CPSR copy with J or T bits EICE reported, but
+ * which we then erased by putting the core into ARM mode.
+ */
+ arm_set_cpsr(armv4_5, cpsr | cpsr_mask);
if (!is_arm_mode(armv4_5->core_mode))
{
diff --git a/src/target/arm920t.c b/src/target/arm920t.c
index 739df3ea..8a03554f 100644
--- a/src/target/arm920t.c
+++ b/src/target/arm920t.c
@@ -603,7 +603,6 @@ int arm920t_soft_reset_halt(struct target *target)
cpsr |= 0xd3;
arm_set_cpsr(armv4_5, cpsr);
armv4_5->cpsr->dirty = 1;
- armv4_5->core_state = ARMV4_5_STATE_ARM;
/* start fetching from 0x0 */
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c
index 7ecc7824..aa299890 100644
--- a/src/target/arm926ejs.c
+++ b/src/target/arm926ejs.c
@@ -572,7 +572,6 @@ int arm926ejs_soft_reset_halt(struct target *target)
cpsr |= 0xd3;
arm_set_cpsr(armv4_5, cpsr);
armv4_5->cpsr->dirty = 1;
- armv4_5->core_state = ARMV4_5_STATE_ARM;
/* start fetching from 0x0 */
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c
index 3156c666..22e11869 100644
--- a/src/target/armv4_5.c
+++ b/src/target/armv4_5.c
@@ -372,6 +372,24 @@ void arm_set_cpsr(struct arm *arm, uint32_t cpsr)
arm->spsr = (mode == ARMV4_5_MODE_USR || mode == ARMV4_5_MODE_SYS)
? NULL
: arm->core_cache->reg_list + arm->map[16];
+
+ /* Older ARMs won't have the J bit */
+ enum armv4_5_state state;
+
+ if (cpsr & (1 << 5)) { /* T */
+ if (cpsr & (1 << 24)) { /* J */
+ LOG_WARNING("ThumbEE -- incomplete support");
+ state = ARM_STATE_THUMB_EE;
+ } else
+ state = ARMV4_5_STATE_THUMB;
+ } else {
+ if (cpsr & (1 << 24)) { /* J */
+ LOG_ERROR("Jazelle state handling is BROKEN!");
+ state = ARMV4_5_STATE_JAZELLE;
+ } else
+ state = ARMV4_5_STATE_ARM;
+ }
+ arm->core_state = state;
}
/**
@@ -481,49 +499,27 @@ static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
/* Except for CPSR, the "reg" command exposes a writeback model
* for the register cache.
*/
- buf_set_u32(reg->value, 0, 32, value);
- reg->dirty = 1;
- reg->valid = 1;
+ if (reg == armv4_5_target->cpsr) {
+ arm_set_cpsr(armv4_5_target, value);
- if (reg == armv4_5_target->cpsr)
- {
- /* FIXME handle J bit too; mostly for ThumbEE, also Jazelle */
- if (value & 0x20)
- {
- /* T bit should be set */
- if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
- {
- /* change state to Thumb */
- LOG_DEBUG("changing to Thumb state");
- armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
- }
- }
- else
- {
- /* T bit should be cleared */
- if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
- {
- /* change state to ARM */
- LOG_DEBUG("changing to ARM state");
- armv4_5_target->core_state = ARMV4_5_STATE_ARM;
- }
- }
-
- /* REVISIT Why only update core for mode change, not also
- * for state changes? Possibly older cores need to stay
- * in ARM mode during halt mode debug, not execute Thumb;
- * v6/v7a/v7r seem to do that automatically...
+ /* Older cores need help to be in ARM mode during halt
+ * mode debug, so we clear the J and T bits if we flush.
+ * For newer cores (v6/v7a/v7r) we don't need that, but
+ * it won't hurt since CPSR is always flushed anyway.
*/
-
- if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
- {
+ if (armv4_5_target->core_mode !=
+ (enum armv4_5_mode)(value & 0x1f)) {
LOG_DEBUG("changing ARM core mode to '%s'",
arm_mode_name(value & 0x1f));
+ value &= ~((1 << 24) | (1 << 5));
armv4_5_target->write_core_reg(target, reg,
16, ARMV4_5_MODE_ANY, value);
- arm_set_cpsr(armv4_5_target, value);
}
+ } else {
+ buf_set_u32(reg->value, 0, 32, value);
+ reg->valid = 1;
}
+ reg->dirty = 1;
return ERROR_OK;
}
@@ -1240,7 +1236,6 @@ int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
arm_set_cpsr(armv4_5, ARMV4_5_MODE_USR);
- armv4_5->core_state = ARMV4_5_STATE_ARM;
/* core_type may be overridden by subtype logic */
armv4_5->core_type = ARMV4_5_MODE_ANY;
diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index 71de3b79..fa26b6ab 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -650,29 +650,6 @@ static int cortex_a8_debug_entry(struct target *target)
arm_set_cpsr(armv4_5, cpsr);
- i = (cpsr >> 5) & 1; /* T */
- i |= (cpsr >> 23) & 1; /* J << 1 */
- switch (i) {
- case 0: /* J = 0, T = 0 */
- armv4_5->core_state = ARMV4_5_STATE_ARM;
- break;
- case 1: /* J = 0, T = 1 */
- armv4_5->core_state = ARMV4_5_STATE_THUMB;
- break;
- case 2: /* J = 1, T = 0 */
- LOG_WARNING("Jazelle state -- not handled");
- armv4_5->core_state = ARMV4_5_STATE_JAZELLE;
- break;
- case 3: /* J = 1, T = 1 */
- /* ThumbEE is very much like Thumb, but some of the
- * instructions are different. Single stepping and
- * breakpoints need updating...
- */
- LOG_WARNING("ThumbEE -- incomplete support");
- armv4_5->core_state = ARM_STATE_THUMB_EE;
- break;
- }
-
/* update cache */
for (i = 0; i <= ARM_PC; i++)
{
diff --git a/src/target/xscale.c b/src/target/xscale.c
index 659caec1..e8a3e49f 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -960,12 +960,6 @@ static int xscale_debug_entry(struct target *target)
LOG_DEBUG("target entered debug state in %s mode",
arm_mode_name(armv4_5->core_mode));
- if (buffer[9] & 0x20)
- armv4_5->core_state = ARMV4_5_STATE_THUMB;
- else
- armv4_5->core_state = ARMV4_5_STATE_ARM;
-
-
/* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS))
{