arch-power: Modify Interrupt handler for DSI and ISI
authorkajoljain379 <kajoljain797@gmail.com>
Wed, 20 Mar 2019 09:45:37 +0000 (15:15 +0530)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 24 Jan 2021 03:59:33 +0000 (03:59 +0000)
* Modify Interrupt handler for Data storage (DSI) and Instruction
  Storage Interrupt (ISI).
* Added function to check mode of instruction.
* Added function to prepare registers for DSI.
* Added function to prepare registers for ISI.

Change-Id: I62ee5116c2acdbad225f7dc7fe72bb95d9462dc4
Signed-off-by: kajoljain379 <kajoljain797@gmail.com>
src/arch/power/faults.hh
src/arch/power/radixwalk.cc
src/arch/power/radixwalk.hh

index 81ea3480bdc4534081d8268cdfc700c6fe35bcb7..48f149fb9cf3650bfb909f58fe08a89b6ed70457 100644 (file)
@@ -136,6 +136,10 @@ class PowerInterrupt : public PowerFaultBase
     }
 };
 
+//SRR1 value is correctly set by the entity raising
+//Instruction Storage Interrupt. So, no need to
+//Update here.
+
 class InstrStorageInterrupt : public PowerInterrupt
 {
 public:
@@ -143,41 +147,14 @@ public:
   {
   }
   virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst =
-                       StaticInst::nullStaticInstPtr , uint64_t bitSet = 0)
+                       StaticInst::nullStaticInstPtr)
     {
       tc->setIntReg(INTREG_SRR0 , tc->instAddr());
-      PowerInterrupt::updateSRR1(tc, bitSet);
       PowerInterrupt::updateMsr(tc);
       tc->pcState(InstrStoragePCSet);
     }
 };
 
-class InstrInvalidInterrupt : public InstrStorageInterrupt
-{
-public:
-  InstrInvalidInterrupt()
-    {
-    }
-    virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst =
-                       StaticInst::nullStaticInstPtr)
-    {
-      InstrStorageInterrupt::invoke(tc, inst ,setBitMask(INVALID_SET_BIT));
-    }
-};
-
-//When permissions or privilege violates
-class InstrPriStorageInterrupt : public InstrStorageInterrupt
-{
-public:
-  InstrPriStorageInterrupt()
-    {
-    }
-    virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst =
-                       StaticInst::nullStaticInstPtr)
-    {
-      InstrStorageInterrupt::invoke(tc, inst ,setBitMask(PERMISSION_BIT));
-    }
-};
 
 class DataStorageInterrupt :public PowerInterrupt
 {
@@ -186,47 +163,15 @@ public:
     {
     }
     virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst =
-                       StaticInst::nullStaticInstPtr ,uint64_t bitSet = 0)
+                       StaticInst::nullStaticInstPtr)
     {
-      Msr msr = tc->readIntReg(INTREG_MSR);
       tc->setIntReg(INTREG_SRR0 , tc->instAddr());
-      PowerInterrupt::updateSRR1(tc, 0);
-      uint64_t dsisr = tc->readIntReg(INTREG_DSISR);
-      dsisr = (dsisr & DSISR_MASK) | bitSet;
-      if (msr.dr)
-        dsisr = setbit(33, dsisr);
-      tc->setIntReg(INTREG_DSISR, dsisr);
+      PowerInterrupt::updateSRR1(tc);
       PowerInterrupt::updateMsr(tc);
       tc->pcState(DataStoragePCSet);
     }
 };
 
-class DataInvalidInterrupt : public DataStorageInterrupt
-{
-public:
-  DataInvalidInterrupt()
-    {
-    }
-    virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst =
-                       StaticInst::nullStaticInstPtr)
-    {
-      DataStorageInterrupt::invoke(tc, inst ,setBitMask(INVALID_SET_BIT));
-    }
-};
-
-//When permissions or privilege violates
-class DataPriStorageInterrupt : public DataStorageInterrupt
-{
-public:
-  DataPriStorageInterrupt()
-    {
-    }
-    virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst =
-                       StaticInst::nullStaticInstPtr)
-    {
-      DataStorageInterrupt::invoke(tc, inst ,setBitMask(PERMISSION_BIT));
-    }
-};
 
 //TODO: Need to add Floating point and TM Bad thing fault handler
 class ProgramInterrupt : public PowerInterrupt
index efa3422e42f28e27ea98eef2249d5c6bc75d8e5b..a293c595afde1784f82f65b5ab751d13daebb6da 100644 (file)
@@ -15,6 +15,7 @@
 #define PRTB_MASK      0x0ffffffffffff
 #define PRTB_ALIGN     4
 #define TABLE_BASE_ALIGN     PRTB_SHIFT
+#define DSISR_MASK    0x00000000ffffffff
 
 #define RPDB_SHIFT     8
 #define RPDB_MASK      0x0fffffffffffff
@@ -88,6 +89,40 @@ RadixWalk::writePhysMem(uint64_t addr, uint64_t dataSize)
     return ret;
 }
 
+Fault
+RadixWalk::prepareDSI(ThreadContext * tc, RequestPtr req,
+                    BaseTLB::Mode mode, uint64_t BitMask)
+{
+    uint64_t dsisr = tc->readIntReg(INTREG_DSISR);
+    dsisr = (dsisr & (~(DSISR_MASK))) | BitMask;
+    if (mode == BaseTLB::Write)
+      dsisr = dsisr | ISSTORE;
+    tc->setIntReg(INTREG_DSISR, dsisr);
+    tc->setIntReg(INTREG_DAR, req->getVaddr());
+    return std::make_shared<DataStorageInterrupt>();
+}
+
+Fault
+RadixWalk::prepareISI(ThreadContext * tc, RequestPtr req,
+                     uint64_t BitMask)
+{
+    Msr msr = tc->readIntReg(INTREG_MSR);
+    //here unsetting SRR1 bits 33-36 and 42-47 according to ISA
+    uint64_t srr1 = ((msr & unsetMask(31, 27)) & unsetMask(22,16)) | BitMask;
+    tc->setIntReg(INTREG_SRR1, srr1);
+    return std::make_shared<InstrStorageInterrupt>();
+}
+
+Fault
+RadixWalk::prepareSI(ThreadContext * tc, RequestPtr req,
+                    BaseTLB::Mode mode, uint64_t BitMask)
+{
+    if (mode != BaseTLB::Execute)
+      return prepareDSI(tc, req, mode, BitMask);
+    else
+      return prepareISI(tc, req, BitMask);
+}
+
 uint32_t geteffLPID(ThreadContext *tc)
 {
     Msr msr = tc->readIntReg(INTREG_MSR);
index dae379bfffd808124146b4c41aa653da9e336646..850c952e8e53032001a043b229159070716d30c1 100644 (file)
@@ -70,6 +70,14 @@ namespace PowerISA
         std::pair<Addr,Fault> walkTree(Addr vaddr ,uint64_t curBase ,
                          ThreadContext * tc ,BaseTLB::Mode mode ,
                          uint64_t curSize ,uint64_t usefulBits);
+        Fault prepareSI(ThreadContext * tc,
+              RequestPtr req, BaseTLB::Mode mode, uint64_t BitMask);
+
+        Fault prepareISI(ThreadContext * tc,
+              RequestPtr req, uint64_t BitMask);
+
+        Fault prepareDSI(ThreadContext * tc, RequestPtr req,
+                         BaseTLB::Mode mode,uint64_t BitMask);
 
         typedef PowerRadixWalkParams Params;