summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/target/armv4_5.c2
-rw-r--r--src/target/armv4_5.h1
-rw-r--r--src/target/armv7a.c7
-rw-r--r--src/target/armv7a.h14
-rw-r--r--src/target/cortex_a8.c50
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;