[PATCH] dbtr: Add support for icount trigger type
Anup Patel
anup at brainfault.org
Wed Aug 27 22:10:46 PDT 2025
On Fri, Jul 25, 2025 at 12:01 AM Jesse Taube <jesse at rivosinc.com> wrote:
>
> The linux kernel needs icount to implement hardware breakpoints.
>
> Signed-off-by: Jesse Taube <jesse at rivosinc.com>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
Applied this patch to the riscv/opensbi repo.
Thanks,
Anup
> ---
> include/sbi/riscv_dbtr.h | 44 ++++++++++++++++++++++++++++++++++++++++
> lib/sbi/sbi_dbtr.c | 35 ++++++++++++++++++++++++++++++++
> 2 files changed, 79 insertions(+)
>
> diff --git a/include/sbi/riscv_dbtr.h b/include/sbi/riscv_dbtr.h
> index 96c7d3e3..e249eaed 100644
> --- a/include/sbi/riscv_dbtr.h
> +++ b/include/sbi/riscv_dbtr.h
> @@ -122,6 +122,50 @@ enum {
> RV_DBTR_DECLARE_BIT_MASK(MC, TYPE, 4),
> };
>
> +
> +/* ICOUNT - Match Control Type Register */
> +enum {
> + RV_DBTR_DECLARE_BIT(ICOUNT, ACTION, 0),
> + RV_DBTR_DECLARE_BIT(ICOUNT, U, 6),
> + RV_DBTR_DECLARE_BIT(ICOUNT, S, 7),
> + RV_DBTR_DECLARE_BIT(ICOUNT, PENDING, 8),
> + RV_DBTR_DECLARE_BIT(ICOUNT, M, 9),
> + RV_DBTR_DECLARE_BIT(ICOUNT, COUNT, 10),
> + RV_DBTR_DECLARE_BIT(ICOUNT, HIT, 24),
> + RV_DBTR_DECLARE_BIT(ICOUNT, VU, 25),
> + RV_DBTR_DECLARE_BIT(ICOUNT, VS, 26),
> +#if __riscv_xlen == 64
> + RV_DBTR_DECLARE_BIT(ICOUNT, DMODE, 59),
> + RV_DBTR_DECLARE_BIT(ICOUNT, TYPE, 60),
> +#elif __riscv_xlen == 32
> + RV_DBTR_DECLARE_BIT(ICOUNT, DMODE, 27),
> + RV_DBTR_DECLARE_BIT(ICOUNT, TYPE, 28),
> +#else
> + #error "Unknown __riscv_xlen"
> +#endif
> +};
> +
> +enum {
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, ACTION, 6),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, U, 1),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, S, 1),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, PENDING, 1),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, M, 1),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, COUNT, 14),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, HIT, 1),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, VU, 1),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, VS, 1),
> +#if __riscv_xlen == 64
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, DMODE, 1),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, TYPE, 4),
> +#elif __riscv_xlen == 32
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, DMODE, 1),
> + RV_DBTR_DECLARE_BIT_MASK(ICOUNT, TYPE, 4),
> +#else
> + #error "Unknown __riscv_xlen"
> +#endif
> +};
> +
> /* MC6 - Match Control 6 Type Register */
> enum {
> RV_DBTR_DECLARE_BIT(MC6, LOAD, 0),
> diff --git a/lib/sbi/sbi_dbtr.c b/lib/sbi/sbi_dbtr.c
> index a832c7f1..c30c2fd6 100644
> --- a/lib/sbi/sbi_dbtr.c
> +++ b/lib/sbi/sbi_dbtr.c
> @@ -336,6 +336,19 @@ static void dbtr_trigger_setup(struct sbi_dbtr_trigger *trig,
> if (__test_bit(RV_DBTR_BIT(MC6, VS), &tdata1))
> __set_bit(RV_DBTR_BIT(TS, VS), &trig->state);
> break;
> + case RISCV_DBTR_TRIG_ICOUNT:
> + if (__test_bit(RV_DBTR_BIT(ICOUNT, U), &tdata1))
> + __set_bit(RV_DBTR_BIT(TS, U), &trig->state);
> +
> + if (__test_bit(RV_DBTR_BIT(ICOUNT, S), &tdata1))
> + __set_bit(RV_DBTR_BIT(TS, S), &trig->state);
> +
> + if (__test_bit(RV_DBTR_BIT(ICOUNT, VU), &tdata1))
> + __set_bit(RV_DBTR_BIT(TS, VU), &trig->state);
> +
> + if (__test_bit(RV_DBTR_BIT(ICOUNT, 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));
> @@ -379,6 +392,16 @@ static void dbtr_trigger_enable(struct sbi_dbtr_trigger *trig)
> update_bit(state & RV_DBTR_BIT_MASK(TS, S),
> RV_DBTR_BIT(MC6, S), &trig->tdata1);
> break;
> + case RISCV_DBTR_TRIG_ICOUNT:
> + update_bit(state & RV_DBTR_BIT_MASK(TS, VU),
> + RV_DBTR_BIT(ICOUNT, VU), &trig->tdata1);
> + update_bit(state & RV_DBTR_BIT_MASK(TS, VS),
> + RV_DBTR_BIT(ICOUNT, VS), &trig->tdata1);
> + update_bit(state & RV_DBTR_BIT_MASK(TS, U),
> + RV_DBTR_BIT(ICOUNT, U), &trig->tdata1);
> + update_bit(state & RV_DBTR_BIT_MASK(TS, S),
> + RV_DBTR_BIT(ICOUNT, S), &trig->tdata1);
> + break;
> default:
> break;
> }
> @@ -418,6 +441,12 @@ static void dbtr_trigger_disable(struct sbi_dbtr_trigger *trig)
> __clear_bit(RV_DBTR_BIT(MC6, U), &trig->tdata1);
> __clear_bit(RV_DBTR_BIT(MC6, S), &trig->tdata1);
> break;
> + case RISCV_DBTR_TRIG_ICOUNT:
> + __clear_bit(RV_DBTR_BIT(ICOUNT, VU), &trig->tdata1);
> + __clear_bit(RV_DBTR_BIT(ICOUNT, VS), &trig->tdata1);
> + __clear_bit(RV_DBTR_BIT(ICOUNT, U), &trig->tdata1);
> + __clear_bit(RV_DBTR_BIT(ICOUNT, S), &trig->tdata1);
> + break;
> default:
> break;
> }
> @@ -441,6 +470,7 @@ static int dbtr_trigger_supported(unsigned long type)
> switch (type) {
> case RISCV_DBTR_TRIG_MCONTROL:
> case RISCV_DBTR_TRIG_MCONTROL6:
> + case RISCV_DBTR_TRIG_ICOUNT:
> return 1;
> default:
> break;
> @@ -462,6 +492,11 @@ static int dbtr_trigger_valid(unsigned long type, unsigned long tdata)
> !(tdata & RV_DBTR_BIT_MASK(MC6, M)))
> return 1;
> break;
> + case RISCV_DBTR_TRIG_ICOUNT:
> + if (!(tdata & RV_DBTR_BIT_MASK(ICOUNT, DMODE)) &&
> + !(tdata & RV_DBTR_BIT_MASK(ICOUNT, M)))
> + return 1;
> + break;
> default:
> break;
> }
> --
> 2.43.0
>
More information about the opensbi
mailing list