diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index e5dc148..4a7046a 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -781,13 +781,14 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t &val) { - val = csr[mie]; +template iss::status riscv_hart_m_p::read_hartid(unsigned addr, reg_t &val) { + val = mhartid_reg; return iss::Ok; } -template iss::status riscv_hart_m_p::read_hartid(unsigned addr, reg_t &val) { - val = mhartid_reg; +template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t &val) { + auto mask = get_irq_mask(); + val = csr[mie] & mask; return iss::Ok; } @@ -799,13 +800,14 @@ template iss::status riscv_hart_m_p } template iss::status riscv_hart_m_p::read_ip(unsigned addr, reg_t &val) { - val = csr[mip]; + auto mask = get_irq_mask(); + val = csr[mip] & mask; return iss::Ok; } template iss::status riscv_hart_m_p::write_ip(unsigned addr, reg_t val) { auto mask = get_irq_mask(); - mask &= ~(1 << 7); // MTIP is read only + mask &= 0xf; // only xSIP is writable csr[mip] = (csr[mip] & ~mask) | (val & mask); check_interrupt(); return iss::Ok; diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index f9e6ab2..b1ed4f1 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -181,7 +181,7 @@ public: }; using hart_state_type = hart_state; - constexpr reg_t get_irq_wrmask(size_t mode) { + constexpr reg_t get_irq_mask(size_t mode) { std::array m = {{ 0b000100010001, // U mode 0b001100110011, // S mode @@ -925,7 +925,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_ie(unsigned addr, reg_t &val) { - auto mask = get_irq_wrmask((addr >> 8) & 0x3); + auto mask = get_irq_mask((addr >> 8) & 0x3); val = csr[mie] & mask; if(this->reg.PRIV!=3) val &= csr[mideleg]; @@ -933,14 +933,14 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_ie(unsigned addr, reg_t val) { - auto mask = get_irq_wrmask((addr >> 8) & 0x3); + auto mask = get_irq_mask((addr >> 8) & 0x3); csr[mie] = (csr[mie] & ~mask) | (val & mask); check_interrupt(); return iss::Ok; } template iss::status riscv_hart_mu_p::read_ip(unsigned addr, reg_t &val) { - auto mask = get_irq_wrmask((addr >> 8) & 0x3); + auto mask = get_irq_mask((addr >> 8) & 0x3); val = csr[mip] & mask; if(this->reg.PRIV!=3) val &= csr[mideleg]; @@ -948,10 +948,8 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_ip(unsigned addr, reg_t val) { - auto mask = get_irq_wrmask((addr >> 8) & 0x3); - mask &= ~(8 << 4); // MTIP is read only - if(this->reg.PRIV!=3) - mask &= ~(3 << 4); // STIP and UTIP are read only in user and supervisor mode + auto mask = get_irq_mask((addr >> 8) & 0x3); + mask &= 0xf; // only xSIP is writable csr[mip] = (csr[mip] & ~mask) | (val & mask); check_interrupt(); return iss::Ok;