Fixed handling of compressed ISA
This commit is contained in:
		| @@ -435,6 +435,8 @@ public: | ||||
|     virtual uint64_t leave_trap(uint64_t flags) override; | ||||
|     void wait_until(uint64_t flags) override; | ||||
|  | ||||
|     void notify_phase(iss::arch_if::exec_phase phase); | ||||
|  | ||||
|     void disass_output(uint64_t pc, const std::string instr) override { | ||||
|         std::stringstream s; | ||||
|         s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0') | ||||
| @@ -468,6 +470,7 @@ protected: | ||||
|  | ||||
| private: | ||||
|     iss::status read_cycle(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 write_status(unsigned addr, reg_t val); | ||||
|     iss::status read_ie(unsigned addr, reg_t &val); | ||||
| @@ -489,6 +492,10 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp() | ||||
|     for (unsigned addr = mcycle; addr <= hpmcounter31; ++addr) csr_wr_cb[addr] = nullptr; | ||||
|     for (unsigned addr = mcycleh; addr <= hpmcounter31h; ++addr) csr_wr_cb[addr] = nullptr; | ||||
|     // special handling | ||||
|     csr_rd_cb[time] = &riscv_hart_msu_vp<BASE>::read_time; | ||||
|     csr_wr_cb[time] = nullptr; | ||||
|     csr_rd_cb[timeh] = &riscv_hart_msu_vp<BASE>::read_time; | ||||
|     csr_wr_cb[timeh] = nullptr; | ||||
|     csr_rd_cb[mcycle] = &riscv_hart_msu_vp<BASE>::read_cycle; | ||||
|     csr_rd_cb[mcycleh] = &riscv_hart_msu_vp<BASE>::read_cycle; | ||||
|     csr_rd_cb[minstret] = &riscv_hart_msu_vp<BASE>::read_cycle; | ||||
| @@ -781,6 +788,17 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigne | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t &val) { | ||||
| 	uint64_t time_val=this->reg.icount>>12; | ||||
|     if (addr == time) { | ||||
|         val = static_cast<reg_t>(time_val); | ||||
|     } else if (addr == timeh) { | ||||
|         if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err; | ||||
|         val = static_cast<reg_t>(time_val >> 32); | ||||
|     } | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_status(unsigned addr, reg_t &val) { | ||||
|     auto req_priv_lvl = addr >> 8; | ||||
|     if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data); | ||||
| @@ -862,8 +880,9 @@ iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length | ||||
|     if ((paddr.val + length) > mem.size()) return iss::Err; | ||||
|     switch (paddr.val) { | ||||
|     case 0x0200BFF8: { // CLINT base, mtime reg | ||||
|         uint64_t mtime = this->reg.icount >> 12 /*12*/; | ||||
|         std::copy((uint8_t *)&mtime, ((uint8_t *)&mtime) + length, data); | ||||
|     	if(sizeof(reg_t)<length) return iss::Err; | ||||
|     	reg_t time_val=this->csr[time]; | ||||
|         std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data); | ||||
|     } break; | ||||
|     case 0x10008000: { | ||||
|         const mem_type::page_type &p = mem(paddr.val / mem.page_size); | ||||
| @@ -954,6 +973,11 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template<typename BASE> | ||||
| inline void riscv_hart_msu_vp<BASE>::notify_phase(iss::arch_if::exec_phase phase) { | ||||
| 	BASE::notify_phase(phase); | ||||
| } | ||||
|  | ||||
| template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() { | ||||
|     auto status = state.mstatus; | ||||
|     auto ip = csr[mip]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user