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;
}
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_ie(unsigned addr, reg_t &val) {
val = csr[mie];
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_hartid(unsigned addr, reg_t &val) {
val = mhartid_reg;
return iss::Ok;
}
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_hartid(unsigned addr, reg_t &val) {
val = mhartid_reg;
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_ie(unsigned addr, reg_t &val) {
auto mask = get_irq_mask();
val = csr[mie] & mask;
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) {
val = csr[mip];
auto mask = get_irq_mask();
val = csr[mip] & mask;
return iss::Ok;
}
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();
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;

View File

@ -181,7 +181,7 @@ public:
};
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 = {{
0b000100010001, // U 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) {
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 <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) {
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 <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;
if(this->reg.PRIV!=3)
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) {
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;