[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