diff --git a/src/isa/riscv64/local-include/intr.h b/src/isa/riscv64/local-include/intr.h index cb840f57..33e5f924 100644 --- a/src/isa/riscv64/local-include/intr.h +++ b/src/isa/riscv64/local-include/intr.h @@ -88,6 +88,7 @@ enum { word_t raise_intr(word_t NO, vaddr_t epc); #define return_on_mem_ex() do { if (cpu.mem_exception != MEM_OK) return; } while (0) +word_t gen_gva(word_t NO, bool is_hls, bool is_mem_access_virtual); bool intr_deleg_S(word_t exceptionNO); bool intr_deleg_VS(word_t exceptionNO); diff --git a/src/isa/riscv64/system/intr.c b/src/isa/riscv64/system/intr.c index c525f795..8d379ad2 100644 --- a/src/isa/riscv64/system/intr.c +++ b/src/isa/riscv64/system/intr.c @@ -26,6 +26,12 @@ void update_mmu_state(); trap_info_t trapInfo = {}; #ifdef CONFIG_RVH +word_t gen_gva(word_t NO, bool is_hls, bool is_mem_access_virtual) { + return ((NO == EX_IAM || NO == EX_IAF || NO == EX_BP || NO == EX_IPF) && cpu.v) || + ((NO == EX_LAM || NO == EX_LAF || NO == EX_SAM || NO == EX_SAF || NO == EX_LPF || NO == EX_SPF) && (is_hls || cpu.v || is_mem_access_virtual)) || + (NO == EX_IGPF || NO == EX_LGPF || NO == EX_SGPF); +} + bool intr_deleg_S(word_t exceptionNO) { bool isNMI = MUXDEF(CONFIG_RV_SMRNMI, cpu.hasNMI && (exceptionNO & INTR_BIT), false); word_t deleg = (exceptionNO & INTR_BIT ? mideleg->val : medeleg->val); @@ -179,9 +185,7 @@ word_t raise_intr(word_t NO, vaddr_t epc) { trap_pc = get_trap_pc(vstvec->val, vscause->val); } else if(delegS && !s_EX_DT){ - int v = (mstatus->mprv)? mstatus->mpv : cpu.v; - hstatus->gva = (NO == EX_IGPF || NO == EX_LGPF || NO == EX_SGPF || - ((v || hld_st_temp) && ((0 <= NO && NO <= 7 && NO != 2) || NO == EX_IPF || NO == EX_LPF || NO == EX_SPF))); + hstatus->gva = gen_gva(NO, hld_st_temp, false); hstatus->spv = cpu.v; if(cpu.v){ hstatus->spvp = cpu.mode; @@ -243,9 +247,8 @@ word_t raise_intr(word_t NO, vaddr_t epc) { trap_pc = get_trap_pc(stvec->val, scause->val); } else if((delegM || vs_EX_DT || s_EX_DT) && !m_EX_DT){ #ifdef CONFIG_RVH - int v = (mstatus->mprv)? mstatus->mpv : cpu.v; - mstatus->gva = (NO == EX_IGPF || NO == EX_LGPF || NO == EX_SGPF || - ((v || hld_st_temp) && ((0 <= NO && NO <= 7 && NO != 2) || NO == EX_IPF || NO == EX_LPF || NO == EX_SPF))); + bool is_mem_access_virtual = mstatus->mprv && mstatus->mpv && (mstatus->mpp != MODE_M); + mstatus->gva = gen_gva(NO, hld_st_temp, is_mem_access_virtual); mstatus->mpv = cpu.v; cpu.v = 0;set_sys_state_flag(SYS_STATE_FLUSH_TCACHE); #endif