diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | riscv/triggers.cc | 46 | ||||
-rw-r--r-- | riscv/triggers.h | 6 |
3 files changed, 53 insertions, 1 deletions
@@ -38,7 +38,7 @@ Spike supports the following RISC-V ISA features: - Svpbmt extension, v1.0 - Svinval extension, v1.0 - Debug v0.14 - - 4 triggers support type=2 (mcontrol), type=4 (itrigger), type=5 (etrigger), and type=15 (disabled) + - 4 triggers support type=2 (mcontrol), type=4 (itrigger), type=5 (etrigger), type=6 (mcontrol6), and type=15 (disabled) - Smepmp extension v1.0 - Smstateen extension, v1.0 - Sscofpmf v0.5.2 diff --git a/riscv/triggers.cc b/riscv/triggers.cc index 69f9cd0..0ff36e8 100644 --- a/riscv/triggers.cc +++ b/riscv/triggers.cc @@ -234,6 +234,50 @@ mcontrol_common_t::match_t mcontrol_common_t::legalize_match(reg_t val) const no } } +reg_t mcontrol6_t::tdata1_read(const processor_t * const proc) const noexcept { + unsigned xlen = proc->get_const_xlen(); + reg_t tdata1 = 0; + tdata1 = set_field(tdata1, CSR_MCONTROL6_TYPE(xlen), 6); + tdata1 = set_field(tdata1, CSR_MCONTROL6_DMODE(xlen), dmode); + tdata1 = set_field(tdata1, CSR_MCONTROL6_VS, proc->extension_enabled('H') ? vs : 0); + tdata1 = set_field(tdata1, CSR_MCONTROL6_VU, proc->extension_enabled('H') ? vu : 0); + tdata1 = set_field(tdata1, CSR_MCONTROL6_HIT, hit); + tdata1 = set_field(tdata1, CSR_MCONTROL6_SELECT, select); + tdata1 = set_field(tdata1, CSR_MCONTROL6_TIMING, timing); + tdata1 = set_field(tdata1, CSR_MCONTROL6_ACTION, action); + tdata1 = set_field(tdata1, CSR_MCONTROL6_CHAIN, chain); + tdata1 = set_field(tdata1, CSR_MCONTROL6_MATCH, match); + tdata1 = set_field(tdata1, CSR_MCONTROL6_M, m); + tdata1 = set_field(tdata1, CSR_MCONTROL6_S, s); + tdata1 = set_field(tdata1, CSR_MCONTROL6_U, u); + tdata1 = set_field(tdata1, CSR_MCONTROL6_EXECUTE, execute); + tdata1 = set_field(tdata1, CSR_MCONTROL6_STORE, store); + tdata1 = set_field(tdata1, CSR_MCONTROL6_LOAD, load); + return tdata1; +} + +void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept { + auto xlen = proc->get_const_xlen(); + assert(get_field(val, CSR_MCONTROL6_TYPE(xlen)) == CSR_TDATA1_TYPE_MCONTROL6); + dmode = get_field(val, CSR_MCONTROL6_DMODE(xlen)); + vs = get_field(val, CSR_MCONTROL6_VS); + vu = get_field(val, CSR_MCONTROL6_VU); + hit = get_field(val, CSR_MCONTROL6_HIT); + select = get_field(val, CSR_MCONTROL6_SELECT); + timing = get_field(val, CSR_MCONTROL6_TIMING); + action = legalize_action(get_field(val, CSR_MCONTROL6_ACTION)); + chain = allow_chain ? get_field(val, CSR_MCONTROL6_CHAIN) : 0; + match = legalize_match(get_field(val, CSR_MCONTROL6_MATCH)); + m = get_field(val, CSR_MCONTROL6_M); + s = proc->extension_enabled_const('S') ? get_field(val, CSR_MCONTROL6_S) : 0; + u = proc->extension_enabled_const('U') ? get_field(val, CSR_MCONTROL6_U) : 0; + execute = get_field(val, CSR_MCONTROL6_EXECUTE); + store = get_field(val, CSR_MCONTROL6_STORE); + load = get_field(val, CSR_MCONTROL6_LOAD); + if (execute) + timing = 0; +} + reg_t itrigger_t::tdata1_read(const processor_t * const proc) const noexcept { auto xlen = proc->get_xlen(); @@ -378,6 +422,7 @@ bool module_t::tdata1_write(unsigned index, const reg_t val) noexcept case CSR_TDATA1_TYPE_MCONTROL: triggers[index] = new mcontrol_t(); break; case CSR_TDATA1_TYPE_ITRIGGER: triggers[index] = new itrigger_t(); break; case CSR_TDATA1_TYPE_ETRIGGER: triggers[index] = new etrigger_t(); break; + case CSR_TDATA1_TYPE_MCONTROL6: triggers[index] = new mcontrol6_t(); break; default: triggers[index] = new disabled_trigger_t(); break; } @@ -467,6 +512,7 @@ reg_t module_t::tinfo_read(unsigned UNUSED index) const noexcept return (1 << CSR_TDATA1_TYPE_MCONTROL) | (1 << CSR_TDATA1_TYPE_ITRIGGER) | (1 << CSR_TDATA1_TYPE_ETRIGGER) | + (1 << CSR_TDATA1_TYPE_MCONTROL6) | (1 << CSR_TDATA1_TYPE_DISABLED); } diff --git a/riscv/triggers.h b/riscv/triggers.h index cefca51..62d6db8 100644 --- a/riscv/triggers.h +++ b/riscv/triggers.h @@ -223,6 +223,12 @@ public: virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override; }; +class mcontrol6_t : public mcontrol_common_t { +public: + virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override; + virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override; +}; + class module_t { public: module_t(unsigned count); |