Compare commits
	
		
			1 Commits
		
	
	
		
			c376e34b2b
			...
			42efced1eb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 42efced1eb | 
| @@ -377,8 +377,8 @@ protected: | ||||
|  | ||||
|     std::vector<uint8_t> tcm; | ||||
|  | ||||
|     iss::status read_csr_reg(unsigned addr, reg_t& val); | ||||
|     iss::status write_csr_reg(unsigned addr, reg_t val); | ||||
|     iss::status read_plain(unsigned addr, reg_t& val); | ||||
|     iss::status write_plain(unsigned addr, reg_t val); | ||||
|     iss::status read_null(unsigned addr, reg_t& val); | ||||
|     iss::status write_null(unsigned addr, reg_t val) { return iss::status::Ok; } | ||||
|     iss::status read_cycle(unsigned addr, reg_t& val); | ||||
| @@ -399,17 +399,19 @@ protected: | ||||
|     iss::status read_intstatus(unsigned addr, reg_t& val); | ||||
|     iss::status write_intthresh(unsigned addr, reg_t val); | ||||
|     iss::status write_xtvt(unsigned addr, reg_t val); | ||||
|     iss::status write_dcsr_dcsr(unsigned addr, reg_t val); | ||||
|     iss::status read_dcsr_reg(unsigned addr, reg_t& val); | ||||
|     iss::status write_dcsr_reg(unsigned addr, reg_t val); | ||||
|     iss::status read_dpc_reg(unsigned addr, reg_t& val); | ||||
|     iss::status write_dpc_reg(unsigned addr, reg_t val); | ||||
|     iss::status write_dcsr(unsigned addr, reg_t val); | ||||
|     iss::status read_debug(unsigned addr, reg_t& val); | ||||
|     iss::status write_dscratch(unsigned addr, reg_t val); | ||||
|     iss::status read_dpc(unsigned addr, reg_t& val); | ||||
|     iss::status write_dpc(unsigned addr, reg_t val); | ||||
|     iss::status read_fcsr(unsigned addr, reg_t& val); | ||||
|     iss::status write_fcsr(unsigned addr, reg_t val); | ||||
|  | ||||
|     virtual iss::status read_custom_csr_reg(unsigned addr, reg_t& val) { return iss::status::Err; }; | ||||
|     virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) { return iss::status::Err; }; | ||||
|     virtual iss::status read_custom_csr(unsigned addr, reg_t& val) { return iss::status::Err; }; | ||||
|     virtual iss::status write_custom_csr(unsigned addr, reg_t val) { return iss::status::Err; }; | ||||
|  | ||||
|     void register_custom_csr_rd(unsigned addr) { csr_rd_cb[addr] = &this_class::read_custom_csr_reg; } | ||||
|     void register_custom_csr_wr(unsigned addr) { csr_wr_cb[addr] = &this_class::write_custom_csr_reg; } | ||||
|     void register_custom_csr_rd(unsigned addr) { csr_rd_cb[addr] = &this_class::read_custom_csr; } | ||||
|     void register_custom_csr_wr(unsigned addr) { csr_wr_cb[addr] = &this_class::write_custom_csr; } | ||||
|  | ||||
|     reg_t mhartid_reg{0x0}; | ||||
|  | ||||
| @@ -446,18 +448,21 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg) | ||||
|     csr[mimpid] = 1; | ||||
|  | ||||
|     uart_buf.str(""); | ||||
|     if(traits<BASE>::FLEN > 0) | ||||
|         csr_rd_cb[fcsr] = &this_class::read_fcsr; | ||||
|     csr_wr_cb[fcsr] = &this_class::write_fcsr; | ||||
|     for(unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr) { | ||||
|         csr_rd_cb[addr] = &this_class::read_null; | ||||
|         csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|         csr_wr_cb[addr] = &this_class::write_plain; | ||||
|     } | ||||
|     if(traits<BASE>::XLEN == 32) | ||||
|         for(unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr) { | ||||
|             csr_rd_cb[addr] = &this_class::read_null; | ||||
|             csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|             csr_wr_cb[addr] = &this_class::write_plain; | ||||
|         } | ||||
|     for(unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr) { | ||||
|         csr_rd_cb[addr] = &this_class::read_null; | ||||
|         csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|         csr_wr_cb[addr] = &this_class::write_plain; | ||||
|     } | ||||
|     for(unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr) { | ||||
|         csr_rd_cb[addr] = &this_class::read_null; | ||||
| @@ -465,18 +470,17 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg) | ||||
|     if(traits<BASE>::XLEN == 32) | ||||
|         for(unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr) { | ||||
|             csr_rd_cb[addr] = &this_class::read_null; | ||||
|             // csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|         } | ||||
|     // common regs | ||||
|     const std::array<unsigned, 4> roaddrs{{misa, mvendorid, marchid, mimpid}}; | ||||
|     for(auto addr : roaddrs) { | ||||
|         csr_rd_cb[addr] = &this_class::read_csr_reg; | ||||
|         csr_rd_cb[addr] = &this_class::read_plain; | ||||
|         csr_wr_cb[addr] = &this_class::write_null; | ||||
|     } | ||||
|     const std::array<unsigned, 4> rwaddrs{{mepc, mtvec, mscratch, mtval}}; | ||||
|     for(auto addr : rwaddrs) { | ||||
|         csr_rd_cb[addr] = &this_class::read_csr_reg; | ||||
|         csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|         csr_rd_cb[addr] = &this_class::read_plain; | ||||
|         csr_wr_cb[addr] = &this_class::write_plain; | ||||
|     } | ||||
|     // special handling & overrides | ||||
|     csr_rd_cb[time] = &this_class::read_time; | ||||
| @@ -517,7 +521,7 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg) | ||||
|     csr_wr_cb[marchid] = &this_class::write_null; | ||||
|     csr_wr_cb[mimpid] = &this_class::write_null; | ||||
|     if(FEAT & FEAT_CLIC) { | ||||
|         csr_rd_cb[mtvt] = &this_class::read_csr_reg; | ||||
|         csr_rd_cb[mtvt] = &this_class::read_plain; | ||||
|         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; | ||||
| @@ -527,7 +531,7 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg) | ||||
|         //        csr_wr_cb[mscratchcsw] = &this_class::write_csr_reg; | ||||
|         //        csr_rd_cb[mscratchcswl] = &this_class::read_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_plain; | ||||
|         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; | ||||
| @@ -553,14 +557,14 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg) | ||||
|         insert_mem_range(cfg.tcm_base, cfg.tcm_size, read_clic_cb, write_clic_cb); | ||||
|     } | ||||
|     if(FEAT & FEAT_DEBUG) { | ||||
|         csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; | ||||
|         csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; | ||||
|         csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg; | ||||
|         csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg; | ||||
|         csr_wr_cb[dpc] = &this_class::write_dpc_reg; | ||||
|         csr_rd_cb[dpc] = &this_class::read_dpc_reg; | ||||
|         csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; | ||||
|         csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; | ||||
|         csr_wr_cb[dscratch0] = &this_class::write_dscratch; | ||||
|         csr_rd_cb[dscratch0] = &this_class::read_debug; | ||||
|         csr_wr_cb[dscratch1] = &this_class::write_dscratch; | ||||
|         csr_rd_cb[dscratch1] = &this_class::read_debug; | ||||
|         csr_wr_cb[dpc] = &this_class::write_dpc; | ||||
|         csr_rd_cb[dpc] = &this_class::read_dpc; | ||||
|         csr_wr_cb[dcsr] = &this_class::write_dcsr; | ||||
|         csr_rd_cb[dcsr] = &this_class::read_debug; | ||||
|     } | ||||
|     hart_mem_rd_delegate = [this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return this->read_mem(a, l, d); }; | ||||
|     hart_mem_wr_delegate = [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return this->write_mem(a, l, d); }; | ||||
| @@ -665,7 +669,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co | ||||
|                 } | ||||
|                 phys_addr_t phys_addr{access, space, addr}; | ||||
|                 auto res = iss::Err; | ||||
|                 if(access != access_type::FETCH && memfn_range.size()) { | ||||
|                 if(!is_fetch(access) && memfn_range.size()) { | ||||
|                     auto it = | ||||
|                         std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a) { | ||||
|                             return std::get<0>(a) <= phys_addr.val && (std::get<0>(a) + std::get<1>(a)) > phys_addr.val; | ||||
| @@ -692,11 +696,6 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co | ||||
|         case traits<BASE>::CSR: { | ||||
|             if(length != sizeof(reg_t)) | ||||
|                 return iss::Err; | ||||
|             // We emulate the FCSR in the architectural state | ||||
|             if(addr == 3) { | ||||
|                 *data = this->get_fcsr(); | ||||
|                 return iss::Ok; | ||||
|             } | ||||
|             return read_csr(addr, *reinterpret_cast<reg_t* const>(data)); | ||||
|         } break; | ||||
|         case traits<BASE>::FENCE: { | ||||
| @@ -767,7 +766,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c | ||||
|                 } | ||||
|                 phys_addr_t phys_addr{access, space, addr}; | ||||
|                 auto res = iss::Err; | ||||
|                 if(access != access_type::FETCH && memfn_range.size()) { | ||||
|                 if(!is_fetch(access) && memfn_range.size()) { | ||||
|                     auto it = | ||||
|                         std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a) { | ||||
|                             return std::get<0>(a) <= phys_addr.val && (std::get<0>(a) + std::get<1>(a)) > phys_addr.val; | ||||
| @@ -798,8 +797,6 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c | ||||
|             case 0x10023000: // UART1 base, TXFIFO reg | ||||
|                 uart_buf << (char)data[0]; | ||||
|                 if(((char)data[0]) == '\n' || data[0] == 0) { | ||||
|                     // CPPLOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send | ||||
|                     // '"<<uart_buf.str()<<"'"; | ||||
|                     std::cout << uart_buf.str(); | ||||
|                     uart_buf.str(""); | ||||
|                 } | ||||
| @@ -828,11 +825,6 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c | ||||
|         case traits<BASE>::CSR: { | ||||
|             if(length != sizeof(reg_t)) | ||||
|                 return iss::Err; | ||||
|             // We emulate the FCSR in the architectural state | ||||
|             if(addr == 3) { | ||||
|                 this->set_fcsr(*data); | ||||
|                 return iss::Ok; | ||||
|             } | ||||
|             return write_csr(addr, *reinterpret_cast<const reg_t*>(data)); | ||||
|         } break; | ||||
|         case traits<BASE>::FENCE: { | ||||
| @@ -889,12 +881,6 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_csr(unsigned addr, reg_t v | ||||
|     return (this->*(it->second))(addr, val); | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_csr_reg(unsigned addr, reg_t& val) { | ||||
|     val = csr[addr]; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) { | ||||
|     val = 0; | ||||
| @@ -902,7 +888,13 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_csr_reg(unsigned addr, reg_t val) { | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_plain(unsigned addr, reg_t& val) { | ||||
|     val = csr[addr]; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_plain(unsigned addr, reg_t val) { | ||||
|     csr[addr] = val; | ||||
|     return iss::Ok; | ||||
| } | ||||
| @@ -1052,7 +1044,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_epc(unsigned addr, reg_t v | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, reg_t val) { | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr(unsigned addr, reg_t val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     //                  +-------------- ebreakm | ||||
| @@ -1064,7 +1056,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, r | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, reg_t& val) { | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_debug(unsigned addr, reg_t& val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     val = csr[addr]; | ||||
| @@ -1072,7 +1064,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, reg | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, reg_t val) { | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dscratch(unsigned addr, reg_t val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     csr[addr] = val; | ||||
| @@ -1080,7 +1072,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, re | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg_t& val) { | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dpc(unsigned addr, reg_t& val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     val = this->reg.DPC; | ||||
| @@ -1088,7 +1080,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg_ | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dpc_reg(unsigned addr, reg_t val) { | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dpc(unsigned addr, reg_t val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     this->reg.DPC = val; | ||||
| @@ -1101,6 +1093,18 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_intstatus(unsigned addr, re | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_fcsr(unsigned addr, reg_t& val) { | ||||
|     val = this->get_fcsr(); | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_fcsr(unsigned addr, reg_t val) { | ||||
|     this->set_fcsr(val); | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_intthresh(unsigned addr, reg_t val) { | ||||
|     csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1; | ||||
|   | ||||
| @@ -39,7 +39,9 @@ | ||||
| #include "iss/instrumentation_if.h" | ||||
| #include "iss/log_categories.h" | ||||
| #include "iss/vm_if.h" | ||||
| #include "iss/vm_types.h" | ||||
| #include "riscv_hart_common.h" | ||||
| #include <stdexcept> | ||||
| #ifndef FMT_HEADER_ONLY | ||||
| #define FMT_HEADER_ONLY | ||||
| #endif | ||||
|   | ||||
| @@ -39,7 +39,9 @@ | ||||
| #include "iss/instrumentation_if.h" | ||||
| #include "iss/log_categories.h" | ||||
| #include "iss/vm_if.h" | ||||
| #include "iss/vm_types.h" | ||||
| #include "riscv_hart_common.h" | ||||
| #include <stdexcept> | ||||
| #ifndef FMT_HEADER_ONLY | ||||
| #define FMT_HEADER_ONLY | ||||
| #endif | ||||
| @@ -302,8 +304,8 @@ public: | ||||
|     void set_mhartid(reg_t mhartid) { mhartid_reg = mhartid; }; | ||||
|  | ||||
|     void disass_output(uint64_t pc, const std::string instr) override { | ||||
|         CLOG(INFO, disass) << fmt::format("0x{:016x}    {:40} [p:{};s:0x{:x};c:{}]", pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, | ||||
|                                           this->reg.icount + cycle_offset); | ||||
|         NSCLOG(INFO, LOGCAT) << fmt::format("0x{:016x}    {:40} [p:{};s:0x{:x};c:{}]", pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, | ||||
|                                             this->reg.icount + cycle_offset); | ||||
|     }; | ||||
|  | ||||
|     iss::instrumentation_if* get_instrumentation_if() override { return &instr_if; } | ||||
| @@ -402,8 +404,8 @@ protected: | ||||
|  | ||||
|     std::vector<uint8_t> tcm; | ||||
|  | ||||
|     iss::status read_csr_reg(unsigned addr, reg_t& val); | ||||
|     iss::status write_csr_reg(unsigned addr, reg_t val); | ||||
|     iss::status read_plain(unsigned addr, reg_t& val); | ||||
|     iss::status write_plain(unsigned addr, reg_t val); | ||||
|     iss::status read_null(unsigned addr, reg_t& val); | ||||
|     iss::status write_null(unsigned addr, reg_t val) { return iss::status::Ok; } | ||||
|     iss::status read_cycle(unsigned addr, reg_t& val); | ||||
| @@ -426,15 +428,17 @@ protected: | ||||
|     iss::status read_intstatus(unsigned addr, reg_t& val); | ||||
|     iss::status write_intthresh(unsigned addr, reg_t val); | ||||
|     iss::status write_xtvt(unsigned addr, reg_t val); | ||||
|     iss::status write_dcsr_dcsr(unsigned addr, reg_t val); | ||||
|     iss::status read_dcsr_reg(unsigned addr, reg_t& val); | ||||
|     iss::status write_dcsr_reg(unsigned addr, reg_t val); | ||||
|     iss::status read_dpc_reg(unsigned addr, reg_t& val); | ||||
|     iss::status write_dpc_reg(unsigned addr, reg_t val); | ||||
|     iss::status write_pmpcfg_reg(unsigned addr, reg_t val); | ||||
|     iss::status write_dcsr(unsigned addr, reg_t val); | ||||
|     iss::status read_debug(unsigned addr, reg_t& val); | ||||
|     iss::status write_dscratch(unsigned addr, reg_t val); | ||||
|     iss::status read_dpc(unsigned addr, reg_t& val); | ||||
|     iss::status write_dpc(unsigned addr, reg_t val); | ||||
|     iss::status read_fcsr(unsigned addr, reg_t& val); | ||||
|     iss::status write_fcsr(unsigned addr, reg_t val); | ||||
|     iss::status write_pmpcfg(unsigned addr, reg_t val); | ||||
|  | ||||
|     virtual iss::status read_custom_csr_reg(unsigned addr, reg_t& val) { return iss::status::Err; }; | ||||
|     virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) { return iss::status::Err; }; | ||||
|     virtual iss::status read_custom_csr(unsigned addr, reg_t& val) { return iss::status::Err; }; | ||||
|     virtual iss::status write_custom_csr(unsigned addr, reg_t val) { return iss::status::Err; }; | ||||
|  | ||||
|     void register_custom_csr_rd(unsigned addr) { csr_rd_cb[addr] = &this_class::read_custom_csr_reg; } | ||||
|     void register_custom_csr_wr(unsigned addr) { csr_wr_cb[addr] = &this_class::write_custom_csr_reg; } | ||||
| @@ -474,18 +478,21 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg) | ||||
|     csr[mimpid] = 1; | ||||
|  | ||||
|     uart_buf.str(""); | ||||
|     if(traits<BASE>::FLEN > 0) | ||||
|         csr_rd_cb[fcsr] = &this_class::read_fcsr; | ||||
|     csr_wr_cb[fcsr] = &this_class::write_fcsr; | ||||
|     for(unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr) { | ||||
|         csr_rd_cb[addr] = &this_class::read_null; | ||||
|         csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|         csr_wr_cb[addr] = &this_class::write_plain; | ||||
|     } | ||||
|     if(traits<BASE>::XLEN == 32) | ||||
|         for(unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr) { | ||||
|             csr_rd_cb[addr] = &this_class::read_null; | ||||
|             csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|             csr_wr_cb[addr] = &this_class::write_plain; | ||||
|         } | ||||
|     for(unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr) { | ||||
|         csr_rd_cb[addr] = &this_class::read_null; | ||||
|         csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|         csr_wr_cb[addr] = &this_class::write_plain; | ||||
|     } | ||||
|     for(unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr) { | ||||
|         csr_rd_cb[addr] = &this_class::read_null; | ||||
| @@ -493,12 +500,11 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg) | ||||
|     if(traits<BASE>::XLEN == 32) | ||||
|         for(unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr) { | ||||
|             csr_rd_cb[addr] = &this_class::read_null; | ||||
|             // csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|         } | ||||
|     // common regs | ||||
|     const std::array<unsigned, 4> roaddrs{{misa, mvendorid, marchid, mimpid}}; | ||||
|     for(auto addr : roaddrs) { | ||||
|         csr_rd_cb[addr] = &this_class::read_csr_reg; | ||||
|         csr_rd_cb[addr] = &this_class::read_plain; | ||||
|         csr_wr_cb[addr] = &this_class::write_null; | ||||
|     } | ||||
|     const std::array<unsigned, 8> rwaddrs{{ | ||||
| @@ -512,8 +518,8 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg) | ||||
|         utval, | ||||
|     }}; | ||||
|     for(auto addr : rwaddrs) { | ||||
|         csr_rd_cb[addr] = &this_class::read_csr_reg; | ||||
|         csr_wr_cb[addr] = &this_class::write_csr_reg; | ||||
|         csr_rd_cb[addr] = &this_class::read_plain; | ||||
|         csr_wr_cb[addr] = &this_class::write_plain; | ||||
|     } | ||||
|     // special handling & overrides | ||||
|     csr_rd_cb[time] = &this_class::read_time; | ||||
| @@ -558,18 +564,18 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg) | ||||
|  | ||||
|     if(FEAT & FEAT_PMP) { | ||||
|         for(size_t i = pmpaddr0; i <= pmpaddr15; ++i) { | ||||
|             csr_rd_cb[i] = &this_class::read_csr_reg; | ||||
|             csr_wr_cb[i] = &this_class::write_csr_reg; | ||||
|             csr_rd_cb[i] = &this_class::read_plain; | ||||
|             csr_wr_cb[i] = &this_class::write_plain; | ||||
|         } | ||||
|         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; | ||||
|             csr_rd_cb[i] = &this_class::read_plain; | ||||
|             csr_wr_cb[i] = &this_class::write_pmpcfg; | ||||
|         } | ||||
|     } | ||||
|     if(FEAT & FEAT_EXT_N) { | ||||
|         csr_rd_cb[mideleg] = &this_class::read_csr_reg; | ||||
|         csr_rd_cb[mideleg] = &this_class::read_plain; | ||||
|         csr_wr_cb[mideleg] = &this_class::write_ideleg; | ||||
|         csr_rd_cb[medeleg] = &this_class::read_csr_reg; | ||||
|         csr_rd_cb[medeleg] = &this_class::read_plain; | ||||
|         csr_wr_cb[medeleg] = &this_class::write_edeleg; | ||||
|         csr_rd_cb[uie] = &this_class::read_ie; | ||||
|         csr_wr_cb[uie] = &this_class::write_ie; | ||||
| @@ -583,7 +589,7 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg) | ||||
|         csr_rd_cb[utvec] = &this_class::read_tvec; | ||||
|     } | ||||
|     if(FEAT & FEAT_CLIC) { | ||||
|         csr_rd_cb[mtvt] = &this_class::read_csr_reg; | ||||
|         csr_rd_cb[mtvt] = &this_class::read_plain; | ||||
|         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; | ||||
| @@ -593,14 +599,14 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg) | ||||
|         //        csr_wr_cb[mscratchcsw] = &this_class::write_csr_reg; | ||||
|         //        csr_rd_cb[mscratchcswl] = &this_class::read_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_plain; | ||||
|         csr_wr_cb[mintthresh] = &this_class::write_intthresh; | ||||
|         if(FEAT & FEAT_EXT_N) { | ||||
|             csr_rd_cb[utvt] = &this_class::read_csr_reg; | ||||
|             csr_rd_cb[utvt] = &this_class::read_plain; | ||||
|             csr_wr_cb[utvt] = &this_class::write_xtvt; | ||||
|             csr_rd_cb[uintstatus] = &this_class::read_intstatus; | ||||
|             csr_wr_cb[uintstatus] = &this_class::write_null; | ||||
|             csr_rd_cb[uintthresh] = &this_class::read_csr_reg; | ||||
|             csr_rd_cb[uintthresh] = &this_class::read_plain; | ||||
|             csr_wr_cb[uintthresh] = &this_class::write_intthresh; | ||||
|         } | ||||
|         clic_int_reg.resize(cfg.clic_num_irq, clic_int_reg_t{.raw = 0}); | ||||
| @@ -629,14 +635,14 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg) | ||||
|         insert_mem_range(cfg.tcm_base, cfg.tcm_size, read_clic_cb, write_clic_cb); | ||||
|     } | ||||
|     if(FEAT & FEAT_DEBUG) { | ||||
|         csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; | ||||
|         csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; | ||||
|         csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg; | ||||
|         csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg; | ||||
|         csr_wr_cb[dpc] = &this_class::write_dpc_reg; | ||||
|         csr_rd_cb[dpc] = &this_class::read_dpc_reg; | ||||
|         csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; | ||||
|         csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; | ||||
|         csr_wr_cb[dscratch0] = &this_class::write_dscratch; | ||||
|         csr_rd_cb[dscratch0] = &this_class::read_debug; | ||||
|         csr_wr_cb[dscratch1] = &this_class::write_dscratch; | ||||
|         csr_rd_cb[dscratch1] = &this_class::read_debug; | ||||
|         csr_wr_cb[dpc] = &this_class::write_dpc; | ||||
|         csr_rd_cb[dpc] = &this_class::read_dpc; | ||||
|         csr_wr_cb[dcsr] = &this_class::write_dcsr; | ||||
|         csr_rd_cb[dcsr] = &this_class::read_debug; | ||||
|     } | ||||
|     hart_mem_rd_delegate = [this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return this->read_mem(a, l, d); }; | ||||
|     hart_mem_wr_delegate = [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return this->write_mem(a, l, d); }; | ||||
| @@ -725,7 +731,7 @@ inline void riscv_hart_mu_p<BASE, FEAT, LOGCAT>::insert_mem_range(uint64_t base, | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| inline iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_pmpcfg_reg(unsigned addr, reg_t val) { | ||||
| inline iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_pmpcfg(unsigned addr, reg_t val) { | ||||
|     csr[addr] = val & 0x9f9f9f9f; | ||||
|     return iss::Ok; | ||||
| } | ||||
| @@ -988,8 +994,6 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write(const address_type type, | ||||
|             case 0x10023000: // UART1 base, TXFIFO reg | ||||
|                 uart_buf << (char)data[0]; | ||||
|                 if(((char)data[0]) == '\n' || data[0] == 0) { | ||||
|                     // CPPLOG(INFO)<<"UART"<<((addr>>16)&0x3)<<" send | ||||
|                     // '"<<uart_buf.str()<<"'"; | ||||
|                     std::cout << uart_buf.str(); | ||||
|                     uart_buf.str(""); | ||||
|                 } | ||||
| @@ -1074,12 +1078,6 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_csr(unsigned addr, reg_t | ||||
|     return (this->*(it->second))(addr, val); | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_csr_reg(unsigned addr, reg_t& val) { | ||||
|     val = csr[addr]; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) { | ||||
|     val = 0; | ||||
| @@ -1087,7 +1085,13 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_csr_reg(unsigned addr, reg_t val) { | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_plain(unsigned addr, reg_t& val) { | ||||
|     val = csr[addr]; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_plain(unsigned addr, reg_t val) { | ||||
|     csr[addr] = val; | ||||
|     return iss::Ok; | ||||
| } | ||||
| @@ -1161,6 +1165,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_tvec(unsigned addr, reg_t& | ||||
|     val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_status(unsigned addr, reg_t& val) { | ||||
|     val = state.mstatus & hart_state_type::get_mask((addr >> 8) & 0x3); | ||||
| @@ -1272,7 +1277,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_epc(unsigned addr, reg_t | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, reg_t val) { | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr(unsigned addr, reg_t val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     //                  +-------------- ebreakm | ||||
| @@ -1284,7 +1289,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, reg_t& val) { | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_debug(unsigned addr, reg_t& val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     val = csr[addr]; | ||||
| @@ -1292,7 +1297,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, re | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, reg_t val) { | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dscratch(unsigned addr, reg_t val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     csr[addr] = val; | ||||
| @@ -1300,7 +1305,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, r | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg_t& val) { | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dpc(unsigned addr, reg_t& val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     val = this->reg.DPC; | ||||
| @@ -1308,7 +1313,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dpc_reg(unsigned addr, reg_t val) { | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dpc(unsigned addr, reg_t val) { | ||||
|     if(!debug_mode_active()) | ||||
|         throw illegal_instruction_fault(this->fault_data); | ||||
|     this->reg.DPC = val; | ||||
| @@ -1324,6 +1329,18 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_intstatus(unsigned addr, r | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_fcsr(unsigned addr, reg_t& val) { | ||||
|     val = this->get_fcsr(); | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_fcsr(unsigned addr, reg_t val) { | ||||
|     this->set_fcsr(val); | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_intthresh(unsigned addr, reg_t val) { | ||||
|     csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user