armv7m: add gdb target description support
Change-Id: I7c01109c0b85d208fb04a7ae1185fab4b2ab96b8 Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk> Reviewed-on: http://openocd.zylin.com/1620 Tested-by: jenkins Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
This commit is contained in:
parent
f90e911026
commit
1255b18fc6
|
@ -81,35 +81,35 @@ static const struct {
|
||||||
unsigned id;
|
unsigned id;
|
||||||
const char *name;
|
const char *name;
|
||||||
unsigned bits;
|
unsigned bits;
|
||||||
|
enum reg_type type;
|
||||||
|
const char *group;
|
||||||
|
const char *feature;
|
||||||
} armv7m_regs[] = {
|
} armv7m_regs[] = {
|
||||||
{ ARMV7M_R0, "r0", 32 },
|
{ ARMV7M_R0, "r0", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" },
|
||||||
{ ARMV7M_R1, "r1", 32 },
|
{ ARMV7M_R1, "r1", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" },
|
||||||
{ ARMV7M_R2, "r2", 32 },
|
{ ARMV7M_R2, "r2", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" },
|
||||||
{ ARMV7M_R3, "r3", 32 },
|
{ 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_R4, "r4", 32 },
|
{ ARMV7M_MSP, "msp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" },
|
||||||
{ ARMV7M_R5, "r5", 32 },
|
{ ARMV7M_PSP, "psp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" },
|
||||||
{ ARMV7M_R6, "r6", 32 },
|
|
||||||
{ ARMV7M_R7, "r7", 32 },
|
|
||||||
|
|
||||||
{ ARMV7M_R8, "r8", 32 },
|
{ ARMV7M_PRIMASK, "primask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||||
{ ARMV7M_R9, "r9", 32 },
|
{ ARMV7M_BASEPRI, "basepri", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||||
{ ARMV7M_R10, "r10", 32 },
|
{ ARMV7M_FAULTMASK, "faultmask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||||
{ ARMV7M_R11, "r11", 32 },
|
{ ARMV7M_CONTROL, "control", 2, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||||
|
|
||||||
{ 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 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs)
|
#define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs)
|
||||||
|
@ -242,9 +242,6 @@ static int armv7m_write_core_reg(struct target *target, struct reg *r,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns generic ARM userspace registers to GDB.
|
* 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 armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
|
||||||
int *reg_list_size, enum target_register_class reg_class)
|
int *reg_list_size, enum target_register_class reg_class)
|
||||||
|
@ -252,24 +249,18 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
|
||||||
struct armv7m_common *armv7m = target_to_armv7m(target);
|
struct armv7m_common *armv7m = target_to_armv7m(target);
|
||||||
int i;
|
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));
|
*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
|
||||||
|
if (*reg_list == NULL)
|
||||||
|
return ERROR_FAIL;
|
||||||
|
|
||||||
/*
|
for (i = 0; i < *reg_list_size; i++)
|
||||||
* 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->arm.core_cache->reg_list[i];
|
(*reg_list)[i] = &armv7m->arm.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;
|
|
||||||
(*reg_list)[25] = &armv7m->arm.core_cache->reg_list[ARMV7M_xPSR];
|
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,6 +518,7 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target)
|
||||||
struct reg_cache *cache = malloc(sizeof(struct reg_cache));
|
struct reg_cache *cache = malloc(sizeof(struct reg_cache));
|
||||||
struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
|
struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
|
||||||
struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
|
struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
|
||||||
|
struct reg_feature *feature;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Build the process context cache */
|
/* Build the process context cache */
|
||||||
|
@ -548,11 +540,30 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target)
|
||||||
reg_list[i].valid = 0;
|
reg_list[i].valid = 0;
|
||||||
reg_list[i].type = &armv7m_reg_type;
|
reg_list[i].type = &armv7m_reg_type;
|
||||||
reg_list[i].arch_info = &arch_info[i];
|
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->cpsr = reg_list + ARMV7M_xPSR;
|
||||||
arm->pc = reg_list + ARMV7M_PC;
|
arm->pc = reg_list + ARMV7M_PC;
|
||||||
arm->core_cache = cache;
|
arm->core_cache = cache;
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue