Peter Yuen has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/40076 )

Change subject: arch-riscv: Fixing interrupt handling order and effect of mideleg
......................................................................

arch-riscv: Fixing interrupt handling order and effect of mideleg

This patch fixes the issues listed in:
https://gem5.atlassian.net/browse/GEM5-887
https://gem5.atlassian.net/browse/GEM5-889

The code change has been verified by booting FS linux.
Software, timer and external interrupts work as expected.

Change-Id: I6ce4fc843d2e0338355152c3fc33c966d6b4a481
---
M src/arch/riscv/interrupts.hh
1 file changed, 19 insertions(+), 6 deletions(-)



diff --git a/src/arch/riscv/interrupts.hh b/src/arch/riscv/interrupts.hh
index e1460ab..10638dd 100644
--- a/src/arch/riscv/interrupts.hh
+++ b/src/arch/riscv/interrupts.hh
@@ -72,16 +72,24 @@
     {
         INTERRUPT mask = 0;
         STATUS status = tc->readMiscReg(MISCREG_STATUS);
+        INTERRUPT mideleg = tc->readMiscReg(MISCREG_MIDELEG);
+        INTERRUPT sideleg = tc->readMiscReg(MISCREG_SIDELEG);
         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;
+                mask.mei = mideleg.mei ^ status.uie;
+                mask.mti = mideleg.mti ^ status.uie;
+                mask.msi = mideleg.msi ^ status.uie;
+                mask.sei = sideleg.sei ^ status.uie;
+                mask.sti = sideleg.sti ^ status.uie;
+                mask.ssi = sideleg.ssi ^ status.uie;
                 if (status.uie)
                     mask.uei = mask.uti = mask.usi = 1;
                 break;
             case PRV_S:
-                mask.mei = mask.mti = mask.msi = 1;
+                mask.mei = mideleg.mei ^ status.sie;
+                mask.mti = mideleg.mti ^ status.sie;
+                mask.msi = mideleg.msi ^ status.sie;
                 if (status.sie)
                     mask.sei = mask.sti = mask.ssi = 1;
                 mask.uei = mask.uti = mask.usi = 0;
@@ -111,9 +119,14 @@
     {
         assert(checkInterrupts());
         std::bitset<NumInterruptTypes> mask = globalMask();
-        for (int c = 0; c < NumInterruptTypes; c++)
-            if (checkInterrupt(c) && mask[c])
-                return std::make_shared<InterruptFault>(c);
+        const std::vector<int> interrupt_order {
+            INT_EXT_MACHINE, INT_TIMER_MACHINE, INT_SOFTWARE_MACHINE,
+            INT_EXT_SUPER, INT_TIMER_SUPER, INT_SOFTWARE_SUPER,
+            INT_EXT_USER, INT_TIMER_USER, INT_SOFTWARE_USER
+        };
+        for (const int &id : interrupt_order)
+            if (checkInterrupt(id) && mask[id])
+                return std::make_shared<InterruptFault>(id);
         return NoFault;
     }


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40076
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I6ce4fc843d2e0338355152c3fc33c966d6b4a481
Gerrit-Change-Number: 40076
Gerrit-PatchSet: 1
Gerrit-Owner: Peter Yuen <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to