X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farmv7m.c;h=93df5877eb21de6ed0f7b7ff6625df0f7c55eb0a;hb=9d925776b4504f71306b16467c1b731e57b6e7d0;hp=ee05e47299a0ba22c3adc7ddbf6b983124c5dadc;hpb=08ee7bb982b16742f52cfdc6c649d82ffa2eb177;p=openocd.git diff --git a/src/target/armv7m.c b/src/target/armv7m.c index ee05e47299..93df5877eb 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -17,19 +19,6 @@ * Copyright (C) 2019 by Tomas Vanek * * vanekt@fbl.cz * * * - * 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 * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * * ARMv7-M Architecture, Application Level Reference Manual * * ARM DDI 0405C (September 2008) * * * @@ -44,6 +33,8 @@ #include "algorithm.h" #include "register.h" #include "semihosting_common.h" +#include +#include #if 0 #define _DEBUG_INSTRUCTION_EXECUTION_ @@ -62,7 +53,7 @@ const int armv7m_psp_reg_map[ARMV7M_NUM_CORE_REGS] = { ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7, ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11, ARMV7M_R12, ARMV7M_PSP, ARMV7M_R14, ARMV7M_PC, - ARMV7M_xPSR, + ARMV7M_XPSR, }; /* MSP is used in handler and some thread modes */ @@ -71,7 +62,7 @@ const int armv7m_msp_reg_map[ARMV7M_NUM_CORE_REGS] = { ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7, ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11, ARMV7M_R12, ARMV7M_MSP, ARMV7M_R14, ARMV7M_PC, - ARMV7M_xPSR, + ARMV7M_XPSR, }; /* @@ -106,7 +97,7 @@ static const struct { { 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_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" }, @@ -125,27 +116,27 @@ 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" }, + /* ARMv8-M security extension (TrustZone) specific registers */ + { ARMV8M_MSP_NS, "msp_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" }, + { ARMV8M_PSP_NS, "psp_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" }, + { ARMV8M_MSP_S, "msp_s", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" }, + { ARMV8M_PSP_S, "psp_s", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" }, + { ARMV8M_MSPLIM_S, "msplim_s", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" }, + { ARMV8M_PSPLIM_S, "psplim_s", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" }, + { ARMV8M_MSPLIM_NS, "msplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" }, + { ARMV8M_PSPLIM_NS, "psplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" }, { 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_PRIMASK_S, "primask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" }, + { ARMV8M_BASEPRI_S, "basepri_s", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" }, + { ARMV8M_FAULTMASK_S, "faultmask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" }, + { ARMV8M_CONTROL_S, "control_s", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" }, { 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" }, + { ARMV8M_PRIMASK_NS, "primask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" }, + { ARMV8M_BASEPRI_NS, "basepri_ns", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" }, + { ARMV8M_FAULTMASK_NS, "faultmask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" }, + { ARMV8M_CONTROL_NS, "control_ns", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" }, /* FPU registers */ { ARMV7M_D0, "d0", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, @@ -249,12 +240,12 @@ 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) +uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) { switch (arm_reg_id) { case ARMV7M_R0 ... ARMV7M_R14: case ARMV7M_PC: - case ARMV7M_xPSR: + case ARMV7M_XPSR: case ARMV7M_MSP: case ARMV7M_PSP: /* NOTE: we "know" here that the register identifiers @@ -287,7 +278,7 @@ static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) } } -static bool armv7m_map_reg_packing(unsigned int arm_reg_id, +bool armv7m_map_reg_packing(unsigned int arm_reg_id, unsigned int *reg32_id, uint32_t *offset) { @@ -474,7 +465,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++) @@ -537,11 +528,17 @@ int armv7m_start_algorithm(struct target *target, /* Store all non-debug execution registers to armv7m_algorithm_info context */ for (unsigned i = 0; i < armv7m->arm.core_cache->num_regs; i++) { + struct reg *reg = &armv7m->arm.core_cache->reg_list[i]; + if (!reg->exist) + continue; - armv7m_algorithm_info->context[i] = buf_get_u32( - armv7m->arm.core_cache->reg_list[i].value, - 0, - 32); + if (!reg->valid) + armv7m_get_core_reg(reg); + + if (!reg->valid) + LOG_TARGET_WARNING(target, "Storing invalid register %s", reg->name); + + armv7m_algorithm_info->context[i] = buf_get_u32(reg->value, 0, 32); } for (int i = 0; i < num_mem_params; i++) { @@ -588,7 +585,7 @@ int armv7m_start_algorithm(struct target *target, * Because xPSR.T is populated on reset from the vector table, * it might be 0 if the vector table has "bad" data in it. */ - struct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_xPSR]; + struct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_XPSR]; buf_set_u32(reg->value, 0, 32, 0x01000000); reg->valid = true; reg->dirty = true; @@ -694,16 +691,19 @@ int armv7m_wait_algorithm(struct target *target, } for (int i = armv7m->arm.core_cache->num_regs - 1; i >= 0; i--) { + struct reg *reg = &armv7m->arm.core_cache->reg_list[i]; + if (!reg->exist) + continue; + uint32_t regvalue; - regvalue = buf_get_u32(armv7m->arm.core_cache->reg_list[i].value, 0, 32); + regvalue = buf_get_u32(reg->value, 0, 32); if (regvalue != armv7m_algorithm_info->context[i]) { LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32, - armv7m->arm.core_cache->reg_list[i].name, - armv7m_algorithm_info->context[i]); - buf_set_u32(armv7m->arm.core_cache->reg_list[i].value, + reg->name, armv7m_algorithm_info->context[i]); + buf_set_u32(reg->value, 0, 32, armv7m_algorithm_info->context[i]); - armv7m->arm.core_cache->reg_list[i].valid = true; - armv7m->arm.core_cache->reg_list[i].dirty = true; + reg->valid = true; + reg->dirty = true; } } @@ -735,8 +735,9 @@ int armv7m_arch_state(struct target *target) 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" + LOG_USER("[%s] halted due to %s, current mode: %s %s\n" "xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32 "%s%s", + target_name(target), debug_reason_name(target), arm_mode_name(arm->core_mode), armv7m_exception_string(armv7m->exception_number), @@ -812,7 +813,7 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) LOG_ERROR("unable to allocate reg type list"); } - arm->cpsr = reg_list + ARMV7M_xPSR; + arm->cpsr = reg_list + ARMV7M_XPSR; arm->pc = reg_list + ARMV7M_PC; arm->core_cache = cache; @@ -863,6 +864,7 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m) /* Enable stimulus port #0 by default */ armv7m->trace_config.itm_ter[0] = 1; + arm->core_state = ARM_STATE_THUMB; arm->core_type = ARM_CORE_TYPE_M_PROFILE; arm->arch_info = armv7m; arm->setup_semihosting = armv7m_setup_semihosting; @@ -1093,7 +1095,11 @@ int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found) const struct command_registration armv7m_command_handlers[] = { { - .chain = arm_command_handlers, + .name = "arm", + .mode = COMMAND_ANY, + .help = "ARM command group", + .usage = "", + .chain = arm_all_profiles_command_handlers, }, COMMAND_REGISTRATION_DONE };