From 8c3658939df1ec0866fcc24935acafc19c18a2c3 Mon Sep 17 00:00:00 2001 From: Cui Jin Date: Thu, 31 Dec 2020 16:17:35 +0800 Subject: [PATCH] arch-riscv: fix the wrong cause register setting The most significant bit should be set based on interrupt or exception. I assume in current RV64 implementation the bit should be 63rd, rather than 31st. This causes interrupt handler to get invalid cause code. Minor bug is for the mpie is suppossed to be set to the value of old mie. The fix is verified in FS. Jira Issue: https://gem5.atlassian.net/browse/GEM5-858 Change-Id: I1cc166c254b35f5c1acb3f5774c43149c61cc37a Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38755 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/arch/riscv/faults.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/arch/riscv/faults.cc b/src/arch/riscv/faults.cc index ac4c5823e..5ac2a3c79 100644 --- a/src/arch/riscv/faults.cc +++ b/src/arch/riscv/faults.cc @@ -113,7 +113,7 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) tval = MISCREG_MTVAL; status.mpp = pp; - status.mpie = status.sie; + status.mpie = status.mie; status.mie = 0; break; default: @@ -122,8 +122,12 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) } // Set fault cause, privilege, and return PC - tc->setMiscReg(cause, - (isInterrupt() << (sizeof(uint64_t) * 4 - 1)) | _code); + // Interrupt is indicated on the MSB of cause (bit 63 in RV64) + uint64_t _cause = _code; + if (isInterrupt()) { + _cause |= (1L << 63); + } + tc->setMiscReg(cause, _cause); tc->setMiscReg(epc, tc->instAddr()); tc->setMiscReg(tval, trap_value()); tc->setMiscReg(MISCREG_PRV, prv); -- 2.30.2