diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description index 0c70a41..98cddb2 160000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ b/gen_input/CoreDSL-Instruction-Set-Description @@ -1 +1 @@ -Subproject commit 0c70a41376fb3a529e4f56a9b9d7167c9613958e +Subproject commit 98cddb2999bfc05862a796b157500f7cd0f36ca4 diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 685bc69..699f341 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -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; 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 riscv_hart_m_p::riscv_hart_m_p() : state() , instr_if(*this) { + // reset values csr[misa] = traits::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::riscv_hart_m_p() csr_wr_cb[addr] = &this_class::write_reg; } // common regs - const std::array addrs{{misa, mepc, mtvec, mscratch, mcause, mtval, mscratch}}; + const std::array 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::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 std::pair riscv_hart_m_p::load_file(std::string name, int type) { @@ -406,13 +426,23 @@ iss::status riscv_hart_m_p::read(const address_type type, const access_typ return iss::Err; } try { + auto alignment = access == iss::access_type::FETCH? (traits::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::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::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::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 iss::status riscv_hart_m_p::write_status(unsigned template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t &val) { val = csr[mie]; - val &= csr[mideleg]; + //val &= csr[mideleg]; return iss::Ok; } @@ -688,7 +728,7 @@ template iss::status riscv_hart_m_p::write_ie(unsigned add template iss::status riscv_hart_m_p::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::read_mem(phys_addr_t paddr, unsigned length, u template iss::status riscv_hart_m_p::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 inline void riscv_hart_m_p::reset(uint64_t addres } template void riscv_hart_m_p::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 void riscv_hart_m_p::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 uint64_t riscv_hart_m_p::enter_trap(uint64_t flag if (trap_id == 0) { // exception // store ret addr in xepc register csr[mepc] = static_cast(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 uint64_t riscv_hart_m_p::enter_trap(uint64_t flag template uint64_t riscv_hart_m_p::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; } diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index ce63f8b..d9cb528 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -1228,15 +1228,18 @@ template uint64_t riscv_hart_msu_vp::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 uint64_t riscv_hart_msu_vp::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; } diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index cc4ebd9..50f4d5e 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -870,16 +870,19 @@ template uint64_t riscv_hart_mu_p:: 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; } diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index 037996a..16fa1b4 100644 --- a/incl/iss/arch/tgc_c.h +++ b/incl/iss/arch/tgc_c.h @@ -53,7 +53,7 @@ template <> struct traits { static constexpr std::array 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; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 1a1c244..9fb7759 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -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