Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ if(NOT TARGET dbt-rise-core)
FetchContent_Declare(
dbt_rise_core_git
GIT_REPOSITORY "https://github.com/Minres/DBT-RISE-Core.git"
GIT_TAG 50635c29
GIT_TAG 9b571ff9
GIT_SHALLOW OFF
UPDATE_DISCONNECTED NOT ${UPDATE_EXTERNAL_PROJECT} # When enabled, this option causes the update step to be skipped.
)
Expand Down
28 changes: 21 additions & 7 deletions src/iss/arch/riscv_hart_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
namespace iss {
namespace arch {

enum features_e { FEAT_NONE, FEAT_EXT_N = 1, FEAT_DEBUG = 2 };
enum features_e { FEAT_NONE, FEAT_EXT_N = 1, FEAT_DEBUG = 2, FEAT_AIA = 4 };
enum extension_encoding {
A = 1UL << 0,
B = 1UL << 1,
Expand Down Expand Up @@ -135,12 +135,14 @@ enum riscv_csr {
sie = 0x104,
stvec = 0x105,
scounteren = 0x106,
sieh = 0x114,
// Supervisor Trap Handling
sscratch = 0x140,
sepc = 0x141,
scause = 0x142,
stval = 0x143,
sip = 0x144,
siph = 0x154,
// Supervisor Protection and Translation
satp = 0x180,
/* machine-level CSR */
Expand All @@ -154,18 +156,24 @@ enum riscv_csr {
misa = 0x301,
medeleg = 0x302,
mideleg = 0x303,
midelegh = 0x313, // AIA defined
mie = 0x304,
mieh = 0x314, // AIA defined
mtvec = 0x305,
mcounteren = 0x306,
mtvt = 0x307, // CLIC
mstatush = 0x310,
medelegh = 0x312,
// AIA defined
mvienh = 0x318,
mviph = 0x319,
// Machine Trap Handling
mscratch = 0x340,
mepc = 0x341,
mcause = 0x342,
mtval = 0x343,
mip = 0x344,
miph = 0x354, // AIA defined
mxnti = 0x345, // CLIC
mintstatus = 0xFB1, // MRW Current interrupt levels (CLIC) - addr subject to change
mintthresh = 0x347, // MRW Interrupt-level threshold (CLIC) - addr subject to change
Expand Down Expand Up @@ -648,12 +656,12 @@ template <typename BASE = logging::disass> struct riscv_hart_common : public BAS
this->csr_rd_cb[dcsr] = MK_CSR_RD_CB(read_debug);
}

constexpr reg_t get_irq_mask(size_t mode) {
std::array<const reg_t, 4> m = {{
(std::numeric_limits<reg_t>::max() & ~0xffffULL) | 0b000100010001U, // U mode
(std::numeric_limits<reg_t>::max() & ~0xffffULL) | 0b001100110011U, // S mode
(std::numeric_limits<reg_t>::max() & ~0xffffULL) | 0b011101110111U, // H mode
(std::numeric_limits<reg_t>::max() & ~0xffffULL) | 0b111111111111U // M mode
constexpr uint64_t get_irq_mask(size_t mode) {
std::array<const uint64_t, 4> m = {{
(std::numeric_limits<uint64_t>::max() & ~0xffffULL) | 0b000100010001U, // U mode
(std::numeric_limits<uint64_t>::max() & ~0xffffULL) | 0b001100110011U, // S mode
(std::numeric_limits<uint64_t>::max() & ~0xffffULL) | 0b011101110111U, // H mode
(std::numeric_limits<uint64_t>::max() & ~0xffffULL) | 0b111111111111U // M mode
}};
return m[mode];
}
Expand Down Expand Up @@ -1069,6 +1077,12 @@ template <typename BASE = logging::disass> struct riscv_hart_common : public BAS
reg_t mhartid_reg{0x0};
uint64_t mcycle_csr{0};
uint64_t minstret_csr{0};
uint64_t mie_csr{0};
uint64_t mip_csr{0};
uint64_t mideleg_csr{0};
uint64_t sie_csr{0};
uint64_t sip_csr{0};
uint64_t sideleg_csr{0};
reg_t fault_data;

int64_t cycle_offset{0};
Expand Down
25 changes: 21 additions & 4 deletions src/iss/arch/riscv_hart_m_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p()
if(FEAT & FEAT_DEBUG)
this->add_debug_csrs();

if(FEAT & FEAT_AIA && traits<BASE>::XLEN == 32) {
this->csr_rd_cb[miph] = MK_CSR_RD_CB(read_ip);
this->csr_wr_cb[miph] = MK_CSR_WR_CB(write_plain);
this->csr_rd_cb[mieh] = MK_CSR_RD_CB(read_ie);
this->csr_wr_cb[mieh] = MK_CSR_WR_CB(write_ie);
}
this->rd_func = util::delegate<arch_if::rd_func_sig>::from<this_class, &this_class::read>(this);
this->wr_func = util::delegate<arch_if::wr_func_sig>::from<this_class, &this_class::write>(this);
this->memories.root(*this);
Expand Down Expand Up @@ -304,22 +310,33 @@ 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_ie(unsigned addr, reg_t& val) {
if(unlikely(addr == mieh)) {
val = this->mie_csr >> 32;
return iss::Ok;
}
auto mask = riscv_hart_common<BASE>::get_irq_mask(3);
val = this->csr[mie] & mask;
val = this->mie_csr & mask;
return iss::Ok;
}

template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_ie(unsigned addr, reg_t val) {
uint64_t lval = val;
if(addr == mieh)
lval <<= 32;
// generate mask from allowed writable bits, the number of custom interrupts and the available ie bits
auto mask = riscv_hart_common<BASE>::get_irq_mask(3) & this->clint_custom_irq_mask & ~0x777ULL;
this->csr[mie] = (this->csr[mie] & ~mask) | (val & mask);
this->mie_csr = (this->mie_csr & ~mask) | (lval & mask);
check_interrupt();
return iss::Ok;
}

template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_ip(unsigned addr, reg_t& val) {
if(unlikely(addr == miph)) {
val = this->mip_csr >> 32;
return iss::Ok;
}
auto mask = riscv_hart_common<BASE>::get_irq_mask(3);
val = this->csr[mip] & mask;
val = this->mip_csr & mask;
return iss::Ok;
}

Expand All @@ -333,7 +350,7 @@ template <typename BASE, features_e FEAT> void riscv_hart_m_p<BASE, FEAT>::check
// handled in the following decreasing priority order:
// external interrupts, software interrupts, timer interrupts, then finally
// any synchronous traps.
auto ena_irq = this->csr[mip] & this->csr[mie];
auto ena_irq = this->mip_csr & this->mie_csr;

bool mstatus_mie = this->state.mstatus.MIE;
auto m_enabled = this->reg.PRIV < PRIV_M || mstatus_mie;
Expand Down
49 changes: 36 additions & 13 deletions src/iss/arch/riscv_hart_msu_vp.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,15 @@ riscv_hart_msu_vp<BASE, FEAT>::riscv_hart_msu_vp()
if(FEAT & FEAT_DEBUG)
this->add_debug_csrs();

if(FEAT & FEAT_AIA && traits<BASE>::XLEN == 32) {
this->csr_rd_cb[miph] = MK_CSR_RD_CB(read_ip);
this->csr_wr_cb[miph] = MK_CSR_WR_CB(write_plain);
this->csr_rd_cb[mieh] = MK_CSR_RD_CB(read_ie);
this->csr_wr_cb[mieh] = MK_CSR_WR_CB(write_ie);
this->csr_rd_cb[midelegh] = MK_CSR_RD_CB(read_plain);
this->csr_wr_cb[midelegh] = MK_CSR_WR_CB(write_ideleg);
}

this->rd_func = util::delegate<arch_if::rd_func_sig>::from<this_class, &this_class::read>(this);
this->wr_func = util::delegate<arch_if::wr_func_sig>::from<this_class, &this_class::write>(this);
this->set_next(mmu.get_mem_if());
Expand Down Expand Up @@ -407,11 +416,25 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_msu_vp<BASE, FE
}

template <typename BASE, features_e FEAT> iss::status riscv_hart_msu_vp<BASE, FEAT>::read_ie(unsigned addr, reg_t& val) {
val = this->csr[mie];
if(addr < mie)
val &= this->csr[mideleg];
if(addr < sie)
val &= this->csr[sideleg];
val = this->mie_csr;
if(addr == mie) {
val &= this->mie_csr;
return iss::Ok;
}
if(addr == sie) {
val &= this->sie_csr;
return iss::Ok;
}
if((FEAT & FEAT_AIA) && traits<BASE>::XLEN == 32) {
if(addr == mieh) {
val &= this->mie_csr >> 32;
return iss::Ok;
}
if(addr == sieh) {
val &= this->sie_csr >> 32;
return iss::Ok;
}
}
return iss::Ok;
}

Expand All @@ -423,17 +446,17 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_msu_vp<BASE, FE
mask &= ~0x444ULL; // clear H mode bits
else
mask &= ~0x555ULL; // clear H & U mode bits
this->csr[mie] = (this->csr[mie] & ~mask) | (val & mask);
this->mie_csr = (this->mie_csr & ~mask) | (val & mask);
check_interrupt();
return iss::Ok;
}

template <typename BASE, features_e FEAT> iss::status riscv_hart_msu_vp<BASE, FEAT>::read_ip(unsigned addr, reg_t& val) {
val = this->csr[mip];
if(addr < mip)
val &= this->csr[mideleg];
if(addr < sip)
val &= this->csr[sideleg];
val = this->mip_csr;
if(addr == mideleg)
val &= this->mideleg_csr;
if(addr == sideleg)
val &= this->sideleg_csr;
return iss::Ok;
}

Expand Down Expand Up @@ -476,8 +499,8 @@ template <typename BASE, features_e FEAT> inline void riscv_hart_msu_vp<BASE, FE

template <typename BASE, features_e FEAT> void riscv_hart_msu_vp<BASE, FEAT>::check_interrupt() {
auto status = this->state.mstatus;
auto ip = this->csr[mip];
auto ie = this->csr[mie];
auto ip = this->mip_csr;
auto ie = this->mie_csr;
auto ideleg = this->csr[mideleg];
// Multiple simultaneous interrupts and traps at the same privilege level are
// handled in the following decreasing priority order:
Expand Down
40 changes: 33 additions & 7 deletions src/iss/arch/riscv_hart_mu_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "iss/vm_if.h"
#include "iss/vm_types.h"
#include "riscv_hart_common.h"
#include "util/ities.h"
#include "util/logging.h"
#include <algorithm>
#include <array>
Expand Down Expand Up @@ -149,6 +150,17 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p()
if(FEAT & FEAT_DEBUG)
this->add_debug_csrs();

if(FEAT & FEAT_AIA && traits<BASE>::XLEN == 32) {
this->csr_rd_cb[miph] = MK_CSR_RD_CB(read_ip);
this->csr_wr_cb[miph] = MK_CSR_WR_CB(write_plain);
this->csr_rd_cb[mieh] = MK_CSR_RD_CB(read_ie);
this->csr_wr_cb[mieh] = MK_CSR_WR_CB(write_ie);
if(FEAT & FEAT_EXT_N) {
this->csr_rd_cb[midelegh] = MK_CSR_RD_CB(read_plain);
this->csr_wr_cb[midelegh] = MK_CSR_WR_CB(write_ideleg);
}
}

this->rd_func = util::delegate<arch_if::rd_func_sig>::from<this_class, &this_class::read>(this);
this->wr_func = util::delegate<arch_if::wr_func_sig>::from<this_class, &this_class::write>(this);
this->memories.root(*this);
Expand Down Expand Up @@ -340,34 +352,48 @@ 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) {
if(unlikely(addr == mieh)) {
val = this->mie_csr >> 32;
return iss::Ok;
}
auto mask = riscv_hart_common<BASE>::get_irq_mask((addr >> 8) & 0x3);
val = this->csr[mie] & mask;
val = this->mie_csr & mask;
return iss::Ok;
}

template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ie(unsigned addr, reg_t val) {
uint64_t lval = val;
if(addr == mieh)
lval <<= 32;
// generate mask from allowed writable bits, the number of custom interrupts and the available ie bits
auto mask = riscv_hart_common<BASE>::get_irq_mask((addr >> 8) & 0x3) & FEAT & FEAT_EXT_N;
mask &= this->clint_custom_irq_mask;
if(FEAT & FEAT_EXT_N)
mask &= ~0x666ULL; // clear H & S mode bits
else
mask &= ~0x777ULL; // clear H, S & U mode bits
this->csr[mie] = (this->csr[mie] & ~mask) | (val & mask);
this->mie_csr = (this->mie_csr & ~mask) | (lval & 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) {
if(unlikely(addr == miph)) {
val = this->mip_csr >> 32;
return iss::Ok;
}
auto mask = riscv_hart_common<BASE>::get_irq_mask((addr >> 8) & 0x3);
val = this->csr[mip] & mask;
val = this->mip_csr & mask;
return iss::Ok;
}

template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ideleg(unsigned addr, reg_t val) {
// only U and S mode interrupts can be delegated
auto mask = 0b0001'0001'0001;
this->csr[mideleg] = (this->csr[mideleg] & ~mask) | (val & mask);
uint64_t lval = val;
if(addr == midelegh)
lval <<= 32;
// only U mode interrupts can be delegated
auto mask = 0xffff'0111ul;
this->mideleg_csr = (this->mideleg_csr & ~mask) | (lval & mask);
return iss::Ok;
}

Expand Down Expand Up @@ -396,7 +422,7 @@ template <typename BASE, features_e FEAT> void riscv_hart_mu_p<BASE, FEAT>::chec
// handled in the following decreasing priority order:
// external interrupts, software interrupts, timer interrupts, then finally
// any synchronous traps.
auto ena_irq = this->csr[mip] & this->csr[mie];
auto ena_irq = this->mip_csr & this->mie_csr;

bool mstatus_mie = this->state.mstatus.MIE;
auto m_enabled = this->reg.PRIV < PRIV_M || mstatus_mie;
Expand Down
Loading