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);
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);
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);
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;
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;
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))
{
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);
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);
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;
}
/**
/* 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;
}
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;
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++)
{
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))
{