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; }