target/armv7m: rework Cortex-M register handling part 1
[fw/openocd] / src / target / arm_dpm.c
index f9b30c18722c8732d7d6db5934ac59ccec0f8041..6bfe355ba2e0ed50ea40c687b77dba32f802c8fe 100644 (file)
@@ -108,7 +108,7 @@ static int dpm_mcr(struct target *target, int cpnum,
 /* Toggles between recorded core mode (USR, SVC, etc) and a temporary one.
  * Routines *must* restore the original mode before returning!!
  */
-int dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
+int arm_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
 {
        int retval;
        uint32_t cpsr;
@@ -145,6 +145,9 @@ static int dpm_read_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
                        retval = dpm->instr_read_data_r0(dpm,
                                ARMV4_5_VMOV(1, 1, 0, ((regnum - ARM_VFP_V3_D0) >> 4),
                                ((regnum - ARM_VFP_V3_D0) & 0xf)), &value_r0);
+                       if (retval != ERROR_OK)
+                               break;
+
                        /* read r1 via dcc */
                        retval = dpm->instr_read_data_dcc(dpm,
                                ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
@@ -168,7 +171,7 @@ static int dpm_read_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
 }
 
 /* just read the register -- rely on the core mode being right */
-static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
+int arm_dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
 {
        uint32_t value;
        int retval;
@@ -203,13 +206,12 @@ static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
                                        LOG_WARNING("Jazelle PC adjustment unknown");
                                        break;
                                default:
-                                       LOG_WARNING("unknow core state");
+                                       LOG_WARNING("unknown core state");
                                        break;
                        }
                        break;
                case ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:
                        return dpm_read_reg_u64(dpm, r, regnum);
-                       break;
                case ARM_VFP_V3_FPSCR:
                        /* "VMRS r0, FPSCR"; then return via DCC */
                        retval = dpm->instr_read_data_r0(dpm,
@@ -248,6 +250,9 @@ static int dpm_write_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum
                        retval = dpm->instr_write_data_dcc(dpm,
                                ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
                                value_r1);
+                       if (retval != ERROR_OK)
+                               break;
+
                        /* write value_r0 to r0 via dcc then,
                         * move to double word register from r0:r1: "vmov vm, r0, r1"
                         */
@@ -288,7 +293,6 @@ static int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
                        break;
                case ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:
                        return dpm_write_reg_u64(dpm, r, regnum);
-                       break;
                case ARM_VFP_V3_FPSCR:
                        /* move to r0 from DCC, then "VMSR FPSCR, r0" */
                        retval = dpm->instr_write_data_r0(dpm,
@@ -331,7 +335,7 @@ static int dpm_write_pc_core_state(struct arm_dpm *dpm, struct reg *r)
 }
 
 /**
- * Read basic registers of the the current context:  R0 to R15, and CPSR;
+ * Read basic registers of the current context:  R0 to R15, and CPSR;
  * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
  * In normal operation this is called on entry to halting debug state,
  * possibly after some other operations supporting restore of debug state
@@ -352,7 +356,7 @@ int arm_dpm_read_current_registers(struct arm_dpm *dpm)
        for (unsigned i = 0; i < 2; i++) {
                r = arm->core_cache->reg_list + i;
                if (!r->valid) {
-                       retval = dpm_read_reg(dpm, r, i);
+                       retval = arm_dpm_read_reg(dpm, r, i);
                        if (retval != ERROR_OK)
                                goto fail;
                }
@@ -372,7 +376,7 @@ int arm_dpm_read_current_registers(struct arm_dpm *dpm)
                if (r->valid)
                        continue;
 
-               retval = dpm_read_reg(dpm, r, i);
+               retval = arm_dpm_read_reg(dpm, r, i);
                if (retval != ERROR_OK)
                        goto fail;
        }
@@ -543,7 +547,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
 
                                /* REVISIT error checks */
                                if (tmode != ARM_MODE_ANY) {
-                                       retval = dpm_modeswitch(dpm, tmode);
+                                       retval = arm_dpm_modeswitch(dpm, tmode);
                                        if (retval != ERROR_OK)
                                                goto done;
                                }
@@ -564,7 +568,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
         * or it's dirty.  Must write PC to ensure the return address is
         * defined, and must not write it before CPSR.
         */
-       retval = dpm_modeswitch(dpm, ARM_MODE_ANY);
+       retval = arm_dpm_modeswitch(dpm, ARM_MODE_ANY);
        if (retval != ERROR_OK)
                goto done;
        arm->cpsr->dirty = false;
@@ -671,18 +675,18 @@ static int arm_dpm_read_core_reg(struct target *target, struct reg *r,
                return retval;
 
        if (mode != ARM_MODE_ANY) {
-               retval = dpm_modeswitch(dpm, mode);
+               retval = arm_dpm_modeswitch(dpm, mode);
                if (retval != ERROR_OK)
                        goto fail;
        }
 
-       retval = dpm_read_reg(dpm, r, regnum);
+       retval = arm_dpm_read_reg(dpm, r, regnum);
        if (retval != ERROR_OK)
                goto fail;
        /* always clean up, regardless of error */
 
        if (mode != ARM_MODE_ANY)
-               /* (void) */ dpm_modeswitch(dpm, ARM_MODE_ANY);
+               /* (void) */ arm_dpm_modeswitch(dpm, ARM_MODE_ANY);
 
 fail:
        /* (void) */ dpm->finish(dpm);
@@ -715,7 +719,7 @@ static int arm_dpm_write_core_reg(struct target *target, struct reg *r,
                return retval;
 
        if (mode != ARM_MODE_ANY) {
-               retval = dpm_modeswitch(dpm, mode);
+               retval = arm_dpm_modeswitch(dpm, mode);
                if (retval != ERROR_OK)
                        goto fail;
        }
@@ -724,7 +728,7 @@ static int arm_dpm_write_core_reg(struct target *target, struct reg *r,
        /* always clean up, regardless of error */
 
        if (mode != ARM_MODE_ANY)
-               /* (void) */ dpm_modeswitch(dpm, ARM_MODE_ANY);
+               /* (void) */ arm_dpm_modeswitch(dpm, ARM_MODE_ANY);
 
 fail:
        /* (void) */ dpm->finish(dpm);
@@ -773,9 +777,9 @@ static int arm_dpm_full_context(struct target *target)
                                 * in FIQ mode we need to patch mode.
                                 */
                                if (mode != ARM_MODE_ANY)
-                                       retval = dpm_modeswitch(dpm, mode);
+                                       retval = arm_dpm_modeswitch(dpm, mode);
                                else
-                                       retval = dpm_modeswitch(dpm, ARM_MODE_USR);
+                                       retval = arm_dpm_modeswitch(dpm, ARM_MODE_USR);
 
                                if (retval != ERROR_OK)
                                        goto done;
@@ -784,7 +788,7 @@ static int arm_dpm_full_context(struct target *target)
                                continue;
 
                        /* CPSR was read, so "R16" must mean SPSR */
-                       retval = dpm_read_reg(dpm,
+                       retval = arm_dpm_read_reg(dpm,
                                        &cache->reg_list[i],
                                        (r->num == 16) ? 17 : r->num);
                        if (retval != ERROR_OK)
@@ -793,7 +797,7 @@ static int arm_dpm_full_context(struct target *target)
 
        } while (did_read);
 
-       retval = dpm_modeswitch(dpm, ARM_MODE_ANY);
+       retval = arm_dpm_modeswitch(dpm, ARM_MODE_ANY);
        /* (void) */ dpm->finish(dpm);
 done:
        return retval;
@@ -1092,10 +1096,11 @@ int arm_dpm_setup(struct arm_dpm *dpm)
 
        dpm->nbp = 1 + ((dpm->didr >> 24) & 0xf);
        dpm->nwp = 1 + ((dpm->didr >> 28) & 0xf);
-       dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp);
-       dpm->dwp = calloc(dpm->nwp, sizeof *dpm->dwp);
+       dpm->dbp = calloc(dpm->nbp, sizeof(*dpm->dbp));
+       dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp));
 
        if (!dpm->dbp || !dpm->dwp) {
+               arm_free_reg_cache(arm);
                free(dpm->dbp);
                free(dpm->dwp);
                return ERROR_FAIL;