armv7m.h: relax dependency from 'arm_adi_v5.h'
[fw/openocd] / src / target / armv7m.c
index f14ce0d880ae83c490ea9d705c24ee0fdcd42961..ffc8ca875db0675a477fd11142d8ec207efaf41a 100644 (file)
@@ -44,6 +44,8 @@
 #include "algorithm.h"
 #include "register.h"
 #include "semihosting_common.h"
+#include <helper/log.h>
+#include <helper/binarybuffer.h>
 
 #if 0
 #define _DEBUG_INSTRUCTION_EXECUTION_
@@ -125,6 +127,29 @@ static const struct {
        { ARMV7M_FAULTMASK, "faultmask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
        { ARMV7M_CONTROL, "control", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
 
+       /* ARMv8-M specific registers */
+       { ARMV8M_MSP_NS, "msp_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+       { ARMV8M_PSP_NS, "psp_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+       { ARMV8M_MSP_S, "msp_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+       { ARMV8M_PSP_S, "psp_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+       { ARMV8M_MSPLIM_S, "msplim_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+       { ARMV8M_PSPLIM_S, "psplim_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+       { ARMV8M_MSPLIM_NS, "msplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+       { ARMV8M_PSPLIM_NS, "psplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+
+       { ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S, "pmsk_bpri_fltmsk_ctrl_s", 32, REG_TYPE_INT, NULL, NULL },
+       { ARMV8M_PRIMASK_S, "primask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+       { ARMV8M_BASEPRI_S, "basepri_s", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+       { ARMV8M_FAULTMASK_S, "faultmask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+       { ARMV8M_CONTROL_S, "control_s", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+
+       { ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS, "pmsk_bpri_fltmsk_ctrl_ns", 32, REG_TYPE_INT, NULL, NULL },
+       { ARMV8M_PRIMASK_NS, "primask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+       { ARMV8M_BASEPRI_NS, "basepri_ns", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+       { ARMV8M_FAULTMASK_NS, "faultmask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+       { ARMV8M_CONTROL_NS, "control_ns", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+
+       /* FPU registers */
        { ARMV7M_D0, "d0", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" },
        { ARMV7M_D1, "d1", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" },
        { ARMV7M_D2, "d2", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" },
@@ -166,10 +191,10 @@ int armv7m_restore_context(struct target *target)
         * packing of ARMV7M_PMSK_BPRI_FLTMSK_CTRL!
         * See also comments in the register table above */
        for (i = cache->num_regs - 1; i >= 0; i--) {
-               if (cache->reg_list[i].dirty) {
-                       armv7m->arm.write_core_reg(target, &cache->reg_list[i], i,
-                                                  ARM_MODE_ANY, cache->reg_list[i].value);
-               }
+               struct reg *r = &cache->reg_list[i];
+
+               if (r->exist && r->dirty)
+                       armv7m->arm.write_core_reg(target, r, i, ARM_MODE_ANY, r->value);
        }
 
        return ERROR_OK;
@@ -243,6 +268,15 @@ static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id)
        case ARMV7M_PMSK_BPRI_FLTMSK_CTRL:
                return ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL;
 
+       case ARMV8M_MSP_NS...ARMV8M_PSPLIM_NS:
+               return arm_reg_id - ARMV8M_MSP_NS + ARMV8M_REGSEL_MSP_NS;
+
+       case ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S:
+               return ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S;
+
+       case ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS:
+               return ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_NS;
+
        case ARMV7M_FPSCR:
                return ARMV7M_REGSEL_FPSCR;
 
@@ -258,28 +292,26 @@ static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id)
 static bool armv7m_map_reg_packing(unsigned int arm_reg_id,
                                        unsigned int *reg32_id, uint32_t *offset)
 {
+
        switch (arm_reg_id) {
 
-       case ARMV7M_PRIMASK:
+       case ARMV7M_PRIMASK...ARMV7M_CONTROL:
                *reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
-               *offset = 0;
+               *offset = arm_reg_id - ARMV7M_PRIMASK;
                return true;
-       case ARMV7M_BASEPRI:
-               *reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
-               *offset = 1;
+       case ARMV8M_PRIMASK_S...ARMV8M_CONTROL_S:
+               *reg32_id = ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S;
+               *offset = arm_reg_id - ARMV8M_PRIMASK_S;
                return true;
-       case ARMV7M_FAULTMASK:
-               *reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
-               *offset = 2;
-               return true;
-       case ARMV7M_CONTROL:
-               *reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
-               *offset = 3;
+       case ARMV8M_PRIMASK_NS...ARMV8M_CONTROL_NS:
+               *reg32_id = ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS;
+               *offset = arm_reg_id - ARMV8M_PRIMASK_NS;
                return true;
 
        default:
                return false;
        }
+
 }
 
 static int armv7m_read_core_reg(struct target *target, struct reg *r,
@@ -299,11 +331,17 @@ static int armv7m_read_core_reg(struct target *target, struct reg *r,
 
        if (r->size <= 8) {
                /* any 8-bit or shorter register is packed */
-               uint32_t offset = 0;    /* silence false gcc warning */
+               uint32_t offset;
                unsigned int reg32_id;
 
                bool is_packed = armv7m_map_reg_packing(num, &reg32_id, &offset);
-               assert(is_packed);
+               if (!is_packed) {
+                       /* We should not get here as all 8-bit or shorter registers
+                        * are packed */
+                       assert(false);
+                       /* assert() does nothing if NDEBUG is defined */
+                       return ERROR_FAIL;
+               }
                struct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id];
 
                /* Read 32-bit container register if not cached */
@@ -364,11 +402,17 @@ static int armv7m_write_core_reg(struct target *target, struct reg *r,
 
        if (r->size <= 8) {
                /* any 8-bit or shorter register is packed */
-               uint32_t offset = 0;    /* silence false gcc warning */
+               uint32_t offset;
                unsigned int reg32_id;
 
                bool is_packed = armv7m_map_reg_packing(num, &reg32_id, &offset);
-               assert(is_packed);
+               if (!is_packed) {
+                       /* We should not get here as all 8-bit or shorter registers
+                        * are packed */
+                       assert(false);
+                       /* assert() does nothing if NDEBUG is defined */
+                       return ERROR_FAIL;
+               }
                struct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id];
 
                if (!r32->valid) {
@@ -432,7 +476,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
                size = ARMV7M_NUM_CORE_REGS;
 
        *reg_list = malloc(sizeof(struct reg *) * size);
-       if (*reg_list == NULL)
+       if (!*reg_list)
                return ERROR_FAIL;
 
        for (i = 0; i < size; i++)
@@ -517,7 +561,7 @@ int armv7m_start_algorithm(struct target *target,
                        continue;
 
                struct reg *reg =
-                       register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, 0);
+                       register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, false);
 /*             uint32_t regvalue; */
 
                if (!reg) {
@@ -633,7 +677,7 @@ int armv7m_wait_algorithm(struct target *target,
                if (reg_params[i].direction != PARAM_OUT) {
                        struct reg *reg = register_get_by_name(armv7m->arm.core_cache,
                                        reg_params[i].reg_name,
-                                       0);
+                                       false);
 
                        if (!reg) {
                                LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
@@ -743,7 +787,8 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target)
                reg_list[i].value = arch_info[i].value;
                reg_list[i].dirty = false;
                reg_list[i].valid = false;
-               reg_list[i].hidden = i == ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
+               reg_list[i].hidden = (i == ARMV7M_PMSK_BPRI_FLTMSK_CTRL ||
+                               i == ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS || i == ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S);
                reg_list[i].type = &armv7m_reg_type;
                reg_list[i].arch_info = &arch_info[i];
 
@@ -924,7 +969,7 @@ int armv7m_blank_check_memory(struct target *target,
                blocks_to_check = num_blocks;
 
        struct algo_block *params = malloc((blocks_to_check+1)*sizeof(struct algo_block));
-       if (params == NULL) {
+       if (!params) {
                retval = ERROR_FAIL;
                goto cleanup1;
        }