ARMv7-A: use standard ARM core states
authorDavid Brownell <dbrownell@users.sourceforge.net>
Thu, 19 Nov 2009 10:33:01 +0000 (02:33 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Thu, 19 Nov 2009 10:33:01 +0000 (02:33 -0800)
We don't want an ARMv7-specific core state enumeration just to
add ThumbEE state.  Update the generic stuff to handle that,
and replace the V7-specific bits with it.

For Cortex-A8:  on debug entry, check both the T and J bits
instead of just the T bit.  When the J bit is set, set the
right state and warn appropriately.

(And while we're at it, move the generic arm struct to the front
of the v7a structure, for somewhat better code generation.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
src/target/armv4_5.c
src/target/armv4_5.h
src/target/armv7a.c
src/target/armv7a.h
src/target/cortex_a8.c

index 6c6f2bfec581c6faff1ea8617b95e503f96183e8..5e882e67fb76406eaf5956edff49c54ea0df0bd4 100644 (file)
@@ -227,7 +227,7 @@ enum armv4_5_mode armv4_5_number_to_mode(int number)
 
 char* armv4_5_state_strings[] =
 {
 
 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[] =
 };
 
 static const struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] =
index e3d053c98295dcc1b5ca2feaaace593b2add9a92..6b1dd769d192c7ba87127bdd15b9d3073da86e3b 100644 (file)
@@ -52,6 +52,7 @@ typedef enum armv4_5_state
        ARMV4_5_STATE_ARM,
        ARMV4_5_STATE_THUMB,
        ARMV4_5_STATE_JAZELLE,
        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[];
 } armv4_5_state_t;
 
 extern char* armv4_5_state_strings[];
index 98e3fa3f23793d19e99806f00cd7413951c612f8..ea883c16d682ba294fe8ad8624a317f58f48d420 100644 (file)
 #include <unistd.h>
 
 
 #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;
 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",
        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),
                 Jim_Nvp_value2name_simple(nvp_target_debug_reason,
                                target->debug_reason)->name,
                 arm_mode_name(armv4_5->core_mode),
index f31a7af84ad97400720dbc98b1f181609ccab7c6..635cd40e639c8094cb3194572b4cd14eb416a383 100644 (file)
 #include "armv4_5_mmu.h"
 #include "armv4_5_cache.h"
 
 #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,
 enum
 {
        ARM_PC  = 15,
@@ -64,9 +55,9 @@ enum
 
 struct armv7a_common
 {
 
 struct armv7a_common
 {
+       struct arm armv4_5_common;
        int common_magic;
        struct reg_cache *core_cache;
        int common_magic;
        struct reg_cache *core_cache;
-       enum armv7a_state core_state;
 
        /* arm adp debug port */
        struct swjdp_common swjdp_info;
 
        /* 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;
 
        /* 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,
 
        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;
        int common_magic;
 
        enum armv4_5_mode core_mode;
-       enum armv7a_state core_state;
+       enum armv4_5_state core_state;
 };
 
 struct armv7a_core_reg
 };
 
 struct armv7a_core_reg
index fc788446f194874fc1288c90a4bb9ffb28117d69..d62740c2716294f922c11298b76c4f4b0f96275d 100644 (file)
@@ -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
         */
        /* 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;
                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;
                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,
        }
        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;
        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;
 
        /* 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 */
        }
 
        /* 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;
        {
                // 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;
 
        /* 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;
 
        stepbreakpoint.type = BKPT_HARD;
        stepbreakpoint.set = 0;
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)