fixes xcause and u-mode clic CSRs

This commit is contained in:
2023-03-15 12:27:39 +01:00
parent c2758e8321
commit fedbff5971
3 changed files with 70 additions and 9 deletions

View File

@ -319,6 +319,7 @@ protected:
iss::status read_time(unsigned addr, reg_t &val);
iss::status read_status(unsigned addr, reg_t &val);
iss::status write_status(unsigned addr, reg_t val);
iss::status read_cause(unsigned addr, reg_t &val);
iss::status write_cause(unsigned addr, reg_t val);
iss::status read_ie(unsigned addr, reg_t &val);
iss::status write_ie(unsigned addr, reg_t val);
@ -394,8 +395,8 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
// common regs
const std::array<unsigned, 14> addrs{{
misa, mvendorid, marchid, mimpid,
mepc, mtvec, mscratch, mcause, mtval,
uepc, utvec, uscratch, ucause, utval,
mepc, mtvec, mscratch, mtval,
uepc, utvec, uscratch, utval,
}};
for(auto addr: addrs) {
csr_rd_cb[addr] = &this_class::read_csr_reg;
@ -419,6 +420,7 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
csr_wr_cb[minstreth] = &this_class::write_instret;
csr_rd_cb[mstatus] = &this_class::read_status;
csr_wr_cb[mstatus] = &this_class::write_status;
csr_rd_cb[mcause] = &this_class::read_cause;
csr_wr_cb[mcause] = &this_class::write_cause;
csr_rd_cb[mtvec] = &this_class::read_tvec;
csr_wr_cb[mepc] = &this_class::write_epc;
@ -456,14 +458,15 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
csr_wr_cb[uepc] = &this_class::write_epc;
csr_rd_cb[ustatus] = &this_class::read_status;
csr_wr_cb[ustatus] = &this_class::write_status;
csr_rd_cb[ucause] = &this_class::read_cause;
csr_wr_cb[ucause] = &this_class::write_cause;
csr_rd_cb[utvec] = &this_class::read_tvec;
}
if(FEAT & FEAT_CLIC) {
csr_rd_cb[mtvt] = &this_class::read_csr_reg;
csr_wr_cb[mtvt] = &this_class::write_xtvt;
csr_rd_cb[mxnti] = &this_class::read_csr_reg;
csr_wr_cb[mxnti] = &this_class::write_csr_reg;
// csr_rd_cb[mxnti] = &this_class::read_csr_reg;
// csr_wr_cb[mxnti] = &this_class::write_csr_reg;
csr_rd_cb[mintstatus] = &this_class::read_csr_reg;
csr_wr_cb[mintstatus] = &this_class::write_null;
// csr_rd_cb[mscratchcsw] = &this_class::read_csr_reg;
@ -472,7 +475,14 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
// csr_wr_cb[mscratchcswl] = &this_class::write_csr_reg;
csr_rd_cb[mintthresh] = &this_class::read_csr_reg;
csr_wr_cb[mintthresh] = &this_class::write_intthresh;
if(FEAT & FEAT_EXT_N){
csr_rd_cb[utvt] = &this_class::read_csr_reg;
csr_wr_cb[utvt] = &this_class::write_xtvt;
csr_rd_cb[uintstatus] = &this_class::read_csr_reg;
csr_wr_cb[uintstatus] = &this_class::write_null;
csr_rd_cb[uintthresh] = &this_class::read_csr_reg;
csr_wr_cb[uintthresh] = &this_class::write_intthresh;
}
clic_int_reg.resize(cfg.clic_num_irq, clic_int_reg_t{.raw=0});
clic_cfg_reg=0x30;
clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq;
@ -1015,8 +1025,38 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
return iss::Ok;
}
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::read_cause(unsigned addr, reg_t &val) {
auto res = csr[addr];
if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) {
auto mode = (addr >> 8) & 0x3;
switch(mode) {
case 0:
res |= state.mstatus.UPIE<<27;
break;
default:
res |= state.mstatus.MPIE<<27;
res |= state.mstatus.MPP<<28;
break;
}
}
val=res;
return iss::Ok;
}
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_cause(unsigned addr, reg_t val) {
csr[addr] = val & ((1UL<<(traits<BASE>::XLEN-1))|(mcause_max_irq-1));
if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) {
auto mode = (addr >> 8) & 0x3;
switch(mode) {
case 0:
state.mstatus.UPIE=(val>>27)&0x1;
break;
default:
state.mstatus.MPIE=(val>>27)&0x1;
state.mstatus.MPP=(val>>28)&0x3;
break;
}
}
return iss::Ok;
}