]> git.sur5r.net Git - openocd/commitdiff
ARM: simplify ARMv7-A register handling
authorDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 18 Nov 2009 22:46:14 +0000 (14:46 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 18 Nov 2009 22:46:14 +0000 (14:46 -0800)
ARMv7-A doesn't need to duplicate all the standard ARM code
for register handling.

 - Switch Cortex-A8 to use the standard register code
 - Remove duplicated infrastructure from ARMv7-A
 - Have ARMv7-A arch_state() show CPSR, like other ARMs

Add comments to show where the Cortex-A8 isn't actually doing
the right thing for register reads/writes, unless core happens
to be in the right mode to start with.  (Looks like maybe there
may be generic confusion between saved/current PSR values in all
the ARM code ...)

Make related ARMv7-A and Cortex-A8 symbols properly static.

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

index e13b33b4e04ff667c995d67a7012ee9be9b48b5b..6aa9d2f57010abdbde433c752982253e39ad0dc3 100644 (file)
 #include <unistd.h>
 
 
-char* armv7a_core_reg_list[] =
-{
-       "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-       "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
-       "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
-       "r13_irq", "lr_irq",
-       "r13_svc", "lr_svc",
-       "r13_abt", "lr_abt",
-       "r13_und", "lr_und",
-       "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
-       "r13_mon", "lr_mon", "spsr_mon"
-};
-
-char* armv7a_state_strings[] =
+static const char *armv7a_state_strings[] =
 {
        "ARM", "Thumb", "Jazelle", "ThumbEE"
 };
 
-struct armv7a_core_reg armv7a_core_reg_list_arch_info[] =
-{
-       {0, ARMV4_5_MODE_ANY, NULL, NULL},
-       {1, ARMV4_5_MODE_ANY, NULL, NULL},
-       {2, ARMV4_5_MODE_ANY, NULL, NULL},
-       {3, ARMV4_5_MODE_ANY, NULL, NULL},
-       {4, ARMV4_5_MODE_ANY, NULL, NULL},
-       {5, ARMV4_5_MODE_ANY, NULL, NULL},
-       {6, ARMV4_5_MODE_ANY, NULL, NULL},
-       {7, ARMV4_5_MODE_ANY, NULL, NULL},
-       {8, ARMV4_5_MODE_ANY, NULL, NULL},
-       {9, ARMV4_5_MODE_ANY, NULL, NULL},
-       {10, ARMV4_5_MODE_ANY, NULL, NULL},
-       {11, ARMV4_5_MODE_ANY, NULL, NULL},
-       {12, ARMV4_5_MODE_ANY, NULL, NULL},
-       {13, ARMV4_5_MODE_USR, NULL, NULL},
-       {14, ARMV4_5_MODE_USR, NULL, NULL},
-       {15, ARMV4_5_MODE_ANY, NULL, NULL},
-
-       {8, ARMV4_5_MODE_FIQ, NULL, NULL},
-       {9, ARMV4_5_MODE_FIQ, NULL, NULL},
-       {10, ARMV4_5_MODE_FIQ, NULL, NULL},
-       {11, ARMV4_5_MODE_FIQ, NULL, NULL},
-       {12, ARMV4_5_MODE_FIQ, NULL, NULL},
-       {13, ARMV4_5_MODE_FIQ, NULL, NULL},
-       {14, ARMV4_5_MODE_FIQ, NULL, NULL},
-
-       {13, ARMV4_5_MODE_IRQ, NULL, NULL},
-       {14, ARMV4_5_MODE_IRQ, NULL, NULL},
-
-       {13, ARMV4_5_MODE_SVC, NULL, NULL},
-       {14, ARMV4_5_MODE_SVC, NULL, NULL},
-
-       {13, ARMV4_5_MODE_ABT, NULL, NULL},
-       {14, ARMV4_5_MODE_ABT, NULL, NULL},
-
-       {13, ARMV4_5_MODE_UND, NULL, NULL},
-       {14, ARMV4_5_MODE_UND, NULL, NULL},
-
-       {16, ARMV4_5_MODE_ANY, NULL, NULL},
-       {16, ARMV4_5_MODE_FIQ, NULL, NULL},
-       {16, ARMV4_5_MODE_IRQ, NULL, NULL},
-       {16, ARMV4_5_MODE_SVC, NULL, NULL},
-       {16, ARMV4_5_MODE_ABT, NULL, NULL},
-       {16, ARMV4_5_MODE_UND, NULL, NULL},
-
-       {13, ARMV7A_MODE_MON, NULL, NULL},
-       {14, ARMV7A_MODE_MON, NULL, NULL},
-       {16, ARMV7A_MODE_MON, NULL, NULL}
-};
-
-/* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
-int armv7a_core_reg_map[8][17] =
-{
-       {       /* USR */
-               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
-       },
-       {       /* FIQ */
-               0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
-       },
-       {       /* IRQ */
-               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
-       },
-       {       /* SVC */
-               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
-       },
-       {       /* ABT */
-               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
-       },
-       {       /* UND */
-               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
-       },
-       {       /* SYS */
-               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
-       },
-       {       /* MON */
-               /* TODO Fix the register mapping for mon, we need r13_mon,
-                * r14_mon and spsr_mon
-                */
-               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
-       }
-};
-
-void armv7a_show_fault_registers(struct target *target)
+static void armv7a_show_fault_registers(struct target *target)
 {
        uint32_t dfsr, ifsr, dfar, ifar;
        struct armv7a_common *armv7a = target_to_armv7a(target);
@@ -169,16 +73,14 @@ int armv7a_arch_state(struct target *target)
        }
 
        LOG_USER("target halted in %s state due to %s, current mode: %s\n"
-                        "%s: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\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],
                 Jim_Nvp_value2name_simple(nvp_target_debug_reason,
                                target->debug_reason)->name,
                 arm_mode_name(armv4_5->core_mode),
-                armv7a_core_reg_list[armv7a_core_reg_map[
-                       armv7a_mode_to_number(armv4_5->core_mode)][16]],
-                buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
-                               armv4_5->core_mode, 16).value, 0, 32),
+                buf_get_u32(armv4_5->core_cache
+                               ->reg_list[ARMV4_5_CPSR].value, 0, 32),
                 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
                 state[armv7a->armv4_5_mmu.mmu_enabled],
                 state[armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
index e781e72070abdcdca11a8b7630861bb445c46972..b0083619fd0de888956bdf7ee045ae01609d181f 100644 (file)
@@ -45,15 +45,6 @@ typedef enum armv7a_state
        ARMV7A_STATE_THUMBEE,
 } armv7a_state_t;
 
-extern char *armv7a_state_strings[];
-
-extern int armv7a_core_reg_map[8][17];
-
-#define ARMV7A_CORE_REG_MODE(cache, mode, num) \
-               cache->reg_list[armv7a_core_reg_map[armv7a_mode_to_number(mode)][num]]
-#define ARMV7A_CORE_REG_MODENUM(cache, mode, num) \
-               cache->reg_list[armv7a_core_reg_map[mode][num]]
-
 enum
 {
        ARM_PC  = 15,
@@ -102,9 +93,6 @@ struct armv7a_common
        struct armv4_5_mmu_common armv4_5_mmu;
        struct arm armv4_5_common;
 
-//     int (*full_context)(struct target *target);
-//     int (*read_core_reg)(struct target *target, int num, enum armv7a_mode mode);
-//     int (*write_core_reg)(struct target *target, int num, enum armv7a_mode mode, u32 value);
        int (*read_cp15)(struct target *target,
                        uint32_t op1, uint32_t op2,
                        uint32_t CRn, uint32_t CRm, uint32_t *value);
@@ -149,44 +137,4 @@ struct reg_cache *armv7a_build_reg_cache(struct target *target,
 int armv7a_register_commands(struct command_context *cmd_ctx);
 int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a);
 
-/* map psr mode bits to linear number */
-static inline int armv7a_mode_to_number(enum armv7a_mode mode)
-{
-       switch (mode)
-       {
-               case ARMV7A_MODE_USR: return 0; break;
-               case ARMV7A_MODE_FIQ: return 1; break;
-               case ARMV7A_MODE_IRQ: return 2; break;
-               case ARMV7A_MODE_SVC: return 3; break;
-               case ARMV7A_MODE_ABT: return 4; break;
-               case ARMV7A_MODE_UND: return 5; break;
-               case ARMV7A_MODE_SYS: return 6; break;
-               case ARMV7A_MODE_MON: return 7; break;
-               case ARMV7A_MODE_ANY: return 0; break;  /* map MODE_ANY to user mode */
-               default:
-                       LOG_ERROR("invalid mode value encountered, val %d", mode);
-                       return -1;
-       }
-}
-
-/* map linear number to mode bits */
-static inline enum armv7a_mode armv7a_number_to_mode(int number)
-{
-       switch(number)
-       {
-               case 0: return ARMV7A_MODE_USR; break;
-               case 1: return ARMV7A_MODE_FIQ; break;
-               case 2: return ARMV7A_MODE_IRQ; break;
-               case 3: return ARMV7A_MODE_SVC; break;
-               case 4: return ARMV7A_MODE_ABT; break;
-               case 5: return ARMV7A_MODE_UND; break;
-               case 6: return ARMV7A_MODE_SYS; break;
-               case 7: return ARMV7A_MODE_MON; break;
-               default:
-                       LOG_ERROR("mode index out of bounds");
-                       return ARMV7A_MODE_ANY;
-       }
-};
-
-
 #endif /* ARMV4_5_H */
index f8ff3920e3eff553ec28ba52960bf9ce423e9355..b69f182580280536ecf617996c1b9c572f6c0908 100644 (file)
@@ -242,16 +242,18 @@ static int cortex_a8_dap_read_coreregister_u32(struct target *target,
 
        if (reg < 15)
        {
-               /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0,  0xEE000E15 */
+               /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0"  0xEE00nE15 */
                cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, reg, 0, 5, 0));
        }
        else if (reg == 15)
        {
+               /* "MOV r0, r15"; then move r0 to DCCTX */
                cortex_a8_exec_opcode(target, 0xE1A0000F);
                cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
        }
        else if (reg == 16)
        {
+               /* "MRS r0, CPSR"; then move r0 to DCCTX */
                cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, 0));
                cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
        }
@@ -480,7 +482,7 @@ static int cortex_a8_resume(struct target *target, int current,
 
        /* current = 1: continue on current pc, otherwise continue at <address> */
        resume_pc = buf_get_u32(
-                       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).value,
                        0, 32);
        if (!current)
@@ -501,12 +503,12 @@ static int cortex_a8_resume(struct target *target, int current,
                resume_pc |= 0x1;
        }
        LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
-       buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).value,
                        0, 32, resume_pc);
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                        armv4_5->core_mode, 15).dirty = 1;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                        armv4_5->core_mode, 15).valid = 1;
 
        cortex_a8_restore_context(target);
@@ -627,19 +629,23 @@ static int cortex_a8_debug_entry(struct target *target)
 
        for (i = 0; i <= ARM_PC; i++)
        {
-               buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, i).value,
                                0, 32, regfile[i]);
-               ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, i).valid = 1;
-               ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, i).dirty = 0;
        }
-       buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+
+       /* 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);
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
+       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;
 
        /* Fixup PC Resume Address */
        if (armv7a->core_state == ARMV7A_STATE_THUMB)
@@ -652,15 +658,15 @@ static int cortex_a8_debug_entry(struct target *target)
                // ARM state
                regfile[ARM_PC] -= 8;
        }
-       buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, ARM_PC).value,
                        0, 32, regfile[ARM_PC]);
 
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
-               .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
+               .dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 0).valid;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
-               .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
+               .dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).valid;
 
 #if 0
@@ -738,13 +744,13 @@ static int cortex_a8_step(struct target *target, int current, uint32_t address,
        /* current = 1: continue on current pc, otherwise continue at <address> */
        if (!current)
        {
-               buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, ARM_PC).value,
                                0, 32, address);
        }
        else
        {
-               address = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               address = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, ARM_PC).value,
                                0, 32);
        }
@@ -756,7 +762,8 @@ static int cortex_a8_step(struct target *target, int current, uint32_t address,
        handle_breakpoints = 1;
        if (handle_breakpoints) {
                breakpoint = breakpoint_find(target,
-                               buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                               buf_get_u32(ARMV4_5_CORE_REG_MODE(
+                                       armv4_5->core_cache,
                                        armv4_5->core_mode, 15).value,
                        0, 32));
                if (breakpoint)
@@ -812,10 +819,11 @@ static int cortex_a8_restore_context(struct target *target)
 
        for (i = 15; i >= 0; i--)
        {
-               if (ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, i).dirty)
                {
-                       value = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       value = buf_get_u32(ARMV4_5_CORE_REG_MODE(
+                                               armv4_5->core_cache,
                                                armv4_5->core_mode, i).value,
                                        0, 32);
                        /* TODO Check return values */
@@ -859,13 +867,13 @@ static int cortex_a8_load_core_reg_u32(struct target *target, int num,
 
        /* Register other than r0 - r14 uses r0 for access */
        if (num > 14)
-               ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 0).dirty =
-                       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 0).valid;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).dirty =
-                       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).valid;
 
        return ERROR_OK;
@@ -895,9 +903,9 @@ static int cortex_a8_store_core_reg_u32(struct target *target, int num,
                if (retval != ERROR_OK)
                {
                        LOG_ERROR("JTAG failure %i", retval);
-                       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, num).dirty =
-                               ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, num).valid;
                        return ERROR_JTAG_DEVICE_ERROR;
                }
@@ -920,6 +928,8 @@ static int cortex_a8_read_core_reg(struct target *target, int num,
        int retval;
        struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
+       /* FIXME cortex may not be in "mode" ... */
+
        cortex_a8_dap_read_coreregister_u32(target, &value, num);
 
        if ((retval = jtag_execute_queue()) != ERROR_OK)
@@ -927,28 +937,30 @@ static int cortex_a8_read_core_reg(struct target *target, int num,
                return retval;
        }
 
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
-       buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
+       buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                        mode, num).value, 0, 32, value);
 
        return ERROR_OK;
 }
 
-int cortex_a8_write_core_reg(struct target *target, int num,
+static int cortex_a8_write_core_reg(struct target *target, int num,
                enum armv4_5_mode mode, uint32_t value)
 {
        int retval;
        struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
+       /* FIXME cortex may not be in "mode" ... */
+
        cortex_a8_dap_write_coreregister_u32(target, value, num);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
                return retval;
        }
 
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
 
        return ERROR_OK;
 }