Introduce support for SBI Debug Trigger Extension
v2 cover Introduce support for SBI Debug Trigger Extension
RISC-V Debug specification includes Sdtrig ISA extension which describes Trigger Module. Triggers can cause a breakpoint exception or trace action without execution of a special instruction. They can be used to implement hardware breakpoints and watchpoints for native debugging.
The SBI Debug Trigger extension v6 can be found at:
https://lists.riscv.org/g/tech-debug/topic/99825362#1302
This patch is an initial implementation of SBI Debug Trigger Extension(v6) in OpenSBI. It is based on similar patchset from Sergey Matyukevich.
(http://lists.infradead.org/pipermail/opensbi/2022-October/003531.html)
The following features are supported:
* mcontrol, mcontrol6 triggers
* Breakpoint and trace actions
Linux Kernel Branch (Breakpoint driver support):
https://github.com/hschauhan/riscv-linux/tree/sdtrig-v6
NOTE: Chained triggers are not supported
Changes from v1:
- Rebased to latest OpenSBI master
- Other cosmetic changes as per the comments
Himanshu Chauhan (7):
include: sbi: Introduce common endianess conversion macro
include: sbi: Add TINFO debug trigger CSR
include: sbi: Introduce debug trigger register encodings
lib: sbi: Introduce the SBI debug triggers extension support
include: sbi: Add SBI debug trigger extension related defines
lib: sbi: Implement SBI debug trigger extension
lib: sbi: Print number of debug triggers found
include/sbi/riscv_dbtr.h | 249 ++++++++++ include/sbi/riscv_encoding.h | 1 + include/sbi/sbi_byteorder.h | 10 + include/sbi/sbi_dbtr.h | 127 +++++ include/sbi/sbi_ecall_interface.h | 11 + lib/sbi/Kconfig | 4 + lib/sbi/objects.mk | 4 + lib/sbi/sbi_dbtr.c | 742 ++++++++++++++++++++++++++++++ lib/sbi/sbi_ecall_dbtr.c | 73 +++ lib/sbi/sbi_init.c | 11 + 10 files changed, 1232 insertions(+) create mode 100644 include/sbi/riscv_dbtr.h create mode 100644 include/sbi/sbi_dbtr.h create mode 100644 lib/sbi/sbi_dbtr.c create mode 100644 lib/sbi/sbi_ecall_dbtr.c
Signature · 1 line
2.34.1
PATCH v2 1/7 include: sbi: Introduce common endianess conversion macro
Introduce cpu_to_lle and lle_to_cpu macros which invoke correct word length cpu_to_le<64/32> conversion based on __riscv_xlen.
--- include/sbi/sbi_byteorder.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
include/sbi/sbi_byteorder.h +10 -0
@@ -58,4 +58,14 @@#define le64_to_cpu (x) ((uint64_t)BSWAP64(x))#endif +#if __riscv_xlen ==64 +#define cpu_to_lle cpu_to_le64 +#define lle_to_cpu le64_to_cpu +#elif __riscv_xlen ==32 +#define cpu_to_lle cpu_to_le32 +#define lle_to_cpu le32_to_cpu +#else +#error "Unknown __riscv_xlen" +#endif +#endif /* __SBI_BYTEORDER_H__ */
Signature · 1 line
2.34.1
PATCH v2 1/7 include: sbi: Introduce common endianess conversion macro
Quoted 6 lines · On Mon, Jan 8, 2024 at 12:25?PM Himanshu Chauhan <[email protected]>…
Introduce
cpu_to_lleandlle_to_cpumacros which invoke correct word length cpu_to_le<64/32> conversion based on__riscv_xlen.Signed-off-by Himanshu Chauhan <[email protected]>
Already reviewed previously.
Regards,
Anup
Quoted 31 lines
--- include/sbi/sbi_byteorder.h | 10 ++++++++++ 1 file changed, 10 insertions(+)include/sbi/sbi_byteorder.h +10
-1@@ -58,4 +58,14 @@#define le64_to_cpu (x) ((uint64_t)BSWAP64(x))#endif +#if __riscv_xlen ==64 +#define cpu_to_lle cpu_to_le64 +#define lle_to_cpu le64_to_cpu +#elif __riscv_xlen ==32 +#define cpu_to_lle cpu_to_le32 +#define lle_to_cpu le32_to_cpu +#else +#error "Unknown __riscv_xlen" +#endif +#endif /* __SBI_BYTEORDER_H__ */ --2.34.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
PATCH v2 2/7 include: sbi: Add TINFO debug trigger CSR
In reply to Himanshu ChauhanAdd the missing TINFO debug trigger CSR.
--- include/sbi/riscv_encoding.h | 1 + 1 file changed, 1 insertion(+)
include/sbi/riscv_encoding.h +1 -0
@@ -686,6 +686,7 @@#define CSR_TDATA1 0x7a1#define CSR_TDATA2 0x7a2#define CSR_TDATA3 0x7a3 +#define CSR_TINFO 0x7a4/* Debug Mode Registers */ #define CSR_DCSR 0x7b0
Signature · 1 line
2.34.1
PATCH v2 2/7 include: sbi: Add TINFO debug trigger CSR
Quoted 4 lines · On Mon, Jan 8, 2024 at 12:25?PM Himanshu Chauhan <[email protected]>…
Add the missing TINFO debug trigger CSR.
Signed-off-by Himanshu Chauhan <[email protected]>
Already reviewed previously.
Regards,
Anup
Quoted 24 lines
--- include/sbi/riscv_encoding.h | 1 + 1 file changed, 1 insertion(+)include/sbi/riscv_encoding.h +1
-1@@ -686,6 +686,7 @@#define CSR_TDATA1 0x7a1#define CSR_TDATA2 0x7a2#define CSR_TDATA3 0x7a3 +#define CSR_TINFO 0x7a4/* Debug Mode Registers */ #define CSR_DCSR 0x7b0 --2.34.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
PATCH v2 3/7 include: sbi: Introduce debug trigger register encodings
In reply to Himanshu ChauhanThis patch introduces Mcontrol and M6 control register encodings along with macros to manipulate them.
--- include/sbi/riscv_dbtr.h | 249 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 include/sbi/riscv_dbtr.h
include/sbi/riscv_dbtr.h new file +249 -0
@@ -0,0 +1,249 @@ +/* +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright (c) 2023 Ventana Micro System, Inc. +* +* Authors: +* Himanshu Chauhan <[email protected]> +*/ + +#ifndef __RISCV_DBTR_H__ +#define __RISCV_DBTR_H__ + +#define RV_MAX_TRIGGERS 32 + +enum { +RISCV_DBTR_TRIG_NONE =0 , +RISCV_DBTR_TRIG_LEGACY , +RISCV_DBTR_TRIG_MCONTROL , +RISCV_DBTR_TRIG_ICOUNT , +RISCV_DBTR_TRIG_ITRIGGER , +RISCV_DBTR_TRIG_ETRIGGER , +RISCV_DBTR_TRIG_MCONTROL6 , +}; + +#define RV_DBTR_BIT (_prefix, _name) \ + RV_DBTR_##_prefix##_##_name##_BIT + +#define RV_DBTR_BIT_MASK (_prefix, _name) \ + RV_DBTR_##_prefix##_name##_BIT_MASK + +#define RV_DBTR_DECLARE_BIT (_prefix, _name, _val) \ + RV_DBTR_BIT(_prefix, _name) = _val + +#define RV_DBTR_DECLARE_BIT_MASK (_prefix, _name, _width) \ + RV_DBTR_BIT_MASK(_prefix, _name) = \ + (((1UL << _width) - 1) << RV_DBTR_BIT(_prefix, _name)) + +#define CLEAR_DBTR_BIT (_target, _prefix, _bit_name) \ + __clear_bit(RV_DBTR_BIT(_prefix, _bit_name), &_target) + +#define SET_DBTR_BIT (_target, _prefix, _bit_name) \ + __set_bit(RV_DBTR_BIT(_prefix, _bit_name), &_target) + +/* Trigger Data 1 */ +enum { + RV_DBTR_DECLARE_BIT(TDATA1, DATA, 0), +#if __riscv_xlen ==64 + RV_DBTR_DECLARE_BIT(TDATA1, DMODE, 59), + RV_DBTR_DECLARE_BIT(TDATA1, TYPE, 60), +#elif __riscv_xlen ==32 + RV_DBTR_DECLARE_BIT(TDATA1, DMODE, 27), + RV_DBTR_DECLARE_BIT(TDATA1, TYPE, 28), +#else + #error "Unknown __riscv_xlen" +#endif +}; + +enum { +#if __riscv_xlen == 64 + RV_DBTR_DECLARE_BIT_MASK(TDATA1, DATA, 59), +#elif __riscv_xlen == 32 + RV_DBTR_DECLARE_BIT_MASK(TDATA1, DATA, 27), +#else + #error "Unknown __riscv_xlen" +#endif + RV_DBTR_DECLARE_BIT_MASK(TDATA1, DMODE, 1), + RV_DBTR_DECLARE_BIT_MASK(TDATA1, TYPE, 4), +}; + +/* MC - Match Control Type Register */ +enum { + RV_DBTR_DECLARE_BIT(MC, LOAD, 0), + RV_DBTR_DECLARE_BIT(MC, STORE, 1), + RV_DBTR_DECLARE_BIT(MC, EXEC, 2), + RV_DBTR_DECLARE_BIT(MC, U, 3), + RV_DBTR_DECLARE_BIT(MC, S, 4), + RV_DBTR_DECLARE_BIT(MC, RES2, 5), + RV_DBTR_DECLARE_BIT(MC, M, 6), + RV_DBTR_DECLARE_BIT(MC, MATCH, 7), + RV_DBTR_DECLARE_BIT(MC, CHAIN, 11), + RV_DBTR_DECLARE_BIT(MC, ACTION, 12), + RV_DBTR_DECLARE_BIT(MC, SIZELO, 16), + RV_DBTR_DECLARE_BIT(MC, TIMING, 18), + RV_DBTR_DECLARE_BIT(MC, SELECT, 19), + RV_DBTR_DECLARE_BIT(MC, HIT, 20), +#if __riscv_xlen >= 64 + RV_DBTR_DECLARE_BIT(MC, SIZEHI, 21), +#endif +#if __riscv_xlen == 64 + RV_DBTR_DECLARE_BIT(MC, MASKMAX, 53), + RV_DBTR_DECLARE_BIT(MC, DMODE, 59), + RV_DBTR_DECLARE_BIT(MC, TYPE, 60), +#elif __riscv_xlen == 32 + RV_DBTR_DECLARE_BIT(MC, MASKMAX, 21), + RV_DBTR_DECLARE_BIT(MC, DMODE, 27), + RV_DBTR_DECLARE_BIT(MC, TYPE, 28), +#else +#error "Unknown __riscv_xlen" +#endif +}; + +enum { + RV_DBTR_DECLARE_BIT_MASK(MC, LOAD, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, STORE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, EXEC, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, U, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, S, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, RES2, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, M, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, MATCH, 4), + RV_DBTR_DECLARE_BIT_MASK(MC, CHAIN, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, ACTION, 4), + RV_DBTR_DECLARE_BIT_MASK(MC, SIZELO, 2), + RV_DBTR_DECLARE_BIT_MASK(MC, TIMING, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, SELECT, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, HIT, 1), +#if __riscv_xlen >=64 + RV_DBTR_DECLARE_BIT_MASK(MC, SIZEHI, 2), +#endif + RV_DBTR_DECLARE_BIT_MASK(MC, MASKMAX, 6), + RV_DBTR_DECLARE_BIT_MASK(MC, DMODE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, TYPE, 4), +}; + +/* MC6 - Match Control 6 Type Register */ +enum { + RV_DBTR_DECLARE_BIT(MC6, LOAD, 0), + RV_DBTR_DECLARE_BIT(MC6, STORE, 1), + RV_DBTR_DECLARE_BIT(MC6, EXEC, 2), + RV_DBTR_DECLARE_BIT(MC6, U, 3), + RV_DBTR_DECLARE_BIT(MC6, S, 4), + RV_DBTR_DECLARE_BIT(MC6, RES2, 5), + RV_DBTR_DECLARE_BIT(MC6, M, 6), + RV_DBTR_DECLARE_BIT(MC6, MATCH, 7), + RV_DBTR_DECLARE_BIT(MC6, CHAIN, 11), + RV_DBTR_DECLARE_BIT(MC6, ACTION, 12), + RV_DBTR_DECLARE_BIT(MC6, SIZE, 16), + RV_DBTR_DECLARE_BIT(MC6, TIMING, 20), + RV_DBTR_DECLARE_BIT(MC6, SELECT, 21), + RV_DBTR_DECLARE_BIT(MC6, HIT, 22), + RV_DBTR_DECLARE_BIT(MC6, VU, 23), + RV_DBTR_DECLARE_BIT(MC6, VS, 24), +#if __riscv_xlen == 64 + RV_DBTR_DECLARE_BIT(MC6, DMODE, 59), + RV_DBTR_DECLARE_BIT(MC6, TYPE, 60), +#elif __riscv_xlen == 32 + RV_DBTR_DECLARE_BIT(MC6, DMODE, 27), + RV_DBTR_DECLARE_BIT(MC6, TYPE, 28), +#else + #error "Unknown __riscv_xlen" +#endif +}; + +enum { + RV_DBTR_DECLARE_BIT_MASK(MC6, LOAD, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, STORE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, EXEC, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, U, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, S, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, RES2, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, M, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, MATCH, 4), + RV_DBTR_DECLARE_BIT_MASK(MC6, CHAIN, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, ACTION, 4), + RV_DBTR_DECLARE_BIT_MASK(MC6, SIZE, 4), + RV_DBTR_DECLARE_BIT_MASK(MC6, TIMING, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, SELECT, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, HIT, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, VU, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, VS, 1), +#if __riscv_xlen == 64 + RV_DBTR_DECLARE_BIT_MASK(MC6, DMODE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, TYPE, 4), +#elif __riscv_xlen == 32 + RV_DBTR_DECLARE_BIT_MASK(MC6, DMODE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, TYPE, 4), +#else + #error "Unknown __riscv_xlen" +#endif +}; + +#define RV_DBTR_SET_TDATA1_TYPE(_t1, _type) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(TDATA1, TYPE); \ + _t1 |= (((unsigned long)_type \ + << RV_DBTR_BIT(TDATA1, TYPE)) \ + & RV_DBTR_BIT_MASK(TDATA1, TYPE)); \ + }while (0); + +#define RV_DBTR_SET_MC_TYPE(_t1, _type) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK (MC ,TYPE ); \ + _t1 |= (((unsigned long )_type \ + <<RV_DBTR_BIT (MC ,TYPE )) \ + &RV_DBTR_BIT_MASK (MC ,TYPE )); \ + }while (0 ); + +#define RV_DBTR_SET_MC6_TYPE (_t1, _type) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(MC6, TYPE); \ + _t1 |= (((unsigned long)_type \ + << RV_DBTR_BIT(MC6, TYPE)) \ + & RV_DBTR_BIT_MASK(MC6, TYPE)); \ + }while (0); + +#define RV_DBTR_SET_MC_EXEC (_t1) \ + SET_DBTR_BIT(_t1, MC, EXEC) + +#define RV_DBTR_SET_MC_LOAD (_t1) \ + SET_DBTR_BIT(_t1, MC, LOAD) + +#define RV_DBTR_SET_MC_STORE (_t1) \ + SET_DBTR_BIT(_t1, MC, STORE) + +#define RV_DBTR_SET_MC_SIZELO (_t1, _val) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(MC, SIZELO); \ + _t1 |= ((_val << RV_DBTR_BIT(MC, SIZELO)) \ + & RV_DBTR_BIT_MASK(MC, SIZELO)); \ + } while(0); + +#define RV_DBTR_SET_MC_SIZEHI (_t1, _val) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(MC, SIZEHI); \ + _t1 |= ((_val << RV_DBTR_BIT(MC, SIZEHI)) \ + & RV_DBTR_BIT_MASK(MC, SIZEHI)); \ + } while(0); + +#define RV_DBTR_SET_MC6_EXEC (_t1) \ + SET_DBTR_BIT(_t1, MC6, EXEC) + +#define RV_DBTR_SET_MC6_LOAD (_t1) \ + SET_DBTR_BIT(_t1, MC6, LOAD) + +#define RV_DBTR_SET_MC6_STORE (_t1) \ + SET_DBTR_BIT(_t1, MC6, STORE) + +#define RV_DBTR_SET_MC6_SIZE (_t1, _val) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(MC6, SIZE); \ + _t1 |= ((_val << RV_DBTR_BIT(MC6, SIZE)) \ + & RV_DBTR_BIT_MASK(MC6, SIZE)); \ + } while(0); + +typedef unsigned long riscv_dbtr_tdata1_mcontrol_t ; +typedef unsigned long riscv_dbtr_tdata1_mcontrol6_t ; +typedef unsigned long riscv_dbtr_tdata1_t ; + +#endif /* __RISCV_DBTR_H__ */
Signature · 1 line
2.34.1
PATCH v2 3/7 include: sbi: Introduce debug trigger register encodings
Quoted 5 lines · On Mon, Jan 8, 2024 at 12:25?PM Himanshu Chauhan <[email protected]>…
This patch introduces Mcontrol and M6 control register encodings along with macros to manipulate them.
Signed-off-by Himanshu Chauhan <[email protected]>
Already reviewed previously.
Regards,
Anup
Quoted 268 lines
--- include/sbi/riscv_dbtr.h | 249 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 include/sbi/riscv_dbtr.hinclude/sbi/riscv_dbtr.h new file +249
-1@@ -0,0 +1,249 @@ +/* +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright (c) 2023 Ventana Micro System, Inc. +* +* Authors: +* Himanshu Chauhan <[email protected]> +*/ + +#ifndef __RISCV_DBTR_H__ +#define __RISCV_DBTR_H__ + +#define RV_MAX_TRIGGERS 32 + +enum { +RISCV_DBTR_TRIG_NONE =0 , +RISCV_DBTR_TRIG_LEGACY , +RISCV_DBTR_TRIG_MCONTROL , +RISCV_DBTR_TRIG_ICOUNT , +RISCV_DBTR_TRIG_ITRIGGER , +RISCV_DBTR_TRIG_ETRIGGER , +RISCV_DBTR_TRIG_MCONTROL6 , +}; + +#define RV_DBTR_BIT (_prefix, _name) \ + RV_DBTR_##_prefix##_##_name##_BIT + +#define RV_DBTR_BIT_MASK (_prefix, _name) \ + RV_DBTR_##_prefix##_name##_BIT_MASK + +#define RV_DBTR_DECLARE_BIT (_prefix, _name, _val) \ + RV_DBTR_BIT(_prefix, _name) = _val + +#define RV_DBTR_DECLARE_BIT_MASK (_prefix, _name, _width) \ + RV_DBTR_BIT_MASK(_prefix, _name) = \ + (((1UL << _width) - 1) << RV_DBTR_BIT(_prefix, _name)) + +#define CLEAR_DBTR_BIT (_target, _prefix, _bit_name) \ + __clear_bit(RV_DBTR_BIT(_prefix, _bit_name), &_target) + +#define SET_DBTR_BIT (_target, _prefix, _bit_name) \ + __set_bit(RV_DBTR_BIT(_prefix, _bit_name), &_target) + +/* Trigger Data 1 */ +enum { + RV_DBTR_DECLARE_BIT(TDATA1, DATA, 0), +#if __riscv_xlen ==64 + RV_DBTR_DECLARE_BIT(TDATA1, DMODE, 59), + RV_DBTR_DECLARE_BIT(TDATA1, TYPE, 60), +#elif __riscv_xlen ==32 + RV_DBTR_DECLARE_BIT(TDATA1, DMODE, 27), + RV_DBTR_DECLARE_BIT(TDATA1, TYPE, 28), +#else + #error "Unknown __riscv_xlen" +#endif +}; + +enum { +#if __riscv_xlen == 64 + RV_DBTR_DECLARE_BIT_MASK(TDATA1, DATA, 59), +#elif __riscv_xlen == 32 + RV_DBTR_DECLARE_BIT_MASK(TDATA1, DATA, 27), +#else + #error "Unknown __riscv_xlen" +#endif + RV_DBTR_DECLARE_BIT_MASK(TDATA1, DMODE, 1), + RV_DBTR_DECLARE_BIT_MASK(TDATA1, TYPE, 4), +}; + +/* MC - Match Control Type Register */ +enum { + RV_DBTR_DECLARE_BIT(MC, LOAD, 0), + RV_DBTR_DECLARE_BIT(MC, STORE, 1), + RV_DBTR_DECLARE_BIT(MC, EXEC, 2), + RV_DBTR_DECLARE_BIT(MC, U, 3), + RV_DBTR_DECLARE_BIT(MC, S, 4), + RV_DBTR_DECLARE_BIT(MC, RES2, 5), + RV_DBTR_DECLARE_BIT(MC, M, 6), + RV_DBTR_DECLARE_BIT(MC, MATCH, 7), + RV_DBTR_DECLARE_BIT(MC, CHAIN, 11), + RV_DBTR_DECLARE_BIT(MC, ACTION, 12), + RV_DBTR_DECLARE_BIT(MC, SIZELO, 16), + RV_DBTR_DECLARE_BIT(MC, TIMING, 18), + RV_DBTR_DECLARE_BIT(MC, SELECT, 19), + RV_DBTR_DECLARE_BIT(MC, HIT, 20), +#if __riscv_xlen >= 64 + RV_DBTR_DECLARE_BIT(MC, SIZEHI, 21), +#endif +#if __riscv_xlen == 64 + RV_DBTR_DECLARE_BIT(MC, MASKMAX, 53), + RV_DBTR_DECLARE_BIT(MC, DMODE, 59), + RV_DBTR_DECLARE_BIT(MC, TYPE, 60), +#elif __riscv_xlen == 32 + RV_DBTR_DECLARE_BIT(MC, MASKMAX, 21), + RV_DBTR_DECLARE_BIT(MC, DMODE, 27), + RV_DBTR_DECLARE_BIT(MC, TYPE, 28), +#else +#error "Unknown __riscv_xlen" +#endif +}; + +enum { + RV_DBTR_DECLARE_BIT_MASK(MC, LOAD, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, STORE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, EXEC, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, U, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, S, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, RES2, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, M, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, MATCH, 4), + RV_DBTR_DECLARE_BIT_MASK(MC, CHAIN, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, ACTION, 4), + RV_DBTR_DECLARE_BIT_MASK(MC, SIZELO, 2), + RV_DBTR_DECLARE_BIT_MASK(MC, TIMING, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, SELECT, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, HIT, 1), +#if __riscv_xlen >=64 + RV_DBTR_DECLARE_BIT_MASK(MC, SIZEHI, 2), +#endif + RV_DBTR_DECLARE_BIT_MASK(MC, MASKMAX, 6), + RV_DBTR_DECLARE_BIT_MASK(MC, DMODE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC, TYPE, 4), +}; + +/* MC6 - Match Control 6 Type Register */ +enum { + RV_DBTR_DECLARE_BIT(MC6, LOAD, 0), + RV_DBTR_DECLARE_BIT(MC6, STORE, 1), + RV_DBTR_DECLARE_BIT(MC6, EXEC, 2), + RV_DBTR_DECLARE_BIT(MC6, U, 3), + RV_DBTR_DECLARE_BIT(MC6, S, 4), + RV_DBTR_DECLARE_BIT(MC6, RES2, 5), + RV_DBTR_DECLARE_BIT(MC6, M, 6), + RV_DBTR_DECLARE_BIT(MC6, MATCH, 7), + RV_DBTR_DECLARE_BIT(MC6, CHAIN, 11), + RV_DBTR_DECLARE_BIT(MC6, ACTION, 12), + RV_DBTR_DECLARE_BIT(MC6, SIZE, 16), + RV_DBTR_DECLARE_BIT(MC6, TIMING, 20), + RV_DBTR_DECLARE_BIT(MC6, SELECT, 21), + RV_DBTR_DECLARE_BIT(MC6, HIT, 22), + RV_DBTR_DECLARE_BIT(MC6, VU, 23), + RV_DBTR_DECLARE_BIT(MC6, VS, 24), +#if __riscv_xlen == 64 + RV_DBTR_DECLARE_BIT(MC6, DMODE, 59), + RV_DBTR_DECLARE_BIT(MC6, TYPE, 60), +#elif __riscv_xlen == 32 + RV_DBTR_DECLARE_BIT(MC6, DMODE, 27), + RV_DBTR_DECLARE_BIT(MC6, TYPE, 28), +#else + #error "Unknown __riscv_xlen" +#endif +}; + +enum { + RV_DBTR_DECLARE_BIT_MASK(MC6, LOAD, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, STORE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, EXEC, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, U, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, S, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, RES2, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, M, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, MATCH, 4), + RV_DBTR_DECLARE_BIT_MASK(MC6, CHAIN, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, ACTION, 4), + RV_DBTR_DECLARE_BIT_MASK(MC6, SIZE, 4), + RV_DBTR_DECLARE_BIT_MASK(MC6, TIMING, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, SELECT, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, HIT, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, VU, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, VS, 1), +#if __riscv_xlen == 64 + RV_DBTR_DECLARE_BIT_MASK(MC6, DMODE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, TYPE, 4), +#elif __riscv_xlen == 32 + RV_DBTR_DECLARE_BIT_MASK(MC6, DMODE, 1), + RV_DBTR_DECLARE_BIT_MASK(MC6, TYPE, 4), +#else + #error "Unknown __riscv_xlen" +#endif +}; + +#define RV_DBTR_SET_TDATA1_TYPE(_t1, _type) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(TDATA1, TYPE); \ + _t1 |= (((unsigned long)_type \ + << RV_DBTR_BIT(TDATA1, TYPE)) \ + & RV_DBTR_BIT_MASK(TDATA1, TYPE)); \ + }while (0); + +#define RV_DBTR_SET_MC_TYPE(_t1, _type) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK (MC ,TYPE ); \ + _t1 |= (((unsigned long )_type \ + <<RV_DBTR_BIT (MC ,TYPE )) \ + &RV_DBTR_BIT_MASK (MC ,TYPE )); \ + }while (0 ); + +#define RV_DBTR_SET_MC6_TYPE (_t1, _type) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(MC6, TYPE); \ + _t1 |= (((unsigned long)_type \ + << RV_DBTR_BIT(MC6, TYPE)) \ + & RV_DBTR_BIT_MASK(MC6, TYPE)); \ + }while (0); + +#define RV_DBTR_SET_MC_EXEC (_t1) \ + SET_DBTR_BIT(_t1, MC, EXEC) + +#define RV_DBTR_SET_MC_LOAD (_t1) \ + SET_DBTR_BIT(_t1, MC, LOAD) + +#define RV_DBTR_SET_MC_STORE (_t1) \ + SET_DBTR_BIT(_t1, MC, STORE) + +#define RV_DBTR_SET_MC_SIZELO (_t1, _val) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(MC, SIZELO); \ + _t1 |= ((_val << RV_DBTR_BIT(MC, SIZELO)) \ + & RV_DBTR_BIT_MASK(MC, SIZELO)); \ + } while(0); + +#define RV_DBTR_SET_MC_SIZEHI (_t1, _val) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(MC, SIZEHI); \ + _t1 |= ((_val << RV_DBTR_BIT(MC, SIZEHI)) \ + & RV_DBTR_BIT_MASK(MC, SIZEHI)); \ + } while(0); + +#define RV_DBTR_SET_MC6_EXEC (_t1) \ + SET_DBTR_BIT(_t1, MC6, EXEC) + +#define RV_DBTR_SET_MC6_LOAD (_t1) \ + SET_DBTR_BIT(_t1, MC6, LOAD) + +#define RV_DBTR_SET_MC6_STORE (_t1) \ + SET_DBTR_BIT(_t1, MC6, STORE) + +#define RV_DBTR_SET_MC6_SIZE (_t1, _val) \ + do { \ + _t1 &= ~RV_DBTR_BIT_MASK(MC6, SIZE); \ + _t1 |= ((_val << RV_DBTR_BIT(MC6, SIZE)) \ + & RV_DBTR_BIT_MASK(MC6, SIZE)); \ + } while(0); + +typedef unsigned long riscv_dbtr_tdata1_mcontrol_t ; +typedef unsigned long riscv_dbtr_tdata1_mcontrol6_t ; +typedef unsigned long riscv_dbtr_tdata1_t ; + +#endif /* __RISCV_DBTR_H__ */ --2.34.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
PATCH v2 4/7 lib: sbi: Introduce the SBI debug triggers extension support
In reply to Himanshu ChauhanRISC-V Debug specification includes Sdtrig ISA extension which describes Trigger Module. Triggers can cause a breakpoint exception or trace action without execution of a special instruction. They can be used to implement hardware breakpoints and watchpoints for native debugging.
The SBI Debut Trigger extension (Draft v6) can be found at:
https://lists.riscv.org/g/tech-debug/topic/99825362#1302
This patch is an initial implementation of SBI Debug Trigger Extension (Draft v6) in OpenSBI.
The following features are supported:
* mcontrol, mcontrol6 triggers
* Breakpoint and trace actions
NOTE: Chained triggers are not supported
--- include/sbi/sbi_dbtr.h | 127 +++++++ lib/sbi/objects.mk | 1 + lib/sbi/sbi_dbtr.c | 742 +++++++++++++++++++++++++++++++++++++++++ lib/sbi/sbi_init.c | 9 + 4 files changed, 879 insertions(+) create mode 100644 include/sbi/sbi_dbtr.h create mode 100644 lib/sbi/sbi_dbtr.c
include/sbi/sbi_dbtr.h new file +127 -0
@@ -0,0 +1,127 @@ +/* +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright (c) 2023 Ventana Micro Systems, Inc. +* +* Authors: +* Himanshu Chauhan <[email protected]> +*/ + +#ifndef __SBI_DBTR_H__ +#define __SBI_DBTR_H__ + +#include <sbi/riscv_dbtr.h> + +#include <sbi/sbi_hartmask.h> +#include <sbi/sbi_scratch.h> +#include <sbi/sbi_domain.h> +#include <sbi/sbi_types.h> +#include <sbi/sbi_byteorder.h> + +enum { + RV_DBTR_DECLARE_BIT(TS, MAPPED, 0), /* trigger mapped to hw trigger */ + RV_DBTR_DECLARE_BIT(TS, U, 1), + RV_DBTR_DECLARE_BIT(TS, S, 2), + RV_DBTR_DECLARE_BIT(TS, VU, 3), + RV_DBTR_DECLARE_BIT(TS, VS, 4), + RV_DBTR_DECLARE_BIT(TS, HAVE_TRIG, 5), /* H/w dbtr details available */ + RV_DBTR_DECLARE_BIT(TS, HW_IDX, 8), /* Hardware index of trigger */ +}; + +enum { + RV_DBTR_DECLARE_BIT_MASK(TS, MAPPED, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, U, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, S, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, VU, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, VS, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, HAVE_TRIG, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, HW_IDX, (__riscv_xlen-9)), +}; + +#if __riscv_xlen ==64 +#define SBI_DBTR_SHMEM_INVALID_ADDR 0xFFFFFFFFFFFFFFFFUL +#elif __riscv_xlen ==32 +#define SBI_DBTR_SHMEM_INVALID_ADDR 0xFFFFFFFFUL +#error "Unexpected __riscv_xlen" +#endif + +struct sbi_dbtr_shmem { +unsigned long phys_lo; +unsigned long phys_hi; +}; + +struct sbi_dbtr_trigger { +unsigned long index; +unsigned long type_mask; +unsigned long state; +unsigned long tdata1; +unsigned long tdata2; +unsigned long tdata3; +}; + +struct sbi_dbtr_data_msg { +unsigned long tstate; +unsigned long tdata1; +unsigned long tdata2; +unsigned long tdata3; +}; + +struct sbi_dbtr_id_msg { +unsigned long idx; +}; + +struct sbi_dbtr_hart_triggers_state { +struct sbi_dbtr_trigger triggers[RV_MAX_TRIGGERS ]; +struct sbi_dbtr_shmem shmem; +u32 total_trigs; +u32 available_trigs; +u32 hartid; +}; + +#define TDATA1_GET_TYPE (_t1) \ + EXTRACT_FIELD(_t1, RV_DBTR_BIT_MASK(TDATA1, TYPE)) + +/* Set the hardware index of trigger in logical trigger state */ +#define SET_TRIG_HW_INDEX (_state, _idx) \ + do { \ + _state &= ~RV_DBTR_BIT_MASK(TS, HW_IDX); \ + _state |= (((unsigned long)_idx \ + << RV_DBTR_BIT(TS, HW_IDX)) \ + & RV_DBTR_BIT_MASK(TS, HW_IDX)); \ + }while (0); + +/** SBI shared mem messages layout */ +struct sbi_dbtr_shmem_entry { +struct sbi_dbtr_data_msg data; +struct sbi_dbtr_id_msg id; +}; + +#define SBI_DBTR_SHMEM_ALIGN_MASK ((__riscv_xlen / 8) - 1) + +/** Initialize debug triggers */ +int sbi_dbtr_init (struct sbi_scratch *scratch,bool coldboot); + +/** SBI DBTR extension functions */ +int sbi_dbtr_supported (void ); +int sbi_dbtr_setup_shmem (const struct sbi_domain *dom,unsigned long smode, +unsigned long shmem_phys_lo, +unsigned long shmem_phys_hi); +int sbi_dbtr_num_trig (unsigned long trig_tdata1,unsigned long *out); +int sbi_dbtr_read_trig (const struct sbi_domain *dom,unsigned long smode, +unsigned long trig_idx_base,unsigned long trig_count); +int sbi_dbtr_install_trig (const struct sbi_domain *dom,unsigned long smode, +unsigned long trig_count,unsigned long *out); +int sbi_dbtr_uninstall_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask); +int sbi_dbtr_enable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask); +int sbi_dbtr_update_trig (const struct sbi_domain *dom, +unsigned long smode, +unsigned long trig_idx_base, +unsigned long trig_idx_mask); +int sbi_dbtr_disable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask); + +int sbi_dbtr_get_total_triggers (void ); + +#endif
lib/sbi/objects.mk +1 -0
@@ -70,6 +70,7 @@ libsbi-objs-y += sbi_irqchip.o libsbi-objs-y += sbi_misaligned_ldst.o libsbi-objs-y += sbi_platform.o libsbi-objs-y += sbi_pmu.o +libsbi-objs-y += sbi_dbtr.o libsbi-objs-y += sbi_scratch.o libsbi-objs-y += sbi_string.o libsbi-objs-y += sbi_system.o
lib/sbi/sbi_dbtr.c new file +742 -0
742 lines not on this page · raw message
lib/sbi/sbi_init.c +9 -0
@@ -23,6 +23,7 @@#include <sbi/sbi_irqchip.h> #include <sbi/sbi_platform.h> #include <sbi/sbi_pmu.h> +#include <sbi/sbi_dbtr.h> #include <sbi/sbi_system.h> #include <sbi/sbi_string.h> #include <sbi/sbi_timer.h>
@@ -322,6 +323,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)sbi_hart_hang (); } + rc =sbi_dbtr_init (scratch, true); +if (rc) +sbi_hart_hang (); +sbi_boot_print_banner (scratch); rc =sbi_irqchip_init (scratch, true);
@@ -439,6 +444,10 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,if (rc)sbi_hart_hang (); + rc =sbi_dbtr_init (scratch, false); +if (rc) +sbi_hart_hang (); + rc =sbi_irqchip_init (scratch, false);if (rc)sbi_hart_hang ();
Signature · 1 line
2.34.1
PATCH v2 4/7 lib: sbi: Introduce the SBI debug triggers extension support
Quoted 13 lines · On Mon, Jan 8, 2024 at 12:25?PM Himanshu Chauhan <[email protected]>…
RISC-V Debug specification includes Sdtrig ISA extension which describes Trigger Module. Triggers can cause a breakpoint exception or trace action without execution of a special instruction. They can be used to implement hardware breakpoints and watchpoints for native debugging.
The SBI Debut Trigger extension (Draft v6) can be found at:
https://lists.riscv.org/g/tech-debug/topic/99825362#1302This patch is an initial implementation of SBI Debug Trigger Extension (Draft v6) in OpenSBI.
Quoted 7 lines
The following features are supported:
* mcontrol, mcontrol6 triggers
* Breakpoint and trace actionsNOTE: Chained triggers are not supported
Signed-off-by Himanshu Chauhan <[email protected]>
We need another patch just before this patch which detects the presence of Sdtrig extension based on ISA string. The Txyz CSRs are only available when the Sdtrig extension is available.
Quoted 319 lines
--- include/sbi/sbi_dbtr.h | 127 +++++++ lib/sbi/objects.mk | 1 + lib/sbi/sbi_dbtr.c | 742 +++++++++++++++++++++++++++++++++++++++++ lib/sbi/sbi_init.c | 9 + 4 files changed, 879 insertions(+) create mode 100644 include/sbi/sbi_dbtr.h create mode 100644 lib/sbi/sbi_dbtr.cinclude/sbi/sbi_dbtr.h new file +127
-0@@ -0,0 +1,127 @@ +/* +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright (c) 2023 Ventana Micro Systems, Inc. +* +* Authors: +* Himanshu Chauhan <[email protected]> +*/ + +#ifndef __SBI_DBTR_H__ +#define __SBI_DBTR_H__ + +#include <sbi/riscv_dbtr.h> + +#include <sbi/sbi_hartmask.h> +#include <sbi/sbi_scratch.h> +#include <sbi/sbi_domain.h> +#include <sbi/sbi_types.h> +#include <sbi/sbi_byteorder.h> + +enum { + RV_DBTR_DECLARE_BIT(TS, MAPPED, 0), /* trigger mapped to hw trigger */ + RV_DBTR_DECLARE_BIT(TS, U, 1), + RV_DBTR_DECLARE_BIT(TS, S, 2), + RV_DBTR_DECLARE_BIT(TS, VU, 3), + RV_DBTR_DECLARE_BIT(TS, VS, 4), + RV_DBTR_DECLARE_BIT(TS, HAVE_TRIG, 5), /* H/w dbtr details available */ + RV_DBTR_DECLARE_BIT(TS, HW_IDX, 8), /* Hardware index of trigger */ +}; + +enum { + RV_DBTR_DECLARE_BIT_MASK(TS, MAPPED, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, U, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, S, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, VU, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, VS, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, HAVE_TRIG, 1), + RV_DBTR_DECLARE_BIT_MASK(TS, HW_IDX, (__riscv_xlen-9)), +}; + +#if __riscv_xlen ==64 +#define SBI_DBTR_SHMEM_INVALID_ADDR 0xFFFFFFFFFFFFFFFFUL +#elif __riscv_xlen ==32 +#define SBI_DBTR_SHMEM_INVALID_ADDR 0xFFFFFFFFUL +#error "Unexpected __riscv_xlen" +#endif + +struct sbi_dbtr_shmem { +unsigned long phys_lo; +unsigned long phys_hi; +}; + +struct sbi_dbtr_trigger { +unsigned long index; +unsigned long type_mask; +unsigned long state; +unsigned long tdata1; +unsigned long tdata2; +unsigned long tdata3; +}; + +struct sbi_dbtr_data_msg { +unsigned long tstate; +unsigned long tdata1; +unsigned long tdata2; +unsigned long tdata3; +}; + +struct sbi_dbtr_id_msg { +unsigned long idx; +}; + +struct sbi_dbtr_hart_triggers_state { +struct sbi_dbtr_trigger triggers[RV_MAX_TRIGGERS ]; +struct sbi_dbtr_shmem shmem; +u32 total_trigs; +u32 available_trigs; +u32 hartid; +}; + +#define TDATA1_GET_TYPE (_t1) \ + EXTRACT_FIELD(_t1, RV_DBTR_BIT_MASK(TDATA1, TYPE)) + +/* Set the hardware index of trigger in logical trigger state */ +#define SET_TRIG_HW_INDEX (_state, _idx) \ + do { \ + _state &= ~RV_DBTR_BIT_MASK(TS, HW_IDX); \ + _state |= (((unsigned long)_idx \ + << RV_DBTR_BIT(TS, HW_IDX)) \ + & RV_DBTR_BIT_MASK(TS, HW_IDX)); \ + }while (0); + +/** SBI shared mem messages layout */ +struct sbi_dbtr_shmem_entry { +struct sbi_dbtr_data_msg data; +struct sbi_dbtr_id_msg id; +}; + +#define SBI_DBTR_SHMEM_ALIGN_MASK ((__riscv_xlen / 8) - 1) + +/** Initialize debug triggers */ +int sbi_dbtr_init (struct sbi_scratch *scratch,bool coldboot); + +/** SBI DBTR extension functions */ +int sbi_dbtr_supported (void ); +int sbi_dbtr_setup_shmem (const struct sbi_domain *dom,unsigned long smode, +unsigned long shmem_phys_lo, +unsigned long shmem_phys_hi); +int sbi_dbtr_num_trig (unsigned long trig_tdata1,unsigned long *out); +int sbi_dbtr_read_trig (const struct sbi_domain *dom,unsigned long smode, +unsigned long trig_idx_base,unsigned long trig_count); +int sbi_dbtr_install_trig (const struct sbi_domain *dom,unsigned long smode, +unsigned long trig_count,unsigned long *out); +int sbi_dbtr_uninstall_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask); +int sbi_dbtr_enable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask); +int sbi_dbtr_update_trig (const struct sbi_domain *dom, +unsigned long smode, +unsigned long trig_idx_base, +unsigned long trig_idx_mask); +int sbi_dbtr_disable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask); + +int sbi_dbtr_get_total_triggers (void ); + +#endif lib/sbi/objects.mk +1
-0@@ -70,6 +70,7 @@ libsbi-objs-y += sbi_irqchip.o libsbi-objs-y += sbi_misaligned_ldst.o libsbi-objs-y += sbi_platform.o libsbi-objs-y += sbi_pmu.o +libsbi-objs-y += sbi_dbtr.o libsbi-objs-y += sbi_scratch.o libsbi-objs-y += sbi_string.o libsbi-objs-y += sbi_system.olib/sbi/sbi_dbtr.c new file +159
-0@@ -0,0 +1,742 @@ +/* +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright (c) 2023 Ventana Micro Systems, Inc. +* +* Author(s): +* Himanshu Chauhan <[email protected]> +*/ + +#include <sbi/sbi_ecall_interface.h> +#include <sbi/sbi_csr_detect.h> +#include <sbi/sbi_platform.h> +#include <sbi/sbi_console.h> +#include <sbi/sbi_trap.h> +#include <sbi/sbi_dbtr.h> +#include <sbi/sbi_heap.h> +#include <sbi/riscv_encoding.h> +#include <sbi/riscv_asm.h> + + +/** Offset of pointer to HART's debug triggers info in scratch space */ +static unsigned long hart_state_ptr_offset; + +#define dbtr_get_hart_state_ptr (__scratch) \ + sbi_scratch_read_type((__scratch), void *, hart_state_ptr_offset) + +#define dbtr_thishart_state_ptr () \ + dbtr_get_hart_state_ptr(sbi_scratch_thishart_ptr()) + +#define dbtr_set_hart_state_ptr (__scratch, __hart_state) \ + sbi_scratch_write_type((__scratch), void *, hart_state_ptr_offset, \ + (__hart_state)) + +#define INDEX_TO_TRIGGER (_index) \ + ({ \ + struct sbi_dbtr_trigger *__trg = NULL; \ + struct sbi_dbtr_hart_triggers_state *__hs = NULL; \ + __hs = dbtr_get_hart_state_ptr(sbi_scratch_thishart_ptr()); \ + __trg = &__hs->triggers[_index]; \ + (__trg); \ + }) + +#define for_each_trig_entry (_base, _max, _etype, _entry) \ + for (int _idx = 0; _entry = ((_etype *)_base + _idx), \ + _idx < _max; \ + _idx++, _entry = ((_etype *)_base + _idx)) + +#if __riscv_xlen ==64 +#define DBTR_SHMEM_MAKE_PHYS (_p_hi, _p_lo) (((u64)(_p_hi) << 32) | (_p_lo)) +#elif __riscv_xlen ==32 +#define DBTR_SHMEM_MAKE_PHYS (_p_hi, _p_lo) (((u64)(_p_hi) << 32) | (_p_lo)) +#else +#error "Undefined XLEN" +#endif + +static inline int sbi_dbtr_shmem_disabled (void ) +{ +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + + hs =dbtr_get_hart_state_ptr (sbi_scratch_thishart_ptr ()); + +if (!hs) +return 1 ; + +return (hs->shmem.phys_lo ==SBI_DBTR_SHMEM_INVALID_ADDR && + hs->shmem.phys_hi ==SBI_DBTR_SHMEM_INVALID_ADDR + ?1 :0 ); +} + +static inline void sbi_dbtr_disable_shmem (void ) +{ +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + + hs =dbtr_get_hart_state_ptr (sbi_scratch_thishart_ptr ()); + +if (!hs) +return ; + + hs->shmem.phys_lo =SBI_DBTR_SHMEM_INVALID_ADDR ; + hs->shmem.phys_hi =SBI_DBTR_SHMEM_INVALID_ADDR ; +} + +static inline void *hart_shmem_base (void ) +{ +struct sbi_dbtr_shmem * shmem; +unsigned long phys_hi, phys_lo; +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + + hs =dbtr_get_hart_state_ptr (sbi_scratch_thishart_ptr ()); + +if (!hs) +return NULL ; + + shmem = &hs->shmem; + + phys_hi = (shmem->phys_hi ==SBI_DBTR_SHMEM_INVALID_ADDR + ? shmem->phys_hi :0 ); + phys_lo = (shmem->phys_lo ==SBI_DBTR_SHMEM_INVALID_ADDR + ?0 : shmem->phys_lo); + +return ((void *)DBTR_SHMEM_MAKE_PHYS (phys_hi, phys_lo)); +} + +static void sbi_trigger_init (struct sbi_dbtr_trigger *trig, +unsigned long type_mask,unsigned long idx) +{ + trig->type_mask = type_mask; + trig->state =0 ; + trig->tdata1 =0 ; + trig->tdata2 =0 ; + trig->tdata3 =0 ; + trig->index = idx; +} + +static inline struct sbi_dbtr_trigger *sbi_alloc_trigger (void ) +{ +int i; +struct sbi_dbtr_trigger *f_trig =NULL ; +struct sbi_dbtr_hart_triggers_state *hart_state; + + hart_state =dbtr_thishart_state_ptr (); +if (!hart_state) +return NULL ; + +if (hart_state->available_trigs <=0 ) +return NULL ; + +for (i =0 ; i < hart_state->total_trigs; i++) { + f_trig =INDEX_TO_TRIGGER (i); +if (f_trig->state &RV_DBTR_BIT (TS ,MAPPED )) +continue ; + hart_state->available_trigs--; +break ; + } + +if (i == hart_state->total_trigs) +return NULL ; + +__set_bit (RV_DBTR_BIT (TS ,MAPPED ), &f_trig->state); + +return f_trig; +} + +static inline void sbi_free_trigger (struct sbi_dbtr_trigger *trig) +{ +struct sbi_dbtr_hart_triggers_state *hart_state; + +if (trig ==NULL ) +return ; + + hart_state =dbtr_thishart_state_ptr (); +if (!hart_state) +return ; + + trig->state =0 ; + trig->tdata1 =0 ; + trig->tdata2 =0 ; + trig->tdata3 =0 ; +
lib/sbi/sbi_dbtr.c line 169
Quoted 10 lines
lib/sbi/sbi_dbtr.c new file +10
-0+ hart_state->available_trigs++; +} + +int sbi_dbtr_init (struct sbi_scratch *scratch,bool coldboot) +{ +struct sbi_trap_info trap = {0 }; +unsigned long tdata1; +unsigned long val; +int i; +struct sbi_dbtr_hart_triggers_state *hart_state =NULL ;
Do nothing is Sdtrig extension is not available.
Quoted 10 lines
lib/sbi/sbi_dbtr.c new file +10
-0+ +if (coldboot) { + hart_state_ptr_offset = sbi_scratch_alloc_type_offset(void *); +if (!hart_state_ptr_offset) +return SBI_ENOMEM ; + } + + hart_state =dbtr_get_hart_state_ptr (scratch); +if (!hart_state) { + hart_state =sbi_zalloc (sizeof (*hart_state));
lib/sbi/sbi_dbtr.c line 189
Quoted 10 lines
lib/sbi/sbi_dbtr.c new file +10
-0+if (!hart_state) +return SBI_ENOMEM ; + hart_state->hartid =current_hartid (); +dbtr_set_hart_state_ptr (scratch, hart_state); + } + +/* disable the shared memory */ +sbi_dbtr_disable_shmem (); + +for (i =0 ; i <RV_MAX_TRIGGERS ; i++) {
This for-loop should only be done once on each HART otherwise it will increase the HART bring-up time for runtime HART hotplug.
Quoted 59 lines
lib/sbi/sbi_dbtr.c new file +59
-0+csr_write_allowed (CSR_TSELECT , (ulong)&trap, i); +if (trap.cause) +break ; + + val =csr_read_allowed (CSR_TSELECT , (ulong)&trap); +if (trap.cause) +break ; + +/* +* Read back tselect and check that it contains the +* written value +*/ +if (val != i) +break ; + + val =csr_read_allowed (CSR_TINFO , (ulong)&trap); +if (trap.cause) { +/* +* If reading tinfo caused an exception, the +* debugger must read tdata1 to discover the +* type. +*/ + tdata1 =csr_read_allowed (CSR_TDATA1 , + (ulong)&trap); +if (trap.cause) +break ; + +if (TDATA1_GET_TYPE (tdata1) ==0 ) +break ; + +sbi_trigger_init (INDEX_TO_TRIGGER (i), +BIT (TDATA1_GET_TYPE (tdata1)), + i); + hart_state->total_trigs++; + }else { +if (val ==1 ) +break ; + +sbi_trigger_init (INDEX_TO_TRIGGER (i), val, i); + hart_state->total_trigs++; + } + } + + hart_state->available_trigs = hart_state->total_trigs; + +return 0 ; +} + +int sbi_dbtr_supported (void ) +{ +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return 0 ; + +return !!hs->total_trigs; +} +
lib/sbi/sbi_dbtr.c line 258
Quoted 10 lines
lib/sbi/sbi_dbtr.c new file +10
-0+int sbi_dbtr_get_total_triggers (void ) +{ +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return 0 ; + +return hs->total_trigs; +}
sbi_dbtr_supported() and sbi_dbtr_get_total_triggers() are doing the same thing. Why not keep only one of them ?
lib/sbi/sbi_dbtr.c line 271
Quoted 13 lines
lib/sbi/sbi_dbtr.c new file +13
-0+ +int sbi_dbtr_setup_shmem (const struct sbi_domain *dom,unsigned long smode, +unsigned long shmem_phys_lo, +unsigned long shmem_phys_hi) +{ +u32 hartid =current_hartid (); +struct sbi_dbtr_hart_triggers_state *hart_state; + +if (smode !=PRV_S ) { +sbi_dprintf ("%s: Non supervisor mode. Access denied\n" , + __func__); +return SBI_ERR_DENIED ; + }
Drop the smode parameter and check over here because on HART with just M-mode and U-mode we should allow this function.
Quoted 295 lines
lib/sbi/sbi_dbtr.c new file +295
-0+ +if (dom && !sbi_domain_is_assigned_hart (dom, hartid)) { +sbi_dprintf ("%s: calling hart not assigned to this domain\n" , + __func__); +return SBI_ERR_DENIED ; + } + +/* call is to disable shared memory */ +if (shmem_phys_lo ==SBI_DBTR_SHMEM_INVALID_ADDR + && shmem_phys_hi ==SBI_DBTR_SHMEM_INVALID_ADDR ) { +sbi_dbtr_disable_shmem (); +return SBI_SUCCESS ; + } + +/* the shared memory must be disabled on this hart */ +if (!sbi_dbtr_shmem_disabled ()) +return SBI_ERR_ALREADY_AVAILABLE ; + +/* lower physical address must be XLEN/8 bytes aligned */ +if (shmem_phys_lo &SBI_DBTR_SHMEM_ALIGN_MASK ) +return SBI_ERR_INVALID_PARAM ; + +if (dom && !sbi_domain_check_addr (dom, shmem_phys_lo, smode, +SBI_DOMAIN_READ |SBI_DOMAIN_WRITE )) +return SBI_ERR_INVALID_ADDRESS ; + +if (shmem_phys_hi !=SBI_DBTR_SHMEM_INVALID_ADDR ) { +if (dom && + !sbi_domain_check_addr (dom, shmem_phys_hi, smode, +SBI_DOMAIN_READ |SBI_DOMAIN_WRITE )) +return SBI_ERR_INVALID_ADDRESS ; + } + + hart_state =dbtr_thishart_state_ptr (); +if (!hart_state) +return SBI_ERR_FAILED ; + + hart_state->shmem.phys_lo = shmem_phys_lo; + hart_state->shmem.phys_hi = shmem_phys_hi; + +return SBI_SUCCESS ; +} + +static void dbtr_trigger_setup (struct sbi_dbtr_trigger *trig, +struct sbi_dbtr_data_msg *recv) +{ +unsigned long tdata1; + +if (!trig) +return ; + + trig->tdata1 =lle_to_cpu (recv->tdata1); + trig->tdata2 =lle_to_cpu (recv->tdata2); + trig->tdata3 =lle_to_cpu (recv->tdata3); + + tdata1 =lle_to_cpu (recv->tdata1); + + trig->state =0 ; + +__set_bit (RV_DBTR_BIT (TS ,MAPPED ), &trig->state); + +SET_TRIG_HW_INDEX (trig->state, trig->index); + +switch (TDATA1_GET_TYPE (tdata1)) { +case RISCV_DBTR_TRIG_MCONTROL : +if (__test_bit (RV_DBTR_BIT (MC ,U ), &tdata1)) +__set_bit (RV_DBTR_BIT (TS ,U ), &trig->state); + +if (__test_bit (RV_DBTR_BIT (MC ,S ), &tdata1)) +__set_bit (RV_DBTR_BIT (TS ,S ), &trig->state); +break ; +case RISCV_DBTR_TRIG_MCONTROL6 : +if (__test_bit (RV_DBTR_BIT (MC6 ,U ), &tdata1)) +__set_bit (RV_DBTR_BIT (TS ,U ), &trig->state); + +if (__test_bit (RV_DBTR_BIT (MC6 ,S ), &tdata1)) +__set_bit (RV_DBTR_BIT (TS ,S ), &trig->state); + +if (__test_bit (RV_DBTR_BIT (MC6 ,VU ), &tdata1)) +__set_bit (RV_DBTR_BIT (TS ,VU ), &trig->state); + +if (__test_bit (RV_DBTR_BIT (MC6 ,VS ), &tdata1)) +__set_bit (RV_DBTR_BIT (TS ,VS ), &trig->state); +break ; +default : +sbi_dprintf ("%s: Unknown type (tdata1: 0x%lx Type: %ld)\n" , + __func__, tdata1,TDATA1_GET_TYPE (tdata1)); +break ; + } +} + +static inline void update_bit (unsigned long new,int nr,volatile unsigned long *addr) +{ +if (new) +__set_bit (nr, addr); +else +__clear_bit (nr, addr); +} + +static void dbtr_trigger_enable (struct sbi_dbtr_trigger *trig) +{ +unsigned long state; +unsigned long tdata1; + +if (!trig && !(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return ; + + state = trig->state; + tdata1 = trig->tdata1; + +switch (TDATA1_GET_TYPE (tdata1)) { +case RISCV_DBTR_TRIG_MCONTROL : +update_bit (state &RV_DBTR_BIT_MASK (TS ,U ), +RV_DBTR_BIT (MC ,U ), &trig->tdata1); +update_bit (state &RV_DBTR_BIT_MASK (TS ,S ), +RV_DBTR_BIT (MC ,S ), &trig->tdata1); +break ; +case RISCV_DBTR_TRIG_MCONTROL6 : +update_bit (state &RV_DBTR_BIT_MASK (TS ,VU ), +RV_DBTR_BIT (MC6 ,VU ), &trig->tdata1); +update_bit (state &RV_DBTR_BIT_MASK (TS ,VS ), +RV_DBTR_BIT (MC6 ,VS ), &trig->tdata1); +update_bit (state &RV_DBTR_BIT_MASK (TS ,U ), +RV_DBTR_BIT (MC6 ,U ), &trig->tdata1); +update_bit (state &RV_DBTR_BIT_MASK (TS ,S ), +RV_DBTR_BIT (MC6 ,S ), &trig->tdata1); +break ; +default : +break ; + } + +/* +* RISC-V Debug Support v1.0.0 section 5.5: +* Debugger cannot simply set a trigger by writing tdata1, then tdata2, +* etc. The current value of tdata2 might not be legal with the new +* value of tdata1. To help with this situation, it is guaranteed that +* writing 0 to tdata1 disables the trigger, and leaves it in a state +* where tdata2 and tdata3 can be written with any value that makes +* sense for any trigger type supported by this trigger. +*/ +csr_write (CSR_TSELECT , trig->index); +csr_write (CSR_TDATA1 ,0x0 ); +csr_write (CSR_TDATA2 , trig->tdata2); +csr_write (CSR_TDATA1 , trig->tdata1); +} + +static void dbtr_trigger_disable (struct sbi_dbtr_trigger *trig) +{ +unsigned long tdata1; + +if (!trig && !(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return ; + + tdata1 = trig->tdata1; + +switch (TDATA1_GET_TYPE (tdata1)) { +case RISCV_DBTR_TRIG_MCONTROL : +__clear_bit (RV_DBTR_BIT (MC ,U ), &trig->tdata1); +__clear_bit (RV_DBTR_BIT (MC ,S ), &trig->tdata1); +break ; +case RISCV_DBTR_TRIG_MCONTROL6 : +__clear_bit (RV_DBTR_BIT (MC6 ,VU ), &trig->tdata1); +__clear_bit (RV_DBTR_BIT (MC6 ,VS ), &trig->tdata1); +__clear_bit (RV_DBTR_BIT (MC6 ,U ), &trig->tdata1); +__clear_bit (RV_DBTR_BIT (MC6 ,S ), &trig->tdata1); +break ; +default : +break ; + } + +csr_write (CSR_TSELECT , trig->index); +csr_write (CSR_TDATA1 , trig->tdata1); +} + +static void dbtr_trigger_clear (struct sbi_dbtr_trigger *trig) +{ +if (!trig && !(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return ; + +csr_write (CSR_TSELECT , trig->index); +csr_write (CSR_TDATA1 ,0x0 ); +csr_write (CSR_TDATA2 ,0x0 ); +} + +static int dbtr_trigger_supported (unsigned long type) +{ +switch (type) { +case RISCV_DBTR_TRIG_MCONTROL : +case RISCV_DBTR_TRIG_MCONTROL6 : +return 1 ; +default : +break ; + } + +return 0 ; +} + +static int dbtr_trigger_valid (unsigned long type,unsigned long tdata) +{ +switch (type) { +case RISCV_DBTR_TRIG_MCONTROL : +if (!(tdata &RV_DBTR_BIT_MASK (MC ,DMODE )) && + !(tdata &RV_DBTR_BIT_MASK (MC ,M ))) +return 1 ; +break ; +case RISCV_DBTR_TRIG_MCONTROL6 : +if (!(tdata &RV_DBTR_BIT_MASK (MC6 ,DMODE )) && + !(tdata &RV_DBTR_BIT_MASK (MC6 ,M ))) +return 1 ; +break ; +default : +break ; + } + +return 0 ; +} + +int sbi_dbtr_num_trig (unsigned long data,unsigned long *out) +{ +unsigned long type =TDATA1_GET_TYPE (data); +u32 hartid =current_hartid (); +unsigned long total =0 ; +struct sbi_dbtr_trigger *trig; +int i; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +if (data ==0 ) { + *out = hs->total_trigs; +return SBI_SUCCESS ; + } + +for (i =0 ; i < hs->total_trigs; i++) { + trig =INDEX_TO_TRIGGER (i); + +if (__test_bit (type, &trig->type_mask)) + total++; + } + +sbi_dprintf ("%s: hart%d: total triggers of type %lu: %lu\n" , + __func__, hartid, type, total); + + *out = total; +return SBI_SUCCESS ; +} + +int sbi_dbtr_read_trig (const struct sbi_domain *dom,unsigned long smode, +unsigned long trig_idx_base,unsigned long trig_count) +{ +struct sbi_dbtr_data_msg *xmit; +u32 hartid =current_hartid (); +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_shmem_entry *entry; +void *shmem_base =NULL ; +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + +if (smode !=PRV_S ) +return SBI_ERR_DENIED ; +if (dom && !sbi_domain_is_assigned_hart (dom, hartid)) +return SBI_ERR_DENIED ; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +if (trig_idx_base >= hs->total_trigs || + trig_idx_base + trig_count >= hs->total_trigs) +return SBI_ERR_INVALID_PARAM ; + +if (sbi_dbtr_shmem_disabled ()) +return SBI_ERR_NO_SHMEM ; + + shmem_base =hart_shmem_base (); + +for_each_trig_entry (shmem_base, trig_count,typeof (*entry), entry) { +sbi_hart_map_saddr ((unsigned long )entry,sizeof (*entry)); + xmit = &entry->data; + trig =INDEX_TO_TRIGGER ((_idx + trig_idx_base)); + xmit->tstate =cpu_to_lle (trig->state); + xmit->tdata1 =cpu_to_lle (trig->tdata1); + xmit->tdata2 =cpu_to_lle (trig->tdata2); + xmit->tdata3 =cpu_to_lle (trig->tdata3); +sbi_hart_unmap_saddr (); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_install_trig (const struct sbi_domain *dom,unsigned long smode, +unsigned long trig_count,unsigned long *out) +{ +u32 hartid =current_hartid ();
lib/sbi/sbi_dbtr.c line 576
Quoted 10 lines
lib/sbi/sbi_dbtr.c new file +10
-0+void *shmem_base =NULL ; +struct sbi_dbtr_shmem_entry *entry; +struct sbi_dbtr_data_msg *recv; +struct sbi_dbtr_id_msg *xmit; +unsigned long ctrl; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + +if (smode !=PRV_S ) +return SBI_ERR_DENIED ;
Same as above, drop the smode check and parameter.
Quoted 109 lines
lib/sbi/sbi_dbtr.c new file +109
-0+if (dom && !sbi_domain_is_assigned_hart (dom, hartid)) +return SBI_ERR_DENIED ; + +if (sbi_dbtr_shmem_disabled ()) +return SBI_ERR_NO_SHMEM ; + + shmem_base =hart_shmem_base (); + hs =dbtr_thishart_state_ptr (); + +/* Check requested triggers configuration */ +for_each_trig_entry (shmem_base, trig_count,typeof (*entry), entry) { +sbi_hart_map_saddr ((unsigned long )entry,sizeof (*entry)); + recv = (struct sbi_dbtr_data_msg *)(&entry->data); + ctrl = recv->tdata1; + +if (!dbtr_trigger_supported (TDATA1_GET_TYPE (ctrl))) { + *out = _idx; +sbi_hart_unmap_saddr (); +return SBI_ERR_FAILED ; + } + +if (!dbtr_trigger_valid (TDATA1_GET_TYPE (ctrl), ctrl)) { + *out = _idx; +sbi_hart_unmap_saddr (); +return SBI_ERR_FAILED ; + } +sbi_hart_unmap_saddr (); + } + +if (hs->available_trigs < trig_count) { + *out = hs->available_trigs; +return SBI_ERR_FAILED ; + } + +/* Install triggers */ +for_each_trig_entry (shmem_base, trig_count,typeof (*entry), entry) { +/* +* Since we have already checked if enough triggers are +* available, trigger allocation must succeed. +*/ + trig =sbi_alloc_trigger (); + +sbi_hart_map_saddr ((unsigned long )entry,sizeof (*entry)); + + recv = (struct sbi_dbtr_data_msg *)(&entry->data); + xmit = (struct sbi_dbtr_id_msg *)(&entry->id); + +dbtr_trigger_setup (trig, recv); +dbtr_trigger_enable (trig); + xmit->idx =cpu_to_lle (trig->index); +sbi_hart_unmap_saddr (); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_uninstall_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +if (!(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return SBI_ERR_INVALID_PARAM ; + +dbtr_trigger_clear (trig); + +sbi_free_trigger (trig); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_enable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +sbi_dprintf ("%s: enable trigger %lu\n" , __func__, idx); +dbtr_trigger_enable (trig); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_update_trig (const struct sbi_domain *dom, +unsigned long smode, +unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base;
lib/sbi/sbi_dbtr.c line 695
Quoted 10 lines
lib/sbi/sbi_dbtr.c new file +10
-0+u32 hartid =current_hartid (); +struct sbi_dbtr_data_msg *recv; +unsigned long uidx =0 ; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_shmem_entry *entry; +void *shmem_base =NULL ; +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + +if (smode !=PRV_S ) +return SBI_ERR_DENIED ;
Same as above, drop the smode check and parameter.
Quoted 85 lines
lib/sbi/sbi_dbtr.c new file +47
-0+if (dom && !sbi_domain_is_assigned_hart (dom, hartid)) +return SBI_ERR_DENIED ; + +if (sbi_dbtr_shmem_disabled ()) +return SBI_ERR_NO_SHMEM ; + + shmem_base =hart_shmem_base (); + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); + +if (!(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return SBI_ERR_INVALID_PARAM ; + + entry = (shmem_base + uidx *sizeof (*entry)); + recv = &entry->data; + + trig->tdata2 =lle_to_cpu (recv->tdata2); +dbtr_trigger_enable (trig); + uidx++; + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_disable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +dbtr_trigger_disable (trig); + } + +return SBI_SUCCESS ; +}lib/sbi/sbi_init.c +9
-1@@ -23,6 +23,7 @@#include <sbi/sbi_irqchip.h> #include <sbi/sbi_platform.h> #include <sbi/sbi_pmu.h> +#include <sbi/sbi_dbtr.h> #include <sbi/sbi_system.h> #include <sbi/sbi_string.h> #include <sbi/sbi_timer.h> @@ -322,6 +323,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)sbi_hart_hang (); } + rc =sbi_dbtr_init (scratch, true); +if (rc) +sbi_hart_hang (); +sbi_boot_print_banner (scratch); rc =sbi_irqchip_init (scratch, true);@@ -439,6 +444,10 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,if (rc)sbi_hart_hang (); + rc =sbi_dbtr_init (scratch, false); +if (rc) +sbi_hart_hang (); + rc =sbi_irqchip_init (scratch, false);if (rc)sbi_hart_hang (); --2.34.1
Quoted 4 lines
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
Regards,
Anup
PATCH v2 4/7 lib: sbi: Introduce the SBI debug triggers extension support
Hi Anup,
Quoted 3 lines · Anup Patel
Quoted 2 lines
<snip>
Quoted 8 lines
Quoted 8 lines
lib/sbi/sbi_dbtr.c new file +8
-0+int sbi_dbtr_install_trig (const struct sbi_domain *dom,unsigned long smode, +unsigned long trig_count,unsigned long *out) +{ +u32 hartid =current_hartid (); +void *shmem_base =NULL ; +struct sbi_dbtr_shmem_entry *entry; +struct sbi_dbtr_data_msg *recv; +struct sbi_dbtr_id_msg *xmit;
Quoted 8 lines
lib/sbi/sbi_dbtr.c line 576
Quoted 6 lines
lib/sbi/sbi_dbtr.c new file +6
-0+unsigned long ctrl; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + +if (smode !=PRV_S ) +return SBI_ERR_DENIED ;Same as above, drop the smode check and parameter.
We cannot completely drop the smode parameter here because it is used for domain address access validation. The check of S_PRV can be dropped.
Regards
Himanshu
Quoted 215 lines
Quoted 110 lines
lib/sbi/sbi_dbtr.c new file +109
-0+if (dom && !sbi_domain_is_assigned_hart (dom, hartid)) +return SBI_ERR_DENIED ; + +if (sbi_dbtr_shmem_disabled ()) +return SBI_ERR_NO_SHMEM ; + + shmem_base =hart_shmem_base (); + hs =dbtr_thishart_state_ptr (); + +/* Check requested triggers configuration */ +for_each_trig_entry (shmem_base, trig_count,typeof (*entry), entry) { +sbi_hart_map_saddr ((unsigned long )entry,sizeof (*entry)); + recv = (struct sbi_dbtr_data_msg *)(&entry->data); + ctrl = recv->tdata1; + +if (!dbtr_trigger_supported (TDATA1_GET_TYPE (ctrl))) { + *out = _idx; +sbi_hart_unmap_saddr (); +return SBI_ERR_FAILED ; + } + +if (!dbtr_trigger_valid (TDATA1_GET_TYPE (ctrl), ctrl)) { + *out = _idx; +sbi_hart_unmap_saddr (); +return SBI_ERR_FAILED ; + } +sbi_hart_unmap_saddr (); + } + +if (hs->available_trigs < trig_count) { + *out = hs->available_trigs; +return SBI_ERR_FAILED ; + } + +/* Install triggers */ +for_each_trig_entry (shmem_base, trig_count,typeof (*entry), entry) { +/* +* Since we have already checked if enough triggers are +* available, trigger allocation must succeed. +*/ + trig =sbi_alloc_trigger (); + +sbi_hart_map_saddr ((unsigned long )entry,sizeof (*entry)); + + recv = (struct sbi_dbtr_data_msg *)(&entry->data); + xmit = (struct sbi_dbtr_id_msg *)(&entry->id); + +dbtr_trigger_setup (trig, recv); +dbtr_trigger_enable (trig); + xmit->idx =cpu_to_lle (trig->index); +sbi_hart_unmap_saddr (); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_uninstall_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +if (!(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return SBI_ERR_INVALID_PARAM ; + +dbtr_trigger_clear (trig); + +sbi_free_trigger (trig); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_enable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +sbi_dprintf ("%s: enable trigger %lu\n" , __func__, idx); +dbtr_trigger_enable (trig); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_update_trig (const struct sbi_domain *dom, +unsigned long smode, +unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base;lib/sbi/sbi_dbtr.c line 695
Quoted 10 lines
lib/sbi/sbi_dbtr.c new file +10
-0+u32 hartid =current_hartid (); +struct sbi_dbtr_data_msg *recv; +unsigned long uidx =0 ; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_shmem_entry *entry; +void *shmem_base =NULL ; +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + +if (smode !=PRV_S ) +return SBI_ERR_DENIED ;Same as above, drop the smode check and parameter.
Quoted 85 lines
lib/sbi/sbi_dbtr.c new file +47
-0+if (dom && !sbi_domain_is_assigned_hart (dom, hartid)) +return SBI_ERR_DENIED ; + +if (sbi_dbtr_shmem_disabled ()) +return SBI_ERR_NO_SHMEM ; + + shmem_base =hart_shmem_base (); + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); + +if (!(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return SBI_ERR_INVALID_PARAM ; + + entry = (shmem_base + uidx *sizeof (*entry)); + recv = &entry->data; + + trig->tdata2 =lle_to_cpu (recv->tdata2); +dbtr_trigger_enable (trig); + uidx++; + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_disable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +dbtr_trigger_disable (trig); + } + +return SBI_SUCCESS ; +}lib/sbi/sbi_init.c +9
-1@@ -23,6 +23,7 @@#include <sbi/sbi_irqchip.h> #include <sbi/sbi_platform.h> #include <sbi/sbi_pmu.h> +#include <sbi/sbi_dbtr.h> #include <sbi/sbi_system.h> #include <sbi/sbi_string.h> #include <sbi/sbi_timer.h> @@ -322,6 +323,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)sbi_hart_hang (); } + rc =sbi_dbtr_init (scratch, true); +if (rc) +sbi_hart_hang (); +sbi_boot_print_banner (scratch); rc =sbi_irqchip_init (scratch, true);@@ -439,6 +444,10 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,if (rc)sbi_hart_hang (); + rc =sbi_dbtr_init (scratch, false); +if (rc) +sbi_hart_hang (); + rc =sbi_irqchip_init (scratch, false);if (rc)sbi_hart_hang (); --2.34.1
Quoted 4 lines
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbiRegards,
Anup
PATCH v2 4/7 lib: sbi: Introduce the SBI debug triggers extension support
Quoted 26 lines · On Tue, Jan 9, 2024 at 9:01?PM Himanshu Chauhan <[email protected]>…
Hi Anup,
Quoted 3 lines · Anup Patel
Quoted 2 lines
<snip>
Quoted 8 lines
Quoted 8 lines
lib/sbi/sbi_dbtr.c new file +8
-0+int sbi_dbtr_install_trig (const struct sbi_domain *dom,unsigned long smode, +unsigned long trig_count,unsigned long *out) +{ +u32 hartid =current_hartid (); +void *shmem_base =NULL ; +struct sbi_dbtr_shmem_entry *entry; +struct sbi_dbtr_data_msg *recv; +struct sbi_dbtr_id_msg *xmit;Quoted 8 lines
lib/sbi/sbi_dbtr.c line 576
Quoted 6 lines
lib/sbi/sbi_dbtr.c new file +6
-0+unsigned long ctrl; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + +if (smode !=PRV_S ) +return SBI_ERR_DENIED ;Same as above, drop the smode check and parameter.
Quoted 1 line
We cannot completely drop the smode parameter here because it is used for domain address access validation. The check of
S_PRVcan be dropped.
Okay, at least drop the sanity check.
Regards,
Anup
Quoted 221 lines
Regards
HimanshuQuoted 215 lines
Quoted 110 lines
lib/sbi/sbi_dbtr.c new file +109
-0+if (dom && !sbi_domain_is_assigned_hart (dom, hartid)) +return SBI_ERR_DENIED ; + +if (sbi_dbtr_shmem_disabled ()) +return SBI_ERR_NO_SHMEM ; + + shmem_base =hart_shmem_base (); + hs =dbtr_thishart_state_ptr (); + +/* Check requested triggers configuration */ +for_each_trig_entry (shmem_base, trig_count,typeof (*entry), entry) { +sbi_hart_map_saddr ((unsigned long )entry,sizeof (*entry)); + recv = (struct sbi_dbtr_data_msg *)(&entry->data); + ctrl = recv->tdata1; + +if (!dbtr_trigger_supported (TDATA1_GET_TYPE (ctrl))) { + *out = _idx; +sbi_hart_unmap_saddr (); +return SBI_ERR_FAILED ; + } + +if (!dbtr_trigger_valid (TDATA1_GET_TYPE (ctrl), ctrl)) { + *out = _idx; +sbi_hart_unmap_saddr (); +return SBI_ERR_FAILED ; + } +sbi_hart_unmap_saddr (); + } + +if (hs->available_trigs < trig_count) { + *out = hs->available_trigs; +return SBI_ERR_FAILED ; + } + +/* Install triggers */ +for_each_trig_entry (shmem_base, trig_count,typeof (*entry), entry) { +/* +* Since we have already checked if enough triggers are +* available, trigger allocation must succeed. +*/ + trig =sbi_alloc_trigger (); + +sbi_hart_map_saddr ((unsigned long )entry,sizeof (*entry)); + + recv = (struct sbi_dbtr_data_msg *)(&entry->data); + xmit = (struct sbi_dbtr_id_msg *)(&entry->id); + +dbtr_trigger_setup (trig, recv); +dbtr_trigger_enable (trig); + xmit->idx =cpu_to_lle (trig->index); +sbi_hart_unmap_saddr (); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_uninstall_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +if (!(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return SBI_ERR_INVALID_PARAM ; + +dbtr_trigger_clear (trig); + +sbi_free_trigger (trig); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_enable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +sbi_dprintf ("%s: enable trigger %lu\n" , __func__, idx); +dbtr_trigger_enable (trig); + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_update_trig (const struct sbi_domain *dom, +unsigned long smode, +unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base;lib/sbi/sbi_dbtr.c line 695
Quoted 10 lines
lib/sbi/sbi_dbtr.c new file +10
-0+u32 hartid =current_hartid (); +struct sbi_dbtr_data_msg *recv; +unsigned long uidx =0 ; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_shmem_entry *entry; +void *shmem_base =NULL ; +struct sbi_dbtr_hart_triggers_state *hs =NULL ; + +if (smode !=PRV_S ) +return SBI_ERR_DENIED ;Same as above, drop the smode check and parameter.
Quoted 85 lines
lib/sbi/sbi_dbtr.c new file +47
-0+if (dom && !sbi_domain_is_assigned_hart (dom, hartid)) +return SBI_ERR_DENIED ; + +if (sbi_dbtr_shmem_disabled ()) +return SBI_ERR_NO_SHMEM ; + + shmem_base =hart_shmem_base (); + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); + +if (!(trig->state &RV_DBTR_BIT_MASK (TS ,MAPPED ))) +return SBI_ERR_INVALID_PARAM ; + + entry = (shmem_base + uidx *sizeof (*entry)); + recv = &entry->data; + + trig->tdata2 =lle_to_cpu (recv->tdata2); +dbtr_trigger_enable (trig); + uidx++; + } + +return SBI_SUCCESS ; +} + +int sbi_dbtr_disable_trig (unsigned long trig_idx_base, +unsigned long trig_idx_mask) +{ +unsigned long trig_mask = trig_idx_mask << trig_idx_base; +unsigned long idx = trig_idx_base; +struct sbi_dbtr_trigger *trig; +struct sbi_dbtr_hart_triggers_state *hs; + + hs =dbtr_thishart_state_ptr (); +if (!hs) +return SBI_ERR_FAILED ; + +for_each_set_bit_from (idx, &trig_mask, hs->total_trigs) { + trig =INDEX_TO_TRIGGER (idx); +dbtr_trigger_disable (trig); + } + +return SBI_SUCCESS ; +}lib/sbi/sbi_init.c +9
-1@@ -23,6 +23,7 @@#include <sbi/sbi_irqchip.h> #include <sbi/sbi_platform.h> #include <sbi/sbi_pmu.h> +#include <sbi/sbi_dbtr.h> #include <sbi/sbi_system.h> #include <sbi/sbi_string.h> #include <sbi/sbi_timer.h> @@ -322,6 +323,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)sbi_hart_hang (); } + rc =sbi_dbtr_init (scratch, true); +if (rc) +sbi_hart_hang (); +sbi_boot_print_banner (scratch); rc =sbi_irqchip_init (scratch, true);@@ -439,6 +444,10 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,if (rc)sbi_hart_hang (); + rc =sbi_dbtr_init (scratch, false); +if (rc) +sbi_hart_hang (); + rc =sbi_irqchip_init (scratch, false);if (rc)sbi_hart_hang (); --2.34.1
Quoted 4 lines
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbiRegards,
Anup
PATCH v2 5/7 include: sbi: Add SBI debug trigger extension related defines
In reply to Himanshu ChauhanThis patch adds defines for SBI debug trigger extension and function IDs to access the extension.
--- include/sbi/sbi_ecall_interface.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
include/sbi/sbi_ecall_interface.h +11 -0
@@ -32,6 +32,7 @@#define SBI_EXT_DBCN 0x4442434E#define SBI_EXT_SUSP 0x53555350#define SBI_EXT_CPPC 0x43505043 +#define SBI_EXT_DBTR 0x44425452/* SBI function IDs for BASE extension*/ #define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
@@ -105,6 +106,16 @@#define SBI_EXT_PMU_COUNTER_FW_READ_HI 0x6#define SBI_EXT_PMU_SNAPSHOT_SET_SHMEM 0x7 +/* SBI function IDs for DBTR extension */ +#define SBI_EXT_DBTR_NUM_TRIGGERS 0x0 +#define SBI_EXT_DBTR_SETUP_SHMEM 0x1 +#define SBI_EXT_DBTR_TRIGGER_READ 0x2 +#define SBI_EXT_DBTR_TRIGGER_INSTALL 0x3 +#define SBI_EXT_DBTR_TRIGGER_UPDATE 0x4 +#define SBI_EXT_DBTR_TRIGGER_UNINSTALL 0x5 +#define SBI_EXT_DBTR_TRIGGER_ENABLE 0x6 +#define SBI_EXT_DBTR_TRIGGER_DISABLE 0x7 +/** General pmu event codes specified in SBI PMU extension */ enum sbi_pmu_hw_generic_events_t {SBI_PMU_HW_NO_EVENT =0 ,
Signature · 1 line
2.34.1
PATCH v2 5/7 include: sbi: Add SBI debug trigger extension related defines
Quoted 5 lines · On Mon, Jan 8, 2024 at 12:25?PM Himanshu Chauhan <[email protected]>…
This patch adds defines for SBI debug trigger extension and function IDs to access the extension.
Signed-off-by Himanshu Chauhan <[email protected]>
Already reviewed previously.
Regards,
Anup
Quoted 41 lines
--- include/sbi/sbi_ecall_interface.h | 11 +++++++++++ 1 file changed, 11 insertions(+)include/sbi/sbi_ecall_interface.h +11
-1@@ -32,6 +32,7 @@#define SBI_EXT_DBCN 0x4442434E#define SBI_EXT_SUSP 0x53555350#define SBI_EXT_CPPC 0x43505043 +#define SBI_EXT_DBTR 0x44425452/* SBI function IDs for BASE extension*/ #define SBI_EXT_BASE_GET_SPEC_VERSION 0x0@@ -105,6 +106,16 @@#define SBI_EXT_PMU_COUNTER_FW_READ_HI 0x6#define SBI_EXT_PMU_SNAPSHOT_SET_SHMEM 0x7 +/* SBI function IDs for DBTR extension */ +#define SBI_EXT_DBTR_NUM_TRIGGERS 0x0 +#define SBI_EXT_DBTR_SETUP_SHMEM 0x1 +#define SBI_EXT_DBTR_TRIGGER_READ 0x2 +#define SBI_EXT_DBTR_TRIGGER_INSTALL 0x3 +#define SBI_EXT_DBTR_TRIGGER_UPDATE 0x4 +#define SBI_EXT_DBTR_TRIGGER_UNINSTALL 0x5 +#define SBI_EXT_DBTR_TRIGGER_ENABLE 0x6 +#define SBI_EXT_DBTR_TRIGGER_DISABLE 0x7 +/** General pmu event codes specified in SBI PMU extension */ enum sbi_pmu_hw_generic_events_t {SBI_PMU_HW_NO_EVENT =0 , --2.34.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
PATCH v2 6/7 lib: sbi: Implement SBI debug trigger extension
In reply to Himanshu ChauhanThis patch adds functions to register ecalls for debug triggers and handler to handle the debug trigger function IDs.
--- lib/sbi/Kconfig | 4 +++ lib/sbi/objects.mk | 3 ++ lib/sbi/sbi_ecall_dbtr.c | 73 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 lib/sbi/sbi_ecall_dbtr.c
lib/sbi/Kconfig +4 -0
@@ -46,4 +46,8 @@ config SBI_ECALL_VENDOR bool "Platform-defined vendor extensions" default y +config SBI_ECALL_DBTR + bool "Debug Trigger Extension" + default y + endmenu
lib/sbi/objects.mk +3 -0
@@ -52,6 +52,9 @@ libsbi-objs-$(CONFIG_SBI_ECALL_LEGACY) += sbi_ecall_legacy.o carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_VENDOR) += ecall_vendor libsbi-objs-$(CONFIG_SBI_ECALL_VENDOR) += sbi_ecall_vendor.o +carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_DBTR) += ecall_dbtr +libsbi-objs-$(CONFIG_SBI_ECALL_DBTR) += sbi_ecall_dbtr.o + libsbi-objs-y += sbi_bitmap.o libsbi-objs-y += sbi_bitops.o libsbi-objs-y += sbi_console.o
lib/sbi/sbi_ecall_dbtr.c new file +73 -0
73 lines not on this page · raw message
Signature · 1 line
2.34.1
PATCH v2 6/7 lib: sbi: Implement SBI debug trigger extension
Quoted 5 lines · On Mon, Jan 8, 2024 at 12:25?PM Himanshu Chauhan <[email protected]>…
This patch adds functions to register ecalls for debug triggers and handler to handle the debug trigger function IDs.
Signed-off-by Himanshu Chauhan <[email protected]>
Already reviewed previously.
Regards,
Anup
Quoted 121 lines
--- lib/sbi/Kconfig | 4 +++ lib/sbi/objects.mk | 3 ++ lib/sbi/sbi_ecall_dbtr.c | 73 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 lib/sbi/sbi_ecall_dbtr.clib/sbi/Kconfig +4
-0@@ -46,4 +46,8 @@ config SBI_ECALL_VENDOR bool "Platform-defined vendor extensions" default y +config SBI_ECALL_DBTR + bool "Debug Trigger Extension" + default y + endmenulib/sbi/objects.mk +3
-0@@ -52,6 +52,9 @@ libsbi-objs-$(CONFIG_SBI_ECALL_LEGACY) += sbi_ecall_legacy.o carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_VENDOR) += ecall_vendor libsbi-objs-$(CONFIG_SBI_ECALL_VENDOR) += sbi_ecall_vendor.o +carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_DBTR) += ecall_dbtr +libsbi-objs-$(CONFIG_SBI_ECALL_DBTR) += sbi_ecall_dbtr.o + libsbi-objs-y += sbi_bitmap.o libsbi-objs-y += sbi_bitops.o libsbi-objs-y += sbi_console.olib/sbi/sbi_ecall_dbtr.c new file +73
-1@@ -0,0 +1,73 @@ +/* +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright (c) 2023 Ventana Micro Systems Inc. +* +* Author(s): +* Himanshu Chauhan <[email protected]> +*/ + +#include <sbi/sbi_ecall.h> +#include <sbi/sbi_ecall_interface.h> +#include <sbi/sbi_error.h> +#include <sbi/sbi_trap.h> +#include <sbi/sbi_domain.h> +#include <sbi/sbi_dbtr.h> + +static int sbi_ecall_dbtr_handler (unsigned long extid,unsigned long funcid, +struct sbi_trap_regs *regs, +struct sbi_ecall_return *out) +{ +unsigned long smode = (csr_read (CSR_MSTATUS ) &MSTATUS_MPP ) >> +MSTATUS_MPP_SHIFT ; +const struct sbi_domain *dom =sbi_domain_thishart_ptr (); +int ret =0 ; + +switch (funcid) { +case SBI_EXT_DBTR_NUM_TRIGGERS : + ret =sbi_dbtr_num_trig (regs->a0, &out->value); +break ; +case SBI_EXT_DBTR_SETUP_SHMEM : + ret =sbi_dbtr_setup_shmem (dom, smode, regs->a0, regs->a1); +break ; +case SBI_EXT_DBTR_TRIGGER_READ : + ret =sbi_dbtr_read_trig (dom, smode, regs->a0, regs->a1); +break ; +case SBI_EXT_DBTR_TRIGGER_INSTALL : + ret =sbi_dbtr_install_trig (dom, smode, regs->a0, &out->value); +break ; +case SBI_EXT_DBTR_TRIGGER_UNINSTALL : + ret =sbi_dbtr_uninstall_trig (regs->a0, regs->a1); +break ; +case SBI_EXT_DBTR_TRIGGER_ENABLE : + ret =sbi_dbtr_enable_trig (regs->a0, regs->a1); +break ; +case SBI_EXT_DBTR_TRIGGER_UPDATE : + ret =sbi_dbtr_update_trig (dom, smode, regs->a0, regs->a1); +break ; +case SBI_EXT_DBTR_TRIGGER_DISABLE : + ret =sbi_dbtr_disable_trig (regs->a0, regs->a1); +break ; +default : + ret =SBI_ENOTSUPP ; + }; + +return ret; +} + +struct sbi_ecall_extension ecall_dbtr; + +static int sbi_ecall_dbtr_register_extensions (void ) +{ +if (!sbi_dbtr_supported ()) +return 0 ; + +return sbi_ecall_register_extension (&ecall_dbtr); +} + +struct sbi_ecall_extension ecall_dbtr = { + .extid_start =SBI_EXT_DBTR , + .extid_end =SBI_EXT_DBTR , + .handle = sbi_ecall_dbtr_handler, + .register_extensions = sbi_ecall_dbtr_register_extensions, +}; --2.34.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
PATCH v2 7/7 lib: sbi: Print number of debug triggers found
In reply to Himanshu ChauhanPrint the total number of triggers found on the boot hart.
--- lib/sbi/sbi_init.c | 2 ++ 1 file changed, 2 insertions(+)
lib/sbi/sbi_init.c +2 -0
@@ -184,6 +184,8 @@ static void sbi_boot_print_hart(struct sbi_scratch *scratch, u32 hartid)sbi_printf ("Boot HART MHPM Info : %lu (0x%08x)\n" ,sbi_popcount (sbi_hart_mhpm_mask (scratch)),sbi_hart_mhpm_mask (scratch)); +sbi_printf ("Boot HART Debug Triggers : %d trigger(s) found.\n" , +sbi_dbtr_get_total_triggers ());sbi_hart_delegation_dump (scratch,"Boot HART " ," " ); }
Signature · 1 line
2.34.1
PATCH v2 7/7 lib: sbi: Print number of debug triggers found
Quoted 4 lines · On Mon, Jan 8, 2024 at 12:25?PM Himanshu Chauhan <[email protected]>…
Print the total number of triggers found on the boot hart.
Signed-off-by Himanshu Chauhan <[email protected]>
Already reviewed previously.
Regards,
Anup
Quoted 25 lines
--- lib/sbi/sbi_init.c | 2 ++ 1 file changed, 2 insertions(+)lib/sbi/sbi_init.c +2
-1@@ -184,6 +184,8 @@ static void sbi_boot_print_hart(struct sbi_scratch *scratch, u32 hartid)sbi_printf ("Boot HART MHPM Info : %lu (0x%08x)\n" ,sbi_popcount (sbi_hart_mhpm_mask (scratch)),sbi_hart_mhpm_mask (scratch)); +sbi_printf ("Boot HART Debug Triggers : %d trigger(s) found.\n" , +sbi_dbtr_get_total_triggers ());sbi_hart_delegation_dump (scratch,"Boot HART " ," " ); } --2.34.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi