mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-30 01:51:23 +01:00
dbtr: Add support for icount trigger type
The linux kernel needs icount to implement hardware breakpoints. Signed-off-by: Jesse Taube <jesse@rivosinc.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20250724183120.1822667-1-jesse@rivosinc.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
@@ -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),
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user