diff --git a/riscv/csr_init.cc b/riscv/csr_init.cc index c5ff273d..486763a3 100644 --- a/riscv/csr_init.cc +++ b/riscv/csr_init.cc @@ -148,9 +148,9 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) auto sip = std::make_shared(proc, nonvirtual_sip, vsip); if (xlen == 32 && proc->extension_enabled_const(EXT_SSAIA)) { add_hypervisor_csr(CSR_VSIP, std::make_shared(proc, CSR_VSIP, vsip)); - add_hypervisor_csr(CSR_VSIPH, std::make_shared(proc, CSR_VSIPH, vsip)); + add_hypervisor_csr(CSR_VSIPH, std::make_shared(proc, CSR_VSIPH, vsip)); add_supervisor_csr(CSR_SIP, std::make_shared(proc, CSR_SIP, sip)); - add_supervisor_csr(CSR_SIPH, std::make_shared(proc, CSR_SIPH, sip)); + add_supervisor_csr(CSR_SIPH, std::make_shared(proc, CSR_SIPH, sip)); } else { add_hypervisor_csr(CSR_VSIP, vsip); add_supervisor_csr(CSR_SIP, sip); @@ -159,7 +159,7 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) hvip = std::make_shared(proc, CSR_HVIP, 0); if (xlen == 32 && proc->extension_enabled_const(EXT_SSAIA)) { add_hypervisor_csr(CSR_HVIP, std::make_shared(proc, CSR_HVIP, hvip)); - add_hypervisor_csr(CSR_HVIPH, std::make_shared(proc, CSR_HVIPH, hvip)); + add_hypervisor_csr(CSR_HVIPH, std::make_shared(proc, CSR_HVIPH, hvip)); } else { add_hypervisor_csr(CSR_HVIP, hvip); } @@ -169,9 +169,9 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) auto sie = std::make_shared(proc, nonvirtual_sie, vsie); if (xlen == 32 && proc->extension_enabled_const(EXT_SSAIA)) { add_hypervisor_csr(CSR_VSIE, std::make_shared(proc, CSR_VSIE, vsie)); - add_hypervisor_csr(CSR_VSIEH, std::make_shared(proc, CSR_VSIEH, vsie)); + add_hypervisor_csr(CSR_VSIEH, std::make_shared(proc, CSR_VSIEH, vsie)); add_supervisor_csr(CSR_SIE, std::make_shared(proc, CSR_SIE, sie)); - add_supervisor_csr(CSR_SIEH, std::make_shared(proc, CSR_SIEH, sie)); + add_supervisor_csr(CSR_SIEH, std::make_shared(proc, CSR_SIEH, sie)); } else { add_hypervisor_csr(CSR_VSIE, vsie); add_supervisor_csr(CSR_SIE, sie); @@ -182,7 +182,7 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) mideleg = std::make_shared(proc, CSR_MIDELEG); if (xlen == 32 && proc->extension_enabled_const(EXT_SMAIA)) { add_supervisor_csr(CSR_MIDELEG, std::make_shared(proc, CSR_MIDELEG, mideleg)); - add_supervisor_csr(CSR_MIDELEGH, std::make_shared(proc, CSR_MIDELEGH, mideleg)); + add_supervisor_csr(CSR_MIDELEGH, std::make_shared(proc, CSR_MIDELEGH, mideleg)); } else { add_supervisor_csr(CSR_MIDELEG, mideleg); } diff --git a/riscv/csrs.cc b/riscv/csrs.cc index cd278b91..9b111be1 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -641,6 +641,22 @@ reg_t rv32_high_csr_t::written_value() const noexcept { return (orig->written_value() >> 32) & 0xffffffffU; } +aia_rv32_high_csr_t::aia_rv32_high_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig): + rv32_high_csr_t(proc, addr, orig) { +} + +void aia_rv32_high_csr_t::verify_permissions(insn_t insn, bool write) const { + if (proc->extension_enabled(EXT_SMSTATEEN)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_AIA)) + throw trap_illegal_instruction(insn.bits()); + + if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_AIA)) + throw trap_virtual_instruction(insn.bits()); + } + + aia_rv32_high_csr_t::verify_permissions(insn, write); +} + // implement class sstatus_csr_t sstatus_csr_t::sstatus_csr_t(processor_t* const proc, sstatus_proxy_csr_t_p orig, vsstatus_csr_t_p virt): virtualized_csr_t(proc, orig, virt), diff --git a/riscv/csrs.h b/riscv/csrs.h index 1730b860..ae8bc18e 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -301,6 +301,12 @@ class rv32_high_csr_t: public csr_t { csr_t_p orig; }; +class aia_rv32_high_csr_t: public rv32_high_csr_t { + public: + aia_rv32_high_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; + // sstatus.sdt is read_only 0 when menvcfg.dte = 0 class sstatus_proxy_csr_t final: public base_status_csr_t { public: