diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc index 69c3e34bc2..757007353f 100644 --- a/disasm/isa_parser.cc +++ b/disasm/isa_parser.cc @@ -344,6 +344,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) extension_table[EXT_SMNPM] = true; } else if (ext_str == "ssnpm") { extension_table[EXT_SSNPM] = true; + } else if (ext_str == "shlcofideleg") { + extension_table[EXT_SHLCOFIDELEG] = true; } else if (ext_str.substr(0, 3) == "zvl") { reg_t new_vlen; try { diff --git a/riscv/csr_init.cc b/riscv/csr_init.cc index a03d188d4c..a70830c478 100644 --- a/riscv/csr_init.cc +++ b/riscv/csr_init.cc @@ -109,11 +109,11 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) auto vsip_vsie_accr = std::make_shared( this, - MIP_VS_MASK, // read_mask - MIP_VSSIP, // ip_write_mask - MIP_VS_MASK, // ie_write_mask + MIP_VS_MASK | MIP_LCOFIP, // read_mask + MIP_VSSIP, // ip_write_mask + MIP_VS_MASK | MIP_LCOFIP, // ie_write_mask generic_int_accessor_t::mask_mode_t::HIDELEG, - 1 // shiftamt + 1 // shiftamt ); auto nonvirtual_sip = std::make_shared(proc, CSR_SIP, sip_sie_accr); diff --git a/riscv/csrs.cc b/riscv/csrs.cc index ea535f6fe3..a8f89ce888 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -834,21 +834,23 @@ generic_int_accessor_t::generic_int_accessor_t(state_t* const state, } reg_t generic_int_accessor_t::ip_read() const noexcept { - return (state->mip->read() & deleg_mask() & read_mask) >> shiftamt; + const reg_t val = state->mip->read() & deleg_mask() & read_mask; + return ((val & 0xfff) >> shiftamt) | (val & ~0xfff); } void generic_int_accessor_t::ip_write(const reg_t val) noexcept { const reg_t mask = deleg_mask() & ip_write_mask; - state->mip->write_with_mask(mask, val << shiftamt); + state->mip->write_with_mask(mask, ((val & 0xfff) << shiftamt) | (val & ~0xfff)); } reg_t generic_int_accessor_t::ie_read() const noexcept { - return (state->mie->read() & deleg_mask() & read_mask) >> shiftamt; + const reg_t val = state->mie->read() & deleg_mask() & read_mask; + return ((val & 0xfff) >> shiftamt) | (val & ~0xfff); } void generic_int_accessor_t::ie_write(const reg_t val) noexcept { const reg_t mask = deleg_mask() & ie_write_mask; - state->mie->write_with_mask(mask, val << shiftamt); + state->mie->write_with_mask(mask, ((val & 0xfff) << shiftamt) | (val & ~0xfff)); } reg_t generic_int_accessor_t::deleg_mask() const { @@ -1223,7 +1225,8 @@ void hypervisor_csr_t::verify_permissions(insn_t insn, bool write) const { } hideleg_csr_t::hideleg_csr_t(processor_t* const proc, const reg_t addr, csr_t_p mideleg): - masked_csr_t(proc, addr, MIP_VS_MASK, 0), + masked_csr_t(proc, addr, MIP_VS_MASK | + (proc->extension_enabled(EXT_SHLCOFIDELEG) ? MIP_LCOFIP : 0), 0), mideleg(mideleg) { } diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h index 90e1ec1650..fa9fb4e84e 100644 --- a/riscv/isa_parser.h +++ b/riscv/isa_parser.h @@ -86,6 +86,7 @@ typedef enum { EXT_SMMPM, EXT_SMNPM, EXT_SSNPM, + EXT_SHLCOFIDELEG, NUM_ISA_EXTENSIONS } isa_extension_t;