fix mip handling
This commit is contained in:
parent
fd98ad95f6
commit
2d7973520b
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user