fixes xcause and u-mode clic CSRs
This commit is contained in:
parent
c2758e8321
commit
fedbff5971
|
@ -51,12 +51,18 @@ enum riscv_csr {
|
||||||
ustatus = 0x000,
|
ustatus = 0x000,
|
||||||
uie = 0x004,
|
uie = 0x004,
|
||||||
utvec = 0x005,
|
utvec = 0x005,
|
||||||
|
utvt = 0x007, //CLIC
|
||||||
// User Trap Handling
|
// User Trap Handling
|
||||||
uscratch = 0x040,
|
uscratch = 0x040,
|
||||||
uepc = 0x041,
|
uepc = 0x041,
|
||||||
ucause = 0x042,
|
ucause = 0x042,
|
||||||
utval = 0x043,
|
utval = 0x043,
|
||||||
uip = 0x044,
|
uip = 0x044,
|
||||||
|
uxnti = 0x045, //CLIC
|
||||||
|
uintstatus = 0xCB1, // MRW Current interrupt levels (CLIC) - addr subject to change
|
||||||
|
uintthresh = 0x047, // MRW Interrupt-level threshold (CLIC) - addr subject to change
|
||||||
|
uscratchcsw = 0x048, // MRW Conditional scratch swap on priv mode change (CLIC)
|
||||||
|
uscratchcswl = 0x049, // MRW Conditional scratch swap on level change (CLIC)
|
||||||
// User Floating-Point CSRs
|
// User Floating-Point CSRs
|
||||||
fflags = 0x001,
|
fflags = 0x001,
|
||||||
frm = 0x002,
|
frm = 0x002,
|
||||||
|
|
|
@ -304,6 +304,7 @@ protected:
|
||||||
iss::status read_time(unsigned addr, reg_t &val);
|
iss::status read_time(unsigned addr, reg_t &val);
|
||||||
iss::status read_status(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 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 write_cause(unsigned addr, reg_t val);
|
||||||
iss::status read_ie(unsigned addr, reg_t &val);
|
iss::status read_ie(unsigned addr, reg_t &val);
|
||||||
iss::status write_ie(unsigned addr, reg_t val);
|
iss::status write_ie(unsigned addr, reg_t val);
|
||||||
|
@ -376,7 +377,7 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
|
||||||
// common regs
|
// common regs
|
||||||
const std::array<unsigned, 9> addrs{{
|
const std::array<unsigned, 9> addrs{{
|
||||||
misa, mvendorid, marchid, mimpid,
|
misa, mvendorid, marchid, mimpid,
|
||||||
mepc, mtvec, mscratch, mcause, mtval
|
mepc, mtvec, mscratch, mtval
|
||||||
}};
|
}};
|
||||||
for(auto addr: addrs) {
|
for(auto addr: addrs) {
|
||||||
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
||||||
|
@ -400,6 +401,7 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
|
||||||
csr_wr_cb[minstreth] = &this_class::write_instret;
|
csr_wr_cb[minstreth] = &this_class::write_instret;
|
||||||
csr_rd_cb[mstatus] = &this_class::read_status;
|
csr_rd_cb[mstatus] = &this_class::read_status;
|
||||||
csr_wr_cb[mstatus] = &this_class::write_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_wr_cb[mcause] = &this_class::write_cause;
|
||||||
csr_rd_cb[mtvec] = &this_class::read_tvec;
|
csr_rd_cb[mtvec] = &this_class::read_tvec;
|
||||||
csr_wr_cb[mepc] = &this_class::write_epc;
|
csr_wr_cb[mepc] = &this_class::write_epc;
|
||||||
|
@ -415,8 +417,8 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
|
||||||
if(FEAT & FEAT_CLIC) {
|
if(FEAT & FEAT_CLIC) {
|
||||||
csr_rd_cb[mtvt] = &this_class::read_csr_reg;
|
csr_rd_cb[mtvt] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[mtvt] = &this_class::write_xtvt;
|
csr_wr_cb[mtvt] = &this_class::write_xtvt;
|
||||||
csr_rd_cb[mxnti] = &this_class::read_csr_reg;
|
// csr_rd_cb[mxnti] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[mxnti] = &this_class::write_csr_reg;
|
// csr_wr_cb[mxnti] = &this_class::write_csr_reg;
|
||||||
csr_rd_cb[mintstatus] = &this_class::read_csr_reg;
|
csr_rd_cb[mintstatus] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[mintstatus] = &this_class::write_null;
|
csr_wr_cb[mintstatus] = &this_class::write_null;
|
||||||
// csr_rd_cb[mscratchcsw] = &this_class::read_csr_reg;
|
// csr_rd_cb[mscratchcsw] = &this_class::read_csr_reg;
|
||||||
|
@ -425,7 +427,6 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
|
||||||
// csr_wr_cb[mscratchcswl] = &this_class::write_csr_reg;
|
// csr_wr_cb[mscratchcswl] = &this_class::write_csr_reg;
|
||||||
csr_rd_cb[mintthresh] = &this_class::read_csr_reg;
|
csr_rd_cb[mintthresh] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[mintthresh] = &this_class::write_intthresh;
|
csr_wr_cb[mintthresh] = &this_class::write_intthresh;
|
||||||
|
|
||||||
clic_int_reg.resize(cfg.clic_num_irq, clic_int_reg_t{.raw=0});
|
clic_int_reg.resize(cfg.clic_num_irq, clic_int_reg_t{.raw=0});
|
||||||
clic_cfg_reg=0x20;
|
clic_cfg_reg=0x20;
|
||||||
clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq;
|
clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq;
|
||||||
|
@ -865,8 +866,22 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_cause(unsigned addr, reg_t &val) {
|
||||||
|
auto res = csr[addr];
|
||||||
|
if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) {
|
||||||
|
res |= state.mstatus.MPIE<<27;
|
||||||
|
res |= state.mstatus.MPP<<28;
|
||||||
|
}
|
||||||
|
val=res;
|
||||||
|
return iss::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_cause(unsigned addr, reg_t val) {
|
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_cause(unsigned addr, reg_t val) {
|
||||||
csr[addr] = val & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1));
|
csr[addr] = val & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1));
|
||||||
|
if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) {
|
||||||
|
state.mstatus.MPIE=(val>>27)&0x1;
|
||||||
|
state.mstatus.MPP=(val>>28)&0x3;
|
||||||
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,7 @@ protected:
|
||||||
iss::status read_time(unsigned addr, reg_t &val);
|
iss::status read_time(unsigned addr, reg_t &val);
|
||||||
iss::status read_status(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 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 write_cause(unsigned addr, reg_t val);
|
||||||
iss::status read_ie(unsigned addr, reg_t &val);
|
iss::status read_ie(unsigned addr, reg_t &val);
|
||||||
iss::status write_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
|
// common regs
|
||||||
const std::array<unsigned, 14> addrs{{
|
const std::array<unsigned, 14> addrs{{
|
||||||
misa, mvendorid, marchid, mimpid,
|
misa, mvendorid, marchid, mimpid,
|
||||||
mepc, mtvec, mscratch, mcause, mtval,
|
mepc, mtvec, mscratch, mtval,
|
||||||
uepc, utvec, uscratch, ucause, utval,
|
uepc, utvec, uscratch, utval,
|
||||||
}};
|
}};
|
||||||
for(auto addr: addrs) {
|
for(auto addr: addrs) {
|
||||||
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
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_wr_cb[minstreth] = &this_class::write_instret;
|
||||||
csr_rd_cb[mstatus] = &this_class::read_status;
|
csr_rd_cb[mstatus] = &this_class::read_status;
|
||||||
csr_wr_cb[mstatus] = &this_class::write_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_wr_cb[mcause] = &this_class::write_cause;
|
||||||
csr_rd_cb[mtvec] = &this_class::read_tvec;
|
csr_rd_cb[mtvec] = &this_class::read_tvec;
|
||||||
csr_wr_cb[mepc] = &this_class::write_epc;
|
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_wr_cb[uepc] = &this_class::write_epc;
|
||||||
csr_rd_cb[ustatus] = &this_class::read_status;
|
csr_rd_cb[ustatus] = &this_class::read_status;
|
||||||
csr_wr_cb[ustatus] = &this_class::write_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_wr_cb[ucause] = &this_class::write_cause;
|
||||||
csr_rd_cb[utvec] = &this_class::read_tvec;
|
csr_rd_cb[utvec] = &this_class::read_tvec;
|
||||||
}
|
}
|
||||||
if(FEAT & FEAT_CLIC) {
|
if(FEAT & FEAT_CLIC) {
|
||||||
csr_rd_cb[mtvt] = &this_class::read_csr_reg;
|
csr_rd_cb[mtvt] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[mtvt] = &this_class::write_xtvt;
|
csr_wr_cb[mtvt] = &this_class::write_xtvt;
|
||||||
csr_rd_cb[mxnti] = &this_class::read_csr_reg;
|
// csr_rd_cb[mxnti] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[mxnti] = &this_class::write_csr_reg;
|
// csr_wr_cb[mxnti] = &this_class::write_csr_reg;
|
||||||
csr_rd_cb[mintstatus] = &this_class::read_csr_reg;
|
csr_rd_cb[mintstatus] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[mintstatus] = &this_class::write_null;
|
csr_wr_cb[mintstatus] = &this_class::write_null;
|
||||||
// csr_rd_cb[mscratchcsw] = &this_class::read_csr_reg;
|
// 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_wr_cb[mscratchcswl] = &this_class::write_csr_reg;
|
||||||
csr_rd_cb[mintthresh] = &this_class::read_csr_reg;
|
csr_rd_cb[mintthresh] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[mintthresh] = &this_class::write_intthresh;
|
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_int_reg.resize(cfg.clic_num_irq, clic_int_reg_t{.raw=0});
|
||||||
clic_cfg_reg=0x30;
|
clic_cfg_reg=0x30;
|
||||||
clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq;
|
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;
|
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) {
|
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));
|
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;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue