X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farmv7m.c;h=ccb3e5456e5037abb104b830d0fad151be416f14;hp=92ebb95be18b0d27fa8e4ef3231435ed20554541;hb=a09a75653dbe7ad99da6349285ab6622b80fdc15;hpb=1255b18fc650193094666ba8afd2018089cc9794 diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 92ebb95be1..ccb3e5456e 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -44,7 +44,7 @@ #define _DEBUG_INSTRUCTION_EXECUTION_ #endif -static char *armv7m_exception_strings[] = { +static const char * const armv7m_exception_strings[] = { "", "Reset", "NMI", "HardFault", "MemManage", "BusFault", "UsageFault", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "SVCall", @@ -52,7 +52,7 @@ static char *armv7m_exception_strings[] = { }; /* PSP is used in some thread modes */ -const int armv7m_psp_reg_map[17] = { +const int armv7m_psp_reg_map[ARMV7M_NUM_CORE_REGS] = { ARMV7M_R0, ARMV7M_R1, ARMV7M_R2, ARMV7M_R3, ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7, ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11, @@ -61,7 +61,7 @@ const int armv7m_psp_reg_map[17] = { }; /* MSP is used in handler and some thread modes */ -const int armv7m_msp_reg_map[17] = { +const int armv7m_msp_reg_map[ARMV7M_NUM_CORE_REGS] = { ARMV7M_R0, ARMV7M_R1, ARMV7M_R2, ARMV7M_R3, ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7, ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11, @@ -110,6 +110,25 @@ static const struct { { 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" }, { ARMV7M_CONTROL, "control", 2, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + + { 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" }, + { ARMV7M_D3, "d3", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D4, "d4", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D5, "d5", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D6, "d6", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D7, "d7", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D8, "d8", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D9, "d9", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D10, "d10", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D11, "d11", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D12, "d12", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D13, "d13", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D14, "d14", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + { ARMV7M_D15, "d15", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, + + { ARMV7M_FPSCR, "fpscr", 32, REG_TYPE_INT, "float", "org.gnu.gdb.arm.vfp" }, }; #define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs) @@ -129,10 +148,10 @@ int armv7m_restore_context(struct target *target) if (armv7m->pre_restore_context) armv7m->pre_restore_context(target); - for (i = ARMV7M_NUM_REGS - 1; i >= 0; i--) { + for (i = cache->num_regs - 1; i >= 0; i--) { if (cache->reg_list[i].dirty) { - uint32_t value = buf_get_u32(cache->reg_list[i].value, 0, 32); - armv7m->arm.write_core_reg(target, &cache->reg_list[i], i, ARM_MODE_ANY, value); + armv7m->arm.write_core_reg(target, &cache->reg_list[i], i, + ARM_MODE_ANY, cache->reg_list[i].value); } } @@ -148,7 +167,7 @@ int armv7m_restore_context(struct target *target) * They are assigned by vendors, which generally assign different numbers to * peripherals (such as UART0 or a USB peripheral controller). */ -char *armv7m_exception_string(int number) +const char *armv7m_exception_string(int number) { static char enamebuf[32]; @@ -179,12 +198,11 @@ static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf) { struct arm_reg *armv7m_reg = reg->arch_info; struct target *target = armv7m_reg->target; - uint32_t value = buf_get_u32(buf, 0, 32); if (target->state != TARGET_HALTED) return ERROR_TARGET_NOT_HALTED; - buf_set_u32(reg->value, 0, 32, value); + buf_cpy(buf, reg->value, reg->size); reg->dirty = 1; reg->valid = 1; @@ -202,10 +220,28 @@ static int armv7m_read_core_reg(struct target *target, struct reg *r, assert(num < (int)armv7m->arm.core_cache->num_regs); armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info; - retval = armv7m->load_core_reg_u32(target, - armv7m_core_reg->num, ®_value); - buf_set_u32(armv7m->arm.core_cache->reg_list[num].value, 0, 32, reg_value); + 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); + if (retval != ERROR_OK) + return retval; + buf_set_u32(armv7m->arm.core_cache->reg_list[num].value, 0, 32, reg_value); + } + armv7m->arm.core_cache->reg_list[num].valid = 1; armv7m->arm.core_cache->reg_list[num].dirty = 0; @@ -213,31 +249,47 @@ static int armv7m_read_core_reg(struct target *target, struct reg *r, } static int armv7m_write_core_reg(struct target *target, struct reg *r, - int num, enum arm_mode mode, uint32_t value) + int num, enum arm_mode mode, uint8_t *value) { int retval; - uint32_t reg_value; struct arm_reg *armv7m_core_reg; struct armv7m_common *armv7m = target_to_armv7m(target); assert(num < (int)armv7m->arm.core_cache->num_regs); - reg_value = buf_get_u32(armv7m->arm.core_cache->reg_list[num].value, 0, 32); armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info; - retval = armv7m->store_core_reg_u32(target, - armv7m_core_reg->num, - reg_value); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG failure"); - armv7m->arm.core_cache->reg_list[num].dirty = armv7m->arm.core_cache->reg_list[num].valid; - return ERROR_JTAG_DEVICE_ERROR; + + 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); + + 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; + + 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); + if (retval != ERROR_OK) + goto out_error; } - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value); armv7m->arm.core_cache->reg_list[num].valid = 1; armv7m->arm.core_cache->reg_list[num].dirty = 0; 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; } /** @@ -250,9 +302,9 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int i; if (reg_class == REG_CLASS_ALL) - *reg_list_size = ARMV7M_NUM_REGS; + *reg_list_size = armv7m->arm.core_cache->num_regs; else - *reg_list_size = 17; + *reg_list_size = ARMV7M_NUM_CORE_REGS; *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); if (*reg_list == NULL) @@ -316,7 +368,7 @@ int armv7m_start_algorithm(struct target *target, /* refresh core register cache * Not needed if core register cache is always consistent with target process state */ - for (unsigned i = 0; i < ARMV7M_NUM_REGS; i++) { + for (unsigned i = 0; i < armv7m->arm.core_cache->num_regs; i++) { armv7m_algorithm_info->context[i] = buf_get_u32( armv7m->arm.core_cache->reg_list[i].value, @@ -451,7 +503,7 @@ int armv7m_wait_algorithm(struct target *target, } } - for (int i = ARMV7M_NUM_REGS - 1; i >= 0; i--) { + for (int i = armv7m->arm.core_cache->num_regs - 1; i >= 0; i--) { uint32_t regvalue; regvalue = buf_get_u32(armv7m->arm.core_cache->reg_list[i].value, 0, 32); if (regvalue != armv7m_algorithm_info->context[i]) { @@ -535,7 +587,10 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) reg_list[i].name = armv7m_regs[i].name; reg_list[i].size = armv7m_regs[i].bits; - reg_list[i].value = calloc(1, 4); + size_t storage_size = DIV_ROUND_UP(armv7m_regs[i].bits, 8); + if (storage_size < 4) + storage_size = 4; + reg_list[i].value = calloc(1, storage_size); reg_list[i].dirty = 0; reg_list[i].valid = 0; reg_list[i].type = &armv7m_reg_type; @@ -580,6 +635,9 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m) armv7m->common_magic = ARMV7M_COMMON_MAGIC; armv7m->fp_feature = FP_NONE; + armv7m->trace_config.trace_bus_id = 1; + /* Enable stimulus port #0 by default */ + armv7m->trace_config.itm_ter[0] = 1; arm->core_type = ARM_MODE_THREAD; arm->arch_info = armv7m; @@ -602,7 +660,7 @@ int armv7m_checksum_memory(struct target *target, /* see contrib/loaders/checksum/armv7m_crc.s for src */ - static const uint8_t cortex_m3_crc_code[] = { + static const uint8_t cortex_m_crc_code[] = { /* main: */ 0x02, 0x46, /* mov r2, r0 */ 0x00, 0x20, /* movs r0, #0 */ @@ -636,12 +694,12 @@ int armv7m_checksum_memory(struct target *target, 0xB7, 0x1D, 0xC1, 0x04 /* CRC32XOR: .word 0x04c11db7 */ }; - retval = target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm); + retval = target_alloc_working_area(target, sizeof(cortex_m_crc_code), &crc_algorithm); if (retval != ERROR_OK) return retval; retval = target_write_buffer(target, crc_algorithm->address, - sizeof(cortex_m3_crc_code), (uint8_t *)cortex_m3_crc_code); + sizeof(cortex_m_crc_code), (uint8_t *)cortex_m_crc_code); if (retval != ERROR_OK) goto cleanup; @@ -657,7 +715,7 @@ int armv7m_checksum_memory(struct target *target, int timeout = 20000 * (1 + (count / (1024 * 1024))); retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address, - crc_algorithm->address + (sizeof(cortex_m3_crc_code) - 6), + crc_algorithm->address + (sizeof(cortex_m_crc_code) - 6), timeout, &armv7m_info); if (retval == ERROR_OK)