diff --git a/src/cpu/cpu-exec.c b/src/cpu/cpu-exec.c index 71a7e0569..bfd0ffa5a 100644 --- a/src/cpu/cpu-exec.c +++ b/src/cpu/cpu-exec.c @@ -643,7 +643,7 @@ void cpu_exec(uint64_t n) { PUSH_CONTEXT(&cause); if (cause) { n_remain -= prev_s->idx_in_bb - 1; - MUXDEF(CONFIG_TVAL_EX_II, cpu.instr = prev_s->isa.instr.val, ); + IFDEF(CONFIG_TVAL_EX_II, cpu.instr = prev_s->isa.instr.val); // Here is exception handle #ifdef CONFIG_PERF_OPT update_global(); diff --git a/src/isa/riscv64/Kconfig b/src/isa/riscv64/Kconfig index a386438c5..fb1b0637e 100644 --- a/src/isa/riscv64/Kconfig +++ b/src/isa/riscv64/Kconfig @@ -113,6 +113,11 @@ config RV_SSDBLTRP depends on RV_SMRNMI default n +config NMIE_INIT + bool "Init mnstatus.nmie to 1 and allow software to clear" + depends on RV_SMRNMI + default y + menuconfig RV_ZICNTR bool "RISC-V Zicntr Extensions for Base Counters and Timers, v2.0" default y diff --git a/src/isa/riscv64/init.c b/src/isa/riscv64/init.c index 732e1cb0c..1128ae854 100644 --- a/src/isa/riscv64/init.c +++ b/src/isa/riscv64/init.c @@ -77,9 +77,8 @@ void init_isa() { henvcfg->dte = 1; #endif //CONFIG_RV_SSDBLTRP #ifdef CONFIG_RV_SMRNMI -// mnstatus->nmie = 0; -// as opensbi and linux not support smrnmi, so we init nmie = 1 to pass ci - mnstatus->nmie = 1; +// as opensbi and linux not support smrnmi, so we default init nmie = 1 to pass ci + mnstatus->nmie = ISDEF(CONFIG_NMIE_INIT); #endif //CONFIG_RV_SMRNMI #ifdef CONFIG_RV_SSTC diff --git a/src/isa/riscv64/instr/decode.c b/src/isa/riscv64/instr/decode.c index ab303fadc..f2cb46a44 100644 --- a/src/isa/riscv64/instr/decode.c +++ b/src/isa/riscv64/instr/decode.c @@ -165,7 +165,7 @@ int isa_fetch_decode(Decode *s) { case 0x1: // ebreak case 0x102: // sret case 0x302: // mret - MUXDEF(CONFIG_RV_SMRNMI, case 0x702: ,)// mnret + IFDEF(CONFIG_RV_SMRNMI, case 0x702: )// mnret s->type = INSTR_TYPE_I; } } diff --git a/src/isa/riscv64/system/intr.c b/src/isa/riscv64/system/intr.c index 3107ff9aa..3ca72918c 100644 --- a/src/isa/riscv64/system/intr.c +++ b/src/isa/riscv64/system/intr.c @@ -112,6 +112,7 @@ word_t raise_intr(word_t NO, vaddr_t epc) { bool delegM = !delegS && !isNMI; bool s_EX_DT = MUXDEF(CONFIG_RV_SSDBLTRP, delegS && mstatus->sdt, false); bool m_EX_DT = MUXDEF(CONFIG_RV_SMDBLTRP, delegM && mstatus->mdt, false); + word_t trap_pc = 0; #ifdef CONFIG_RVH bool virtualInterruptIsHvictlInject = MUXDEF(CONFIG_RV_IMSIC, cpu.virtualInterruptIsHvictlInject, false); extern bool hld_st; @@ -137,9 +138,6 @@ word_t raise_intr(word_t NO, vaddr_t epc) { vsstatus->sie = 0; vsstatus->sdt = MUXDEF(CONFIG_RV_SSDBLTRP, henvcfg->dte && menvcfg->dte, 0); vstval->val = trapInfo.tval; - // vsstatus->spp = cpu.mode; - // vsstatus->spie = vsstatus->sie; - // vsstatus->sie = 0; switch (NO) { case EX_IPF: case EX_LPF: case EX_SPF: case EX_LAM: case EX_SAM: @@ -166,9 +164,7 @@ word_t raise_intr(word_t NO, vaddr_t epc) { } cpu.v = 1; cpu.mode = MODE_S; - update_mmu_state(); - clear_trapinfo(); - return get_trap_pc(vstvec->val, vscause->val); + trap_pc = get_trap_pc(vstvec->val, vscause->val); } else if(delegS && !s_EX_DT){ int v = (mstatus->mprv)? mstatus->mpv : cpu.v; @@ -190,22 +186,22 @@ 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); - MUXDEF(CONFIG_RVH, htval->val = trapInfo.tval2;, ) - MUXDEF(CONFIG_RVH, htinst->val = trapInfo.tinst;, ) + IFDEF(CONFIG_RVH, htval->val = trapInfo.tval2); + IFDEF(CONFIG_RVH, htinst->val = trapInfo.tinst); stval->val = trapInfo.tval; switch (NO) { case EX_IPF: case EX_LPF: case EX_SPF: case EX_LAM: case EX_SAM: case EX_IAF: case EX_LAF: case EX_SAF: - MUXDEF(CONFIG_RVH, htval->val = 0, ); - MUXDEF(CONFIG_RVH, htinst->val = 0, ); + IFDEF(CONFIG_RVH, htval->val = 0); + IFDEF(CONFIG_RVH, htinst->val = 0); break; case EX_IGPF: case EX_LGPF: case EX_SGPF: break; case EX_II: case EX_VI: stval->val = MUXDEF(CONFIG_TVAL_EX_II, cpu.instr, 0); - MUXDEF(CONFIG_RVH, htval->val = 0, ); - MUXDEF(CONFIG_RVH, htinst->val = 0, ); + IFDEF(CONFIG_RVH, htval->val = 0); + IFDEF(CONFIG_RVH, htinst->val = 0); break; case EX_BP : #ifdef CONFIG_RV_SDTRIG @@ -220,22 +216,19 @@ word_t raise_intr(word_t NO, vaddr_t epc) { #else stval->val = epc; #endif // CONFIG_RV_SDTRIG - MUXDEF(CONFIG_RVH, htval->val = 0, ); - MUXDEF(CONFIG_RVH, htinst->val = 0, ); + IFDEF(CONFIG_RVH, htval->val = 0); + IFDEF(CONFIG_RVH, htinst->val = 0); break; default: stval->val = 0; - MUXDEF(CONFIG_RVH, htval->val = 0, ); - MUXDEF(CONFIG_RVH, htinst->val = 0, ); + IFDEF(CONFIG_RVH, htval->val = 0); + IFDEF(CONFIG_RVH, htinst->val = 0); } // When a trap (except GPF) is taken into HS-mode, htinst is written with 0. // Todo: support tinst encoding descriped in section // 18.6.3. Transformed Instruction or Pseudoinstruction for mtinst or htinst. cpu.mode = MODE_S; - update_mmu_state(); - clear_trapinfo(); - return get_trap_pc(stvec->val, scause->val); - // return stvec->val; + 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; @@ -250,21 +243,21 @@ word_t raise_intr(word_t NO, vaddr_t epc) { mstatus->mpie = mstatus->mie; mstatus->mie = 0; mtval->val = trapInfo.tval; - MUXDEF(CONFIG_RVH, mtval2->val = trapInfo.tval2;, ) - MUXDEF(CONFIG_RVH, mtinst->val = trapInfo.tinst;, ) + IFDEF(CONFIG_RVH, mtval2->val = trapInfo.tval2); + IFDEF(CONFIG_RVH, mtinst->val = trapInfo.tinst); switch (NO) { case EX_IPF: case EX_LPF: case EX_SPF: case EX_LAM: case EX_SAM: case EX_IAF: case EX_LAF: case EX_SAF: - MUXDEF(CONFIG_RVH, mtval2->val = 0;, ;); - MUXDEF(CONFIG_RVH, mtinst->val = 0;, ;); + IFDEF(CONFIG_RVH, mtval2->val = 0); + IFDEF(CONFIG_RVH, mtinst->val = 0); break; case EX_IGPF: case EX_LGPF: case EX_SGPF: break; case EX_II: case EX_VI: mtval->val = MUXDEF(CONFIG_TVAL_EX_II, cpu.instr, 0); - MUXDEF(CONFIG_RVH, mtval2->val = 0;, ;); - MUXDEF(CONFIG_RVH, mtinst->val = 0;, ;); + IFDEF(CONFIG_RVH, mtval2->val = 0); + IFDEF(CONFIG_RVH, mtinst->val = 0); break; case EX_BP: #ifdef CONFIG_RV_SDTRIG @@ -279,13 +272,13 @@ word_t raise_intr(word_t NO, vaddr_t epc) { #else mtval->val = epc; #endif // CONFIG_RV_SDTRIG - MUXDEF(CONFIG_RVH, mtval2->val = 0;, ;); - MUXDEF(CONFIG_RVH, mtinst->val = 0;, ;); + IFDEF(CONFIG_RVH, mtval2->val = 0); + IFDEF(CONFIG_RVH, mtinst->val = 0); break; default: mtval->val = 0; - MUXDEF(CONFIG_RVH, mtval2->val = 0;, ;); - MUXDEF(CONFIG_RVH, mtinst->val = 0;, ;); + IFDEF(CONFIG_RVH, mtval2->val = 0); + IFDEF(CONFIG_RVH, mtinst->val = 0); } #ifdef CONFIG_RV_SSDBLTRP bool hasEX_DT = vs_EX_DT || s_EX_DT; @@ -294,9 +287,7 @@ word_t raise_intr(word_t NO, vaddr_t epc) { mtval2->val = (hasEX_DT ? NO : mtval2->val); #endif //CONFIG_RV_SSDBLTRP cpu.mode = MODE_M; - update_mmu_state(); - clear_trapinfo(); - return get_trap_pc(mtvec->val, mcause->val); + trap_pc = get_trap_pc(mtvec->val, mcause->val); } #ifdef CONFIG_RV_SMRNMI else if ((m_EX_DT || isNMI) && mnstatus->nmie) { @@ -308,14 +299,12 @@ word_t raise_intr(word_t NO, vaddr_t epc) { mnepc->val = epc; mncause->val = NO; cpu.mode = MODE_M; - update_mmu_state(); - clear_trapinfo(); - return get_trap_pc(mtvec->val, mncause->val); + trap_pc = get_trap_pc(mtvec->val, mncause->val); } #endif //CONFIG_RV_SMRNMI - else { - return 0; - } + update_mmu_state(); + clear_trapinfo(); + return trap_pc; } word_t isa_query_intr() { diff --git a/src/isa/riscv64/system/mmu.c b/src/isa/riscv64/system/mmu.c index 54da5bf28..af5266a59 100644 --- a/src/isa/riscv64/system/mmu.c +++ b/src/isa/riscv64/system/mmu.c @@ -383,20 +383,18 @@ 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; switch (type) { int ex; case MEM_TYPE_IFETCH: - trapInfo.tval = vaddr; longjmp_exception(EX_IPF); break; case MEM_TYPE_READ: ex = cpu.amo ? EX_SPF : EX_LPF; - trapInfo.tval = vaddr; longjmp_exception(ex); break; case MEM_TYPE_WRITE: - trapInfo.tval = vaddr; longjmp_exception(EX_SPF); break; default: @@ -542,48 +540,42 @@ int isa_mmu_check(vaddr_t vaddr, int len, int type) { #endif if(!va_msbs_ok){ if(is_ifetch){ + trapInfo.tval = vaddr; #ifdef CONFIG_RVH if (hld_st || gpf) { - trapInfo.tval = vaddr; trapInfo.tval2 = vaddr >> 2; longjmp_exception(EX_IGPF); } else { - trapInfo.tval = vaddr; longjmp_exception(EX_IPF); } #else - trapInfo.tval = vaddr; longjmp_exception(EX_IPF); #endif } else if(type == MEM_TYPE_READ){ + trapInfo.tval = vaddr; #ifdef CONFIG_RVH int ex; if(hld_st || gpf){ ex = cpu.amo ? EX_SGPF : EX_LGPF; - trapInfo.tval = vaddr; trapInfo.tval2 = vaddr >> 2; } else { ex = cpu.amo ? EX_SPF : EX_LPF; - trapInfo.tval = vaddr; } longjmp_exception(ex); #else int ex = cpu.amo ? EX_SPF : EX_LPF; - trapInfo.tval = vaddr; longjmp_exception(ex); #endif } else { + trapInfo.tval = vaddr; #ifdef CONFIG_RVH if (hld_st || gpf) { - trapInfo.tval = vaddr; trapInfo.tval2 = vaddr >> 2; longjmp_exception(EX_SGPF); } else { - trapInfo.tval = vaddr; longjmp_exception(EX_SPF); } #else - trapInfo.tval = vaddr; longjmp_exception(EX_SPF); #endif } diff --git a/src/isa/riscv64/system/priv.c b/src/isa/riscv64/system/priv.c index 52720dc7a..4e0dc2219 100644 --- a/src/isa/riscv64/system/priv.c +++ b/src/isa/riscv64/system/priv.c @@ -1431,9 +1431,10 @@ static inline void csr_write(word_t *dest, word_t src) { else if (is_write(mnstatus)) { word_t mnstatus_mask = MNSTATUS_MASK; unsigned pre_mnpp = mnstatus->mnpp; -// if ((src & MNSTATUS_NMIE) == 0) { -// mnstatus_mask &= ~MNSTATUS_NMIE; -// } +// as opensbi and linux not support smrnmi, so we default init nmie = 1 and allow nmie set to 0 by software for test + if ((src & MNSTATUS_NMIE) == 0 && !ISDEF(CONFIG_NMIE_INIT)) { + mnstatus_mask &= ~MNSTATUS_NMIE; + } mnstatus->val = mask_bitset(mnstatus->val, mnstatus_mask, src); if (mnstatus->mnpp == MODE_RS) { mnstatus->mnpp = pre_mnpp; @@ -1905,18 +1906,18 @@ static inline void csr_permit_check(uint32_t addr, bool is_write) { has_vi |= csr_counter_enable_check(addr); } // check smstateen - MUXDEF(CONFIG_RV_SMSTATEEN, has_vi |= smstateen_extension_permit_check(dest_access), ); + IFDEF(CONFIG_RV_SMSTATEEN, has_vi |= smstateen_extension_permit_check(dest_access)); // check aia - MUXDEF(CONFIG_RV_IMSIC, has_vi |= aia_extension_permit_check(dest_access, is_write), ); + IFDEF(CONFIG_RV_IMSIC, has_vi |= aia_extension_permit_check(dest_access, is_write)); //check satp(satp & hgatp) has_vi |= satp_permit_check(dest_access); //check fp - MUXNDEF(CONFIG_FPU_NONE, has_vi |= fp_permit_check(dest_access), ); + IFNDEF(CONFIG_FPU_NONE, has_vi |= fp_permit_check(dest_access)); //check vec - MUXDEF(CONFIG_RVV, has_vi |= vec_permit_check(dest_access), ); + IFDEF(CONFIG_RVV, has_vi |= vec_permit_check(dest_access)); if (has_vi) longjmp_exception(EX_VI);