X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farmv7m.c;h=92ebb95be18b0d27fa8e4ef3231435ed20554541;hp=780e81b5baf92dca1f7b5313639e04ca0acb712e;hb=1255b18fc650193094666ba8afd2018089cc9794;hpb=861df4574d351731b8651ff5cd71a6d51e491d3f diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 780e81b5ba..92ebb95be1 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -24,9 +24,9 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * - * ARMv7-M Architecture, Application Level Reference Manual * + * ARMv7-M Architecture, Application Level Reference Manual * * ARM DDI 0405C (September 2008) * * * ***************************************************************************/ @@ -44,11 +44,6 @@ #define _DEBUG_INSTRUCTION_EXECUTION_ #endif -/** Maps from enum armv7m_mode (except ARMV7M_MODE_ANY) to name. */ -char *armv7m_mode_strings[] = { - "Thread", "Thread (User)", "Handler", -}; - static char *armv7m_exception_strings[] = { "", "Reset", "NMI", "HardFault", "MemManage", "BusFault", "UsageFault", "RESERVED", @@ -74,19 +69,6 @@ const int armv7m_msp_reg_map[17] = { ARMV7M_xPSR, }; -#ifdef ARMV7_GDB_HACKS -uint8_t armv7m_gdb_dummy_cpsr_value[] = {0, 0, 0, 0}; - -struct reg armv7m_gdb_dummy_cpsr_reg = { - .name = "GDB dummy cpsr register", - .value = armv7m_gdb_dummy_cpsr_value, - .dirty = 0, - .valid = 1, - .size = 32, - .arch_info = NULL, -}; -#endif - /* * These registers are not memory-mapped. The ARMv7-M profile includes * memory mapped registers too, such as for the NVIC (interrupt controller) @@ -99,35 +81,35 @@ static const struct { unsigned id; const char *name; unsigned bits; + enum reg_type type; + const char *group; + const char *feature; } armv7m_regs[] = { - { ARMV7M_R0, "r0", 32 }, - { ARMV7M_R1, "r1", 32 }, - { ARMV7M_R2, "r2", 32 }, - { ARMV7M_R3, "r3", 32 }, - - { ARMV7M_R4, "r4", 32 }, - { ARMV7M_R5, "r5", 32 }, - { ARMV7M_R6, "r6", 32 }, - { ARMV7M_R7, "r7", 32 }, - - { ARMV7M_R8, "r8", 32 }, - { ARMV7M_R9, "r9", 32 }, - { ARMV7M_R10, "r10", 32 }, - { ARMV7M_R11, "r11", 32 }, - - { ARMV7M_R12, "r12", 32 }, - { ARMV7M_R13, "sp", 32 }, - { ARMV7M_R14, "lr", 32 }, - { ARMV7M_PC, "pc", 32 }, - - { ARMV7M_xPSR, "xPSR", 32 }, - { ARMV7M_MSP, "msp", 32 }, - { ARMV7M_PSP, "psp", 32 }, - - { ARMV7M_PRIMASK, "primask", 1 }, - { ARMV7M_BASEPRI, "basepri", 8 }, - { ARMV7M_FAULTMASK, "faultmask", 1 }, - { ARMV7M_CONTROL, "control", 2 }, + { ARMV7M_R0, "r0", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R1, "r1", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R2, "r2", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R3, "r3", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R4, "r4", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R5, "r5", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R6, "r6", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R7, "r7", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R8, "r8", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R9, "r9", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R10, "r10", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R11, "r11", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R12, "r12", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R13, "sp", 32, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R14, "lr", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_PC, "pc", 32, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_xPSR, "xPSR", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + + { 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" }, + + { 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" }, + { ARMV7M_CONTROL, "control", 2, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, }; #define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs) @@ -140,6 +122,7 @@ int armv7m_restore_context(struct target *target) { int i; struct armv7m_common *armv7m = target_to_armv7m(target); + struct reg_cache *cache = armv7m->arm.core_cache; LOG_DEBUG(" "); @@ -147,8 +130,10 @@ int armv7m_restore_context(struct target *target) armv7m->pre_restore_context(target); for (i = ARMV7M_NUM_REGS - 1; i >= 0; i--) { - if (armv7m->core_cache->reg_list[i].dirty) - armv7m->write_core_reg(target, 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); + } } return ERROR_OK; @@ -178,21 +163,21 @@ char *armv7m_exception_string(int number) static int armv7m_get_core_reg(struct reg *reg) { int retval; - struct armv7m_core_reg *armv7m_reg = reg->arch_info; + struct arm_reg *armv7m_reg = reg->arch_info; struct target *target = armv7m_reg->target; - struct armv7m_common *armv7m = target_to_armv7m(target); + struct arm *arm = target_to_arm(target); if (target->state != TARGET_HALTED) return ERROR_TARGET_NOT_HALTED; - retval = armv7m->read_core_reg(target, armv7m_reg->num); + retval = arm->read_core_reg(target, reg, armv7m_reg->num, arm->core_mode); return retval; } static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf) { - struct armv7m_core_reg *armv7m_reg = reg->arch_info; + struct arm_reg *armv7m_reg = reg->arch_info; struct target *target = armv7m_reg->target; uint32_t value = buf_get_u32(buf, 0, 32); @@ -206,94 +191,75 @@ static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf) return ERROR_OK; } -static int armv7m_read_core_reg(struct target *target, unsigned num) +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 armv7m_core_reg *armv7m_core_reg; + struct arm_reg *armv7m_core_reg; struct armv7m_common *armv7m = target_to_armv7m(target); - if (num >= ARMV7M_NUM_REGS) - return ERROR_COMMAND_SYNTAX_ERROR; + assert(num < (int)armv7m->arm.core_cache->num_regs); - armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info; + armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info; retval = armv7m->load_core_reg_u32(target, - armv7m_core_reg->type, - armv7m_core_reg->num, - ®_value); - buf_set_u32(armv7m->core_cache->reg_list[num].value, 0, 32, reg_value); - armv7m->core_cache->reg_list[num].valid = 1; - armv7m->core_cache->reg_list[num].dirty = 0; + armv7m_core_reg->num, ®_value); + + 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; return retval; } -static int armv7m_write_core_reg(struct target *target, unsigned num) +static int armv7m_write_core_reg(struct target *target, struct reg *r, + int num, enum arm_mode mode, uint32_t value) { int retval; uint32_t reg_value; - struct armv7m_core_reg *armv7m_core_reg; + struct arm_reg *armv7m_core_reg; struct armv7m_common *armv7m = target_to_armv7m(target); - if (num >= ARMV7M_NUM_REGS) - return ERROR_COMMAND_SYNTAX_ERROR; + assert(num < (int)armv7m->arm.core_cache->num_regs); - reg_value = buf_get_u32(armv7m->core_cache->reg_list[num].value, 0, 32); - armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info; + 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->type, armv7m_core_reg->num, reg_value); if (retval != ERROR_OK) { LOG_ERROR("JTAG failure"); - armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid; + armv7m->arm.core_cache->reg_list[num].dirty = armv7m->arm.core_cache->reg_list[num].valid; return ERROR_JTAG_DEVICE_ERROR; } + LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value); - armv7m->core_cache->reg_list[num].valid = 1; - armv7m->core_cache->reg_list[num].dirty = 0; + armv7m->arm.core_cache->reg_list[num].valid = 1; + armv7m->arm.core_cache->reg_list[num].dirty = 0; return ERROR_OK; } /** * Returns generic ARM userspace registers to GDB. - * GDB doesn't quite understand that most ARMs don't have floating point - * hardware, so this also fakes a set of long-obsolete FPA registers that - * are not used in EABI based software stacks. */ -int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size) +int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], + int *reg_list_size, enum target_register_class reg_class) { struct armv7m_common *armv7m = target_to_armv7m(target); int i; - *reg_list_size = 26; + if (reg_class == REG_CLASS_ALL) + *reg_list_size = ARMV7M_NUM_REGS; + else + *reg_list_size = 17; + *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); + if (*reg_list == NULL) + return ERROR_FAIL; - /* - * GDB register packet format for ARM: - * - the first 16 registers are r0..r15 - * - (obsolete) 8 FPA registers - * - (obsolete) FPA status - * - CPSR - */ - for (i = 0; i < 16; i++) - (*reg_list)[i] = &armv7m->core_cache->reg_list[i]; - - for (i = 16; i < 24; i++) - (*reg_list)[i] = &arm_gdb_dummy_fp_reg; - (*reg_list)[24] = &arm_gdb_dummy_fps_reg; - -#ifdef ARMV7_GDB_HACKS - /* use dummy cpsr reg otherwise gdb may try and set the thumb bit */ - (*reg_list)[25] = &armv7m_gdb_dummy_cpsr_reg; - - /* ARMV7M is always in thumb mode, try to make GDB understand this - * if it does not support this arch */ - *((char *)armv7m->arm.pc->value) |= 1; -#else - (*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR]; -#endif + for (i = 0; i < *reg_list_size; i++) + (*reg_list)[i] = &armv7m->arm.core_cache->reg_list[i]; return ERROR_OK; } @@ -332,7 +298,7 @@ int armv7m_start_algorithm(struct target *target, { struct armv7m_common *armv7m = target_to_armv7m(target); struct armv7m_algorithm *armv7m_algorithm_info = arch_info; - enum armv7m_mode core_mode = armv7m->core_mode; + enum arm_mode core_mode = armv7m->arm.core_mode; int retval = ERROR_OK; /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint @@ -351,10 +317,9 @@ 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++) { - if (!armv7m->core_cache->reg_list[i].valid) - armv7m->read_core_reg(target, i); + armv7m_algorithm_info->context[i] = buf_get_u32( - armv7m->core_cache->reg_list[i].value, + armv7m->arm.core_cache->reg_list[i].value, 0, 32); } @@ -370,7 +335,7 @@ int armv7m_start_algorithm(struct target *target, for (int i = 0; i < num_reg_params; i++) { struct reg *reg = - register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0); + register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, 0); /* uint32_t regvalue; */ if (!reg) { @@ -388,13 +353,23 @@ int armv7m_start_algorithm(struct target *target, armv7m_set_core_reg(reg, reg_params[i].value); } - if (armv7m_algorithm_info->core_mode != ARMV7M_MODE_ANY) { + if (armv7m_algorithm_info->core_mode != ARM_MODE_ANY && + armv7m_algorithm_info->core_mode != core_mode) { + + /* we cannot set ARM_MODE_HANDLER, so use ARM_MODE_THREAD instead */ + if (armv7m_algorithm_info->core_mode == ARM_MODE_HANDLER) { + armv7m_algorithm_info->core_mode = ARM_MODE_THREAD; + LOG_INFO("ARM_MODE_HANDLER not currently supported, using ARM_MODE_THREAD instead"); + } + LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode); - buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, + buf_set_u32(armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].value, 0, 1, armv7m_algorithm_info->core_mode); - armv7m->core_cache->reg_list[ARMV7M_CONTROL].dirty = 1; - armv7m->core_cache->reg_list[ARMV7M_CONTROL].valid = 1; + armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = 1; + armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = 1; } + + /* save previous core mode */ armv7m_algorithm_info->core_mode = core_mode; retval = target_resume(target, 0, entry_point, 1, 1); @@ -434,7 +409,7 @@ int armv7m_wait_algorithm(struct target *target, return ERROR_TARGET_TIMEOUT; } - armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc); + armv7m->load_core_reg_u32(target, 15, &pc); if (exit_point && (pc != exit_point)) { LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" PRIx32, pc, @@ -456,7 +431,7 @@ int armv7m_wait_algorithm(struct target *target, /* Copy core register values to reg_params[] */ for (int i = 0; i < num_reg_params; i++) { if (reg_params[i].direction != PARAM_OUT) { - struct reg *reg = register_get_by_name(armv7m->core_cache, + struct reg *reg = register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, 0); @@ -478,19 +453,28 @@ int armv7m_wait_algorithm(struct target *target, for (int i = ARMV7M_NUM_REGS - 1; i >= 0; i--) { uint32_t regvalue; - regvalue = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32); + regvalue = buf_get_u32(armv7m->arm.core_cache->reg_list[i].value, 0, 32); if (regvalue != armv7m_algorithm_info->context[i]) { LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32, - armv7m->core_cache->reg_list[i].name, + armv7m->arm.core_cache->reg_list[i].name, armv7m_algorithm_info->context[i]); - buf_set_u32(armv7m->core_cache->reg_list[i].value, + buf_set_u32(armv7m->arm.core_cache->reg_list[i].value, 0, 32, armv7m_algorithm_info->context[i]); - armv7m->core_cache->reg_list[i].valid = 1; - armv7m->core_cache->reg_list[i].dirty = 1; + armv7m->arm.core_cache->reg_list[i].valid = 1; + armv7m->arm.core_cache->reg_list[i].dirty = 1; } } - armv7m->core_mode = armv7m_algorithm_info->core_mode; + /* restore previous core mode */ + if (armv7m_algorithm_info->core_mode != armv7m->arm.core_mode) { + LOG_DEBUG("restoring core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode); + buf_set_u32(armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].value, + 0, 1, armv7m_algorithm_info->core_mode); + armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = 1; + armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = 1; + } + + armv7m->arm.core_mode = armv7m_algorithm_info->core_mode; return retval; } @@ -502,13 +486,13 @@ int armv7m_arch_state(struct target *target) struct arm *arm = &armv7m->arm; uint32_t ctrl, sp; - ctrl = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 32); - sp = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_R13].value, 0, 32); + ctrl = buf_get_u32(arm->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 32); + sp = buf_get_u32(arm->core_cache->reg_list[ARMV7M_R13].value, 0, 32); LOG_USER("target halted due to %s, current mode: %s %s\n" "xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32 "%s", debug_reason_name(target), - armv7m_mode_strings[armv7m->core_mode], + arm_mode_name(arm->core_mode), armv7m_exception_string(armv7m->exception_number), buf_get_u32(arm->cpsr->value, 0, 32), buf_get_u32(arm->pc->value, 0, 32), @@ -518,6 +502,7 @@ int armv7m_arch_state(struct target *target) return ERROR_OK; } + static const struct reg_arch_type armv7m_reg_type = { .get = armv7m_get_core_reg, .set = armv7m_set_core_reg, @@ -532,25 +517,22 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); struct reg_cache *cache = malloc(sizeof(struct reg_cache)); struct reg *reg_list = calloc(num_regs, sizeof(struct reg)); - struct armv7m_core_reg *arch_info = calloc(num_regs, sizeof(struct armv7m_core_reg)); + struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg)); + struct reg_feature *feature; int i; -#ifdef ARMV7_GDB_HACKS - register_init_dummy(&armv7m_gdb_dummy_cpsr_reg); -#endif - /* Build the process context cache */ cache->name = "arm v7m registers"; cache->next = NULL; cache->reg_list = reg_list; cache->num_regs = num_regs; (*cache_p) = cache; - armv7m->core_cache = cache; for (i = 0; i < num_regs; i++) { arch_info[i].num = armv7m_regs[i].id; arch_info[i].target = target; - arch_info[i].armv7m_common = armv7m; + arch_info[i].arm = arm; + reg_list[i].name = armv7m_regs[i].name; reg_list[i].size = armv7m_regs[i].bits; reg_list[i].value = calloc(1, 4); @@ -558,11 +540,30 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) reg_list[i].valid = 0; reg_list[i].type = &armv7m_reg_type; reg_list[i].arch_info = &arch_info[i]; + + reg_list[i].group = armv7m_regs[i].group; + reg_list[i].number = i; + reg_list[i].exist = true; + reg_list[i].caller_save = true; /* gdb defaults to true */ + + feature = calloc(1, sizeof(struct reg_feature)); + if (feature) { + feature->name = armv7m_regs[i].feature; + reg_list[i].feature = feature; + } else + LOG_ERROR("unable to allocate feature list"); + + reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type)); + if (reg_list[i].reg_data_type) + reg_list[i].reg_data_type->type = armv7m_regs[i].type; + else + LOG_ERROR("unable to allocate reg type list"); } arm->cpsr = reg_list + ARMV7M_xPSR; arm->pc = reg_list + ARMV7M_PC; arm->core_cache = cache; + return cache; } @@ -584,11 +585,8 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m) arm->arch_info = armv7m; arm->setup_semihosting = armv7m_setup_semihosting; - /* FIXME remove v7m-specific r/w core_reg functions; - * use the generic ARM core support.. - */ - armv7m->read_core_reg = armv7m_read_core_reg; - armv7m->write_core_reg = armv7m_write_core_reg; + arm->read_core_reg = armv7m_read_core_reg; + arm->write_core_reg = armv7m_write_core_reg; return arm_init_arch_info(target, arm); } @@ -602,55 +600,53 @@ int armv7m_checksum_memory(struct target *target, struct reg_param reg_params[2]; int retval; - /* see contib/loaders/checksum/armv7m_crc.s for src */ - - static const uint16_t cortex_m3_crc_code[] = { - 0x4602, /* mov r2, r0 */ - 0xF04F, 0x30FF, /* mov r0, #0xffffffff */ - 0x460B, /* mov r3, r1 */ - 0xF04F, 0x0400, /* mov r4, #0 */ - 0xE013, /* b ncomp */ + /* see contrib/loaders/checksum/armv7m_crc.s for src */ + + static const uint8_t cortex_m3_crc_code[] = { + /* main: */ + 0x02, 0x46, /* mov r2, r0 */ + 0x00, 0x20, /* movs r0, #0 */ + 0xC0, 0x43, /* mvns r0, r0 */ + 0x0A, 0x4E, /* ldr r6, CRC32XOR */ + 0x0B, 0x46, /* mov r3, r1 */ + 0x00, 0x24, /* movs r4, #0 */ + 0x0D, 0xE0, /* b ncomp */ /* nbyte: */ - 0x5D11, /* ldrb r1, [r2, r4] */ - 0xF8DF, 0x7028, /* ldr r7, CRC32XOR */ - 0xEA80, 0x6001, /* eor r0, r0, r1, asl #24 */ - - 0xF04F, 0x0500, /* mov r5, #0 */ + 0x11, 0x5D, /* ldrb r1, [r2, r4] */ + 0x09, 0x06, /* lsls r1, r1, #24 */ + 0x48, 0x40, /* eors r0, r0, r1 */ + 0x00, 0x25, /* movs r5, #0 */ /* loop: */ - 0x2800, /* cmp r0, #0 */ - 0xEA4F, 0x0640, /* mov r6, r0, asl #1 */ - 0xF105, 0x0501, /* add r5, r5, #1 */ - 0x4630, /* mov r0, r6 */ - 0xBFB8, /* it lt */ - 0xEA86, 0x0007, /* eor r0, r6, r7 */ - 0x2D08, /* cmp r5, #8 */ - 0xD1F4, /* bne loop */ - - 0xF104, 0x0401, /* add r4, r4, #1 */ + 0x00, 0x28, /* cmp r0, #0 */ + 0x02, 0xDA, /* bge notset */ + 0x40, 0x00, /* lsls r0, r0, #1 */ + 0x70, 0x40, /* eors r0, r0, r6 */ + 0x00, 0xE0, /* b cont */ + /* notset: */ + 0x40, 0x00, /* lsls r0, r0, #1 */ + /* cont: */ + 0x01, 0x35, /* adds r5, r5, #1 */ + 0x08, 0x2D, /* cmp r5, #8 */ + 0xF6, 0xD1, /* bne loop */ + 0x01, 0x34, /* adds r4, r4, #1 */ /* ncomp: */ - 0x429C, /* cmp r4, r3 */ - 0xD1E9, /* bne nbyte */ - 0xBE00, /* bkpt #0 */ - 0x1DB7, 0x04C1 /* CRC32XOR: .word 0x04C11DB7 */ + 0x9C, 0x42, /* cmp r4, r3 */ + 0xEF, 0xD1, /* bne nbyte */ + 0x00, 0xBE, /* bkpt #0 */ + 0xB7, 0x1D, 0xC1, 0x04 /* CRC32XOR: .word 0x04c11db7 */ }; - uint32_t i; - retval = target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm); if (retval != ERROR_OK) return retval; - /* convert flash writing code into a buffer in target endianness */ - for (i = 0; i < ARRAY_SIZE(cortex_m3_crc_code); i++) { - retval = target_write_u16(target, - crc_algorithm->address + i*sizeof(uint16_t), - cortex_m3_crc_code[i]); - if (retval != ERROR_OK) - goto cleanup; - } + retval = target_write_buffer(target, crc_algorithm->address, + sizeof(cortex_m3_crc_code), (uint8_t *)cortex_m3_crc_code); + if (retval != ERROR_OK) + goto cleanup; armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARMV7M_MODE_ANY; + armv7m_info.core_mode = ARM_MODE_THREAD; init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); init_reg_param(®_params[1], "r1", 32, PARAM_OUT); @@ -667,7 +663,7 @@ int armv7m_checksum_memory(struct target *target, if (retval == ERROR_OK) *checksum = buf_get_u32(reg_params[0].value, 0, 32); else - LOG_ERROR("error executing cortex_m3 crc algorithm"); + LOG_ERROR("error executing cortex_m crc algorithm"); destroy_reg_param(®_params[0]); destroy_reg_param(®_params[1]); @@ -686,15 +682,17 @@ int armv7m_blank_check_memory(struct target *target, struct reg_param reg_params[3]; struct armv7m_algorithm armv7m_info; int retval; - uint32_t i; - static const uint16_t erase_check_code[] = { + /* see contrib/loaders/erase_check/armv7m_erase_check.s for src */ + + static const uint8_t erase_check_code[] = { /* loop: */ - 0xF810, 0x3B01, /* ldrb r3, [r0], #1 */ - 0xEA02, 0x0203, /* and r2, r2, r3 */ - 0x3901, /* subs r1, r1, #1 */ - 0xD1F9, /* bne loop */ - 0xBE00, /* bkpt #0 */ + 0x03, 0x78, /* ldrb r3, [r0] */ + 0x01, 0x30, /* adds r0, #1 */ + 0x1A, 0x40, /* ands r2, r2, r3 */ + 0x01, 0x39, /* subs r1, r1, #1 */ + 0xFA, 0xD1, /* bne loop */ + 0x00, 0xBE /* bkpt #0 */ }; /* make sure we have a working area */ @@ -702,14 +700,13 @@ int armv7m_blank_check_memory(struct target *target, &erase_check_algorithm) != ERROR_OK) return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - /* convert flash writing code into a buffer in target endianness */ - for (i = 0; i < ARRAY_SIZE(erase_check_code); i++) - target_write_u16(target, - erase_check_algorithm->address + i*sizeof(uint16_t), - erase_check_code[i]); + retval = target_write_buffer(target, erase_check_algorithm->address, + sizeof(erase_check_code), (uint8_t *)erase_check_code); + if (retval != ERROR_OK) + return retval; armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARMV7M_MODE_ANY; + armv7m_info.core_mode = ARM_MODE_THREAD; init_reg_param(®_params[0], "r0", 32, PARAM_OUT); buf_set_u32(reg_params[0].value, 0, 32, address);