Compare commits
	
		
			1 Commits
		
	
	
		
			23b9741adf
			...
			2f4b5bd9b2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2f4b5bd9b2 | 
 Submodule gen_input/CoreDSL-Instruction-Set-Description updated: 0c70a41376...98cddb2999
									
								
							| @@ -152,16 +152,28 @@ public: | ||||
|             mstatus = new_val; | ||||
|         } | ||||
|  | ||||
|         T satp; | ||||
|  | ||||
|         static constexpr uint32_t get_mask() { | ||||
|             return 0x807ff9ddUL; // 0b1000 0000 0111 1111 1111 1001 1011 1011  // only machine mode is supported | ||||
|             //return 0x807ff988UL; // 0b1000 0000 0111 1111 1111 1000 1000 1000  // only machine mode is supported | ||||
|             //       +-SD | ||||
|             //       |        +-TSR | ||||
|             //       |        |+-TW | ||||
|             //       |        ||+-TVM | ||||
|             //       |        |||+-MXR | ||||
|             //       |        ||||+-SUM | ||||
|             //       |        |||||+-MPRV | ||||
|             //       |        |||||| +-XS | ||||
|             //       |        |||||| | +-FS | ||||
|             //       |        |||||| | | +-MPP | ||||
|             //       |        |||||| | | |  +-SPP | ||||
|             //       |        |||||| | | |  |+-MPIE | ||||
|             //       |        ||||||/|/|/|  ||   +-MIE | ||||
|             return 0b00000000000000000001100010001000; | ||||
|         } | ||||
|     }; | ||||
|     using hart_state_type = hart_state<reg_t>; | ||||
|  | ||||
|     constexpr reg_t get_irq_mask() { | ||||
|         return 0b101110111011; // only machine mode is supported | ||||
|         return 0b100010001000; // only machine mode is supported | ||||
|     } | ||||
|  | ||||
|     riscv_hart_m_p(); | ||||
| @@ -286,7 +298,12 @@ template <typename BASE> | ||||
| riscv_hart_m_p<BASE>::riscv_hart_m_p() | ||||
| : state() | ||||
| , instr_if(*this) { | ||||
|     // reset values | ||||
|     csr[misa] = traits<BASE>::MISA_VAL; | ||||
|     csr[mvendorid] = 0x669; | ||||
|     csr[marchid] = 0x80000003; | ||||
|     csr[mimpid] = 1; | ||||
|  | ||||
|     uart_buf.str(""); | ||||
|     for (unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr){ | ||||
|         csr_rd_cb[addr] = &this_class::read_null; | ||||
| @@ -309,7 +326,7 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p() | ||||
|         csr_wr_cb[addr] = &this_class::write_reg; | ||||
|     } | ||||
|     // common regs | ||||
|     const std::array<unsigned, 7> addrs{{misa, mepc, mtvec, mscratch, mcause, mtval, mscratch}}; | ||||
|     const std::array<unsigned, 10> addrs{{misa, mvendorid, marchid, mimpid, mepc, mtvec, mscratch, mcause, mtval, mscratch}}; | ||||
|     for(auto addr: addrs) { | ||||
|         csr_rd_cb[addr] = &this_class::read_reg; | ||||
|         csr_wr_cb[addr] = &this_class::write_reg; | ||||
| @@ -338,6 +355,9 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p() | ||||
|     csr_wr_cb[mcounteren] = &this_class::write_null; | ||||
|     csr_rd_cb[mtvec] = &this_class::read_mtvec; | ||||
|     csr_wr_cb[misa] = &this_class::write_null; | ||||
|     csr_wr_cb[mvendorid] = &this_class::write_null; | ||||
|     csr_wr_cb[marchid] = &this_class::write_null; | ||||
|     csr_wr_cb[mimpid] = &this_class::write_null; | ||||
| } | ||||
|  | ||||
| template <typename BASE> std::pair<uint64_t, bool> riscv_hart_m_p<BASE>::load_file(std::string name, int type) { | ||||
| @@ -406,13 +426,23 @@ iss::status riscv_hart_m_p<BASE>::read(const address_type type, const access_typ | ||||
|                 return iss::Err; | ||||
|             } | ||||
|             try { | ||||
|                 auto alignment = access == iss::access_type::FETCH? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length; | ||||
|                 if(alignment>1 && (addr&(alignment-1))){ | ||||
|                     this->reg.trap_state = 1<<31 | 4<<16; | ||||
|                     fault_data=addr; | ||||
|                     return iss::Err; | ||||
|                 } | ||||
|                 auto res = type==iss::address_type::PHYSICAL? | ||||
|                         read_mem( BASE::v2p(phys_addr_t{access, space, addr}), length, data): | ||||
|                         read_mem( BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); | ||||
|                 if (unlikely(res != iss::Ok)) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault | ||||
|                 if (unlikely(res != iss::Ok)){ | ||||
|                     this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault | ||||
|                     fault_data=addr; | ||||
|                 } | ||||
|                 return res; | ||||
|             } catch (trap_access &ta) { | ||||
|                 this->reg.trap_state = (1 << 31) | ta.id; | ||||
|                 fault_data=ta.addr; | ||||
|                 return iss::Err; | ||||
|             } | ||||
|         } break; | ||||
| @@ -438,6 +468,7 @@ iss::status riscv_hart_m_p<BASE>::read(const address_type type, const access_typ | ||||
|         return iss::Ok; | ||||
|     } catch (trap_access &ta) { | ||||
|         this->reg.trap_state = (1 << 31) | ta.id; | ||||
|         fault_data=ta.addr; | ||||
|         return iss::Err; | ||||
|     } | ||||
| } | ||||
| @@ -478,14 +509,22 @@ iss::status riscv_hart_m_p<BASE>::write(const address_type type, const access_ty | ||||
|                 return iss::Err; | ||||
|             } | ||||
|             try { | ||||
|                 if(length>1 && (addr&(length-1))){ | ||||
|                     this->reg.trap_state = 1<<31 | 6<<16; | ||||
|                     fault_data=addr; | ||||
|                     return iss::Err; | ||||
|                 } | ||||
|                 auto res = type==iss::address_type::PHYSICAL? | ||||
|                         write_mem(phys_addr_t{access, space, addr}, length, data): | ||||
|                         write_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); | ||||
|                 if (unlikely(res != iss::Ok)) | ||||
|                     this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault) | ||||
|                 if (unlikely(res != iss::Ok)) { | ||||
|                     this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) | ||||
|                     fault_data=addr; | ||||
|                 } | ||||
|                 return res; | ||||
|             } catch (trap_access &ta) { | ||||
|                 this->reg.trap_state = (1 << 31) | ta.id; | ||||
|                 fault_data=ta.addr; | ||||
|                 return iss::Err; | ||||
|             } | ||||
|  | ||||
| @@ -545,6 +584,7 @@ iss::status riscv_hart_m_p<BASE>::write(const address_type type, const access_ty | ||||
|         return iss::Ok; | ||||
|     } catch (trap_access &ta) { | ||||
|         this->reg.trap_state = (1 << 31) | ta.id; | ||||
|         fault_data=ta.addr; | ||||
|         return iss::Err; | ||||
|     } | ||||
| } | ||||
| @@ -670,7 +710,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_status(unsigned | ||||
|  | ||||
| template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ie(unsigned addr, reg_t &val) { | ||||
|     val = csr[mie]; | ||||
|     val &= csr[mideleg]; | ||||
|     //val &= csr[mideleg]; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| @@ -688,7 +728,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_ie(unsigned add | ||||
|  | ||||
| template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ip(unsigned addr, reg_t &val) { | ||||
|     val = csr[mip]; | ||||
|     val &= csr[mideleg]; | ||||
|     //val &= csr[mideleg]; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| @@ -727,7 +767,6 @@ iss::status riscv_hart_m_p<BASE>::read_mem(phys_addr_t paddr, unsigned length, u | ||||
|  | ||||
| template <typename BASE> | ||||
| iss::status riscv_hart_m_p<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { | ||||
|     if ((paddr.val + length) > mem.size()) return iss::Err; | ||||
|     if(mem_write_cb) return mem_write_cb(paddr, length, data); | ||||
|     switch (paddr.val) { | ||||
|     case 0x10013000: // UART0 base, TXFIFO reg | ||||
| @@ -808,7 +847,7 @@ template <typename BASE> inline void riscv_hart_m_p<BASE>::reset(uint64_t addres | ||||
| } | ||||
|  | ||||
| template <typename BASE> void riscv_hart_m_p<BASE>::check_interrupt() { | ||||
|     auto ideleg = csr[mideleg]; | ||||
|     //auto ideleg = csr[mideleg]; | ||||
|     // Multiple simultaneous interrupts and traps at the same privilege level are | ||||
|     // handled in the following decreasing priority order: | ||||
|     // external interrupts, software interrupts, timer interrupts, then finally | ||||
| @@ -817,7 +856,7 @@ template <typename BASE> void riscv_hart_m_p<BASE>::check_interrupt() { | ||||
|  | ||||
|     bool mie = state.mstatus.MIE; | ||||
|     auto m_enabled = this->reg.PRIV < PRIV_M || (this->reg.PRIV == PRIV_M && mie); | ||||
|     auto enabled_interrupts = m_enabled ? ena_irq & ~ideleg : 0; | ||||
|     auto enabled_interrupts = m_enabled ? ena_irq /*& ~ideleg*/ : 0; | ||||
|  | ||||
|     if (enabled_interrupts != 0) { | ||||
|         int res = 0; | ||||
| @@ -839,7 +878,7 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag | ||||
|     if (trap_id == 0) { // exception | ||||
|         // store ret addr in xepc register | ||||
|         csr[mepc] = static_cast<reg_t>(addr); // store actual address instruction of exception | ||||
|         csr[mtval] = cause==2?instr:fault_data; | ||||
|         csr[mtval] = cause==2?((instr & 0x3)==3?instr:instr&0xffff):fault_data; | ||||
|         fault_data = 0; | ||||
|     } else { | ||||
|         csr[mepc] = this->reg.NEXT_PC; // store next address if interrupt | ||||
| @@ -877,9 +916,11 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag | ||||
|  | ||||
| template <typename BASE> uint64_t riscv_hart_m_p<BASE>::leave_trap(uint64_t flags) { | ||||
|     state.mstatus.MIE = state.mstatus.MPIE; | ||||
|     state.mstatus.MPIE = 1; | ||||
|     // sets the pc to the value stored in the x epc register. | ||||
|     this->reg.NEXT_PC = csr[mepc]; | ||||
|     CLOG(INFO, disass) << "Executing xRET"; | ||||
|     check_interrupt(); | ||||
|     return this->reg.NEXT_PC; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1228,15 +1228,18 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f | ||||
|         this->reg.PRIV = state.mstatus.MPP; | ||||
|         state.mstatus.MPP = 0; // clear mpp to U mode | ||||
|         state.mstatus.MIE = state.mstatus.MPIE; | ||||
|         state.mstatus.MPIE = 1; | ||||
|         break; | ||||
|     case PRIV_S: | ||||
|         this->reg.PRIV = state.mstatus.SPP; | ||||
|         state.mstatus.SPP = 0; // clear spp to U mode | ||||
|         state.mstatus.SIE = state.mstatus.SPIE; | ||||
|         state.mstatus.SPIE = 1; | ||||
|         break; | ||||
|     case PRIV_U: | ||||
|         this->reg.PRIV = 0; | ||||
|         state.mstatus.UIE = state.mstatus.UPIE; | ||||
|         state.mstatus.UPIE = 1; | ||||
|         break; | ||||
|     } | ||||
|     // sets the pc to the value stored in the x epc register. | ||||
| @@ -1244,6 +1247,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f | ||||
|     CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " | ||||
|                        << lvl[this->reg.PRIV]; | ||||
|     update_vm_info(); | ||||
|     check_interrupt(); | ||||
|     return this->reg.NEXT_PC; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -870,16 +870,19 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>:: | ||||
|         this->reg.PRIV = state.mstatus.MPP; | ||||
|         state.mstatus.MPP = 0; // clear mpp to U mode | ||||
|         state.mstatus.MIE = state.mstatus.MPIE; | ||||
|         state.mstatus.MPIE = 1; | ||||
|         break; | ||||
|     case PRIV_U: | ||||
|         this->reg.PRIV = 0; | ||||
|         state.mstatus.UIE = state.mstatus.UPIE; | ||||
|         state.mstatus.UPIE = 1; | ||||
|         break; | ||||
|     } | ||||
|     // sets the pc to the value stored in the x epc register. | ||||
|     this->reg.NEXT_PC = csr[uepc | inst_priv << 8]; | ||||
|     CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " | ||||
|                        << lvl[this->reg.PRIV]; | ||||
|     check_interrupt(); | ||||
|     return this->reg.NEXT_PC; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -53,7 +53,7 @@ template <> struct traits<tgc_c> { | ||||
|     static constexpr std::array<const char*, 35> reg_aliases{ | ||||
|         {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}}; | ||||
|  | ||||
|     enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b01000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0b111111111111, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, eei_aligned_addresses=1, MUL_LEN=64}; | ||||
|     enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b01000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0b111111111111, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; | ||||
|  | ||||
|     constexpr static unsigned FP_REGS_SIZE = 0; | ||||
|  | ||||
|   | ||||
| @@ -875,11 +875,8 @@ private: | ||||
|         try { | ||||
|         { | ||||
|             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||
|             if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0,  4);  | ||||
|             else { | ||||
|                 int16_t res = (int16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||
|                 if(rd != 0) *(X+rd) = res;  | ||||
|             } | ||||
|             int16_t res = (int16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||
|             if(rd != 0) *(X+rd) = res;  | ||||
|         } | ||||
|         } catch(...){} | ||||
|         // post execution stuff | ||||
| @@ -923,11 +920,8 @@ private: | ||||
|         try { | ||||
|         { | ||||
|             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||
|             if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0,  4);  | ||||
|             else { | ||||
|                 int32_t res = (int32_t)readSpace4(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||
|                 if(rd != 0) *(X+rd) = (uint32_t)res;  | ||||
|             } | ||||
|             int32_t res = (int32_t)readSpace4(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||
|             if(rd != 0) *(X+rd) = (uint32_t)res;  | ||||
|         } | ||||
|         } catch(...){} | ||||
|         // post execution stuff | ||||
| @@ -1015,11 +1009,8 @@ private: | ||||
|         try { | ||||
|         { | ||||
|             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||
|             if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0,  4);  | ||||
|             else { | ||||
|                 uint16_t res = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||
|                 if(rd != 0) *(X+rd) = res;  | ||||
|             } | ||||
|             uint16_t res = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||
|             if(rd != 0) *(X+rd) = res;  | ||||
|         } | ||||
|         } catch(...){} | ||||
|         // post execution stuff | ||||
| @@ -1104,8 +1095,7 @@ private: | ||||
|         try { | ||||
|         { | ||||
|             uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||
|             if(traits::eei_aligned_addresses && (store_address & 0x1)) raise(0,  6);  | ||||
|             else writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); | ||||
|             writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); | ||||
|         } | ||||
|         } catch(...){} | ||||
|         // post execution stuff | ||||
| @@ -1149,8 +1139,7 @@ private: | ||||
|         try { | ||||
|         { | ||||
|             uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||
|             if(traits::eei_aligned_addresses && (store_address & 0x3)) raise(0,  6);  | ||||
|             else writeSpace4(traits::MEM, store_address, *(X+rs2)); | ||||
|             writeSpace4(traits::MEM, store_address, *(X+rs2)); | ||||
|         } | ||||
|         } catch(...){} | ||||
|         // post execution stuff | ||||
| @@ -2929,8 +2918,7 @@ private: | ||||
|         try { | ||||
|         { | ||||
|             uint32_t load_address = *(X+(rs1 + 8)) + uimm; | ||||
|             if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0,  4);  | ||||
|             else *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address); | ||||
|             *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address); | ||||
|         } | ||||
|         } catch(...){} | ||||
|         // post execution stuff | ||||
| @@ -2974,8 +2962,7 @@ private: | ||||
|         try { | ||||
|         { | ||||
|             uint32_t load_address = *(X+(rs1 + 8)) + uimm; | ||||
|             if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0,  6);  | ||||
|             else writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8))); | ||||
|             writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8))); | ||||
|         } | ||||
|         } catch(...){} | ||||
|         // post execution stuff | ||||
| @@ -3759,8 +3746,7 @@ private: | ||||
|         try { | ||||
|         if(rd) { | ||||
|             uint32_t offs = *(X+2) + uimm; | ||||
|             if(traits::eei_aligned_addresses && (offs & 0x3)) raise(0,  4);  | ||||
|             else *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); | ||||
|             *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); | ||||
|         } | ||||
|         else raise(0, 2); | ||||
|         } catch(...){} | ||||
| @@ -4035,8 +4021,7 @@ private: | ||||
|         try { | ||||
|         { | ||||
|             uint32_t offs = *(X+2) + uimm; | ||||
|             if(traits::eei_aligned_addresses && (offs & 0x3)) raise(0,  4);  | ||||
|             else writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); | ||||
|             writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); | ||||
|         } | ||||
|         } catch(...){} | ||||
|         // post execution stuff | ||||
|   | ||||
		Reference in New Issue
	
	Block a user