summaryrefslogtreecommitdiff
path: root/src/target/armv4_5.c
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-11-22 03:41:14 -0800
committerDavid Brownell <dbrownell@users.sourceforge.net>2009-11-22 03:41:14 -0800
commitdd9894f481d127266c201d7075ecbdd34b034124 (patch)
treef96d110f7d54368b9435fc9d96018a21c51bfcf0 /src/target/armv4_5.c
parentff810723e051ed1f86cffcb565ade6b4d1fc50c8 (diff)
downloadopenocd+libswd-dd9894f481d127266c201d7075ecbdd34b034124.tar.gz
openocd+libswd-dd9894f481d127266c201d7075ecbdd34b034124.tar.bz2
openocd+libswd-dd9894f481d127266c201d7075ecbdd34b034124.tar.xz
openocd+libswd-dd9894f481d127266c201d7075ecbdd34b034124.zip
ARM: arm_set_cpsr() handles T and J bits
Have arm_set_cpsr() handle the two core state flags, updating the CPU state. This eliminates code in various debug_entry() paths, and marginally improves handling of the J bit. Catch and comment a few holes in the handling of the J bit on ARM926ejs cores ... it's unlikely our users will care about Jazelle mode, but we can at least warn of Impending Doom. If anyone does use it, these breadcrumbs may help them to find the right path through the code. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'src/target/armv4_5.c')
-rw-r--r--src/target/armv4_5.c67
1 files changed, 31 insertions, 36 deletions
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;