This is an automated email from Gerrit. Tomas Vanek ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/5327
-- gerrit commit 78d82db57595c8e3e57c6600ded2689026410b5f Author: Tomas Vanek <[email protected]> Date: Sun Oct 20 10:12:32 2019 +0200 target/armv7m: rework Cortex-M register handling Move primask/basepri/faultmask/control packing/unpacking from cortex_m.c and hla_target.c to armv7m.c armv7m_read_core_reg() and armv7m_write_core_reg() where also the FP 32/64-bit registers conversion takes place. Introduce a new hidden register ARMV7M_PMSK_BPRI_FLTMSK_CTRL for packing/unpacking of special registers in the register cache. Define a new enum with DCRSR.REGSEL selectors. Introduce armv7m_map_id_to_regsel() to unify mapping in one place. Make arm register id coherent with reg_list index. Without this reg_list[ARMV7M_R12] was possible but reg_list[ARMV7M_FPSCR] was out of bounds. Change-Id: Ida0ccdfa9cdb1257a1900b8bfbf172b076374d39 Signed-off-by: Tomas Vanek <[email protected]> diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 2f7f4ab..ee13fbb 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -14,6 +14,9 @@ * Copyright (C) 2018 by Liviu Ionescu * * <[email protected]> * * * + * Copyright (C) 2019 by Tomas Vanek * + * [email protected] * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -108,6 +111,15 @@ static const struct { { ARMV7M_MSP, "msp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" }, { ARMV7M_PSP, "psp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" }, + /* A working register for packing/unpacking special regs, hidden from gdb */ + { ARMV7M_PMSK_BPRI_FLTMSK_CTRL, "pmsk_bpri_fltmsk_ctrl", 32, REG_TYPE_INT, NULL, NULL }, + + /* WARNING: If you use armv7m_write_core_reg() on one of 4 following + * special registers, the new data go to ARMV7M_PMSK_BPRI_FLTMSK_CTRL + * cache only and are not flushed to CPU HW register. + * To trigger write to CPU HW register, add + * armv7m_write_core_reg(,,ARMV7M_PMSK_BPRI_FLTMSK_CTRL,); + */ { ARMV7M_PRIMASK, "primask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, { ARMV7M_BASEPRI, "basepri", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, { ARMV7M_FAULTMASK, "faultmask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, @@ -211,87 +223,149 @@ static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf) return ERROR_OK; } +static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) +{ + switch (arm_reg_id) { + case ARMV7M_R0 ... ARMV7M_PSP: + return arm_reg_id; + + case ARMV7M_PMSK_BPRI_FLTMSK_CTRL: + return ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL; + + case ARMV7M_FPSCR: + return ARMV7M_REGSEL_FPSCR; + + case ARMV7M_D0 ... ARMV7M_D15: + return ARMV7M_REGSEL_S0 + 2 * (arm_reg_id - ARMV7M_D0); + + default: + LOG_ERROR("Bad register ID %u", arm_reg_id); + return arm_reg_id; + } +} + static int armv7m_read_core_reg(struct target *target, struct reg *r, int num, enum arm_mode mode) { uint32_t reg_value; int retval; - struct arm_reg *armv7m_core_reg; struct armv7m_common *armv7m = target_to_armv7m(target); assert(num < (int)armv7m->arm.core_cache->num_regs); + assert(num == (int)r->number); - armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info; + struct arm_reg *armv7m_core_reg = r->arch_info; + + if (r->size <= 8) { + /* Read packed primask/basepri/faultmask/control if not cached */ + + assert(armv7m_core_reg->num >= ARMV7M_PRIMASK + && armv7m_core_reg->num <= ARMV7M_CONTROL); + struct reg *r32; + r32 = &armv7m->arm.core_cache->reg_list[ARMV7M_PMSK_BPRI_FLTMSK_CTRL]; + if (!r32->valid) { + retval = armv7m_read_core_reg(target, r32, ARMV7M_PMSK_BPRI_FLTMSK_CTRL, mode); + if (retval != ERROR_OK) + return retval; + } + + /* Copy required bits of 32-bit register */ + buf_cpy(r32->value + (armv7m_core_reg->num - ARMV7M_PRIMASK), + r->value, r->size); - if ((armv7m_core_reg->num >= ARMV7M_D0) && (armv7m_core_reg->num <= ARMV7M_D15)) { - /* map D0..D15 to S0..S31 */ - size_t regidx = ARMV7M_S0 + 2 * (armv7m_core_reg->num - ARMV7M_D0); - retval = armv7m->load_core_reg_u32(target, regidx, ®_value); - if (retval != ERROR_OK) - return retval; - buf_set_u32(armv7m->arm.core_cache->reg_list[num].value, - 0, 32, reg_value); - retval = armv7m->load_core_reg_u32(target, regidx + 1, ®_value); - if (retval != ERROR_OK) - return retval; - buf_set_u32(armv7m->arm.core_cache->reg_list[num].value + 4, - 0, 32, reg_value); } else { - retval = armv7m->load_core_reg_u32(target, - armv7m_core_reg->num, ®_value); + + uint32_t regsel = armv7m_map_id_to_regsel(armv7m_core_reg->num); + + retval = armv7m->load_core_reg_u32(target, regsel, ®_value); if (retval != ERROR_OK) return retval; - buf_set_u32(armv7m->arm.core_cache->reg_list[num].value, 0, 32, reg_value); + buf_set_u32(r->value, 0, 32, reg_value); + + if (r->size == 64) { + retval = armv7m->load_core_reg_u32(target, regsel + 1, ®_value); + if (retval != ERROR_OK) + return retval; + buf_set_u32(r->value + 4, 0, 32, reg_value); + + uint64_t q = buf_get_u64(r->value, 0, 64); + LOG_DEBUG("read %s value 0x%016" PRIx64 "", r->name, q); + } else { + LOG_DEBUG("read %s value 0x%08" PRIx32 "", r->name, reg_value); + } } - armv7m->arm.core_cache->reg_list[num].valid = true; - armv7m->arm.core_cache->reg_list[num].dirty = false; + r->valid = true; + r->dirty = false; - return retval; + return ERROR_OK; } static int armv7m_write_core_reg(struct target *target, struct reg *r, int num, enum arm_mode mode, uint8_t *value) { int retval; - struct arm_reg *armv7m_core_reg; + uint32_t t; struct armv7m_common *armv7m = target_to_armv7m(target); assert(num < (int)armv7m->arm.core_cache->num_regs); + assert(num == (int)r->number); - armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info; + struct arm_reg *armv7m_core_reg = r->arch_info; - if ((armv7m_core_reg->num >= ARMV7M_D0) && (armv7m_core_reg->num <= ARMV7M_D15)) { - /* map D0..D15 to S0..S31 */ - size_t regidx = ARMV7M_S0 + 2 * (armv7m_core_reg->num - ARMV7M_D0); + if (value != r->value) { + /* If we are not flushing the cache, store the new value to the cache */ + buf_cpy(value, r->value, r->size); + } - uint32_t t = buf_get_u32(value, 0, 32); - retval = armv7m->store_core_reg_u32(target, regidx, t); - if (retval != ERROR_OK) - goto out_error; + if (r->size <= 8) { + /* Write a part to the packed primask/basepri/faultmask/control */ + + assert(armv7m_core_reg->num >= ARMV7M_PRIMASK + && armv7m_core_reg->num <= ARMV7M_CONTROL); + struct reg *r32; + r32 = &armv7m->arm.core_cache->reg_list[ARMV7M_PMSK_BPRI_FLTMSK_CTRL]; + if (!r32->valid) { + /* Before merging with other parts ensure the 32-bit register is valid */ + retval = armv7m_read_core_reg(target, r32, ARMV7M_PMSK_BPRI_FLTMSK_CTRL, mode); + if (retval != ERROR_OK) + return retval; + } + buf_cpy(value, r32->value + (armv7m_core_reg->num - ARMV7M_PRIMASK), + r->size); + r32->dirty = true; - t = buf_get_u32(value + 4, 0, 32); - retval = armv7m->store_core_reg_u32(target, regidx + 1, t); - if (retval != ERROR_OK) - goto out_error; } else { - uint32_t t = buf_get_u32(value, 0, 32); - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, t); - retval = armv7m->store_core_reg_u32(target, armv7m_core_reg->num, t); + uint32_t regsel = armv7m_map_id_to_regsel(armv7m_core_reg->num); + + t = buf_get_u32(value, 0, 32); + retval = armv7m->store_core_reg_u32(target, regsel, t); if (retval != ERROR_OK) goto out_error; + + if (r->size == 64) { + t = buf_get_u32(value + 4, 0, 32); + retval = armv7m->store_core_reg_u32(target, regsel + 1, t); + if (retval != ERROR_OK) + goto out_error; + + uint64_t q = buf_get_u64(value, 0, 64); + LOG_DEBUG("write %s value 0x%016" PRIx64 "", r->name, q); + } else { + LOG_DEBUG("write %s value 0x%08" PRIx32 "", r->name, t); + } } - armv7m->arm.core_cache->reg_list[num].valid = true; - armv7m->arm.core_cache->reg_list[num].dirty = false; + r->valid = true; + r->dirty = false; return ERROR_OK; out_error: - LOG_ERROR("Error setting register"); - armv7m->arm.core_cache->reg_list[num].dirty = armv7m->arm.core_cache->reg_list[num].valid; - return ERROR_JTAG_DEVICE_ERROR; + r->dirty = true; + LOG_ERROR("Error setting register %s", r->name); + return retval; } /** @@ -623,6 +697,7 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) reg_list[i].value = calloc(1, storage_size); reg_list[i].dirty = false; reg_list[i].valid = false; + reg_list[i].hidden = i == ARMV7M_PMSK_BPRI_FLTMSK_CTRL; reg_list[i].type = &armv7m_reg_type; reg_list[i].arch_info = &arch_info[i]; @@ -631,6 +706,9 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) reg_list[i].exist = true; reg_list[i].caller_save = true; /* gdb defaults to true */ + if (reg_list[i].hidden) + continue; + feature = calloc(1, sizeof(struct reg_feature)); if (feature) { feature->name = armv7m_regs[i].feature; diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 01bf19e..a1a2774 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -64,45 +64,21 @@ enum { ARMV7M_PSP, /* this next set of indices is arbitrary */ + + /* working register for packing/unpacking special regs, hidden from gdb */ + ARMV7M_PMSK_BPRI_FLTMSK_CTRL, + + /* WARNING: If you use armv7m_write_core_reg() on one of 4 following + * special registers, the new data go to ARMV7M_PMSK_BPRI_FLTMSK_CTRL + * cache only and are not flushed to CPU HW register. + * To trigger write to CPU HW register, add + * armv7m_write_core_reg(,,ARMV7M_PMSK_BPRI_FLTMSK_CTRL,); + */ ARMV7M_PRIMASK, ARMV7M_BASEPRI, ARMV7M_FAULTMASK, ARMV7M_CONTROL, - /* 32bit Floating-point registers */ - ARMV7M_S0, - ARMV7M_S1, - ARMV7M_S2, - ARMV7M_S3, - ARMV7M_S4, - ARMV7M_S5, - ARMV7M_S6, - ARMV7M_S7, - ARMV7M_S8, - ARMV7M_S9, - ARMV7M_S10, - ARMV7M_S11, - ARMV7M_S12, - ARMV7M_S13, - ARMV7M_S14, - ARMV7M_S15, - ARMV7M_S16, - ARMV7M_S17, - ARMV7M_S18, - ARMV7M_S19, - ARMV7M_S20, - ARMV7M_S21, - ARMV7M_S22, - ARMV7M_S23, - ARMV7M_S24, - ARMV7M_S25, - ARMV7M_S26, - ARMV7M_S27, - ARMV7M_S28, - ARMV7M_S29, - ARMV7M_S30, - ARMV7M_S31, - /* 64bit Floating-point registers */ ARMV7M_D0, ARMV7M_D1, @@ -121,14 +97,52 @@ enum { ARMV7M_D14, ARMV7M_D15, - /* Floating-point status registers */ - ARMV7M_FPSID, + /* Floating-point status register */ ARMV7M_FPSCR, - ARMV7M_FPEXC, ARMV7M_LAST_REG, }; +/* Cortex-M DCRSR.REGSEL selectors */ +enum { + ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL = 0x14, + ARMV7M_REGSEL_FPSCR = 0x21, + + /* 32bit Floating-point registers */ + ARMV7M_REGSEL_S0 = 0x40, + ARMV7M_REGSEL_S1, + ARMV7M_REGSEL_S2, + ARMV7M_REGSEL_S3, + ARMV7M_REGSEL_S4, + ARMV7M_REGSEL_S5, + ARMV7M_REGSEL_S6, + ARMV7M_REGSEL_S7, + ARMV7M_REGSEL_S8, + ARMV7M_REGSEL_S9, + ARMV7M_REGSEL_S10, + ARMV7M_REGSEL_S11, + ARMV7M_REGSEL_S12, + ARMV7M_REGSEL_S13, + ARMV7M_REGSEL_S14, + ARMV7M_REGSEL_S15, + ARMV7M_REGSEL_S16, + ARMV7M_REGSEL_S17, + ARMV7M_REGSEL_S18, + ARMV7M_REGSEL_S19, + ARMV7M_REGSEL_S20, + ARMV7M_REGSEL_S21, + ARMV7M_REGSEL_S22, + ARMV7M_REGSEL_S23, + ARMV7M_REGSEL_S24, + ARMV7M_REGSEL_S25, + ARMV7M_REGSEL_S26, + ARMV7M_REGSEL_S27, + ARMV7M_REGSEL_S28, + ARMV7M_REGSEL_S29, + ARMV7M_REGSEL_S30, + ARMV7M_REGSEL_S31, +}; + enum { FP_NONE = 0, FPv4_SP, @@ -137,7 +151,7 @@ enum { }; #define ARMV7M_NUM_CORE_REGS (ARMV7M_xPSR + 1) -#define ARMV7M_NUM_CORE_REGS_NOFP (ARMV7M_NUM_CORE_REGS + 6) +#define ARMV7M_NUM_CORE_REGS_NOFP (ARMV7M_D0) #define ARMV7M_COMMON_MAGIC 0x2A452A45 @@ -159,8 +173,8 @@ struct armv7m_common { struct armv7m_trace_config trace_config; /* Direct processor core register read and writes */ - int (*load_core_reg_u32)(struct target *target, uint32_t num, uint32_t *value); - int (*store_core_reg_u32)(struct target *target, uint32_t num, uint32_t value); + int (*load_core_reg_u32)(struct target *target, uint32_t regsel, uint32_t *value); + int (*store_core_reg_u32)(struct target *target, uint32_t regsel, uint32_t value); int (*examine_debug_reason)(struct target *target); int (*post_debug_entry)(struct target *target); diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 7f59401..7f6186b 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -56,8 +56,8 @@ static int cortex_m_store_core_reg_u32(struct target *target, uint32_t num, uint32_t value); static void cortex_m_dwt_free(struct target *target); -static int cortexm_dap_read_coreregister_u32(struct target *target, - uint32_t *value, int regnum) +static int cortex_m_load_core_reg_u32(struct target *target, + uint32_t regsel, uint32_t *value) { struct armv7m_common *armv7m = target_to_armv7m(target); int retval; @@ -71,7 +71,7 @@ static int cortexm_dap_read_coreregister_u32(struct target *target, return retval; } - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regnum); + retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regsel); if (retval != ERROR_OK) return retval; @@ -89,8 +89,8 @@ static int cortexm_dap_read_coreregister_u32(struct target *target, return retval; } -static int cortexm_dap_write_coreregister_u32(struct target *target, - uint32_t value, int regnum) +static int cortex_m_store_core_reg_u32(struct target *target, + uint32_t regsel, uint32_t value) { struct armv7m_common *armv7m = target_to_armv7m(target); int retval; @@ -108,7 +108,7 @@ static int cortexm_dap_write_coreregister_u32(struct target *target, if (retval != ERROR_OK) return retval; - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRSR, regnum | DCRSR_WnR); + retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRSR, regsel | DCRSR_WnR); if (retval != ERROR_OK) return retval; @@ -1590,176 +1590,6 @@ void cortex_m_enable_watchpoints(struct target *target) } } -static int cortex_m_load_core_reg_u32(struct target *target, - uint32_t num, uint32_t *value) -{ - int retval; - - /* NOTE: we "know" here that the register identifiers used - * in the v7m header match the Cortex-M3 Debug Core Register - * Selector values for R0..R15, xPSR, MSP, and PSP. - */ - switch (num) { - case 0 ... 18: - /* read a normal core register */ - retval = cortexm_dap_read_coreregister_u32(target, value, num); - - if (retval != ERROR_OK) { - LOG_ERROR("JTAG failure %i", retval); - return ERROR_JTAG_DEVICE_ERROR; - } - LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); - break; - - case ARMV7M_FPSCR: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, DCB_DCRSR, 0x21); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("load from FPSCR value 0x%" PRIx32, *value); - break; - - case ARMV7M_S0 ... ARMV7M_S31: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, DCB_DCRSR, num - ARMV7M_S0 + 0x40); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("load from FPU reg S%d value 0x%" PRIx32, - (int)(num - ARMV7M_S0), *value); - break; - - case ARMV7M_PRIMASK: - case ARMV7M_BASEPRI: - case ARMV7M_FAULTMASK: - case ARMV7M_CONTROL: - /* Cortex-M3 packages these four registers as bitfields - * in one Debug Core register. So say r0 and r2 docs; - * it was removed from r1 docs, but still works. - */ - cortexm_dap_read_coreregister_u32(target, value, 20); - - switch (num) { - case ARMV7M_PRIMASK: - *value = buf_get_u32((uint8_t *)value, 0, 1); - break; - - case ARMV7M_BASEPRI: - *value = buf_get_u32((uint8_t *)value, 8, 8); - break; - - case ARMV7M_FAULTMASK: - *value = buf_get_u32((uint8_t *)value, 16, 1); - break; - - case ARMV7M_CONTROL: - *value = buf_get_u32((uint8_t *)value, 24, 2); - break; - } - - LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "", (int)num, *value); - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -static int cortex_m_store_core_reg_u32(struct target *target, - uint32_t num, uint32_t value) -{ - int retval; - uint32_t reg; - struct armv7m_common *armv7m = target_to_armv7m(target); - - /* NOTE: we "know" here that the register identifiers used - * in the v7m header match the Cortex-M3 Debug Core Register - * Selector values for R0..R15, xPSR, MSP, and PSP. - */ - switch (num) { - case 0 ... 18: - retval = cortexm_dap_write_coreregister_u32(target, value, num); - if (retval != ERROR_OK) { - struct reg *r; - - LOG_ERROR("JTAG failure"); - r = armv7m->arm.core_cache->reg_list + num; - r->dirty = r->valid; - return ERROR_JTAG_DEVICE_ERROR; - } - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); - break; - - case ARMV7M_FPSCR: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, DCB_DCRSR, 0x21 | (1<<16)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("write FPSCR value 0x%" PRIx32, value); - break; - - case ARMV7M_S0 ... ARMV7M_S31: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, DCB_DCRSR, (num - ARMV7M_S0 + 0x40) | (1<<16)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("write FPU reg S%d value 0x%" PRIx32, - (int)(num - ARMV7M_S0), value); - break; - - case ARMV7M_PRIMASK: - case ARMV7M_BASEPRI: - case ARMV7M_FAULTMASK: - case ARMV7M_CONTROL: - /* Cortex-M3 packages these four registers as bitfields - * in one Debug Core register. So say r0 and r2 docs; - * it was removed from r1 docs, but still works. - */ - cortexm_dap_read_coreregister_u32(target, ®, 20); - - switch (num) { - case ARMV7M_PRIMASK: - buf_set_u32((uint8_t *)®, 0, 1, value); - break; - - case ARMV7M_BASEPRI: - buf_set_u32((uint8_t *)®, 8, 8, value); - break; - - case ARMV7M_FAULTMASK: - buf_set_u32((uint8_t *)®, 16, 1, value); - break; - - case ARMV7M_CONTROL: - buf_set_u32((uint8_t *)®, 24, 2, value); - break; - } - - cortexm_dap_write_coreregister_u32(target, reg, 20); - - LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value); - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - static int cortex_m_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) { diff --git a/src/target/hla_target.c b/src/target/hla_target.c index 60ed7d6..188dfc6 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -50,184 +50,50 @@ static inline struct hl_interface_s *target_to_adapter(struct target *target) } static int adapter_load_core_reg_u32(struct target *target, - uint32_t num, uint32_t *value) + uint32_t regsel, uint32_t *value) { int retval; struct hl_interface_s *adapter = target_to_adapter(target); - LOG_DEBUG("%s", __func__); - - /* NOTE: we "know" here that the register identifiers used - * in the v7m header match the Cortex-M3 Debug Core Register - * Selector values for R0..R15, xPSR, MSP, and PSP. - */ - switch (num) { - case 0 ... 18: + switch (regsel) { + case ARMV7M_R0 ... ARMV7M_PSP: + case ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL: /* read a normal core register */ - retval = adapter->layout->api->read_reg(adapter->handle, num, value); - - if (retval != ERROR_OK) { - LOG_ERROR("JTAG failure %i", retval); - return ERROR_JTAG_DEVICE_ERROR; - } - LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); - break; - - case ARMV7M_FPSCR: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("load from FPSCR value 0x%" PRIx32, *value); + retval = adapter->layout->api->read_reg(adapter->handle, regsel, value); break; - case ARMV7M_S0 ... ARMV7M_S31: + default: /* Floating-point Status and Registers */ - retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64); + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, regsel); if (retval != ERROR_OK) return retval; retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("load from FPU reg S%d value 0x%" PRIx32, - (int)(num - ARMV7M_S0), *value); - break; - - case ARMV7M_PRIMASK: - case ARMV7M_BASEPRI: - case ARMV7M_FAULTMASK: - case ARMV7M_CONTROL: - /* Cortex-M3 packages these four registers as bitfields - * in one Debug Core register. So say r0 and r2 docs; - * it was removed from r1 docs, but still works. - */ - retval = adapter->layout->api->read_reg(adapter->handle, 20, value); - if (retval != ERROR_OK) - return retval; - - switch (num) { - case ARMV7M_PRIMASK: - *value = buf_get_u32((uint8_t *) value, 0, 1); - break; - - case ARMV7M_BASEPRI: - *value = buf_get_u32((uint8_t *) value, 8, 8); - break; - - case ARMV7M_FAULTMASK: - *value = buf_get_u32((uint8_t *) value, 16, 1); - break; - - case ARMV7M_CONTROL: - *value = buf_get_u32((uint8_t *) value, 24, 2); - break; - } - - LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "", - (int)num, *value); - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; } - return ERROR_OK; + return retval; } static int adapter_store_core_reg_u32(struct target *target, - uint32_t num, uint32_t value) + uint32_t regsel, uint32_t value) { int retval; - uint32_t reg; - struct armv7m_common *armv7m = target_to_armv7m(target); struct hl_interface_s *adapter = target_to_adapter(target); - LOG_DEBUG("%s", __func__); - - /* NOTE: we "know" here that the register identifiers used - * in the v7m header match the Cortex-M3 Debug Core Register - * Selector values for R0..R15, xPSR, MSP, and PSP. - */ - switch (num) { - case 0 ... 18: - retval = adapter->layout->api->write_reg(adapter->handle, num, value); - - if (retval != ERROR_OK) { - struct reg *r; - - LOG_ERROR("JTAG failure"); - r = armv7m->arm.core_cache->reg_list + num; - r->dirty = r->valid; - return ERROR_JTAG_DEVICE_ERROR; - } - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); - break; - - case ARMV7M_FPSCR: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("write FPSCR value 0x%" PRIx32, value); + switch (regsel) { + case ARMV7M_R0 ... ARMV7M_PSP: + case ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL: + retval = adapter->layout->api->write_reg(adapter->handle, regsel, value); break; - case ARMV7M_S0 ... ARMV7M_S31: + default: /* Floating-point Status and Registers */ retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value); if (retval != ERROR_OK) return retval; - retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("write FPU reg S%d value 0x%" PRIx32, - (int)(num - ARMV7M_S0), value); - break; - - case ARMV7M_PRIMASK: - case ARMV7M_BASEPRI: - case ARMV7M_FAULTMASK: - case ARMV7M_CONTROL: - /* Cortex-M3 packages these four registers as bitfields - * in one Debug Core register. So say r0 and r2 docs; - * it was removed from r1 docs, but still works. - */ - - adapter->layout->api->read_reg(adapter->handle, 20, ®); - - switch (num) { - case ARMV7M_PRIMASK: - buf_set_u32((uint8_t *) ®, 0, 1, value); - break; - - case ARMV7M_BASEPRI: - buf_set_u32((uint8_t *) ®, 8, 8, value); - break; - - case ARMV7M_FAULTMASK: - buf_set_u32((uint8_t *) ®, 16, 1, value); - break; - - case ARMV7M_CONTROL: - buf_set_u32((uint8_t *) ®, 24, 2, value); - break; - } - - adapter->layout->api->write_reg(adapter->handle, 20, reg); - - LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value); - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, regsel | DCRSR_WnR); } - return ERROR_OK; + return retval; } static int adapter_examine_debug_reason(struct target *target) -- _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
