Change the layout to show the "Secure Monitor" registers too,
when they're present.

Instead of lining registers for each of six (or seven) modes up 
in adjacent vertical columns, display each mode's registers (or
shadows) in a single block, avoiding duplicate value displays.

This also lets us shrink the line length to fits in standard 80
character lines ... six or seven 18-character columns can't fit.

Relabel "r13" as "sp", so it's more meaningful.
---
Merged this ... sample output, from an ARM9 (without support
for the Secure Monitor mode):

> arm reg
System and User mode registers
      r0: 000003e8       r1: 00ff8000       r2: 00000601       r3: 00002800 
      r4: 00000010       r5: 01e11000       r6: 00000001       r7: 01e11000 
      r8: 00000001       r9: 00000002      r10: 00000237      r11: 00ff8000 
     r12: 0000023a   sp_usr: 90390944   lr_usr: 238440a9       pc: 00008000 
    cpsr: 000000d3 

FIQ mode shadow registers
  r8_fiq: 601100a2   r9_fiq: 740f0188  r10_fiq: d1d683b4  r11_fiq: 496c1a00 
 r12_fiq: 310549ea   sp_fiq: 00007ffc   lr_fiq: 0000987c spsr_fiq: 00000010 

Supervisor mode shadow registers
  sp_svc: 00007f24   lr_svc: 00008a20 spsr_svc: 00000010 

Abort mode shadow registers
  sp_abt: 40480085   lr_abt: 4409025c spsr_abt: 00000010 

IRQ mode shadow registers
  sp_irq: 2a720808   lr_irq: 0f8e11c4 spsr_irq: 00000010 

Undefined instruction mode shadow registers
  sp_und: 2f2082f0   lr_und: 2186812c spsr_und: 00000010 
> 

 src/target/armv4_5.c |  148 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 113 insertions(+), 35 deletions(-)

--- a/src/target/armv4_5.c
+++ b/src/target/armv4_5.c
@@ -39,26 +39,59 @@
 static const char *armv4_5_core_reg_list[] =
 {
        "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-       "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
+       "r8", "r9", "r10", "r11", "r12", "sp_usr", "lr_usr", "pc",
 
-       "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", 
"lr_fiq",
+       "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq", "lr_fiq",
 
-       "r13_irq", "lr_irq",
+       "sp_irq", "lr_irq",
 
-       "r13_svc", "lr_svc",
+       "sp_svc", "lr_svc",
 
-       "r13_abt", "lr_abt",
+       "sp_abt", "lr_abt",
 
-       "r13_und", "lr_und",
+       "sp_und", "lr_und",
 
        "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
 
-       "r13_mon", "lr_mon", "spsr_mon",
+       "sp_mon", "lr_mon", "spsr_mon",
+};
+
+static const uint8_t arm_usr_indices[17] = {
+       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ARMV4_5_CPSR,
+};
+
+static const uint8_t arm_fiq_indices[8] = {
+       16, 17, 18, 19, 20, 21, 22, ARMV4_5_SPSR_FIQ,
+};
+
+static const uint8_t arm_irq_indices[3] = {
+       23, 24, ARMV4_5_SPSR_IRQ,
+};
+
+static const uint8_t arm_svc_indices[3] = {
+       25, 26, ARMV4_5_SPSR_SVC,
+};
+
+static const uint8_t arm_abt_indices[3] = {
+       27, 28, ARMV4_5_SPSR_ABT,
+};
+
+static const uint8_t arm_und_indices[3] = {
+       29, 30, ARMV4_5_SPSR_UND,
+};
+
+static const uint8_t arm_mon_indices[3] = {
+       37, 38, ARM_SPSR_MON,
 };
 
 static const struct {
        const char *name;
-       unsigned psr;
+       unsigned short psr;
+       /* For user and system modes, these list indices for all registers.
+        * otherwise they're just indices for the shadow registers and SPSR.
+        */
+       unsigned short n_indices;
+       const uint8_t *indices;
 } arm_mode_data[] = {
        /* Seven modes are standard from ARM7 on. "System" and "User" share
         * the same registers; other modes shadow from 3 to 8 registers.
@@ -66,30 +99,44 @@ static const struct {
        {
                .name = "User",
                .psr = ARMV4_5_MODE_USR,
+               .n_indices = ARRAY_SIZE(arm_usr_indices),
+               .indices = arm_usr_indices,
        },
        {
                .name = "FIQ",
                .psr = ARMV4_5_MODE_FIQ,
+               .n_indices = ARRAY_SIZE(arm_fiq_indices),
+               .indices = arm_fiq_indices,
        },
        {
                .name = "Supervisor",
                .psr = ARMV4_5_MODE_SVC,
+               .n_indices = ARRAY_SIZE(arm_svc_indices),
+               .indices = arm_svc_indices,
        },
        {
                .name = "Abort",
                .psr = ARMV4_5_MODE_ABT,
+               .n_indices = ARRAY_SIZE(arm_abt_indices),
+               .indices = arm_abt_indices,
        },
        {
                .name = "IRQ",
                .psr = ARMV4_5_MODE_IRQ,
+               .n_indices = ARRAY_SIZE(arm_irq_indices),
+               .indices = arm_irq_indices,
        },
        {
-               .name = "Undefined" /* instruction */,
+               .name = "Undefined instruction",
                .psr = ARMV4_5_MODE_UND,
+               .n_indices = ARRAY_SIZE(arm_und_indices),
+               .indices = arm_und_indices,
        },
        {
                .name = "System",
                .psr = ARMV4_5_MODE_SYS,
+               .n_indices = ARRAY_SIZE(arm_usr_indices),
+               .indices = arm_usr_indices,
        },
        /* TrustZone "Security Extensions" add a secure monitor mode.
         * This is distinct from a "debug monitor" which can support
@@ -98,6 +145,8 @@ static const struct {
        {
                .name = "Secure Monitor",
                .psr = ARM_MODE_MON,
+               .n_indices = ARRAY_SIZE(arm_mon_indices),
+               .indices = arm_mon_indices,
        },
 };
 
@@ -461,11 +510,10 @@ int armv4_5_arch_state(struct target *ta
 
 COMMAND_HANDLER(handle_armv4_5_reg_command)
 {
-       char output[128];
-       int output_len;
-       int mode, num;
        struct target *target = get_current_target(CMD_CTX);
        struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
+       unsigned num_regs;
+       struct reg *regs;
 
        if (!is_arm(armv4_5))
        {
@@ -476,7 +524,7 @@ COMMAND_HANDLER(handle_armv4_5_reg_comma
        if (target->state != TARGET_HALTED)
        {
                command_print(CMD_CTX, "error: target must be halted for 
register accesses");
-               return ERROR_OK;
+               return ERROR_FAIL;
        }
 
        if (!is_arm_mode(armv4_5->core_mode))
@@ -488,31 +536,61 @@ COMMAND_HANDLER(handle_armv4_5_reg_comma
                return ERROR_FAIL;
        }
 
-       for (num = 0; num <= 15; num++)
-       {
-               output_len = 0;
-               for (mode = 0; mode < 6; mode++)
-               {
-                       if (!ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, 
mode, num).valid)
-                       {
-                               armv4_5->full_context(target);
-                       }
-                       output_len += snprintf(output + output_len,
-                                              128 - output_len,
+       num_regs = armv4_5->core_cache->num_regs;
+       regs = armv4_5->core_cache->reg_list;
+
+       for (unsigned mode = 0; mode < ARRAY_SIZE(arm_mode_data); mode++) {
+               const char *name;
+               char *sep = "\n";
+               char *shadow = "";
+
+               /* label this bank of registers (or shadows) */
+               switch (arm_mode_data[mode].psr) {
+               case ARMV4_5_MODE_SYS:
+                       continue;
+               case ARMV4_5_MODE_USR:
+                       name = "System and User";
+                       sep = "";
+                       break;
+               case ARM_MODE_MON:
+                       if (armv4_5->core_type != ARM_MODE_MON)
+                               continue;
+                       /* FALLTHROUGH */
+               default:
+                       name = arm_mode_data[mode].name;
+                       shadow = "shadow ";
+                       break;
+               }
+               command_print(CMD_CTX, "%s%s mode %sregisters",
+                               sep, name, shadow);
+
+               /* display N rows of up to 4 registers each */
+               for (unsigned i = 0; i < arm_mode_data[mode].n_indices;) {
+                       char output[80];
+                       int output_len = 0;
+
+                       for (unsigned j = 0; j < 4; j++, i++) {
+                               uint32_t value;
+                               struct reg *reg = regs;
+
+                               if (i >= arm_mode_data[mode].n_indices)
+                                       break;
+
+                               reg += arm_mode_data[mode].indices[i];
+
+                               /* REVISIT be smarter about faults... */
+                               if (!reg->valid)
+                                       armv4_5->full_context(target);
+
+                               value = buf_get_u32(reg->value, 0, 32);
+                               output_len += snprintf(output + output_len,
+                                               sizeof(output) - output_len,
                                               "%8s: %8.8" PRIx32 " ",
-                                              
ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
-                                              
buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 
32));
+                                              reg->name, value);
+                       }
+                       command_print(CMD_CTX, "%s", output);
                }
-               command_print(CMD_CTX, "%s", output);
        }
-       command_print(CMD_CTX,
-                     "    cpsr: %8.8" PRIx32 " spsr_fiq: %8.8" PRIx32 " 
spsr_irq: %8.8" PRIx32 " spsr_svc: %8.8" PRIx32 " spsr_abt: %8.8" PRIx32 " 
spsr_und: %8.8" PRIx32 "",
-                         
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
-                         
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
-                         
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
-                         
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
-                         
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
-                         
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
 
        return ERROR_OK;
 }
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to