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;
|
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue