diff --git a/src/iss/arch/riscv_hart_common.h b/src/iss/arch/riscv_hart_common.h index 704fc2f..4bb2f43 100644 --- a/src/iss/arch/riscv_hart_common.h +++ b/src/iss/arch/riscv_hart_common.h @@ -51,12 +51,18 @@ enum riscv_csr { ustatus = 0x000, uie = 0x004, utvec = 0x005, + utvt = 0x007, //CLIC // User Trap Handling uscratch = 0x040, uepc = 0x041, ucause = 0x042, utval = 0x043, 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 fflags = 0x001, frm = 0x002, diff --git a/src/iss/arch/riscv_hart_m_p.h b/src/iss/arch/riscv_hart_m_p.h index 0652bd6..86d5877 100644 --- a/src/iss/arch/riscv_hart_m_p.h +++ b/src/iss/arch/riscv_hart_m_p.h @@ -304,6 +304,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); @@ -376,7 +377,7 @@ riscv_hart_m_p::riscv_hart_m_p(feature_config cfg) // common regs const std::array addrs{{ misa, mvendorid, marchid, mimpid, - mepc, mtvec, mscratch, mcause, mtval + mepc, mtvec, mscratch, mtval }}; for(auto addr: addrs) { csr_rd_cb[addr] = &this_class::read_csr_reg; @@ -400,6 +401,7 @@ riscv_hart_m_p::riscv_hart_m_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; @@ -415,8 +417,8 @@ riscv_hart_m_p::riscv_hart_m_p(feature_config cfg) 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; @@ -425,7 +427,6 @@ riscv_hart_m_p::riscv_hart_m_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; - clic_int_reg.resize(cfg.clic_num_irq, clic_int_reg_t{.raw=0}); clic_cfg_reg=0x20; clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq; @@ -865,8 +866,22 @@ template iss::status riscv_hart_m_p return iss::Ok; } +template iss::status riscv_hart_m_p::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 iss::status riscv_hart_m_p::write_cause(unsigned addr, reg_t val) { csr[addr] = val & ((1UL<<(traits::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; } diff --git a/src/iss/arch/riscv_hart_mu_p.h b/src/iss/arch/riscv_hart_mu_p.h index 1ca4f96..1c377eb 100644 --- a/src/iss/arch/riscv_hart_mu_p.h +++ b/src/iss/arch/riscv_hart_mu_p.h @@ -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::riscv_hart_mu_p(feature_config cfg) // common regs const std::array 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::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::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::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 iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::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 iss::status riscv_hart_mu_p::write_cause(unsigned addr, reg_t val) { csr[addr] = val & ((1UL<<(traits::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; }