arch-riscv: fix incorrect interrupt checking logic
Whether global interrupt enabling or not is not simply decided by xIE bit in mstatus, it also depends on current privilige level. All level lower/higher than current should be disabled/enabled regardless of the xIE bit. xIE bit is only control the enabling of interrupt in current privilige level. The fix is verified in FS. Jira Issue: https://gem5.atlassian.net/browse/GEM5-883 Change-Id: I37f83ab77af2efbf1da9b81845828d322e49bf5f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/39035 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Ayaz Akram <yazakram@ucdavis.edu> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -72,12 +72,31 @@ class Interrupts : public BaseInterrupts
|
||||
{
|
||||
INTERRUPT mask = 0;
|
||||
STATUS status = tc->readMiscReg(MISCREG_STATUS);
|
||||
if (status.mie)
|
||||
mask.mei = mask.mti = mask.msi = 1;
|
||||
if (status.sie)
|
||||
mask.sei = mask.sti = mask.ssi = 1;
|
||||
if (status.uie)
|
||||
mask.uei = mask.uti = mask.usi = 1;
|
||||
PrivilegeMode prv = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV);
|
||||
switch (prv) {
|
||||
case PRV_U:
|
||||
mask.mei = mask.mti = mask.msi = 1;
|
||||
mask.sei = mask.sti = mask.ssi = 1;
|
||||
if (status.uie)
|
||||
mask.uei = mask.uti = mask.usi = 1;
|
||||
break;
|
||||
case PRV_S:
|
||||
mask.mei = mask.mti = mask.msi = 1;
|
||||
if (status.sie)
|
||||
mask.sei = mask.sti = mask.ssi = 1;
|
||||
mask.uei = mask.uti = mask.usi = 0;
|
||||
break;
|
||||
case PRV_M:
|
||||
if (status.mie)
|
||||
mask.mei = mask.mti = mask.msi = 1;
|
||||
mask.sei = mask.sti = mask.ssi = 0;
|
||||
mask.uei = mask.uti = mask.usi = 0;
|
||||
break;
|
||||
default:
|
||||
panic("Unknown privilege mode %d.", prv);
|
||||
break;
|
||||
}
|
||||
|
||||
return std::bitset<NumInterruptTypes>(mask);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user