diff --git a/src/isa/riscv64/include/isa-def.h b/src/isa/riscv64/include/isa-def.h index 55443d10a..019431443 100644 --- a/src/isa/riscv64/include/isa-def.h +++ b/src/isa/riscv64/include/isa-def.h @@ -21,6 +21,7 @@ #ifdef CONFIG_RVV #include "../instr/rvv/vreg.h" #endif // CONFIG_RVV +#include "../local-include/trapinfo.h" #define FORCE_RAISE_PF @@ -171,6 +172,8 @@ typedef struct { bool critical_error; #endif + trap_info_t trapInfo; + } riscv64_CPU_state; // decode diff --git a/src/isa/riscv64/init.c b/src/isa/riscv64/init.c index cdebd660b..ac1bd0813 100644 --- a/src/isa/riscv64/init.c +++ b/src/isa/riscv64/init.c @@ -60,6 +60,7 @@ void init_isa() { cpu.gpr[0]._64 = 0; cpu.mode = MODE_M; + clear_trapinfo(); IFDEF(CONFIG_RV_SMDBLTRP, cpu.critical_error = 0); // For RV64 systems, the SXL and UXL fields are WARL fields that // control the value of XLEN for S-mode and U-mode, respectively. diff --git a/src/isa/riscv64/instr/rva/amo.c b/src/isa/riscv64/instr/rva/amo.c index d1b2af816..0cd0d75d7 100644 --- a/src/isa/riscv64/instr/rva/amo.c +++ b/src/isa/riscv64/instr/rva/amo.c @@ -19,7 +19,6 @@ #include #include "../local-include/trigger.h" #include "../local-include/intr.h" -#include "../local-include/trapinfo.h" #include "cpu/difftest.h" __attribute__((cold)) def_rtl(amo_slow_path, rtlreg_t *dest, const rtlreg_t *src1, const rtlreg_t *src2) { @@ -78,7 +77,7 @@ def_rtl(amo_slow_path, rtlreg_t *dest, const rtlreg_t *src1, const rtlreg_t *src // Even if scInvalid, SAF (if raised) also needs to be reported // Check address space range and pmp if (!in_pmem(paddr) || !isa_pmp_check_permission(paddr, width, MEM_TYPE_WRITE, cpu.mode)) { - trapInfo.tval = *src1; + cpu.trapInfo.tval = *src1; longjmp_exception(EX_SAF); } } diff --git a/src/isa/riscv64/local-include/trapinfo.h b/src/isa/riscv64/local-include/trapinfo.h index c225c1273..db68712d7 100644 --- a/src/isa/riscv64/local-include/trapinfo.h +++ b/src/isa/riscv64/local-include/trapinfo.h @@ -25,7 +25,6 @@ typedef struct { word_t tinst; } trap_info_t; -extern trap_info_t trapInfo; void clear_trapinfo(); diff --git a/src/isa/riscv64/system/intr.c b/src/isa/riscv64/system/intr.c index c525f7952..0fa64cc65 100644 --- a/src/isa/riscv64/system/intr.c +++ b/src/isa/riscv64/system/intr.c @@ -19,11 +19,9 @@ #include "../local-include/trigger.h" #include "../local-include/csr.h" #include "../local-include/intr.h" -#include "../local-include/trapinfo.h" void update_mmu_state(); -trap_info_t trapInfo = {}; #ifdef CONFIG_RVH bool intr_deleg_S(word_t exceptionNO) { @@ -50,7 +48,7 @@ bool intr_deleg_S(word_t exceptionNO) { #endif void clear_trapinfo(){ - memset(&trapInfo, 0, sizeof(trap_info_t)); + memset(&cpu.trapInfo, 0, sizeof(trap_info_t)); } static word_t get_trap_pc(word_t xtvec, word_t xcause) { @@ -109,7 +107,7 @@ word_t raise_intr(word_t NO, vaddr_t epc) { #ifdef CONFIG_RV_SMRNMI if (!mnstatus->nmie){ #ifdef CONFIG_SHARE - IFDEF(CONFIG_RV_SMDBLTRP,cpu.critical_error = true);// this will compare in difftest + IFDEF(CONFIG_RV_SMDBLTRP, cpu.critical_error = true);// this will compare in difftest #else printf("\33[1;31mHIT CRITICAL ERROR\33[0m: trap when mnstatus.nmie close, please check if software cause a double trap.\n"); nemu_state.state = NEMU_END; @@ -149,7 +147,7 @@ word_t raise_intr(word_t NO, vaddr_t epc) { vsstatus->spie = vsstatus->sie; vsstatus->sie = 0; vsstatus->sdt = MUXDEF(CONFIG_RV_SSDBLTRP, henvcfg->dte && menvcfg->dte, 0); - vstval->val = trapInfo.tval; + vstval->val = cpu.trapInfo.tval; switch (NO) { case EX_IPF: case EX_LPF: case EX_SPF: case EX_LAM: case EX_SAM: @@ -198,9 +196,9 @@ word_t raise_intr(word_t NO, vaddr_t epc) { mstatus->spie = mstatus->sie; mstatus->sie = 0; mstatus->sdt = MUXDEF(CONFIG_RV_SSDBLTRP, menvcfg->dte, 0); - IFDEF(CONFIG_RVH, htval->val = trapInfo.tval2); - IFDEF(CONFIG_RVH, htinst->val = trapInfo.tinst); - stval->val = trapInfo.tval; + IFDEF(CONFIG_RVH, htval->val = cpu.trapInfo.tval2); + IFDEF(CONFIG_RVH, htinst->val = cpu.trapInfo.tinst); + stval->val = cpu.trapInfo.tval; switch (NO) { case EX_IPF: case EX_LPF: case EX_SPF: case EX_LAM: case EX_SAM: @@ -254,9 +252,9 @@ word_t raise_intr(word_t NO, vaddr_t epc) { mstatus->mpp = cpu.mode; mstatus->mpie = mstatus->mie; mstatus->mie = 0; - mtval->val = trapInfo.tval; - IFDEF(CONFIG_RVH, mtval2->val = trapInfo.tval2); - IFDEF(CONFIG_RVH, mtinst->val = trapInfo.tinst); + mtval->val = cpu.trapInfo.tval; + IFDEF(CONFIG_RVH, mtval2->val = cpu.trapInfo.tval2); + IFDEF(CONFIG_RVH, mtinst->val = cpu.trapInfo.tinst); switch (NO) { case EX_IPF: case EX_LPF: case EX_SPF: case EX_LAM: case EX_SAM: diff --git a/src/isa/riscv64/system/mmu.c b/src/isa/riscv64/system/mmu.c index af5266a59..94e150ef0 100644 --- a/src/isa/riscv64/system/mmu.c +++ b/src/isa/riscv64/system/mmu.c @@ -22,7 +22,6 @@ #include "../local-include/csr.h" #include "../local-include/intr.h" #include "../local-include/rtl.h" -#include "../local-include/trapinfo.h" typedef union PageTableEntry { struct { @@ -96,7 +95,7 @@ static inline bool check_permission(PTE *pte, bool ok, vaddr_t vaddr, int type) #endif if (!(ok && pte->x && !pte->pad) || update_ad) { assert(!cpu.amo); - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; longjmp_exception(EX_IPF); return false; } @@ -121,7 +120,7 @@ static inline bool check_permission(PTE *pte, bool ok, vaddr_t vaddr, int type) if (!(ok && can_load && !pte->pad) || update_ad) { if (cpu.amo) Logtr("redirect to AMO page fault exception at pc = " FMT_WORD, cpu.pc); int ex = (cpu.amo ? EX_SPF : EX_LPF); - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; cpu.amo = false; Logtr("Memory read translation exception!"); longjmp_exception(ex); @@ -136,7 +135,7 @@ static inline bool check_permission(PTE *pte, bool ok, vaddr_t vaddr, int type) #endif Logtr("Translate for memory writing v: %d w: %d", pte->v, pte->w); if (!(ok && pte->w && !pte->pad) || update_ad) { - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; cpu.amo = false; longjmp_exception(EX_SPF); return false; @@ -171,9 +170,9 @@ void raise_guest_excep(paddr_t gpaddr, vaddr_t vaddr, int type, bool is_support_ } else { ex = EX_LGPF; } - trapInfo.tval = vaddr; - trapInfo.tval2 = gpaddr >> 2; - trapInfo.tinst = tinst; + cpu.trapInfo.tval = vaddr; + cpu.trapInfo.tval2 = gpaddr >> 2; + cpu.trapInfo.tinst = tinst; longjmp_exception(ex); } @@ -266,7 +265,7 @@ static word_t pte_read(paddr_t addr, int type, int mode, vaddr_t vaddr) { if (unlikely(is_in_mmio(addr))) { int cause = type == MEM_TYPE_IFETCH ? EX_IAF : type == MEM_TYPE_WRITE ? EX_SAF : EX_LAF; - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; longjmp_exception(cause); } #endif @@ -383,7 +382,7 @@ static paddr_t ptw(vaddr_t vaddr, int type) { // update a/d by hardware is_write = (type == MEM_TYPE_WRITE); if (!pte.a || (!pte.d && is_write)) { - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; switch (type) { int ex; @@ -540,10 +539,10 @@ int isa_mmu_check(vaddr_t vaddr, int len, int type) { #endif if(!va_msbs_ok){ if(is_ifetch){ - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; #ifdef CONFIG_RVH if (hld_st || gpf) { - trapInfo.tval2 = vaddr >> 2; + cpu.trapInfo.tval2 = vaddr >> 2; longjmp_exception(EX_IGPF); } else { longjmp_exception(EX_IPF); @@ -552,12 +551,12 @@ int isa_mmu_check(vaddr_t vaddr, int len, int type) { longjmp_exception(EX_IPF); #endif } else if(type == MEM_TYPE_READ){ - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; #ifdef CONFIG_RVH int ex; if(hld_st || gpf){ ex = cpu.amo ? EX_SGPF : EX_LGPF; - trapInfo.tval2 = vaddr >> 2; + cpu.trapInfo.tval2 = vaddr >> 2; } else { ex = cpu.amo ? EX_SPF : EX_LPF; } @@ -567,10 +566,10 @@ int isa_mmu_check(vaddr_t vaddr, int len, int type) { longjmp_exception(ex); #endif } else { - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; #ifdef CONFIG_RVH if (hld_st || gpf) { - trapInfo.tval2 = vaddr >> 2; + cpu.trapInfo.tval2 = vaddr >> 2; longjmp_exception(EX_SGPF); } else { longjmp_exception(EX_SPF); @@ -595,7 +594,7 @@ void isa_misalign_data_addr_check(vaddr_t vaddr, int len, int type) { Logm("addr misaligned happened: vaddr:%lx len:%d type:%d pc:%lx", vaddr, len, type, cpu.pc); if (ISDEF(CONFIG_AC_SOFT)) { int ex = cpu.amo || type == MEM_TYPE_WRITE ? EX_SAM : EX_LAM; - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; longjmp_exception(ex); } } @@ -607,7 +606,7 @@ void isa_vec_misalign_data_addr_check(vaddr_t vaddr, int len, int type) { Logm("addr misaligned happened: vaddr:%lx len:%d type:%d pc:%lx", vaddr, len, type, cpu.pc); if (ISDEF(CONFIG_VECTOR_AC_SOFT)) { int ex = cpu.amo || type == MEM_TYPE_WRITE ? EX_SAM : EX_LAM; - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; longjmp_exception(ex); } } @@ -619,7 +618,7 @@ void isa_amo_misalign_data_addr_check(vaddr_t vaddr, int len, int type) { Logm("addr misaligned happened: vaddr:%lx len:%d type:%d pc:%lx", vaddr, len, type, cpu.pc); if (ISDEF(CONFIG_AMO_AC_SOFT)) { int ex = cpu.amo || type == MEM_TYPE_WRITE ? EX_SAM : EX_LAM; - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; longjmp_exception(ex); } } @@ -663,7 +662,7 @@ int force_raise_pf(vaddr_t vaddr, int type){ } #ifdef CONFIG_RVH if (intr_deleg_VS(EX_IPF)) { - trapInfo.tval = cpu.execution_guide.vstval; + cpu.trapInfo.tval = cpu.execution_guide.vstval; if( vaddr != cpu.execution_guide.vstval && // cross page ipf caused mismatch is legal @@ -678,7 +677,7 @@ int force_raise_pf(vaddr_t vaddr, int type){ #else if(intr_deleg_S(EX_IPF)) { #endif // CONFIG_RVH - trapInfo.tval = cpu.execution_guide.stval; + cpu.trapInfo.tval = cpu.execution_guide.stval; if( vaddr != cpu.execution_guide.stval && // cross page ipf caused mismatch is legal @@ -690,7 +689,7 @@ int force_raise_pf(vaddr_t vaddr, int type){ ); } } else { - trapInfo.tval = cpu.execution_guide.mtval; + cpu.trapInfo.tval = cpu.execution_guide.mtval; if( vaddr != cpu.execution_guide.mtval && // cross page ipf caused mismatch is legal @@ -715,7 +714,7 @@ int force_raise_pf(vaddr_t vaddr, int type){ #endif printf("[NEMU]: force raise LPF\n"); - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; longjmp_exception(EX_LPF); return MEM_RET_FAIL; } else if(type == MEM_TYPE_WRITE && cpu.execution_guide.exception_num == EX_SPF){ @@ -728,7 +727,7 @@ int force_raise_pf(vaddr_t vaddr, int type){ #endif printf("[NEMU]: force raise SPF\n"); - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; longjmp_exception(EX_SPF); return MEM_RET_FAIL; } @@ -757,8 +756,8 @@ int force_raise_gpf(vaddr_t vaddr, int type){ return MEM_RET_OK; } if (intr_deleg_S(EX_IGPF)) { - trapInfo.tval = cpu.execution_guide.stval; - trapInfo.tval2 = cpu.execution_guide.htval; + cpu.trapInfo.tval = cpu.execution_guide.stval; + cpu.trapInfo.tval2 = cpu.execution_guide.htval; if( vaddr != cpu.execution_guide.stval && // cross page ipf caused mismatch is legal @@ -770,8 +769,8 @@ int force_raise_gpf(vaddr_t vaddr, int type){ ); } } else { - trapInfo.tval = cpu.execution_guide.mtval; - trapInfo.tval2 = cpu.execution_guide.mtval2; + cpu.trapInfo.tval = cpu.execution_guide.mtval; + cpu.trapInfo.tval2 = cpu.execution_guide.mtval2; if( vaddr != cpu.execution_guide.mtval && // cross page ipf caused mismatch is legal @@ -796,8 +795,8 @@ int force_raise_gpf(vaddr_t vaddr, int type){ #endif printf("[NEMU]: force raise LGPF\n"); - trapInfo.tval = vaddr; - trapInfo.tval2 = intr_deleg_S(EX_LGPF) ? cpu.execution_guide.htval: cpu.execution_guide.mtval2; + cpu.trapInfo.tval = vaddr; + cpu.trapInfo.tval2 = intr_deleg_S(EX_LGPF) ? cpu.execution_guide.htval: cpu.execution_guide.mtval2; longjmp_exception(EX_LGPF); return MEM_RET_FAIL; } else if(type == MEM_TYPE_WRITE && cpu.execution_guide.exception_num == EX_SGPF){ @@ -810,8 +809,8 @@ int force_raise_gpf(vaddr_t vaddr, int type){ #endif printf("[NEMU]: force raise SGPF\n"); - trapInfo.tval = vaddr; - trapInfo.tval2 = intr_deleg_S(EX_SGPF) ? cpu.execution_guide.htval: cpu.execution_guide.mtval2; + cpu.trapInfo.tval = vaddr; + cpu.trapInfo.tval2 = intr_deleg_S(EX_SGPF) ? cpu.execution_guide.htval: cpu.execution_guide.mtval2; longjmp_exception(EX_SGPF); return MEM_RET_FAIL; } diff --git a/src/memory/paddr.c b/src/memory/paddr.c index 516f2a1ed..293d5ad0b 100644 --- a/src/memory/paddr.c +++ b/src/memory/paddr.c @@ -25,7 +25,6 @@ #include #include "../local-include/csr.h" #include "../local-include/intr.h" -#include "../local-include/trapinfo.h" bool is_in_mmio(paddr_t addr); @@ -134,7 +133,7 @@ static inline void pmem_write(paddr_t addr, int len, word_t data, int cross_page } static inline void raise_access_fault(int cause, vaddr_t vaddr) { - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; // cpu.amo flag must be reset to false before longjmp_exception, // including longjmp_exception(access fault), longjmp_exception(page fault) cpu.amo = false; @@ -157,7 +156,7 @@ static inline void isa_mmio_misalign_data_addr_check(paddr_t paddr, vaddr_t vadd Logm("addr misaligned happened: paddr:" FMT_PADDR " vaddr:" FMT_WORD " len:%d type:%d pc:%lx", paddr, vaddr, len, type, cpu.pc); if (ISDEF(CONFIG_MMIO_AC_SOFT)) { int ex = cpu.amo || type == MEM_TYPE_WRITE ? EX_SAM : EX_LAM; - trapInfo.tval = vaddr; + cpu.trapInfo.tval = vaddr; longjmp_exception(ex); } }