This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6ea3bc1217043f2d88e3e61740df618494955f1a Author: Huang Qi <[email protected]> AuthorDate: Wed Jul 31 15:56:51 2024 +0800 riscv/debug: Add support for steppoint Steppoint can be implemented by icount(instruction count) from RISC-V debug extension, but it may not implemented in all RISC-V cores. Unfortunately, the currently supported RISC-V cores do not implement it. Signed-off-by: Huang Qi <[email protected]> --- arch/risc-v/src/common/riscv_debug.c | 188 +++++++++++++++++++++-------------- 1 file changed, 112 insertions(+), 76 deletions(-) diff --git a/arch/risc-v/src/common/riscv_debug.c b/arch/risc-v/src/common/riscv_debug.c index 8599e6695d..ac330b1bf4 100644 --- a/arch/risc-v/src/common/riscv_debug.c +++ b/arch/risc-v/src/common/riscv_debug.c @@ -78,12 +78,12 @@ * Private Type ****************************************************************************/ -/* Trigger Match Control, from version 0.13.2. +/* Represent the tdata1 register, from the RISC-V Debug Specification 0.13.2 * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf * for more information */ -union mcontrol +union tdata1 { uintptr_t reg; struct @@ -109,7 +109,21 @@ union mcontrol uintptr_t maskmax : 6; uintptr_t dmode : 1; uintptr_t type : 4; - }; + } match; + + struct + { + uintptr_t action: 6; + uintptr_t u : 1; + uintptr_t s : 1; + uintptr_t reserved0 : 1; + uintptr_t m : 1; + uintptr_t count : 14; + uintptr_t hit : 1; + uintptr_t reserved1 : sizeof(uintptr_t) * 8 - 30; + uintptr_t dmode : 1; + uintptr_t type : 4; + } icount; }; struct riscv_debug_trigger @@ -190,7 +204,7 @@ static int riscv_debug_handler(int irq, void *context, void *arg) static int riscv_debug_init(void) { - union mcontrol mc; + union tdata1 reg; /* Attach the debug exception handler */ @@ -223,22 +237,23 @@ static int riscv_debug_init(void) WRITE_CSR(CSR_TSELECT, 0); - mc.reg = READ_CSR(CSR_TDATA1); + reg.reg = READ_CSR(CSR_TDATA1); /* REVISIT: NAPOT match is supported and tested on * QEMU and ESP32C3, prefer to use it. */ - mc.match = MATCH_TYPE_TOPBITS; + reg.match.type = TRIGGER_TYPE_ADDRESS_DATA; + reg.match.match = MATCH_TYPE_TOPBITS; /* Write it to tdata1 and read back * to check if the NAPOT is supported */ - WRITE_CSR(CSR_TDATA1, mc.reg); - mc.reg = READ_CSR(CSR_TDATA1); + WRITE_CSR(CSR_TDATA1, reg.reg); + reg.reg = READ_CSR(CSR_TDATA1); - if (mc.match == MATCH_TYPE_TOPBITS) + if (reg.match.match == MATCH_TYPE_TOPBITS) { g_support_napot = true; } @@ -257,87 +272,38 @@ static int riscv_debug_init(void) } /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_debugpoint_add + * Name: riscv_debug_setup_match ****************************************************************************/ -int up_debugpoint_add(int type, void *addr, size_t size, - debug_callback_t callback, void *arg) +static uintptr_t riscv_debug_setup_match(int type, void *addr, size_t size) { - int slot; - union mcontrol mc; - int ret = OK; - uintptr_t addr_napot; - - /* Initialize the debug module if it is not initialized yet */ - - if (g_debug_initiliazed == false) - { - ret = riscv_debug_init(); - if (ret < 0) - { - return ret; - } - - g_debug_initiliazed = true; - } - - /* Find a free slot */ - - slot = riscv_debug_find_slot(0, 0, 0); - if (slot < 0) - { - return slot; - } - - /* Select the trigger */ - - WRITE_CSR(CSR_TSELECT, slot); - - /* Fetch the current setting from tdata1 */ - - mc.reg = READ_CSR(CSR_TDATA1); - - /* Configure trigger */ - - mc.m = 1; - mc.u = 1; - mc.hit = 0; - mc.dmode = DMODE_TYPE_BOTH; - mc.action = ACTION_TYPE_EXCEPTION; - - mc.execute = 0; - mc.load = 0; - mc.store = 0; + union tdata1 reg; + uintptr_t addr_napot; if (type == DEBUGPOINT_BREAKPOINT) { - mc.execute = 1; + reg.match.execute = 1; } else if (type == DEBUGPOINT_WATCHPOINT_RO) { - mc.load = 1; + reg.match.load = 1; } else if (type == DEBUGPOINT_WATCHPOINT_WO) { - mc.store = 1; + reg.match.store = 1; } else if (type == DEBUGPOINT_WATCHPOINT_RW) { - mc.load = 1; - mc.store = 1; + reg.match.load = 1; + reg.match.store = 1; } - else - { - /* DEBUGPOINT_STEPPOINT is not supported since current test platform - * such as QEMU don't implemented yet. - */ - return -ENOTSUP; - } + reg.match.type = TRIGGER_TYPE_ADDRESS_DATA; + reg.match.m = 1; + reg.match.u = 1; + reg.match.hit = 0; + reg.match.dmode = DMODE_TYPE_BOTH; + reg.match.action = ACTION_TYPE_EXCEPTION; /* From RISC-V Debug Specification: * tdata1(mcontrol) match = 0 : Exact byte match @@ -359,17 +325,87 @@ int up_debugpoint_add(int type, void *addr, size_t size, if (size > 1 && g_support_napot) { - mc.match = MATCH_TYPE_TOPBITS; + reg.match.match = MATCH_TYPE_TOPBITS; addr_napot = ((uintptr_t)addr & ~(size - 1)) | ((size - 1) >> 1); WRITE_CSR(CSR_TDATA2, addr_napot); } else { - mc.match = MATCH_TYPE_EQUAL; + reg.match.match = MATCH_TYPE_EQUAL; WRITE_CSR(CSR_TDATA2, (uintptr_t)addr); } + return reg.reg; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_debugpoint_add + ****************************************************************************/ + +int up_debugpoint_add(int type, void *addr, size_t size, + debug_callback_t callback, void *arg) +{ + int slot; + union tdata1 reg; + int ret = OK; + + /* Initialize the debug module if it is not initialized yet */ + + if (g_debug_initiliazed == false) + { + ret = riscv_debug_init(); + if (ret < 0) + { + return ret; + } + + g_debug_initiliazed = true; + } + + /* Find a free slot */ + + slot = riscv_debug_find_slot(0, 0, 0); + if (slot < 0) + { + return slot; + } + + /* Select the trigger */ + + WRITE_CSR(CSR_TSELECT, slot); + + switch (type) + { + case DEBUGPOINT_STEPPOINT: + /* NOTICE: STEPPOINT implemented but not tested since no such + * hardware that implemented icount is available. + */ + + reg.reg = 0; + reg.icount.type = TRIGGER_TYPE_ICOUNT; + reg.icount.dmode = DMODE_TYPE_BOTH; + reg.icount.count = 1; + reg.icount.hit = 0; + reg.icount.m = 1; + reg.icount.s = 1; + reg.icount.u = 1; + reg.icount.action = ACTION_TYPE_EXCEPTION; + break; + case DEBUGPOINT_BREAKPOINT: + case DEBUGPOINT_WATCHPOINT_RO: + case DEBUGPOINT_WATCHPOINT_RW: + case DEBUGPOINT_WATCHPOINT_WO: + reg.reg = riscv_debug_setup_match(type, addr, size); + break; + default: + return -EINVAL; + } + /* Register the callback and arg */ g_trigger_map[slot].type = type; @@ -377,7 +413,7 @@ int up_debugpoint_add(int type, void *addr, size_t size, g_trigger_map[slot].size = size; g_trigger_map[slot].callback = callback; g_trigger_map[slot].arg = arg; - WRITE_CSR(CSR_TDATA1, mc.reg); + WRITE_CSR(CSR_TDATA1, reg.reg); return 0; }
