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
|
||||
}
|
||||
};
|
||||
|
||||
// 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>;
|
||||
|
||||
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_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_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;
|
||||
reg_t base = 0;
|
||||
auto any_active = false;
|
||||
auto const cfg_reg_size=sizeof(reg_t);
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
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) {
|
||||
any_active=true;
|
||||
auto pmp_a = (cfg & PMP_A) >> 3;
|
||||
|
|
Loading…
Reference in New Issue