Browse Source

AIA: refactor: Let mvip.SEIP be the software-writable bit of mip.SEIP

The mip.SEIP is the logical-OR of a software-writable bit and signal
from an external interrupt controller (e.g., APLIC or IMSIC). The AIA
spec lets the software-writable bit be the mvip.SEIP.

This commit follows the concept that the mvip.SEIP is a sub-component of
mip.SEIP. Writing mip.SEIP actually updates the software-writable bit,
i.e., mvip.SEIP. Reading mip.SEIP returns a value consisting of the
software-writable bit, i.e., mvip.SEIP. The SEIP bit in mip::val becomes
a placeholder for the external interrupt controller.

Accessing mvip.SEIP reads from and writes to mvip.SEIP normally.

Reference: https://github.com/riscv/riscv-aia/issues/64
pull/1988/head
YenHaoChen 2 years ago
committed by Binno
parent
commit
876018811b
  1. 18
      riscv/csrs.cc
  2. 7
      riscv/csrs.h

18
riscv/csrs.cc

@ -783,8 +783,14 @@ mip_csr_t::mip_csr_t(processor_t* const proc, const reg_t addr):
mip_or_mie_csr_t(proc, addr) {
}
void mip_csr_t::write_with_mask(const reg_t mask, const reg_t val) noexcept {
if (mask & MIP_SEIP)
state->mvip->write_with_mask(MIP_SEIP, val); // mvip.SEIP is an alias of mip.SEIP when mvien.SEIP=0
mip_or_mie_csr_t::write_with_mask(mask & ~MIP_SEIP, val);
}
reg_t mip_csr_t::read() const noexcept {
return val | state->hvip->basic_csr_t::read();
return val | state->hvip->basic_csr_t::read() | (state->mvip->basic_csr_t::read() & MIP_SEIP);
}
void mip_csr_t::backdoor_write_with_mask(const reg_t mask, const reg_t val) noexcept {
@ -2004,19 +2010,23 @@ reg_t mvip_csr_t::read() const noexcept {
const reg_t mip = state->mip->read();
const reg_t menvcfg = state->menvcfg->read();
return 0
| (mip & MIP_SEIP)
| (val & MIP_SEIP)
| ((menvcfg & MENVCFG_STCE) ? 0 : (mip & MIP_STIP))
| (((mvien & MIP_SSIP) ? val : mip) & MIP_SSIP)
;
}
bool mvip_csr_t::unlogged_write(const reg_t val) noexcept {
state->mip->write_with_mask(MIP_SEIP, val);
if (!(state->menvcfg->read() & MENVCFG_STCE))
state->mip->write_with_mask(MIP_STIP, val); // mvip.STIP is an alias of mip.STIP when mip.STIP is writable
if (!(state->mvien->read() & MIP_SSIP))
state->mip->write_with_mask(MIP_SSIP, val); // mvip.SSIP is an alias of mip.SSIP when mvien.SSIP=0
const reg_t new_val = ((state->mvien->read() & MIP_SSIP) ? val : basic_csr_t::read()) & MIP_SSIP;
const reg_t new_val = (val & MIP_SEIP) | (((state->mvien->read() & MIP_SSIP) ? val : basic_csr_t::read()) & MIP_SSIP);
return basic_csr_t::unlogged_write(new_val);
}
void mvip_csr_t::write_with_mask(const reg_t mask, const reg_t val) noexcept {
basic_csr_t::unlogged_write((basic_csr_t::read() & ~mask) | (val & mask));
log_write();
}

7
riscv/csrs.h

@ -356,7 +356,7 @@ class mip_or_mie_csr_t: public csr_t {
mip_or_mie_csr_t(processor_t* const proc, const reg_t addr);
virtual reg_t read() const noexcept override;
void write_with_mask(const reg_t mask, const reg_t val) noexcept;
virtual void write_with_mask(const reg_t mask, const reg_t val) noexcept;
protected:
virtual bool unlogged_write(const reg_t val) noexcept override final;
@ -371,6 +371,8 @@ class mip_csr_t: public mip_or_mie_csr_t {
mip_csr_t(processor_t* const proc, const reg_t addr);
virtual reg_t read() const noexcept override final;
void write_with_mask(const reg_t mask, const reg_t val) noexcept override;
// Does not log. Used by external things (clint) that wiggle bits in mip.
void backdoor_write_with_mask(const reg_t mask, const reg_t val) noexcept;
private:
@ -921,6 +923,9 @@ class mvip_csr_t : public basic_csr_t {
public:
mvip_csr_t(processor_t* const proc, const reg_t addr, const reg_t init);
reg_t read() const noexcept override;
void write_with_mask(const reg_t mask, const reg_t val) noexcept;
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
};

Loading…
Cancel
Save