diff options
-rw-r--r-- | src/target/armv4_5.c | 2 | ||||
-rw-r--r-- | src/target/armv4_5.h | 1 | ||||
-rw-r--r-- | src/target/armv7a.c | 7 | ||||
-rw-r--r-- | src/target/armv7a.h | 14 | ||||
-rw-r--r-- | src/target/cortex_a8.c | 50 |
5 files changed, 43 insertions, 31 deletions
diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 6c6f2bfe..5e882e67 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -227,7 +227,7 @@ enum armv4_5_mode armv4_5_number_to_mode(int number) char* armv4_5_state_strings[] = { - "ARM", "Thumb", "Jazelle" + "ARM", "Thumb", "Jazelle", "ThumbEE", }; static const struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] = diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h index e3d053c9..6b1dd769 100644 --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -52,6 +52,7 @@ typedef enum armv4_5_state ARMV4_5_STATE_ARM, ARMV4_5_STATE_THUMB, ARMV4_5_STATE_JAZELLE, + ARM_STATE_THUMB_EE, } armv4_5_state_t; extern char* armv4_5_state_strings[]; diff --git a/src/target/armv7a.c b/src/target/armv7a.c index 98e3fa3f..ea883c16 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -34,11 +34,6 @@ #include <unistd.h> -static const char *armv7a_state_strings[] = -{ - "ARM", "Thumb", "Jazelle", "ThumbEE" -}; - static void armv7a_show_fault_registers(struct target *target) { uint32_t dfsr, ifsr, dfar, ifar; @@ -75,7 +70,7 @@ int armv7a_arch_state(struct target *target) LOG_USER("target halted in %s state due to %s, current mode: %s\n" "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n" "MMU: %s, D-Cache: %s, I-Cache: %s", - armv7a_state_strings[armv7a->core_state], + armv4_5_state_strings[armv4_5->core_state], Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name, arm_mode_name(armv4_5->core_mode), diff --git a/src/target/armv7a.h b/src/target/armv7a.h index f31a7af8..635cd40e 100644 --- a/src/target/armv7a.h +++ b/src/target/armv7a.h @@ -24,15 +24,6 @@ #include "armv4_5_mmu.h" #include "armv4_5_cache.h" - -typedef enum armv7a_state -{ - ARMV7A_STATE_ARM, - ARMV7A_STATE_THUMB, - ARMV7A_STATE_JAZELLE, - ARMV7A_STATE_THUMBEE, -} armv7a_state_t; - enum { ARM_PC = 15, @@ -64,9 +55,9 @@ enum struct armv7a_common { + struct arm armv4_5_common; int common_magic; struct reg_cache *core_cache; - enum armv7a_state core_state; /* arm adp debug port */ struct swjdp_common swjdp_info; @@ -78,7 +69,6 @@ struct armv7a_common /* Cache and Memory Management Unit */ struct armv4_5_mmu_common armv4_5_mmu; - struct arm armv4_5_common; int (*read_cp15)(struct target *target, uint32_t op1, uint32_t op2, @@ -107,7 +97,7 @@ struct armv7a_algorithm int common_magic; enum armv4_5_mode core_mode; - enum armv7a_state core_state; + enum armv4_5_state core_state; }; struct armv7a_core_reg diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c index fc788446..d62740c2 100644 --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -491,16 +491,21 @@ static int cortex_a8_resume(struct target *target, int current, /* 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, @@ -630,9 +635,29 @@ static int cortex_a8_debug_entry(struct target *target) 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; @@ -651,7 +676,7 @@ static int cortex_a8_debug_entry(struct target *target) } /* 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; @@ -775,7 +800,8 @@ static int cortex_a8_step(struct target *target, int current, uint32_t address, /* 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; |