diff options
author | Omair Javaid <omair.javaid@linaro.org> | 2019-03-21 23:33:13 +0500 |
---|---|---|
committer | Matthias Welwarsky <matthias@welwarsky.de> | 2019-06-19 09:35:05 +0100 |
commit | bc94ca241a5d9b1bbd0b0e79f577a27dab58ecd0 (patch) | |
tree | 41398d945ae141098e2ab50cbc0d3042342d52b1 | |
parent | 4dbcb1e79d94a113af9c3da9c6f172782515f35e (diff) | |
download | riscv-openocd-bc94ca241a5d9b1bbd0b0e79f577a27dab58ecd0.zip riscv-openocd-bc94ca241a5d9b1bbd0b0e79f577a27dab58ecd0.tar.gz riscv-openocd-bc94ca241a5d9b1bbd0b0e79f577a27dab58ecd0.tar.bz2 |
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>
-rw-r--r-- | src/target/cortex_m.c | 67 | ||||
-rw-r--r-- | src/target/cortex_m.h | 10 |
2 files changed, 62 insertions, 15 deletions
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index e296039..9aaa5bb 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -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 dwt_num = 0; - uint32_t mask, temp; 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 * may set up breakpoints by hand, e.g. dual-address data value * watchpoint using comparator #1; comparator #0 matching cycle @@ -1425,11 +1415,22 @@ int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint target_write_u32(target, comparator->dwt_comparator_address + 0, comparator->comp); - comparator->mask = mask; - target_write_u32(target, comparator->dwt_comparator_address + 4, - comparator->mask); + 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--; - switch (watchpoint->rw) { + comparator->mask = mask; + target_write_u32(target, comparator->dwt_comparator_address + 4, + comparator->mask); + + switch (watchpoint->rw) { case WPT_READ: comparator->function = 5; break; @@ -1439,7 +1440,26 @@ int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint case WPT_ACCESS: comparator->function = 7; 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, comparator->function); @@ -1982,6 +2002,9 @@ void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target) 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_comp_available = 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 */ 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", i, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf)); 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); 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, MVFR1, &mvfr1); diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 2f29903..54d7a02 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -38,6 +38,12 @@ #define ITM_LAR_KEY 0xC5ACCE55 #define CPUID 0xE000ED00 + +#define ARM_CPUID_PARTNO_MASK 0xFFF0 + +#define CORTEX_M23_PARTNO 0xD200 +#define CORTEX_M33_PARTNO 0xD210 + /* Debug Control Block */ #define DCB_DHCSR 0xE000EDF0 #define DCB_DCRSR 0xE000EDF4 @@ -52,6 +58,9 @@ #define DWT_COMP0 0xE0001020 #define DWT_MASK0 0xE0001024 #define DWT_FUNCTION0 0xE0001028 +#define DWT_DEVARCH 0xE0001FBC + +#define DWT_DEVARCH_ARMV8M 0x101A02 #define FP_CTRL 0xE0002000 #define FP_REMAP 0xE0002004 @@ -181,6 +190,7 @@ struct cortex_m_common { /* Data Watchpoint and Trace (DWT) */ int dwt_num_comp; int dwt_comp_available; + uint32_t dwt_devarch; struct cortex_m_dwt_comparator *dwt_comparator_list; struct reg_cache *dwt_cache; |