From d160a34c5d02094e444c3e571857516304a622ed Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 12 Nov 2018 19:34:19 +0100 Subject: [PATCH] Refactored arch_if to save unneeded constructor calls --- dbt-core | 2 +- riscv/incl/iss/arch/riscv_hart_msu_vp.h | 90 ++++++++++--------- .../incl/iss/debugger/riscv_target_adapter.h | 3 +- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/dbt-core b/dbt-core index 54cf894..d73fee6 160000 --- a/dbt-core +++ b/dbt-core @@ -1 +1 @@ -Subproject commit 54cf894c3f3897a57f366905345514f5e94a5166 +Subproject commit d73fee68dd164c016721ae76d1538136513e6b37 diff --git a/riscv/incl/iss/arch/riscv_hart_msu_vp.h b/riscv/incl/iss/arch/riscv_hart_msu_vp.h index d4075f0..a8a9bab 100644 --- a/riscv/incl/iss/arch/riscv_hart_msu_vp.h +++ b/riscv/incl/iss/arch/riscv_hart_msu_vp.h @@ -467,8 +467,10 @@ public: virtual phys_addr_t virt2phys(const iss::addr_t &addr) override; - iss::status read(const iss::addr_t &addr, unsigned length, uint8_t *const data) override; - iss::status write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) override; + iss::status read(const address_type type, const access_type access, const uint32_t space, + const uint64_t addr, const unsigned length, uint8_t *const data) override; + iss::status write(const address_type type, const access_type access, const uint32_t space, + const uint64_t addr, const unsigned length, const uint8_t *const data) override; virtual uint64_t enter_trap(uint64_t flags) override { return riscv_hart_msu_vp::enter_trap(flags, fault_data); } virtual uint64_t enter_trap(uint64_t flags, uint64_t addr) override; @@ -624,9 +626,9 @@ template std::pair riscv_hart_msu_vp::load const auto fsize = pseg->get_file_size(); // 0x42c/0x0 const auto seg_data = pseg->get_data(); if (fsize > 0) { - auto res = this->write( - phys_addr_t(iss::access_type::DEBUG_WRITE, traits::MEM, pseg->get_physical_address()), - fsize, reinterpret_cast(seg_data)); + auto res = this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, + traits::MEM, pseg->get_physical_address(), + fsize, reinterpret_cast(seg_data)); if (res != iss::Ok) LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex << pseg->get_physical_address(); @@ -647,36 +649,39 @@ template std::pair riscv_hart_msu_vp::load } template -iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned length, uint8_t *const data) { +iss::status riscv_hart_msu_vp::read(const address_type type, const access_type access, const uint32_t space, + const uint64_t addr, const unsigned length, uint8_t *const data) { #ifndef NDEBUG - if (addr.access && iss::access_type::DEBUG) { + if (access && iss::access_type::DEBUG) { LOG(TRACE) << "debug read of " << length << " bytes @addr " << addr; } else { LOG(TRACE) << "read of " << length << " bytes @addr " << addr; } #endif try { - switch (addr.space) { + switch (space) { case traits::MEM: { - if (unlikely((addr.access == iss::access_type::FETCH || addr.access == iss::access_type::DEBUG_FETCH) && (addr.val & 0x1) == 1)) { - fault_data = addr.val; - if (addr.access && iss::access_type::DEBUG) throw trap_access(0, addr.val); + if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) { + fault_data = addr; + if (access && iss::access_type::DEBUG) throw trap_access(0, addr); this->reg.trap_state = (1 << 31); // issue trap 0 return iss::Err; } try { - if (unlikely((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK))) { // we may cross a page boundary + if (unlikely((addr & ~PGMASK) != ((addr + length - 1) & ~PGMASK))) { // we may cross a page boundary vm_info vm = hart_state::decode_vm_info(this->reg.machine_state, state.satp); if (vm.levels != 0) { // VM is active - auto split_addr = (addr.val + length) & ~PGMASK; - auto len1 = split_addr - addr.val; - auto res = read(addr, len1, data); + auto split_addr = (addr + length) & ~PGMASK; + auto len1 = split_addr - addr; + auto res = read(type, access, space, addr, len1, data); if (res == iss::Ok) - res = read(iss::addr_t{addr.access, addr.type, addr.space, split_addr}, length - len1, data + len1); + res = read(type, access, space, split_addr, length - len1, data + len1); return res; } } - auto res = read_mem( BASE::v2p(addr), length, data); + 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 return res; } catch (trap_access &ta) { @@ -686,11 +691,11 @@ iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned leng } break; case traits::CSR: { if (length != sizeof(reg_t)) return iss::Err; - return read_csr(addr.val, *reinterpret_cast(data)); + return read_csr(addr, *reinterpret_cast(data)); } break; case traits::FENCE: { - if ((addr.val + length) > mem.size()) return iss::Err; - switch (addr.val) { + if ((addr + length) > mem.size()) return iss::Err; + switch (addr) { case 2: // SFENCE:VMA lower case 3: { // SFENCE:VMA upper auto tvm = state.mstatus.TVM; @@ -704,10 +709,10 @@ iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned leng } } break; case traits::RES: { - auto it = atomic_reservation.find(addr.val); + auto it = atomic_reservation.find(addr); if (it != atomic_reservation.end() && it->second != 0) { memset(data, 0xff, length); - atomic_reservation.erase(addr.val); + atomic_reservation.erase(addr); } else memset(data, 0, length); } break; @@ -722,9 +727,10 @@ iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned leng } template -iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) { +iss::status riscv_hart_msu_vp::write(const address_type type, const access_type access, const uint32_t space, + const uint64_t addr, const unsigned length, const uint8_t *const data) { #ifndef NDEBUG - const char *prefix = (addr.access && iss::access_type::DEBUG) ? "debug " : ""; + const char *prefix = (access && iss::access_type::DEBUG) ? "debug " : ""; switch (length) { case 8: LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t *)&data[0] << std::dec @@ -747,27 +753,29 @@ iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned len } #endif try { - switch (addr.space) { + switch (space) { case traits::MEM: { - if (unlikely((addr.access && iss::access_type::FETCH) && (addr.val & 0x1) == 1)) { - fault_data = addr.val; - if (addr.access && iss::access_type::DEBUG) throw trap_access(0, addr.val); + if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) { + fault_data = addr; + if (access && iss::access_type::DEBUG) throw trap_access(0, addr); this->reg.trap_state = (1 << 31); // issue trap 0 return iss::Err; } try { - if (unlikely((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK))) { // we may cross a page boundary + if (unlikely((addr & ~PGMASK) != ((addr + length - 1) & ~PGMASK))) { // we may cross a page boundary vm_info vm = hart_state::decode_vm_info(this->reg.machine_state, state.satp); if (vm.levels != 0) { // VM is active - auto split_addr = (addr.val + length) & ~PGMASK; - auto len1 = split_addr - addr.val; - auto res = write(addr, len1, data); + auto split_addr = (addr + length) & ~PGMASK; + auto len1 = split_addr - addr; + auto res = write(type, access, space, addr, len1, data); if (res == iss::Ok) - res = write(iss::addr_t{addr.access, addr.type, addr.space, split_addr}, length - len1, data + len1); + res = write(type, access, space, split_addr, length - len1, data + len1); return res; } } - auto res = write_mem(BASE::v2p(addr), length, data); + 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) return res; @@ -776,7 +784,7 @@ iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned len return iss::Err; } - phys_addr_t paddr = BASE::v2p(addr); + 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 @@ -810,11 +818,11 @@ iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned len } break; case traits::CSR: { if (length != sizeof(reg_t)) return iss::Err; - return write_csr(addr.val, *reinterpret_cast(data)); + return write_csr(addr, *reinterpret_cast(data)); } break; case traits::FENCE: { - if ((addr.val + length) > mem.size()) return iss::Err; - switch (addr.val) { + if ((addr + length) > mem.size()) return iss::Err; + switch (addr) { case 2: case 3: { ptw.clear(); @@ -829,7 +837,7 @@ iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned len } } break; case traits::RES: { - atomic_reservation[addr.val] = data[0]; + atomic_reservation[addr] = data[0]; } break; default: return iss::Err; @@ -1182,8 +1190,8 @@ typename riscv_hart_msu_vp::phys_addr_t riscv_hart_msu_vp::virt2phys // check that physical address of PTE is legal reg_t pte = 0; - const uint8_t res = this->read(phys_addr_t{addr.access, traits::MEM, base + idx * vm.ptesize}, - vm.ptesize, (uint8_t *)&pte); + const uint8_t res = this->read(iss::address_type::PHYSICAL, addr.access, + traits::MEM, base + idx * vm.ptesize, vm.ptesize, (uint8_t *)&pte); if (res != 0) throw trap_load_access_fault(addr.val); const reg_t ppn = pte >> PTE_PPN_SHIFT; diff --git a/riscv/incl/iss/debugger/riscv_target_adapter.h b/riscv/incl/iss/debugger/riscv_target_adapter.h index 6fa259a..7133e34 100644 --- a/riscv/incl/iss/debugger/riscv_target_adapter.h +++ b/riscv/incl/iss/debugger/riscv_target_adapter.h @@ -269,7 +269,8 @@ template status riscv_target_adapter::read_mem(uint64_t ad template status riscv_target_adapter::write_mem(uint64_t addr, const std::vector &data) { auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr}); - return srv->execute_syncronized(&arch_if::write, core, a, data.size(), data.data()); + auto f = [&]() -> status { return core->write(a, data.size(), data.data()); }; + return srv->execute_syncronized(f); } template