/* Make sure that the Armv7 gdb thumb fixups does not
* kill the return address
*/
- if (armv7a->core_state == ARMV7A_STATE_ARM)
+ switch (armv4_5->core_state)
{
+ case ARMV4_5_STATE_ARM:
resume_pc &= 0xFFFFFFFC;
- }
- /* When the return address is loaded into PC
- * bit 0 must be 1 to stay in Thumb state
- */
- if (armv7a->core_state == ARMV7A_STATE_THUMB)
- {
+ break;
+ case ARMV4_5_STATE_THUMB:
+ case ARM_STATE_THUMB_EE:
+ /* When the return address is loaded into PC
+ * bit 0 must be 1 to stay in Thumb state
+ */
resume_pc |= 0x1;
+ break;
+ case ARMV4_5_STATE_JAZELLE:
+ LOG_ERROR("How do I resume into Jazelle state??");
+ return ERROR_FAIL;
}
LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
target->state = TARGET_RUNNING;
/* registers are now invalid */
- armv4_5_invalidate_core_regs(target);
+ register_cache_invalidate(armv4_5->core_cache);
if (!debug_execution)
{
struct armv7a_common *armv7a = target_to_armv7a(target);
struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
struct swjdp_common *swjdp = &armv7a->swjdp_info;
+ struct reg *reg;
LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
/* First load register acessible through core debug port*/
if (!regfile_working_area)
{
+ /* FIXME we don't actually need all these registers;
+ * reading them slows us down. Just R0, PC, CPSR...
+ */
for (i = 0; i <= 15; i++)
cortex_a8_dap_read_coreregister_u32(target,
®file[i], i);
target_free_working_area(target, regfile_working_area);
}
+ /* read Current PSR */
cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16);
pc = regfile[15];
dap_ap_select(swjdp, swjdp_debugap);
LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr);
armv4_5->core_mode = cpsr & 0x1F;
- armv7a->core_state = (cpsr & 0x20)?ARMV7A_STATE_THUMB:ARMV7A_STATE_ARM;
+
+ 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 */
+ reg = armv4_5->core_cache->reg_list + ARMV4_5_CPSR;
+ buf_set_u32(reg->value, 0, 32, cpsr);
+ reg->valid = 1;
+ reg->dirty = 0;
for (i = 0; i <= ARM_PC; i++)
{
- buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
- armv4_5->core_mode, i).value,
- 0, 32, regfile[i]);
- ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
- armv4_5->core_mode, i).valid = 1;
- ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
- armv4_5->core_mode, i).dirty = 0;
- }
+ reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+ armv4_5->core_mode, i);
- /* FIXME for exception states, this caches CPSR as SPSR!! */
- buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
- armv4_5->core_mode, 16).value,
- 0, 32, cpsr);
- ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
- armv4_5->core_mode, 16).valid = 1;
- ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
- armv4_5->core_mode, 16).dirty = 0;
+ buf_set_u32(reg->value, 0, 32, regfile[i]);
+ reg->valid = 1;
+ reg->dirty = 0;
+ }
/* Fixup PC Resume Address */
- if (armv7a->core_state == ARMV7A_STATE_THUMB)
+ if (cpsr & (1 << 5))
{
// T bit set for Thumb or ThumbEE state
regfile[ARM_PC] -= 4;
/* Setup single step breakpoint */
stepbreakpoint.address = address;
- stepbreakpoint.length = (armv7a->core_state == ARMV7A_STATE_THUMB) ? 2 : 4;
+ stepbreakpoint.length = (armv4_5->core_state == ARMV4_5_STATE_THUMB)
+ ? 2 : 4;
stepbreakpoint.type = BKPT_HARD;
stepbreakpoint.set = 0;
static int cortex_a8_assert_reset(struct target *target)
{
+ struct armv7a_common *armv7a = target_to_armv7a(target);
LOG_DEBUG(" ");
/* registers are now invalid */
- armv4_5_invalidate_core_regs(target);
+ register_cache_invalidate(armv7a->armv4_5_common.core_cache);
target->state = TARGET_RESET;
* Cortex-A8 target information and configuration
*/
-static int cortex_a8_examine(struct target *target)
+static int cortex_a8_examine_first(struct target *target)
{
struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
cortex_a8->brp_num , cortex_a8->wrp_num);
- /* Configure core debug access */
- cortex_a8_init_debug_access(target);
-
target_set_examined(target);
+ return ERROR_OK;
+}
+
+static int cortex_a8_examine(struct target *target)
+{
+ int retval = ERROR_OK;
+
+ /* don't re-probe hardware after each reset */
+ if (!target_was_examined(target))
+ retval = cortex_a8_examine_first(target);
+
+ /* Configure core debug access */
+ if (retval == ERROR_OK)
+ retval = cortex_a8_init_debug_access(target);
return retval;
}
struct arm *armv4_5 = &armv7a->armv4_5_common;
struct swjdp_common *swjdp = &armv7a->swjdp_info;
- /* REVISIT v7a setup should be in a v7a-specific routine */
- armv4_5_init_arch_info(target, armv4_5);
- armv7a->common_magic = ARMV7_COMMON_MAGIC;
-
/* Setup struct cortex_a8_common */
cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
armv4_5->arch_info = armv7a;
armv4_5->read_core_reg = cortex_a8_read_core_reg;
armv4_5->write_core_reg = cortex_a8_write_core_reg;
-// armv4_5->full_context = arm7_9_full_context;
-// armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
-// armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
-// armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
-// armv4_5->write_core_reg = armv4_5_write_core_reg;
+ /* REVISIT v7a setup should be in a v7a-specific routine */
+ armv4_5_init_arch_info(target, armv4_5);
+ armv7a->common_magic = ARMV7_COMMON_MAGIC;
target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);