fix mip handling

This commit is contained in:
Eyck Jentzsch 2021-11-09 19:47:34 +01:00
parent fd98ad95f6
commit 2d7973520b
2 changed files with 14 additions and 14 deletions

View File

@ -781,13 +781,14 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_ie(unsigned addr, reg_t &val) { template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_hartid(unsigned addr, reg_t &val) {
val = csr[mie]; val = mhartid_reg;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_hartid(unsigned addr, reg_t &val) { template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_ie(unsigned addr, reg_t &val) {
val = mhartid_reg; auto mask = get_irq_mask();
val = csr[mie] & mask;
return iss::Ok; return iss::Ok;
} }
@ -799,13 +800,14 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
} }
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_ip(unsigned addr, reg_t &val) { template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_ip(unsigned addr, reg_t &val) {
val = csr[mip]; auto mask = get_irq_mask();
val = csr[mip] & mask;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_ip(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_ip(unsigned addr, reg_t val) {
auto mask = get_irq_mask(); 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); csr[mip] = (csr[mip] & ~mask) | (val & mask);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;

View File

@ -181,7 +181,7 @@ public:
}; };
using hart_state_type = hart_state<reg_t>; using hart_state_type = hart_state<reg_t>;
constexpr reg_t get_irq_wrmask(size_t mode) { constexpr reg_t get_irq_mask(size_t mode) {
std::array<const reg_t, 4> m = {{ std::array<const reg_t, 4> m = {{
0b000100010001, // U mode 0b000100010001, // U mode
0b001100110011, // S mode 0b001100110011, // S mode
@ -925,7 +925,7 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
} }
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::read_ie(unsigned addr, reg_t &val) { template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::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; val = csr[mie] & mask;
if(this->reg.PRIV!=3) if(this->reg.PRIV!=3)
val &= csr[mideleg]; val &= csr[mideleg];
@ -933,14 +933,14 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
} }
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ie(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::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); csr[mie] = (csr[mie] & ~mask) | (val & mask);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::read_ip(unsigned addr, reg_t &val) { template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::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; val = csr[mip] & mask;
if(this->reg.PRIV!=3) if(this->reg.PRIV!=3)
val &= csr[mideleg]; val &= csr[mideleg];
@ -948,10 +948,8 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
} }
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ip(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ip(unsigned addr, reg_t val) {
auto mask = get_irq_wrmask((addr >> 8) & 0x3); auto mask = get_irq_mask((addr >> 8) & 0x3);
mask &= ~(8 << 4); // MTIP is read only mask &= 0xf; // only xSIP is writable
if(this->reg.PRIV!=3)
mask &= ~(3 << 4); // STIP and UTIP are read only in user and supervisor mode
csr[mip] = (csr[mip] & ~mask) | (val & mask); csr[mip] = (csr[mip] & ~mask) | (val & mask);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;