Support for debugging on ARMv8-M CPUs
This patch adds ARMv8-M CPUs detection logic in ARMv7m target specific code. Also adds a slightly different watchpoint manipulation logic for ARMv8-M. This is based on ARMv8-M architecture reference manual. Tested on ARM Musca A board. Change-Id: I0652560954ef02c378a7067fab586edf39d3e9cc Signed-off-by: Omair Javaid <omair.javaid@linaro.org> Reviewed-on: http://openocd.zylin.com/4997 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz>bscan_optimization
parent
4dbcb1e79d
commit
bc94ca241a
|
@ -1391,18 +1391,8 @@ int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpo
|
||||||
int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
|
int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
|
||||||
{
|
{
|
||||||
int dwt_num = 0;
|
int dwt_num = 0;
|
||||||
uint32_t mask, temp;
|
|
||||||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||||
|
|
||||||
/* watchpoint params were validated earlier */
|
|
||||||
mask = 0;
|
|
||||||
temp = watchpoint->length;
|
|
||||||
while (temp) {
|
|
||||||
temp >>= 1;
|
|
||||||
mask++;
|
|
||||||
}
|
|
||||||
mask--;
|
|
||||||
|
|
||||||
/* REVISIT Don't fully trust these "not used" records ... users
|
/* REVISIT Don't fully trust these "not used" records ... users
|
||||||
* may set up breakpoints by hand, e.g. dual-address data value
|
* may set up breakpoints by hand, e.g. dual-address data value
|
||||||
* watchpoint using comparator #1; comparator #0 matching cycle
|
* watchpoint using comparator #1; comparator #0 matching cycle
|
||||||
|
@ -1425,6 +1415,17 @@ int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint
|
||||||
target_write_u32(target, comparator->dwt_comparator_address + 0,
|
target_write_u32(target, comparator->dwt_comparator_address + 0,
|
||||||
comparator->comp);
|
comparator->comp);
|
||||||
|
|
||||||
|
if ((cortex_m->dwt_devarch & 0x1FFFFF) != DWT_DEVARCH_ARMV8M) {
|
||||||
|
uint32_t mask = 0, temp;
|
||||||
|
|
||||||
|
/* watchpoint params were validated earlier */
|
||||||
|
temp = watchpoint->length;
|
||||||
|
while (temp) {
|
||||||
|
temp >>= 1;
|
||||||
|
mask++;
|
||||||
|
}
|
||||||
|
mask--;
|
||||||
|
|
||||||
comparator->mask = mask;
|
comparator->mask = mask;
|
||||||
target_write_u32(target, comparator->dwt_comparator_address + 4,
|
target_write_u32(target, comparator->dwt_comparator_address + 4,
|
||||||
comparator->mask);
|
comparator->mask);
|
||||||
|
@ -1440,6 +1441,25 @@ int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint
|
||||||
comparator->function = 7;
|
comparator->function = 7;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
uint32_t data_size = watchpoint->length >> 1;
|
||||||
|
comparator->mask = (watchpoint->length >> 1) | 1;
|
||||||
|
|
||||||
|
switch (watchpoint->rw) {
|
||||||
|
case WPT_ACCESS:
|
||||||
|
comparator->function = 4;
|
||||||
|
break;
|
||||||
|
case WPT_WRITE:
|
||||||
|
comparator->function = 5;
|
||||||
|
break;
|
||||||
|
case WPT_READ:
|
||||||
|
comparator->function = 6;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
comparator->function = comparator->function | (1 << 4) |
|
||||||
|
(data_size << 10);
|
||||||
|
}
|
||||||
|
|
||||||
target_write_u32(target, comparator->dwt_comparator_address + 8,
|
target_write_u32(target, comparator->dwt_comparator_address + 8,
|
||||||
comparator->function);
|
comparator->function);
|
||||||
|
|
||||||
|
@ -1982,6 +2002,9 @@ void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target_read_u32(target, DWT_DEVARCH, &cm->dwt_devarch);
|
||||||
|
LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32, cm->dwt_devarch);
|
||||||
|
|
||||||
cm->dwt_num_comp = (dwtcr >> 28) & 0xF;
|
cm->dwt_num_comp = (dwtcr >> 28) & 0xF;
|
||||||
cm->dwt_comp_available = cm->dwt_num_comp;
|
cm->dwt_comp_available = cm->dwt_num_comp;
|
||||||
cm->dwt_comparator_list = calloc(cm->dwt_num_comp,
|
cm->dwt_comparator_list = calloc(cm->dwt_num_comp,
|
||||||
|
@ -2112,6 +2135,20 @@ int cortex_m_examine(struct target *target)
|
||||||
/* Get CPU Type */
|
/* Get CPU Type */
|
||||||
i = (cpuid >> 4) & 0xf;
|
i = (cpuid >> 4) & 0xf;
|
||||||
|
|
||||||
|
switch (cpuid & ARM_CPUID_PARTNO_MASK) {
|
||||||
|
case CORTEX_M23_PARTNO:
|
||||||
|
i = 23;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CORTEX_M33_PARTNO:
|
||||||
|
i = 33;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected",
|
LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected",
|
||||||
i, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
|
i, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
|
||||||
cortex_m->maskints_erratum = false;
|
cortex_m->maskints_erratum = false;
|
||||||
|
@ -2138,7 +2175,7 @@ int cortex_m_examine(struct target *target)
|
||||||
LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i);
|
LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i);
|
||||||
armv7m->fp_feature = FPv4_SP;
|
armv7m->fp_feature = FPv4_SP;
|
||||||
}
|
}
|
||||||
} else if (i == 7) {
|
} else if (i == 7 || i == 33) {
|
||||||
target_read_u32(target, MVFR0, &mvfr0);
|
target_read_u32(target, MVFR0, &mvfr0);
|
||||||
target_read_u32(target, MVFR1, &mvfr1);
|
target_read_u32(target, MVFR1, &mvfr1);
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,12 @@
|
||||||
#define ITM_LAR_KEY 0xC5ACCE55
|
#define ITM_LAR_KEY 0xC5ACCE55
|
||||||
|
|
||||||
#define CPUID 0xE000ED00
|
#define CPUID 0xE000ED00
|
||||||
|
|
||||||
|
#define ARM_CPUID_PARTNO_MASK 0xFFF0
|
||||||
|
|
||||||
|
#define CORTEX_M23_PARTNO 0xD200
|
||||||
|
#define CORTEX_M33_PARTNO 0xD210
|
||||||
|
|
||||||
/* Debug Control Block */
|
/* Debug Control Block */
|
||||||
#define DCB_DHCSR 0xE000EDF0
|
#define DCB_DHCSR 0xE000EDF0
|
||||||
#define DCB_DCRSR 0xE000EDF4
|
#define DCB_DCRSR 0xE000EDF4
|
||||||
|
@ -52,6 +58,9 @@
|
||||||
#define DWT_COMP0 0xE0001020
|
#define DWT_COMP0 0xE0001020
|
||||||
#define DWT_MASK0 0xE0001024
|
#define DWT_MASK0 0xE0001024
|
||||||
#define DWT_FUNCTION0 0xE0001028
|
#define DWT_FUNCTION0 0xE0001028
|
||||||
|
#define DWT_DEVARCH 0xE0001FBC
|
||||||
|
|
||||||
|
#define DWT_DEVARCH_ARMV8M 0x101A02
|
||||||
|
|
||||||
#define FP_CTRL 0xE0002000
|
#define FP_CTRL 0xE0002000
|
||||||
#define FP_REMAP 0xE0002004
|
#define FP_REMAP 0xE0002004
|
||||||
|
@ -181,6 +190,7 @@ struct cortex_m_common {
|
||||||
/* Data Watchpoint and Trace (DWT) */
|
/* Data Watchpoint and Trace (DWT) */
|
||||||
int dwt_num_comp;
|
int dwt_num_comp;
|
||||||
int dwt_comp_available;
|
int dwt_comp_available;
|
||||||
|
uint32_t dwt_devarch;
|
||||||
struct cortex_m_dwt_comparator *dwt_comparator_list;
|
struct cortex_m_dwt_comparator *dwt_comparator_list;
|
||||||
struct reg_cache *dwt_cache;
|
struct reg_cache *dwt_cache;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue