David Brownell <david-b@pacbell.net>:
Clean up treatment of registers in ARMv7-M and Cortex-M3. - At the arch level: * Just list registers and names; don't impose core-specific policy about how they are accessed. * Each register has a symbol. * Remove the register mode field (irrelevant to debugger) - At the core/implementation level: * Just map the registers to their relevant access methods; don't require the arch level to say how that should work (cores other than Cortex-M3 could do it differently). * Don't use undefined bits from register 20. * Use register IDs that are part of the ARMv7-M interface. In short, there's now a real distinction between the arch and core layers. git-svn-id: svn://svn.berlios.de/openocd/trunk@2554 b42882b7-edfa-0310-969c-e2dbd0fdcd60__archive__
parent
eea0486263
commit
4da019edeb
|
@ -36,6 +36,8 @@
|
|||
|
||||
#include "armv7m.h"
|
||||
|
||||
#define ARRAY_SIZE(x) ((int)(sizeof(x)/sizeof((x)[0])))
|
||||
|
||||
|
||||
#if 0
|
||||
#define _DEBUG_INSTRUCTION_EXECUTION_
|
||||
|
@ -46,7 +48,7 @@ char* armv7m_mode_strings[] =
|
|||
"Thread", "Thread (User)", "Handler",
|
||||
};
|
||||
|
||||
char* armv7m_exception_strings[] =
|
||||
static char *armv7m_exception_strings[] =
|
||||
{
|
||||
"", "Reset", "NMI", "HardFault",
|
||||
"MemManage", "BusFault", "UsageFault", "RESERVED",
|
||||
|
@ -54,16 +56,6 @@ char* armv7m_exception_strings[] =
|
|||
"DebugMonitor", "RESERVED", "PendSV", "SysTick"
|
||||
};
|
||||
|
||||
char* armv7m_core_reg_list[] =
|
||||
{
|
||||
/* Registers accessed through core debug */
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
|
||||
"sp", "lr", "pc",
|
||||
"xPSR", "msp", "psp",
|
||||
/* Registers accessed through special reg 20 */
|
||||
"primask", "basepri", "faultmask", "control"
|
||||
};
|
||||
|
||||
uint8_t armv7m_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
reg_t armv7m_gdb_dummy_fp_reg =
|
||||
|
@ -87,37 +79,47 @@ reg_t armv7m_gdb_dummy_cpsr_reg =
|
|||
};
|
||||
#endif
|
||||
|
||||
armv7m_core_reg_t armv7m_core_reg_list_arch_info[] =
|
||||
{
|
||||
/* CORE_GP are accesible using the core debug registers */
|
||||
{0, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{1, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{2, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{3, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{4, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{5, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{6, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{7, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{8, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{9, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{10, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{11, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{12, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{13, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{14, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
{15, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
|
||||
/*
|
||||
* These registers are not memory-mapped. The ARMv7-M profile includes
|
||||
* memory mapped registers too, such as for the NVIC (interrupt controller)
|
||||
* and SysTick (timer) modules; those can mostly be treated as peripherals.
|
||||
*/
|
||||
static const struct {
|
||||
unsigned id;
|
||||
char *name;
|
||||
} armv7m_regs[] = {
|
||||
{ ARMV7M_R0, "r0" },
|
||||
{ ARMV7M_R1, "r1" },
|
||||
{ ARMV7M_R2, "r2" },
|
||||
{ ARMV7M_R3, "r3" },
|
||||
|
||||
{16, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* xPSR */
|
||||
{17, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* MSP */
|
||||
{18, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* PSP */
|
||||
{ ARMV7M_R4, "r4" },
|
||||
{ ARMV7M_R5, "r5" },
|
||||
{ ARMV7M_R6, "r6" },
|
||||
{ ARMV7M_R7, "r7" },
|
||||
|
||||
/* CORE_SP are accesible using coreregister 20 */
|
||||
{19, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* PRIMASK */
|
||||
{20, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* BASEPRI */
|
||||
{21, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* FAULTMASK */
|
||||
{22, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL} /* CONTROL */
|
||||
{ ARMV7M_R8, "r8" },
|
||||
{ ARMV7M_R9, "r9" },
|
||||
{ ARMV7M_R10, "r10" },
|
||||
{ ARMV7M_R11, "r11" },
|
||||
|
||||
{ ARMV7M_R12, "r12" },
|
||||
{ ARMV7M_R13, "sp" },
|
||||
{ ARMV7M_R14, "lr" },
|
||||
{ ARMV7M_PC, "pc" },
|
||||
|
||||
{ ARMV7M_xPSR, "xPSR" },
|
||||
{ ARMV7M_MSP, "msp" },
|
||||
{ ARMV7M_PSP, "psp" },
|
||||
|
||||
{ ARMV7M_PRIMASK, "primask" },
|
||||
{ ARMV7M_BASEPRI, "basepri" },
|
||||
{ ARMV7M_FAULTMASK, "faultmask" },
|
||||
{ ARMV7M_CONTROL, "control" },
|
||||
};
|
||||
|
||||
#define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs)
|
||||
|
||||
int armv7m_core_reg_arch_type = -1;
|
||||
int armv7m_dummy_core_reg_arch_type = -1;
|
||||
|
||||
|
@ -133,7 +135,7 @@ int armv7m_restore_context(target_t *target)
|
|||
if (armv7m->pre_restore_context)
|
||||
armv7m->pre_restore_context(target);
|
||||
|
||||
for (i = ARMV7NUMCOREREGS-1; i >= 0; i--)
|
||||
for (i = ARMV7M_NUM_REGS - 1; i >= 0; i--)
|
||||
{
|
||||
if (armv7m->core_cache->reg_list[i].dirty)
|
||||
{
|
||||
|
@ -204,7 +206,7 @@ int armv7m_read_core_reg(struct target_s *target, int num)
|
|||
/* get pointers to arch-specific information */
|
||||
armv7m_common_t *armv7m = target->arch_info;
|
||||
|
||||
if ((num < 0) || (num >= ARMV7NUMCOREREGS))
|
||||
if ((num < 0) || (num >= ARMV7M_NUM_REGS))
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info;
|
||||
|
@ -225,7 +227,7 @@ int armv7m_write_core_reg(struct target_s *target, int num)
|
|||
/* get pointers to arch-specific information */
|
||||
armv7m_common_t *armv7m = target->arch_info;
|
||||
|
||||
if ((num < 0) || (num >= ARMV7NUMCOREREGS))
|
||||
if ((num < 0) || (num >= ARMV7M_NUM_REGS))
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
reg_value = buf_get_u32(armv7m->core_cache->reg_list[num].value, 0, 32);
|
||||
|
@ -268,6 +270,13 @@ int armv7m_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_
|
|||
*reg_list_size = 26;
|
||||
*reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
|
||||
|
||||
/*
|
||||
* 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];
|
||||
|
@ -337,7 +346,7 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
|
|||
enum armv7m_mode core_mode = armv7m->core_mode;
|
||||
int retval = ERROR_OK;
|
||||
int i;
|
||||
uint32_t context[ARMV7NUMCOREREGS];
|
||||
uint32_t context[ARMV7M_NUM_REGS];
|
||||
|
||||
if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC)
|
||||
{
|
||||
|
@ -353,7 +362,7 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
|
|||
|
||||
/* refresh core register cache */
|
||||
/* Not needed if core register cache is always consistent with target process state */
|
||||
for (i = 0; i < ARMV7NUMCOREREGS; i++)
|
||||
for (i = 0; i < ARMV7M_NUM_REGS; i++)
|
||||
{
|
||||
if (!armv7m->core_cache->reg_list[i].valid)
|
||||
armv7m->read_core_reg(target, i);
|
||||
|
@ -390,7 +399,8 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
|
|||
if (armv7m_algorithm_info->core_mode != ARMV7M_MODE_ANY)
|
||||
{
|
||||
LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode);
|
||||
buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 1, armv7m_algorithm_info->core_mode);
|
||||
buf_set_u32(armv7m->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;
|
||||
}
|
||||
|
@ -444,14 +454,16 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
|
|||
}
|
||||
}
|
||||
|
||||
for (i = ARMV7NUMCOREREGS-1; i >= 0; i--)
|
||||
for (i = ARMV7M_NUM_REGS; i >= 0; i--)
|
||||
{
|
||||
uint32_t regvalue;
|
||||
regvalue = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32);
|
||||
if (regvalue != context[i])
|
||||
{
|
||||
LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "", armv7m->core_cache->reg_list[i].name, context[i]);
|
||||
buf_set_u32(armv7m->core_cache->reg_list[i].value, 0, 32, context[i]);
|
||||
LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
|
||||
armv7m->core_cache->reg_list[i].name, context[i]);
|
||||
buf_set_u32(armv7m->core_cache->reg_list[i].value,
|
||||
0, 32, context[i]);
|
||||
armv7m->core_cache->reg_list[i].valid = 1;
|
||||
armv7m->core_cache->reg_list[i].dirty = 1;
|
||||
}
|
||||
|
@ -467,12 +479,13 @@ int armv7m_arch_state(struct target_s *target)
|
|||
/* get pointers to arch-specific information */
|
||||
armv7m_common_t *armv7m = target->arch_info;
|
||||
|
||||
LOG_USER("target halted due to %s, current mode: %s %s\nxPSR: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
|
||||
LOG_USER("target halted due to %s, current mode: %s %s\n"
|
||||
"xPSR: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32,
|
||||
Jim_Nvp_value2name_simple(nvp_target_debug_reason,target->debug_reason)->name,
|
||||
armv7m_mode_strings[armv7m->core_mode],
|
||||
armv7m_exception_string(armv7m->exception_number),
|
||||
buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32),
|
||||
buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32));
|
||||
buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_PC].value, 0, 32));
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -482,11 +495,11 @@ reg_cache_t *armv7m_build_reg_cache(target_t *target)
|
|||
/* get pointers to arch-specific information */
|
||||
armv7m_common_t *armv7m = target->arch_info;
|
||||
|
||||
int num_regs = ARMV7NUMCOREREGS;
|
||||
int num_regs = ARMV7M_NUM_REGS;
|
||||
reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
|
||||
reg_cache_t *cache = malloc(sizeof(reg_cache_t));
|
||||
reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
|
||||
armv7m_core_reg_t *arch_info = malloc(sizeof(armv7m_core_reg_t) * num_regs);
|
||||
reg_t *reg_list = calloc(num_regs, sizeof(reg_t));
|
||||
armv7m_core_reg_t *arch_info = calloc(num_regs, sizeof(armv7m_core_reg_t));
|
||||
int i;
|
||||
|
||||
if (armv7m_core_reg_arch_type == -1)
|
||||
|
@ -510,10 +523,10 @@ reg_cache_t *armv7m_build_reg_cache(target_t *target)
|
|||
|
||||
for (i = 0; i < num_regs; i++)
|
||||
{
|
||||
arch_info[i] = armv7m_core_reg_list_arch_info[i];
|
||||
arch_info[i].num = armv7m_regs[i].id;
|
||||
arch_info[i].target = target;
|
||||
arch_info[i].armv7m_common = armv7m;
|
||||
reg_list[i].name = armv7m_core_reg_list[i];
|
||||
reg_list[i].name = armv7m_regs[i].name;
|
||||
reg_list[i].size = 32;
|
||||
reg_list[i].value = calloc(1, 4);
|
||||
reg_list[i].dirty = 0;
|
||||
|
|
|
@ -50,22 +50,43 @@ enum armv7m_regtype
|
|||
ARMV7M_REGISTER_MEMMAP
|
||||
};
|
||||
|
||||
extern char* armv7m_exception_strings[];
|
||||
|
||||
extern char *armv7m_exception_string(int number);
|
||||
|
||||
/* offsets into armv7m core register cache */
|
||||
enum
|
||||
{
|
||||
/* for convenience, the first set of indices match
|
||||
* the Cortex-M3 DCRSR selectors
|
||||
*/
|
||||
ARMV7M_R0,
|
||||
ARMV7M_R1,
|
||||
ARMV7M_R2,
|
||||
ARMV7M_R3,
|
||||
|
||||
ARMV7M_R4,
|
||||
ARMV7M_R5,
|
||||
ARMV7M_R6,
|
||||
ARMV7M_R7,
|
||||
|
||||
ARMV7M_R8,
|
||||
ARMV7M_R9,
|
||||
ARMV7M_R10,
|
||||
ARMV7M_R11,
|
||||
|
||||
ARMV7M_R12,
|
||||
ARMV7M_R13,
|
||||
ARMV7M_R14,
|
||||
ARMV7M_PC = 15,
|
||||
|
||||
ARMV7M_xPSR = 16,
|
||||
ARMV7M_MSP,
|
||||
ARMV7M_PSP,
|
||||
|
||||
/* this next set of indices is arbitrary */
|
||||
ARMV7M_PRIMASK,
|
||||
ARMV7M_BASEPRI,
|
||||
ARMV7M_FAULTMASK,
|
||||
ARMV7M_CONTROL,
|
||||
ARMV7NUMCOREREGS
|
||||
};
|
||||
|
||||
#define ARMV7M_COMMON_MAGIC 0x2A452A45
|
||||
|
@ -107,7 +128,6 @@ typedef struct armv7m_core_reg_s
|
|||
{
|
||||
uint32_t num;
|
||||
enum armv7m_regtype type;
|
||||
enum armv7m_mode mode;
|
||||
target_t *target;
|
||||
armv7m_common_t *armv7m_common;
|
||||
} armv7m_core_reg_t;
|
||||
|
|
|
@ -395,7 +395,9 @@ int cortex_m3_debug_entry(target_t *target)
|
|||
|
||||
/* Examine target state and mode */
|
||||
/* First load register acessible through core debug port*/
|
||||
for (i = 0; i < ARMV7M_PRIMASK; i++)
|
||||
int num_regs = armv7m->core_cache->num_regs;
|
||||
|
||||
for (i = 0; i < num_regs; i++)
|
||||
{
|
||||
if (!armv7m->core_cache->reg_list[i].valid)
|
||||
armv7m->read_core_reg(target, i);
|
||||
|
@ -418,13 +420,6 @@ int cortex_m3_debug_entry(target_t *target)
|
|||
cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff);
|
||||
}
|
||||
|
||||
/* Now we can load SP core registers */
|
||||
for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++)
|
||||
{
|
||||
if (!armv7m->core_cache->reg_list[i].valid)
|
||||
armv7m->read_core_reg(target, i);
|
||||
}
|
||||
|
||||
/* Are we in an exception handler */
|
||||
if (xPSR & 0x1FF)
|
||||
{
|
||||
|
@ -1253,8 +1248,12 @@ int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype typ
|
|||
armv7m_common_t *armv7m = target->arch_info;
|
||||
swjdp_common_t *swjdp = &armv7m->swjdp_info;
|
||||
|
||||
if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
|
||||
{
|
||||
/* 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 = cortexm3_dap_read_coreregister_u32(swjdp, value, num);
|
||||
|
||||
|
@ -1264,35 +1263,41 @@ int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype typ
|
|||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "",(int)num,*value);
|
||||
}
|
||||
else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
|
||||
{
|
||||
/* read other registers */
|
||||
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.
|
||||
*/
|
||||
cortexm3_dap_read_coreregister_u32(swjdp, value, 20);
|
||||
|
||||
switch (num)
|
||||
{
|
||||
case 19:
|
||||
*value = buf_get_u32((uint8_t*)value, 0, 8);
|
||||
case ARMV7M_PRIMASK:
|
||||
*value = buf_get_u32((uint8_t*)value, 0, 1);
|
||||
break;
|
||||
|
||||
case 20:
|
||||
case ARMV7M_BASEPRI:
|
||||
*value = buf_get_u32((uint8_t*)value, 8, 8);
|
||||
break;
|
||||
|
||||
case 21:
|
||||
*value = buf_get_u32((uint8_t*)value, 16, 8);
|
||||
case ARMV7M_FAULTMASK:
|
||||
*value = buf_get_u32((uint8_t*)value, 16, 1);
|
||||
break;
|
||||
|
||||
case 22:
|
||||
*value = buf_get_u32((uint8_t*)value, 24, 8);
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
|
@ -1313,14 +1318,19 @@ int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype ty
|
|||
* in "thumb" mode, or an INVSTATE exception will occur. This is a
|
||||
* hack to deal with the fact that gdb will sometimes "forge"
|
||||
* return addresses, and doesn't set the LSB correctly (i.e., when
|
||||
* printing expressions containing function calls, it sets LR = 0.) */
|
||||
|
||||
if (num == 14)
|
||||
* printing expressions containing function calls, it sets LR = 0.)
|
||||
* Valid exception return codes have bit 0 set too.
|
||||
*/
|
||||
if (num == ARMV7M_R14)
|
||||
value |= 0x01;
|
||||
#endif
|
||||
|
||||
if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
|
||||
{
|
||||
/* 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 = cortexm3_dap_write_coreregister_u32(swjdp, value, num);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
|
@ -1329,38 +1339,43 @@ int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype ty
|
|||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
|
||||
}
|
||||
else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
|
||||
{
|
||||
/* write other registers */
|
||||
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.
|
||||
*/
|
||||
cortexm3_dap_read_coreregister_u32(swjdp, ®, 20);
|
||||
|
||||
switch (num)
|
||||
{
|
||||
case 19:
|
||||
buf_set_u32((uint8_t*)®, 0, 8, value);
|
||||
case ARMV7M_PRIMASK:
|
||||
buf_set_u32((uint8_t*)®, 0, 1, value);
|
||||
break;
|
||||
|
||||
case 20:
|
||||
case ARMV7M_BASEPRI:
|
||||
buf_set_u32((uint8_t*)®, 8, 8, value);
|
||||
break;
|
||||
|
||||
case 21:
|
||||
buf_set_u32((uint8_t*)®, 16, 8, value);
|
||||
case ARMV7M_FAULTMASK:
|
||||
buf_set_u32((uint8_t*)®, 16, 1, value);
|
||||
break;
|
||||
|
||||
case 22:
|
||||
buf_set_u32((uint8_t*)®, 24, 8, value);
|
||||
case ARMV7M_CONTROL:
|
||||
buf_set_u32((uint8_t*)®, 24, 2, value);
|
||||
break;
|
||||
}
|
||||
|
||||
cortexm3_dap_write_coreregister_u32(swjdp, reg, 20);
|
||||
|
||||
LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue