From 5da4e6b424c3e6d348fa6bc275235559734ce900 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 13 May 2022 12:37:47 +0200 Subject: [PATCH] fix alignment check for unaligned debugger accesses --- incl/iss/arch/riscv_hart_m_p.h | 10 +++++----- incl/iss/arch/riscv_hart_msu_vp.h | 8 +++++++- incl/iss/arch/riscv_hart_mu_p.h | 12 ++++++------ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 09d9864..c0059b2 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -567,22 +567,22 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce try { switch (space) { case traits::MEM: { - if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) { + auto alignment = is_fetch(access)? (traits::MISA_VAL&0x100? 2 : 4) : length; + if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { fault_data = addr; - if (access && iss::access_type::DEBUG) throw trap_access(0, addr); + if (is_debug(access)) throw trap_access(0, addr); this->trap_state = (1 << 31); // issue trap 0 return iss::Err; } try { - auto alignment = access == iss::access_type::FETCH? (traits::MISA_VAL&0x100? 2 : 4) : length; - if(alignment>1 && (addr&(alignment-1))){ + if(!is_debug(access) && (addr&(alignment-1))){ this->trap_state = 1<<31 | 4<<16; 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}); auto res = iss::Err; - if(access != access_type::FETCH && memfn_range.size()){ + 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){ return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val; }); diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index ed2e677..a742d08 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -611,13 +611,19 @@ iss::status riscv_hart_msu_vp::read(const address_type type, const access_ try { switch (space) { case traits::MEM: { - if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) { + auto alignment = is_fetch(access)? (traits::MISA_VAL&0x100? 2 : 4) : length; + if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { fault_data = addr; if (access && iss::access_type::DEBUG) throw trap_access(0, addr); this->trap_state = (1 << 31); // issue trap 0 return iss::Err; } try { + if(!is_debug(access) && (addr&(alignment-1))){ + this->trap_state = 1<<31 | 4<<16; + fault_data=addr; + return iss::Err; + } 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); if (vm.levels != 0) { // VM is active diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 440664e..1cf8484 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -705,22 +705,22 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc switch (space) { case traits::MEM: { if(FEAT & FEAT_PMP){ - if(!pmp_check(access, addr, length) && (access&access_type::DEBUG) != access_type::DEBUG) { + if(!pmp_check(access, addr, length) && !is_debug(access)) { fault_data = addr; - if (access && iss::access_type::DEBUG) throw trap_access(0, addr); + if (is_debug(access)) throw trap_access(0, addr); this->trap_state = (1 << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1 return iss::Err; } } - if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) { + auto alignment = is_fetch(access)? (traits::MISA_VAL&0x100? 2 : 4) : length; + if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { fault_data = addr; - if (access && iss::access_type::DEBUG) throw trap_access(0, addr); + if (is_debug(access)) throw trap_access(0, addr); this->trap_state = (1 << 31); // issue trap 0 return iss::Err; } try { - auto alignment = access == iss::access_type::FETCH? (traits::MISA_VAL&0x100? 2 : 4) : length; - if(alignment>1 && (addr&(alignment-1))){ + if(!is_debug(access) && (addr&(alignment-1))){ this->trap_state = 1<<31 | 4<<16; fault_data=addr; return iss::Err;