fixes privilege wrapper for M/U to cope with 64bit
This commit is contained in:
parent
a8a2782329
commit
f626ee2684
|
@ -181,6 +181,89 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// specialization 64bit
|
||||||
|
template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
|
||||||
|
public:
|
||||||
|
BEGIN_BF_DECL(mstatus_t, T);
|
||||||
|
// SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11)))
|
||||||
|
BF_FIELD(SD, 63, 1);
|
||||||
|
// value of XLEN for S-mode
|
||||||
|
BF_FIELD(SXL, 34, 2);
|
||||||
|
// value of XLEN for U-mode
|
||||||
|
BF_FIELD(UXL, 32, 2);
|
||||||
|
// Trap SRET
|
||||||
|
BF_FIELD(TSR, 22, 1);
|
||||||
|
// Timeout Wait
|
||||||
|
BF_FIELD(TW, 21, 1);
|
||||||
|
// Trap Virtual Memory
|
||||||
|
BF_FIELD(TVM, 20, 1);
|
||||||
|
// Make eXecutable Readable
|
||||||
|
BF_FIELD(MXR, 19, 1);
|
||||||
|
// permit Supervisor User Memory access
|
||||||
|
BF_FIELD(SUM, 18, 1);
|
||||||
|
// Modify PRiVilege
|
||||||
|
BF_FIELD(MPRV, 17, 1);
|
||||||
|
// status of additional user-mode extensions and associated state, All off/None dirty or clean, some on/None dirty, some clean/Some dirty
|
||||||
|
BF_FIELD(XS, 15, 2);
|
||||||
|
// floating-point unit status Off/Initial/Clean/Dirty
|
||||||
|
BF_FIELD(FS, 13, 2);
|
||||||
|
// machine previous privilege
|
||||||
|
BF_FIELD(MPP, 11, 2);
|
||||||
|
// supervisor previous privilege
|
||||||
|
BF_FIELD(SPP, 8, 1);
|
||||||
|
// previous machine interrupt-enable
|
||||||
|
BF_FIELD(MPIE, 7, 1);
|
||||||
|
// previous supervisor interrupt-enable
|
||||||
|
BF_FIELD(SPIE, 5, 1);
|
||||||
|
// previous user interrupt-enable
|
||||||
|
BF_FIELD(UPIE, 4, 1);
|
||||||
|
// machine interrupt-enable
|
||||||
|
BF_FIELD(MIE, 3, 1);
|
||||||
|
// supervisor interrupt-enable
|
||||||
|
BF_FIELD(SIE, 1, 1);
|
||||||
|
// user interrupt-enable
|
||||||
|
BF_FIELD(UIE, 0, 1);
|
||||||
|
END_BF_DECL();
|
||||||
|
|
||||||
|
mstatus_t mstatus;
|
||||||
|
|
||||||
|
static const reg_t mstatus_reset_val = 0x1800;
|
||||||
|
|
||||||
|
void write_mstatus(T val, unsigned priv_lvl) {
|
||||||
|
auto mask = get_mask(priv_lvl);
|
||||||
|
auto new_val = (mstatus.backing.val & ~mask) | (val & mask);
|
||||||
|
mstatus = new_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint64_t get_mask(unsigned priv_lvl) {
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
return priv_lvl == PRIV_U ? 0x011ULL : priv_lvl == PRIV_S ? 0x000de133ULL : 0x007ff9ddULL;
|
||||||
|
#else
|
||||||
|
switch (priv_lvl) {
|
||||||
|
case PRIV_U: return 0x00000011UL; // 0b1000 0000 0000 0000 0000 0000 0001 0001
|
||||||
|
default:
|
||||||
|
// +-SD
|
||||||
|
// | +-TSR
|
||||||
|
// | |+-TW
|
||||||
|
// | ||+-TVM
|
||||||
|
// | |||+-MXR
|
||||||
|
// | ||||+-SUM
|
||||||
|
// | |||||+-MPRV
|
||||||
|
// | |||||| +-XS
|
||||||
|
// | |||||| | +-FS
|
||||||
|
// | |||||| | | +-MPP
|
||||||
|
// | |||||| | | | +-SPP
|
||||||
|
// | |||||| | | | |+-MPIE
|
||||||
|
// | |||||| | | | || +-UPIE
|
||||||
|
// | ||||||/|/|/| || |+-MIE
|
||||||
|
// | ||||||/|/|/| || || +-UIE
|
||||||
|
return 0b00000000000000000001100010011001;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
using hart_state_type = hart_state<reg_t>;
|
using hart_state_type = hart_state<reg_t>;
|
||||||
|
|
||||||
constexpr reg_t get_irq_mask(size_t mode) {
|
constexpr reg_t get_irq_mask(size_t mode) {
|
||||||
|
@ -450,7 +533,7 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
|
||||||
csr_rd_cb[i] = &this_class::read_csr_reg;
|
csr_rd_cb[i] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[i] = &this_class::write_csr_reg;
|
csr_wr_cb[i] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
for(size_t i=pmpcfg0; i<=pmpcfg3; ++i){
|
for(size_t i=pmpcfg0; i<pmpcfg0+16/sizeof(reg_t); ++i){
|
||||||
csr_rd_cb[i] = &this_class::read_csr_reg;
|
csr_rd_cb[i] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[i] = &this_class::write_pmpcfg_reg;
|
csr_wr_cb[i] = &this_class::write_pmpcfg_reg;
|
||||||
}
|
}
|
||||||
|
@ -627,9 +710,10 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
|
||||||
constexpr auto PMP_NAPOT =0x3U;
|
constexpr auto PMP_NAPOT =0x3U;
|
||||||
reg_t base = 0;
|
reg_t base = 0;
|
||||||
auto any_active = false;
|
auto any_active = false;
|
||||||
|
auto const cfg_reg_size=sizeof(reg_t);
|
||||||
for (size_t i = 0; i < 16; i++) {
|
for (size_t i = 0; i < 16; i++) {
|
||||||
reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
|
reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
|
||||||
uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
|
uint8_t cfg = csr[pmpcfg0+(i/cfg_reg_size)]>>(i%cfg_reg_size);
|
||||||
if (cfg & PMP_A) {
|
if (cfg & PMP_A) {
|
||||||
any_active=true;
|
any_active=true;
|
||||||
auto pmp_a = (cfg & PMP_A) >> 3;
|
auto pmp_a = (cfg & PMP_A) >> 3;
|
||||||
|
|
Loading…
Reference in New Issue