Compare commits
	
		
			1 Commits
		
	
	
		
			c376e34b2b
			...
			42efced1eb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 42efced1eb | 
| @@ -377,8 +377,8 @@ protected: | |||||||
|  |  | ||||||
|     std::vector<uint8_t> tcm; |     std::vector<uint8_t> tcm; | ||||||
|  |  | ||||||
|     iss::status read_csr_reg(unsigned addr, reg_t& val); |     iss::status read_plain(unsigned addr, reg_t& val); | ||||||
|     iss::status write_csr_reg(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 read_null(unsigned addr, reg_t& val); | ||||||
|     iss::status write_null(unsigned addr, reg_t val) { return iss::status::Ok; } |     iss::status write_null(unsigned addr, reg_t val) { return iss::status::Ok; } | ||||||
|     iss::status read_cycle(unsigned addr, reg_t& val); |     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 read_intstatus(unsigned addr, reg_t& val); | ||||||
|     iss::status write_intthresh(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_xtvt(unsigned addr, reg_t val); | ||||||
|     iss::status write_dcsr_dcsr(unsigned addr, reg_t val); |     iss::status write_dcsr(unsigned addr, reg_t val); | ||||||
|     iss::status read_dcsr_reg(unsigned addr, reg_t& val); |     iss::status read_debug(unsigned addr, reg_t& val); | ||||||
|     iss::status write_dcsr_reg(unsigned addr, reg_t val); |     iss::status write_dscratch(unsigned addr, reg_t val); | ||||||
|     iss::status read_dpc_reg(unsigned addr, reg_t& val); |     iss::status read_dpc(unsigned addr, reg_t& val); | ||||||
|     iss::status write_dpc_reg(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 read_custom_csr(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 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_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; } |     void register_custom_csr_wr(unsigned addr) { csr_wr_cb[addr] = &this_class::write_custom_csr; } | ||||||
|  |  | ||||||
|     reg_t mhartid_reg{0x0}; |     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; |     csr[mimpid] = 1; | ||||||
|  |  | ||||||
|     uart_buf.str(""); |     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) { |     for(unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_null; |         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) |     if(traits<BASE>::XLEN == 32) | ||||||
|         for(unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr) { |         for(unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr) { | ||||||
|             csr_rd_cb[addr] = &this_class::read_null; |             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) { |     for(unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_null; |         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) { |     for(unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_null; |         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) |     if(traits<BASE>::XLEN == 32) | ||||||
|         for(unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr) { |         for(unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr) { | ||||||
|             csr_rd_cb[addr] = &this_class::read_null; |             csr_rd_cb[addr] = &this_class::read_null; | ||||||
|             // csr_wr_cb[addr] = &this_class::write_csr_reg; |  | ||||||
|         } |         } | ||||||
|     // common regs |     // common regs | ||||||
|     const std::array<unsigned, 4> roaddrs{{misa, mvendorid, marchid, mimpid}}; |     const std::array<unsigned, 4> roaddrs{{misa, mvendorid, marchid, mimpid}}; | ||||||
|     for(auto addr : roaddrs) { |     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; |         csr_wr_cb[addr] = &this_class::write_null; | ||||||
|     } |     } | ||||||
|     const std::array<unsigned, 4> rwaddrs{{mepc, mtvec, mscratch, mtval}}; |     const std::array<unsigned, 4> rwaddrs{{mepc, mtvec, mscratch, mtval}}; | ||||||
|     for(auto addr : rwaddrs) { |     for(auto addr : rwaddrs) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_csr_reg; |         csr_rd_cb[addr] = &this_class::read_plain; | ||||||
|         csr_wr_cb[addr] = &this_class::write_csr_reg; |         csr_wr_cb[addr] = &this_class::write_plain; | ||||||
|     } |     } | ||||||
|     // special handling & overrides |     // special handling & overrides | ||||||
|     csr_rd_cb[time] = &this_class::read_time; |     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[marchid] = &this_class::write_null; | ||||||
|     csr_wr_cb[mimpid] = &this_class::write_null; |     csr_wr_cb[mimpid] = &this_class::write_null; | ||||||
|     if(FEAT & FEAT_CLIC) { |     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_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; | ||||||
| @@ -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_wr_cb[mscratchcsw] = &this_class::write_csr_reg; | ||||||
|         //        csr_rd_cb[mscratchcswl] = &this_class::read_csr_reg; |         //        csr_rd_cb[mscratchcswl] = &this_class::read_csr_reg; | ||||||
|         //        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_plain; | ||||||
|         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; | ||||||
| @@ -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); |         insert_mem_range(cfg.tcm_base, cfg.tcm_size, read_clic_cb, write_clic_cb); | ||||||
|     } |     } | ||||||
|     if(FEAT & FEAT_DEBUG) { |     if(FEAT & FEAT_DEBUG) { | ||||||
|         csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; |         csr_wr_cb[dscratch0] = &this_class::write_dscratch; | ||||||
|         csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; |         csr_rd_cb[dscratch0] = &this_class::read_debug; | ||||||
|         csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg; |         csr_wr_cb[dscratch1] = &this_class::write_dscratch; | ||||||
|         csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg; |         csr_rd_cb[dscratch1] = &this_class::read_debug; | ||||||
|         csr_wr_cb[dpc] = &this_class::write_dpc_reg; |         csr_wr_cb[dpc] = &this_class::write_dpc; | ||||||
|         csr_rd_cb[dpc] = &this_class::read_dpc_reg; |         csr_rd_cb[dpc] = &this_class::read_dpc; | ||||||
|         csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; |         csr_wr_cb[dcsr] = &this_class::write_dcsr; | ||||||
|         csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; |         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_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); }; |     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}; |                 phys_addr_t phys_addr{access, space, addr}; | ||||||
|                 auto res = iss::Err; |                 auto res = iss::Err; | ||||||
|                 if(access != access_type::FETCH && memfn_range.size()) { |                 if(!is_fetch(access) && memfn_range.size()) { | ||||||
|                     auto it = |                     auto it = | ||||||
|                         std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a) { |                         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; |                             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: { |         case traits<BASE>::CSR: { | ||||||
|             if(length != sizeof(reg_t)) |             if(length != sizeof(reg_t)) | ||||||
|                 return iss::Err; |                 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)); |             return read_csr(addr, *reinterpret_cast<reg_t* const>(data)); | ||||||
|         } break; |         } break; | ||||||
|         case traits<BASE>::FENCE: { |         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}; |                 phys_addr_t phys_addr{access, space, addr}; | ||||||
|                 auto res = iss::Err; |                 auto res = iss::Err; | ||||||
|                 if(access != access_type::FETCH && memfn_range.size()) { |                 if(!is_fetch(access) && memfn_range.size()) { | ||||||
|                     auto it = |                     auto it = | ||||||
|                         std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a) { |                         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; |                             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 |             case 0x10023000: // UART1 base, TXFIFO reg | ||||||
|                 uart_buf << (char)data[0]; |                 uart_buf << (char)data[0]; | ||||||
|                 if(((char)data[0]) == '\n' || data[0] == 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(); |                     std::cout << uart_buf.str(); | ||||||
|                     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: { |         case traits<BASE>::CSR: { | ||||||
|             if(length != sizeof(reg_t)) |             if(length != sizeof(reg_t)) | ||||||
|                 return iss::Err; |                 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)); |             return write_csr(addr, *reinterpret_cast<const reg_t*>(data)); | ||||||
|         } break; |         } break; | ||||||
|         case traits<BASE>::FENCE: { |         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); |     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> | template <typename BASE, features_e FEAT, typename LOGCAT> | ||||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) { | iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) { | ||||||
|     val = 0; |     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> | 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; |     csr[addr] = val; | ||||||
|     return iss::Ok; |     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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     //                  +-------------- ebreakm |     //                  +-------------- 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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     val = csr[addr]; |     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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     csr[addr] = val; |     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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     val = this->reg.DPC; |     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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     this->reg.DPC = val; |     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; |     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> | template <typename BASE, features_e FEAT, typename LOGCAT> | ||||||
| iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_intthresh(unsigned addr, reg_t val) { | 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; |     csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1; | ||||||
|   | |||||||
| @@ -39,7 +39,9 @@ | |||||||
| #include "iss/instrumentation_if.h" | #include "iss/instrumentation_if.h" | ||||||
| #include "iss/log_categories.h" | #include "iss/log_categories.h" | ||||||
| #include "iss/vm_if.h" | #include "iss/vm_if.h" | ||||||
|  | #include "iss/vm_types.h" | ||||||
| #include "riscv_hart_common.h" | #include "riscv_hart_common.h" | ||||||
|  | #include <stdexcept> | ||||||
| #ifndef FMT_HEADER_ONLY | #ifndef FMT_HEADER_ONLY | ||||||
| #define FMT_HEADER_ONLY | #define FMT_HEADER_ONLY | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -39,7 +39,9 @@ | |||||||
| #include "iss/instrumentation_if.h" | #include "iss/instrumentation_if.h" | ||||||
| #include "iss/log_categories.h" | #include "iss/log_categories.h" | ||||||
| #include "iss/vm_if.h" | #include "iss/vm_if.h" | ||||||
|  | #include "iss/vm_types.h" | ||||||
| #include "riscv_hart_common.h" | #include "riscv_hart_common.h" | ||||||
|  | #include <stdexcept> | ||||||
| #ifndef FMT_HEADER_ONLY | #ifndef FMT_HEADER_ONLY | ||||||
| #define FMT_HEADER_ONLY | #define FMT_HEADER_ONLY | ||||||
| #endif | #endif | ||||||
| @@ -302,7 +304,7 @@ public: | |||||||
|     void set_mhartid(reg_t mhartid) { mhartid_reg = mhartid; }; |     void set_mhartid(reg_t mhartid) { mhartid_reg = mhartid; }; | ||||||
|  |  | ||||||
|     void disass_output(uint64_t pc, const std::string instr) override { |     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, |         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); |                                             this->reg.icount + cycle_offset); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -402,8 +404,8 @@ protected: | |||||||
|  |  | ||||||
|     std::vector<uint8_t> tcm; |     std::vector<uint8_t> tcm; | ||||||
|  |  | ||||||
|     iss::status read_csr_reg(unsigned addr, reg_t& val); |     iss::status read_plain(unsigned addr, reg_t& val); | ||||||
|     iss::status write_csr_reg(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 read_null(unsigned addr, reg_t& val); | ||||||
|     iss::status write_null(unsigned addr, reg_t val) { return iss::status::Ok; } |     iss::status write_null(unsigned addr, reg_t val) { return iss::status::Ok; } | ||||||
|     iss::status read_cycle(unsigned addr, reg_t& val); |     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 read_intstatus(unsigned addr, reg_t& val); | ||||||
|     iss::status write_intthresh(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_xtvt(unsigned addr, reg_t val); | ||||||
|     iss::status write_dcsr_dcsr(unsigned addr, reg_t val); |     iss::status write_dcsr(unsigned addr, reg_t val); | ||||||
|     iss::status read_dcsr_reg(unsigned addr, reg_t& val); |     iss::status read_debug(unsigned addr, reg_t& val); | ||||||
|     iss::status write_dcsr_reg(unsigned addr, reg_t val); |     iss::status write_dscratch(unsigned addr, reg_t val); | ||||||
|     iss::status read_dpc_reg(unsigned addr, reg_t& val); |     iss::status read_dpc(unsigned addr, reg_t& val); | ||||||
|     iss::status write_dpc_reg(unsigned addr, reg_t val); |     iss::status write_dpc(unsigned addr, reg_t val); | ||||||
|     iss::status write_pmpcfg_reg(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 read_custom_csr(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 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_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_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; |     csr[mimpid] = 1; | ||||||
|  |  | ||||||
|     uart_buf.str(""); |     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) { |     for(unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_null; |         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) |     if(traits<BASE>::XLEN == 32) | ||||||
|         for(unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr) { |         for(unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr) { | ||||||
|             csr_rd_cb[addr] = &this_class::read_null; |             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) { |     for(unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_null; |         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) { |     for(unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_null; |         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) |     if(traits<BASE>::XLEN == 32) | ||||||
|         for(unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr) { |         for(unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr) { | ||||||
|             csr_rd_cb[addr] = &this_class::read_null; |             csr_rd_cb[addr] = &this_class::read_null; | ||||||
|             // csr_wr_cb[addr] = &this_class::write_csr_reg; |  | ||||||
|         } |         } | ||||||
|     // common regs |     // common regs | ||||||
|     const std::array<unsigned, 4> roaddrs{{misa, mvendorid, marchid, mimpid}}; |     const std::array<unsigned, 4> roaddrs{{misa, mvendorid, marchid, mimpid}}; | ||||||
|     for(auto addr : roaddrs) { |     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; |         csr_wr_cb[addr] = &this_class::write_null; | ||||||
|     } |     } | ||||||
|     const std::array<unsigned, 8> rwaddrs{{ |     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, |         utval, | ||||||
|     }}; |     }}; | ||||||
|     for(auto addr : rwaddrs) { |     for(auto addr : rwaddrs) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_csr_reg; |         csr_rd_cb[addr] = &this_class::read_plain; | ||||||
|         csr_wr_cb[addr] = &this_class::write_csr_reg; |         csr_wr_cb[addr] = &this_class::write_plain; | ||||||
|     } |     } | ||||||
|     // special handling & overrides |     // special handling & overrides | ||||||
|     csr_rd_cb[time] = &this_class::read_time; |     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) { |     if(FEAT & FEAT_PMP) { | ||||||
|         for(size_t i = pmpaddr0; i <= pmpaddr15; ++i) { |         for(size_t i = pmpaddr0; i <= pmpaddr15; ++i) { | ||||||
|             csr_rd_cb[i] = &this_class::read_csr_reg; |             csr_rd_cb[i] = &this_class::read_plain; | ||||||
|             csr_wr_cb[i] = &this_class::write_csr_reg; |             csr_wr_cb[i] = &this_class::write_plain; | ||||||
|         } |         } | ||||||
|         for(size_t i = pmpcfg0; i < pmpcfg0 + 16 / sizeof(reg_t); ++i) { |         for(size_t i = pmpcfg0; i < pmpcfg0 + 16 / sizeof(reg_t); ++i) { | ||||||
|             csr_rd_cb[i] = &this_class::read_csr_reg; |             csr_rd_cb[i] = &this_class::read_plain; | ||||||
|             csr_wr_cb[i] = &this_class::write_pmpcfg_reg; |             csr_wr_cb[i] = &this_class::write_pmpcfg; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if(FEAT & FEAT_EXT_N) { |     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_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_wr_cb[medeleg] = &this_class::write_edeleg; | ||||||
|         csr_rd_cb[uie] = &this_class::read_ie; |         csr_rd_cb[uie] = &this_class::read_ie; | ||||||
|         csr_wr_cb[uie] = &this_class::write_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; |         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_plain; | ||||||
|         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; | ||||||
| @@ -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_wr_cb[mscratchcsw] = &this_class::write_csr_reg; | ||||||
|         //        csr_rd_cb[mscratchcswl] = &this_class::read_csr_reg; |         //        csr_rd_cb[mscratchcswl] = &this_class::read_csr_reg; | ||||||
|         //        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_plain; | ||||||
|         csr_wr_cb[mintthresh] = &this_class::write_intthresh; |         csr_wr_cb[mintthresh] = &this_class::write_intthresh; | ||||||
|         if(FEAT & FEAT_EXT_N) { |         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_wr_cb[utvt] = &this_class::write_xtvt; | ||||||
|             csr_rd_cb[uintstatus] = &this_class::read_intstatus; |             csr_rd_cb[uintstatus] = &this_class::read_intstatus; | ||||||
|             csr_wr_cb[uintstatus] = &this_class::write_null; |             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; |             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}); | ||||||
| @@ -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); |         insert_mem_range(cfg.tcm_base, cfg.tcm_size, read_clic_cb, write_clic_cb); | ||||||
|     } |     } | ||||||
|     if(FEAT & FEAT_DEBUG) { |     if(FEAT & FEAT_DEBUG) { | ||||||
|         csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; |         csr_wr_cb[dscratch0] = &this_class::write_dscratch; | ||||||
|         csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; |         csr_rd_cb[dscratch0] = &this_class::read_debug; | ||||||
|         csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg; |         csr_wr_cb[dscratch1] = &this_class::write_dscratch; | ||||||
|         csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg; |         csr_rd_cb[dscratch1] = &this_class::read_debug; | ||||||
|         csr_wr_cb[dpc] = &this_class::write_dpc_reg; |         csr_wr_cb[dpc] = &this_class::write_dpc; | ||||||
|         csr_rd_cb[dpc] = &this_class::read_dpc_reg; |         csr_rd_cb[dpc] = &this_class::read_dpc; | ||||||
|         csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; |         csr_wr_cb[dcsr] = &this_class::write_dcsr; | ||||||
|         csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; |         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_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); }; |     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> | 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; |     csr[addr] = val & 0x9f9f9f9f; | ||||||
|     return iss::Ok; |     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 |             case 0x10023000: // UART1 base, TXFIFO reg | ||||||
|                 uart_buf << (char)data[0]; |                 uart_buf << (char)data[0]; | ||||||
|                 if(((char)data[0]) == '\n' || data[0] == 0) { |                 if(((char)data[0]) == '\n' || data[0] == 0) { | ||||||
|                     // CPPLOG(INFO)<<"UART"<<((addr>>16)&0x3)<<" send |  | ||||||
|                     // '"<<uart_buf.str()<<"'"; |  | ||||||
|                     std::cout << uart_buf.str(); |                     std::cout << uart_buf.str(); | ||||||
|                     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); |     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> | template <typename BASE, features_e FEAT, typename LOGCAT> | ||||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) { | iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) { | ||||||
|     val = 0; |     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> | 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; |     csr[addr] = val; | ||||||
|     return iss::Ok; |     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; |     val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2; | ||||||
|     return iss::Ok; |     return iss::Ok; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename BASE, features_e FEAT, typename LOGCAT> | template <typename BASE, features_e FEAT, typename LOGCAT> | ||||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_status(unsigned addr, reg_t& val) { | 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); |     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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     //                  +-------------- ebreakm |     //                  +-------------- 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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     val = csr[addr]; |     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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     csr[addr] = val; |     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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     val = this->reg.DPC; |     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> | 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()) |     if(!debug_mode_active()) | ||||||
|         throw illegal_instruction_fault(this->fault_data); |         throw illegal_instruction_fault(this->fault_data); | ||||||
|     this->reg.DPC = val; |     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; |     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> | template <typename BASE, features_e FEAT, typename LOGCAT> | ||||||
| iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_intthresh(unsigned addr, reg_t val) { | 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; |     csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user