diff options
author | Andrew Waterman <andrew@sifive.com> | 2022-09-20 14:35:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-20 14:35:28 -0700 |
commit | 326fa00f587c43f76d94acbeaed83ffba2e07d3b (patch) | |
tree | 1328145c71687481ab58a9a935cceb956c87d7b9 | |
parent | ccc9791807b59d848e7c8983cea49a16fb4a2912 (diff) | |
parent | 32e199cce48a7b837e026bf072b8fd1a8f9c62f6 (diff) | |
download | spike-326fa00f587c43f76d94acbeaed83ffba2e07d3b.zip spike-326fa00f587c43f76d94acbeaed83ffba2e07d3b.tar.gz spike-326fa00f587c43f76d94acbeaed83ffba2e07d3b.tar.bz2 |
Merge pull request #1036 from plctlab/plct-sscofpmf-dev
add support for sscofpmf extension v0.5.2
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | riscv/csrs.cc | 42 | ||||
-rw-r--r-- | riscv/csrs.h | 9 | ||||
-rw-r--r-- | riscv/isa_parser.cc | 2 | ||||
-rw-r--r-- | riscv/isa_parser.h | 1 | ||||
-rw-r--r-- | riscv/processor.cc | 19 | ||||
-rw-r--r-- | riscv/processor.h | 1 |
7 files changed, 68 insertions, 7 deletions
@@ -41,6 +41,7 @@ Spike supports the following RISC-V ISA features: - Debug v0.14 - Smepmp extension v1.0 - Smstateen extension, v1.0 + - Sscofpmf v0.5.2 As a Spike extension, the remainder of the proposed [Bit-Manipulation Extensions](https://github.com/riscv/riscv-bitmanip) diff --git a/riscv/csrs.cc b/riscv/csrs.cc index e516e4a..858f12d 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -691,6 +691,7 @@ void mip_csr_t::backdoor_write_with_mask(const reg_t mask, const reg_t val) noex reg_t mip_csr_t::write_mask() const noexcept { // MIP_STIP is writable unless SSTC exists and STCE is set in MENVCFG const reg_t supervisor_ints = proc->extension_enabled('S') ? MIP_SSIP | ((state->menvcfg->read() & MENVCFG_STCE) ? 0 : MIP_STIP) | MIP_SEIP : 0; + const reg_t lscof_int = proc->extension_enabled(EXT_SSCOFPMF) ? MIP_LCOFIP : 0; const reg_t vssip_int = proc->extension_enabled('H') ? MIP_VSSIP : 0; const reg_t hypervisor_ints = proc->extension_enabled('H') ? MIP_HS_MASK : 0; // We must mask off sgeip, vstip, and vseip. All three of these @@ -698,8 +699,8 @@ reg_t mip_csr_t::write_mask() const noexcept { // * sgeip is read-only -- write hgeip instead // * vseip is read-only -- write hvip instead // * vstip is read-only -- write hvip instead - return (supervisor_ints | hypervisor_ints) & - (MIP_SEIP | MIP_SSIP | MIP_STIP | vssip_int); + return (supervisor_ints | hypervisor_ints | lscof_int) & + (MIP_SEIP | MIP_SSIP | MIP_STIP | MIP_LCOFIP | vssip_int); } mie_csr_t::mie_csr_t(processor_t* const proc, const reg_t addr): @@ -708,9 +709,10 @@ mie_csr_t::mie_csr_t(processor_t* const proc, const reg_t addr): reg_t mie_csr_t::write_mask() const noexcept { const reg_t supervisor_ints = proc->extension_enabled('S') ? MIP_SSIP | MIP_STIP | MIP_SEIP : 0; + const reg_t lscof_int = proc->extension_enabled(EXT_SSCOFPMF) ? MIP_LCOFIP : 0; const reg_t hypervisor_ints = proc->extension_enabled('H') ? MIP_HS_MASK : 0; const reg_t coprocessor_ints = (reg_t)proc->any_custom_extensions() << IRQ_COP; - const reg_t delegable_ints = supervisor_ints | coprocessor_ints; + const reg_t delegable_ints = supervisor_ints | coprocessor_ints | lscof_int; const reg_t all_ints = delegable_ints | hypervisor_ints | MIP_MSIP | MIP_MTIP | MIP_MEIP; return all_ints; } @@ -806,8 +808,9 @@ void mideleg_csr_t::verify_permissions(insn_t insn, bool write) const { bool mideleg_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t supervisor_ints = proc->extension_enabled('S') ? MIP_SSIP | MIP_STIP | MIP_SEIP : 0; + const reg_t lscof_int = proc->extension_enabled(EXT_SSCOFPMF) ? MIP_LCOFIP : 0; const reg_t coprocessor_ints = (reg_t)proc->any_custom_extensions() << IRQ_COP; - const reg_t delegable_ints = supervisor_ints | coprocessor_ints; + const reg_t delegable_ints = supervisor_ints | coprocessor_ints | lscof_int; return basic_csr_t::unlogged_write(val & delegable_ints); } @@ -1436,3 +1439,34 @@ void virtualized_stimecmp_csr_t::verify_permissions(insn_t insn, bool write) con virtualized_csr_t::verify_permissions(insn, write); } + +scountovf_csr_t::scountovf_csr_t(processor_t* const proc, const reg_t addr): + csr_t(proc, addr) { +} + +void scountovf_csr_t::verify_permissions(insn_t insn, bool write) const { + if (!proc->extension_enabled(EXT_SSCOFPMF)) + throw trap_illegal_instruction(insn.bits()); + csr_t::verify_permissions(insn, write); +} + +reg_t scountovf_csr_t::read() const noexcept { + reg_t val = 0; + for (reg_t i = 3; i <= 31; ++i) { + bool of = state->mevent[i - 3]->read() & MHPMEVENT_OF; + val |= of << i; + } + + /* In M and S modes, scountovf bit X is readable when mcounteren bit X is set, */ + /* and otherwise reads as zero. Similarly, in VS mode, scountovf bit X is readable */ + /* when mcounteren bit X and hcounteren bit X are both set, and otherwise reads as zero. */ + val &= state->mcounteren->read(); + if (state->v) + val &= state->hcounteren->read(); + return val; +} + +bool scountovf_csr_t::unlogged_write(const reg_t val) noexcept { + /* this function is unused */ + return false; +} diff --git a/riscv/csrs.h b/riscv/csrs.h index cabd61e..5dc6da3 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -739,4 +739,13 @@ class virtualized_stimecmp_csr_t: public virtualized_csr_t { virtualized_stimecmp_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt); virtual void verify_permissions(insn_t insn, bool write) const override; }; + +class scountovf_csr_t: public csr_t { + public: + scountovf_csr_t(processor_t* const proc, const reg_t addr); + virtual void verify_permissions(insn_t insn, bool write) const override; + virtual reg_t read() const noexcept override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; #endif diff --git a/riscv/isa_parser.cc b/riscv/isa_parser.cc index 0869bf3..f0cf274 100644 --- a/riscv/isa_parser.cc +++ b/riscv/isa_parser.cc @@ -182,6 +182,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) extension_table[EXT_SMEPMP] = true; } else if (ext_str == "smstateen") { extension_table[EXT_SMSTATEEN] = true; + } else if (ext_str == "sscofpmf") { + extension_table[EXT_SSCOFPMF] = true; } else if (ext_str == "svnapot") { extension_table[EXT_SVNAPOT] = true; } else if (ext_str == "svpbmt") { diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h index 2aed262..f7a8bc8 100644 --- a/riscv/isa_parser.h +++ b/riscv/isa_parser.h @@ -33,6 +33,7 @@ typedef enum { EXT_ZPSFOPERAND, EXT_SMEPMP, EXT_SMSTATEEN, + EXT_SSCOFPMF, EXT_SVNAPOT, EXT_SVPBMT, EXT_SVINVAL, diff --git a/riscv/processor.cc b/riscv/processor.cc index 3d56abc..5ae6bbb 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -228,13 +228,15 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) } for (reg_t i = 3; i <= 31; ++i) { const reg_t which_mevent = CSR_MHPMEVENT3 + i - 3; + const reg_t which_meventh = CSR_MHPMEVENT3H + i - 3; const reg_t which_mcounter = CSR_MHPMCOUNTER3 + i - 3; const reg_t which_mcounterh = CSR_MHPMCOUNTER3H + i - 3; const reg_t which_counter = CSR_HPMCOUNTER3 + i - 3; const reg_t which_counterh = CSR_HPMCOUNTER3H + i - 3; - auto mevent = std::make_shared<const_csr_t>(proc, which_mevent, 0); + const reg_t mevent_mask = proc->extension_enabled_const(EXT_SSCOFPMF) ? MHPMEVENT_VUINH | MHPMEVENT_VSINH | MHPMEVENTH_UINH | + MHPMEVENT_UINH | MHPMEVENT_MINH | MHPMEVENT_OF : 0; + mevent[i - 3] = std::make_shared<masked_csr_t>(proc, which_mevent, mevent_mask, 0); auto mcounter = std::make_shared<const_csr_t>(proc, which_mcounter, 0); - csrmap[which_mevent] = mevent; csrmap[which_mcounter] = mcounter; if (proc->extension_enabled_const(EXT_ZICNTR) && proc->extension_enabled_const(EXT_ZIHPM)) { @@ -242,21 +244,30 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[which_counter] = counter; } if (xlen == 32) { + csrmap[which_mevent] = std::make_shared<rv32_low_csr_t>(proc, which_mevent, mevent[i - 3]);; auto mcounterh = std::make_shared<const_csr_t>(proc, which_mcounterh, 0); csrmap[which_mcounterh] = mcounterh; if (proc->extension_enabled_const(EXT_ZICNTR) && proc->extension_enabled_const(EXT_ZIHPM)) { auto counterh = std::make_shared<counter_proxy_csr_t>(proc, which_counterh, mcounterh); csrmap[which_counterh] = counterh; } + if (proc->extension_enabled_const(EXT_SSCOFPMF)) { + auto meventh = std::make_shared<rv32_high_csr_t>(proc, which_meventh, mevent[i - 3]); + csrmap[which_meventh] = meventh; + } + } else { + csrmap[which_mevent] = mevent[i - 3]; } } csrmap[CSR_MCOUNTINHIBIT] = std::make_shared<const_csr_t>(proc, CSR_MCOUNTINHIBIT, 0); + if (proc->extension_enabled_const(EXT_SSCOFPMF)) + csrmap[CSR_SCOUNTOVF] = std::make_shared<scountovf_csr_t>(proc, CSR_SCOUNTOVF); csrmap[CSR_MIE] = mie = std::make_shared<mie_csr_t>(proc, CSR_MIE); csrmap[CSR_MIP] = mip = std::make_shared<mip_csr_t>(proc, CSR_MIP); auto sip_sie_accr = std::make_shared<generic_int_accessor_t>( this, ~MIP_HS_MASK, // read_mask - MIP_SSIP, // ip_write_mask + MIP_SSIP | MIP_LCOFIP, // ip_write_mask ~MIP_HS_MASK, // ie_write_mask generic_int_accessor_t::mask_mode_t::MIDELEG, 0 // shiftamt @@ -706,6 +717,8 @@ void processor_t::take_interrupt(reg_t pending_interrupts) enabled_interrupts = MIP_SSIP; else if (enabled_interrupts & MIP_STIP) enabled_interrupts = MIP_STIP; + else if (enabled_interrupts & MIP_LCOFIP) + enabled_interrupts = MIP_LCOFIP; else if (enabled_interrupts & MIP_VSEIP) enabled_interrupts = MIP_VSEIP; else if (enabled_interrupts & MIP_VSSIP) diff --git a/riscv/processor.h b/riscv/processor.h index 3937211..7fc4be7 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -145,6 +145,7 @@ struct state_t csr_t_p medeleg; csr_t_p mideleg; csr_t_p mcounteren; + csr_t_p mevent[29]; csr_t_p scounteren; csr_t_p sepc; csr_t_p stval; |