diff --git a/gen_input/templates/CORENAME.cpp.gtl b/gen_input/templates/CORENAME.cpp.gtl index b7468c7..ebdff65 100644 --- a/gen_input/templates/CORENAME.cpp.gtl +++ b/gen_input/templates/CORENAME.cpp.gtl @@ -70,7 +70,7 @@ uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { return reinterpret_cast(®); } -${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &pc) { - return phys_addr_t(pc); // change logical address to physical address +${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &addr) { + return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask); } diff --git a/gen_input/templates/CORENAME.h.gtl b/gen_input/templates/CORENAME.h.gtl index 2debd97..96ba762 100644 --- a/gen_input/templates/CORENAME.h.gtl +++ b/gen_input/templates/CORENAME.h.gtl @@ -137,14 +137,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { inline uint64_t stop_code() { return interrupt_sim; } - inline phys_addr_t v2p(const iss::addr_t& addr){ - if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL || - addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { - return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask); - } else - return virt2phys(addr); - } - virtual phys_addr_t virt2phys(const iss::addr_t& addr); virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } diff --git a/src/iss/arch/riscv_hart_m_p.h b/src/iss/arch/riscv_hart_m_p.h index 5df25e2..632bdd2 100644 --- a/src/iss/arch/riscv_hart_m_p.h +++ b/src/iss/arch/riscv_hart_m_p.h @@ -666,7 +666,7 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce fault_data=addr; return iss::Err; } - auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr}); + phys_addr_t phys_addr{access, space, addr}; auto res = iss::Err; if(access != access_type::FETCH && memfn_range.size()){ auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){ @@ -759,7 +759,7 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc fault_data=addr; return iss::Err; } - auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr}); + phys_addr_t phys_addr{access, space, addr}; auto res = iss::Err; if(access != access_type::FETCH && memfn_range.size()){ auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){ @@ -784,9 +784,8 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc return iss::Err; } - phys_addr_t paddr = BASE::v2p(iss::addr_t{access, type, space, addr}); - if ((paddr.val + length) > mem.size()) return iss::Err; - switch (paddr.val) { + if ((addr + length) > mem.size()) return iss::Err; + switch (addr) { case 0x10013000: // UART0 base, TXFIFO reg case 0x10023000: // UART1 base, TXFIFO reg uart_buf << (char)data[0]; @@ -798,16 +797,16 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc } return iss::Ok; case 0x10008000: { // HFROSC base, hfrosccfg reg - auto &p = mem(paddr.val / mem.page_size); - auto offs = paddr.val & mem.page_addr_mask; + auto &p = mem(addr / mem.page_size); + auto offs = addr & mem.page_addr_mask; std::copy(data, data + length, p.data() + offs); auto &x = *(p.data() + offs + 3); if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1 return iss::Ok; } case 0x10008008: { // HFROSC base, pllcfg reg - auto &p = mem(paddr.val / mem.page_size); - auto offs = paddr.val & mem.page_addr_mask; + auto &p = mem(addr / mem.page_size); + auto offs = addr & mem.page_addr_mask; std::copy(data, data + length, p.data() + offs); auto &x = *(p.data() + offs + 3); x |= 0x80; // set pll lock upon writing diff --git a/src/iss/arch/riscv_hart_msu_vp.h b/src/iss/arch/riscv_hart_msu_vp.h index b107aac..23a805b 100644 --- a/src/iss/arch/riscv_hart_msu_vp.h +++ b/src/iss/arch/riscv_hart_msu_vp.h @@ -430,6 +430,7 @@ template riscv_hart_msu_vp::riscv_hart_msu_vp() : state() , instr_if(*this) { + this->_has_mmu = true; // reset values csr[misa] = traits::MISA_VAL; csr[mvendorid] = 0x669; @@ -632,9 +633,7 @@ iss::status riscv_hart_msu_vp::read(const address_type type, const access_ return res; } } - 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); + auto res = 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 fault_data=addr; @@ -719,6 +718,7 @@ iss::status riscv_hart_msu_vp::write(const address_type type, const access this->reg.trap_state = (1 << 31); // issue trap 0 return iss::Err; } + phys_addr_t paddr = BASE::v2p(iss::addr_t{access, type, space, addr}); try { if (unlikely((addr & ~PGMASK) != ((addr + length - 1) & ~PGMASK))) { // we may cross a page boundary vm_info vm = hart_state_type::decode_vm_info(this->reg.PRIV, state.satp); @@ -731,9 +731,7 @@ iss::status riscv_hart_msu_vp::write(const address_type type, const access return res; } } - 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); + auto res = write_mem(paddr, length, data); if (unlikely(res != iss::Ok)) { this->reg.trap_state = (1UL << 31) | (7UL << 16); // issue trap 7 (Store/AMO access fault) fault_data=addr; @@ -745,7 +743,6 @@ iss::status riscv_hart_msu_vp::write(const address_type type, const access return iss::Err; } - phys_addr_t paddr = BASE::v2p(iss::addr_t{access, type, space, addr}); if ((paddr.val + length) > mem.size()) return iss::Err; switch (paddr.val) { case 0x10013000: // UART0 base, TXFIFO reg diff --git a/src/iss/arch/riscv_hart_mu_p.h b/src/iss/arch/riscv_hart_mu_p.h index 6ac7d9b..da30b21 100644 --- a/src/iss/arch/riscv_hart_mu_p.h +++ b/src/iss/arch/riscv_hart_mu_p.h @@ -834,7 +834,7 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc fault_data=addr; return iss::Err; } - auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr}); + phys_addr_t phys_addr{access, space, addr}; auto res = iss::Err; if(!is_fetch(access) && memfn_range.size()){ auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){ @@ -935,7 +935,7 @@ iss::status riscv_hart_mu_p::write(const address_type type, const ac fault_data=addr; return iss::Err; } - auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr}); + phys_addr_t phys_addr{access, space, addr}; auto res = iss::Err; if(!is_fetch(access) && memfn_range.size()){ auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){ @@ -960,30 +960,29 @@ iss::status riscv_hart_mu_p::write(const address_type type, const ac return iss::Err; } - phys_addr_t paddr = BASE::v2p(iss::addr_t{access, type, space, addr}); - if ((paddr.val + length) > mem.size()) return iss::Err; - switch (paddr.val) { + if ((addr + length) > mem.size()) return iss::Err; + switch (addr) { case 0x10013000: // UART0 base, TXFIFO reg case 0x10023000: // UART1 base, TXFIFO reg uart_buf << (char)data[0]; if (((char)data[0]) == '\n' || data[0] == 0) { - // LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send + // LOG(INFO)<<"UART"<<((addr>>16)&0x3)<<" send // '"<(®); } -tgc_c::phys_addr_t tgc_c::virt2phys(const iss::addr_t &pc) { - return phys_addr_t(pc); // change logical address to physical address +tgc_c::phys_addr_t tgc_c::virt2phys(const iss::addr_t &addr) { + return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); } diff --git a/src/iss/arch/tgc_c.h b/src/iss/arch/tgc_c.h index 2f33ca5..af3b3ba 100644 --- a/src/iss/arch/tgc_c.h +++ b/src/iss/arch/tgc_c.h @@ -195,14 +195,6 @@ struct tgc_c: public arch_if { inline uint64_t stop_code() { return interrupt_sim; } - inline phys_addr_t v2p(const iss::addr_t& addr){ - if (addr.space != traits::MEM || addr.type == iss::address_type::PHYSICAL || - addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { - return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); - } else - return virt2phys(addr); - } - virtual phys_addr_t virt2phys(const iss::addr_t& addr); virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } @@ -262,7 +254,6 @@ struct tgc_c: public arch_if { uint32_t get_fcsr(){return 0;} void set_fcsr(uint32_t val){} - }; } diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index e070215..8ad108e 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -259,15 +259,22 @@ private: }}; iss::status fetch_ins(virt_addr_t pc, uint8_t * data){ - auto phys_pc = this->core.v2p(pc); - //TODO: re-add page handling - //if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary - // if (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err; - // if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction - // if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) return iss::Err; - //} else { - if (this->core.read(phys_pc, 4, data) != iss::Ok) return iss::Err; - //} + if(this->core.has_mmu()) { + auto phys_pc = this->core.virt2phys(pc); +// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary +// if (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err; +// if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction +// if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) +// return iss::Err; +// } else { + if (this->core.read(phys_pc, 4, data) != iss::Ok) + return iss::Err; +// } + } else { + if (this->core.read(phys_addr_t(pc.access, pc.space, pc.val), 4, data) != iss::Ok) + return iss::Err; + + } return iss::Ok; } void populate_decoding_tree(decoding_tree_node* root){ diff --git a/src/vm/llvm/vm_tgc_c.cpp b/src/vm/llvm/vm_tgc_c.cpp index f289f0c..d256089 100644 --- a/src/vm/llvm/vm_tgc_c.cpp +++ b/src/vm/llvm/vm_tgc_c.cpp @@ -4085,7 +4085,8 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, // const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); auto *const data = (uint8_t *)&insn; - paddr = this->core.v2p(pc); + if(this->core.has_mmu()) + paddr = this->core.virt2phys(pc); //TODO: re-add page handling // if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary // auto res = this->core.read(paddr, 2, data); diff --git a/src/vm/tcc/vm_tgc_c.cpp b/src/vm/tcc/vm_tgc_c.cpp index eeca8ec..1be78b8 100644 --- a/src/vm/tcc/vm_tgc_c.cpp +++ b/src/vm/tcc/vm_tgc_c.cpp @@ -3174,7 +3174,8 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, enum {TRAP_ID=1<<16}; code_word_t instr = 0; phys_addr_t paddr(pc); - paddr = this->core.v2p(pc); + if(this->core.has_mmu()) + paddr = this->core.virt2phys(pc); //TODO: re-add page handling // if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary // auto res = this->core.read(paddr, 2, data);