From 414a9c11e48068304cda81380f1322fd4611c5f6 Mon Sep 17 00:00:00 2001 From: YenHaoChen Date: Wed, 16 Nov 2022 15:45:01 +0800 Subject: [PATCH] triggers: add disabled_trigger_t --- README.md | 2 +- riscv/triggers.cc | 34 ++++++++++++++++++++++++++++++++-- riscv/triggers.h | 15 +++++++++++++-- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index eb817ae8..2dec4a54 100644 --- a/README.md +++ b/README.md @@ -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 fixed to type=2 (mcontrol) + - 4 triggers support type=2 (mcontrol) 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 eb35d024..b86b1547 100644 --- a/riscv/triggers.cc +++ b/riscv/triggers.cc @@ -13,6 +13,22 @@ void trigger_with_tdata2_t::tdata2_write(processor_t UNUSED * const proc, const tdata2 = val; } +reg_t disabled_trigger_t::tdata1_read(const processor_t * const proc) const noexcept +{ + auto xlen = proc->get_xlen(); + reg_t tdata1 = 0; + tdata1 = set_field(tdata1, CSR_TDATA1_TYPE(xlen), CSR_TDATA1_TYPE_DISABLED); + tdata1 = set_field(tdata1, CSR_TDATA1_DMODE(xlen), dmode); + return tdata1; +} + +void disabled_trigger_t::tdata1_write(processor_t * const proc, const reg_t val) noexcept +{ + // Any supported tdata.type results in disabled trigger + auto xlen = proc->get_xlen(); + dmode = proc->get_state()->debug_mode ? get_field(val, CSR_TDATA1_DMODE(xlen)) : 0; +} + reg_t mcontrol_t::tdata1_read(const processor_t * const proc) const noexcept { reg_t v = 0; auto xlen = proc->get_xlen(); @@ -182,7 +198,21 @@ bool module_t::tdata1_write(processor_t * const proc, unsigned index, const reg_ if (triggers[index]->get_dmode() && !proc->get_state()->debug_mode) { return false; } - triggers[index]->tdata1_write(proc, val); + + auto xlen = proc->get_xlen(); + + unsigned type = get_field(val, CSR_TDATA1_TYPE(xlen)); + reg_t tdata1 = val; + reg_t tdata2 = triggers[index]->tdata2_read(proc); + + delete triggers[index]; + switch (type) { + case CSR_TDATA1_TYPE_MCONTROL: triggers[index] = new mcontrol_t(); break; + default: triggers[index] = new disabled_trigger_t(); break; + } + + triggers[index]->tdata1_write(proc, tdata1); + triggers[index]->tdata2_write(proc, tdata2); proc->trigger_updated(triggers); return true; } @@ -205,7 +235,7 @@ bool module_t::tdata2_write(processor_t * const proc, unsigned index, const reg_ reg_t module_t::tinfo_read(UNUSED const processor_t * const proc, unsigned UNUSED index) const noexcept { /* In spike, every trigger supports the same types. */ - return 1< data) = 0; + virtual match_result_t memory_access_match(processor_t UNUSED * const proc, + operation_t UNUSED operation, reg_t UNUSED address, std::optional UNUSED data) { return match_result_t(false); } }; class trigger_with_tdata2_t : public trigger_t { @@ -79,6 +79,17 @@ protected: reg_t tdata2; }; +class disabled_trigger_t : public trigger_with_tdata2_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) noexcept override; + + virtual bool get_dmode() const override { return dmode; } + +private: + bool dmode; +}; + class mcontrol_t : public trigger_with_tdata2_t { public: typedef enum