arch-power: Add support for external interrupts
authorKajol Jain <kajoljain797@gmail.com>
Thu, 13 Jun 2019 08:42:02 +0000 (14:12 +0530)
committerSandipan Das <sandipan@linux.ibm.com>
Tue, 20 Aug 2019 06:48:10 +0000 (12:18 +0530)
Change-Id: Ib6f0b12064498483b87d7030ca7551829766fe5b
Signed-off-by: Kajol Jain <kajoljain797@gmail.com>
configs/common/FSConfig.py
src/arch/power/PowerSystem.py
src/arch/power/faults.hh
src/arch/power/interrupts.hh
src/arch/power/isa/decoder.isa
src/arch/power/system.cc

index c293ab1e0ba5ba177ea9b40b3c41553bf92dda79..80a5828b95951f4c07990686d3cb675452b66fbe 100644 (file)
@@ -706,9 +706,12 @@ def makeLinuxPowerSystem(mem_mode, numCPUs=1, mdesc=None, cmdline=None):
     self.system_port = self.membus.slave
     self.intrctrl = IntrControl()
     if not cmdline:
-        cmdline = 'irqpoll lpj=1000000000'
+        cmdline = 'earlyprintk=ttyS0 console=ttyS0 irqpoll lpj=1000000000'
     self.boot_osflags = fillInCmdline(mdesc, cmdline)
-    self.kernel = binary('vmlinux')
+    #self.kernel = binary('vmlinux')
+    self.skiboot = binary('skiboot.elf');
+    self.kernel = binary('vmlinux');
+    self.initramfs = binary('initramfs.cpio');
     self.dtb_filename = binary('gem5-power9-fs.dtb')
     self.multi_thread = True;
     self._num_cpus = 2;
index 67ab7d73a22fd7220ac9a3033f49d0243173a98b..eb1ab6d7dcb1e8261935ba9579ed0038a9cfc46b 100644 (file)
@@ -43,6 +43,10 @@ class PowerSystem(System):
     cxx_header = 'arch/power/system.hh'
     dtb_filename = Param.String("",
         "File that contains the Device Tree Blob. Don't use DTB if empty.")
+    skiboot = Param.String("",
+            "File that contains the OPAL firmware.");
+    initramfs = Param.String("",
+            "File that contains the initramfs image");
     early_kernel_symbols = Param.Bool(False,
         "enable early kernel symbol tables before MMU")
 
index d6c1a31b209cfd91e601f512c9fb3b5b35ec7888..a4191b5ecb11b9e1b2c8115a9903d42c70d1e740 100644 (file)
@@ -52,7 +52,8 @@ enum pcSet
     DataStoragePCSet = 0x300,
     InstrStoragePCSet = 0x400,
     PriDoorbellPCSet = 0xA00,
-    HypDoorbellPCSet = 0xe80
+    HypDoorbellPCSet = 0xe80,
+    DirectExternalPCSet = 0x500
 };
 
 extern long stdout_buf_addr;
@@ -153,6 +154,39 @@ class PowerInterrupt : public PowerFaultBase
     }
 };
 
+class DirectExternalInterrupt : public PowerInterrupt
+{
+  public:
+    DirectExternalInterrupt()
+    {
+    }
+    virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst =
+                        StaticInst::nullStaticInstPtr)
+    {
+      printf("Direct External Interrupt invoked\n");
+      // Refer Power ISA Manual v3.0B Book-III, section 6.5.7.1
+      Lpcr lpcr = tc->readIntReg(INTREG_LPCR);
+
+      if (lpcr.lpes){
+        tc->setIntReg(INTREG_SRR0 , tc->instAddr());
+        PowerInterrupt::updateSRR1(tc);
+        PowerInterrupt::updateMsr(tc);
+        Msr msr =  tc->readIntReg(INTREG_MSR);
+        msr.ri = 0;
+        tc->setIntReg(INTREG_MSR, msr);
+      }
+      else{
+        tc->setIntReg(INTREG_HSRR0 , tc->instAddr());
+        PowerInterrupt::updateHSRR1(tc);
+        PowerInterrupt::updateMsr(tc);
+        Msr msr =  tc->readIntReg(INTREG_MSR);
+        msr.hv = 1;
+        tc->setIntReg(INTREG_MSR, msr);
+      }
+      tc->pcState(DirectExternalPCSet);
+    }
+};
+
 class PriDoorbellInterrupt : public PowerInterrupt
 {
   public:
index 81045d294b08d2d898791d5fe73c919020daa4dc..5dbe6c389be64ca098e3cb8c4b98614bfb06298e 100644 (file)
@@ -116,6 +116,8 @@ class Interrupts : public SimObject
          interrupts[Decrementer] = 1;
        if (msr.ee)
        {
+         if (interrupts[2] == 1)
+           return true;
          for (int i = 0; i < NumInterruptLevels; i++) {
              if (interrupts[i] == 1)
                return true;
@@ -142,6 +144,11 @@ class Interrupts : public SimObject
             clear(DirHypDoorbell,0);
             return std::make_shared<HypDoorbellInterrupt>();
         }
+        else if (interrupts[DirectExt]){
+            clear(DirectExt,0);
+            return std::make_shared<DirectExternalInterrupt>();
+        }
+
         else return NoFault;
     }
 
index 39c0ddef73ee83f053095be1fd5a2546d1d89c48..9e89d7419d98c5925f4e785a32106dbefbc9212d 100644 (file)
@@ -698,6 +698,7 @@ decode PO default Unknown::unknown() {
                 0x378: mtmmcr0({{MMCR0 = Rs;}});
                 0x380: mtcfar({{ CFAR = Rs; }});
                 0x390: mttbl({{ TBL = Rs; }});
+                0x33c: mtspr({{ }});
                 0x3a0: mtamr({{AMR = Rs;}}, [ IsPrivileged ]);
                 0x3a1: mtiamr({{IAMR = Rs;}});
                 0x3a4: mtuamor({{UAMOR = Rs;}}, [ IsPrivileged ]);
index db44eb58fdc89c9b8e72c31fd192b326404a8a30..2acee2695cca7a4b9e808e2c584782caedf0e300 100644 (file)
@@ -70,7 +70,8 @@ PowerSystem::initState()
                     (int)threadContexts.size());
 
     ThreadContext *tc = threadContexts[0];
-    tc->pcState(tc->getSystemPtr()->kernelEntry);
+    //tc->pcState(tc->getSystemPtr()->kernelEntry);
+    tc->pcState(0x10); // For skiboot
     //Sixty Four, little endian,Hypervisor bits are enabled.
     // IR and DR bits are disabled.
     Msr msr = 0x9000000000000001;
@@ -78,7 +79,8 @@ PowerSystem::initState()
     // This PVR is specific to power9
     // Setting TB register to 0
     tc->setIntReg(INTREG_TB , 0x0);
-    tc->setIntReg(INTREG_PVR , 0x004e1100);
+    //tc->setIntReg(INTREG_PVR , 0x004e1100);
+    tc->setIntReg(INTREG_PVR , 0x004e0200);
     tc->setIntReg(INTREG_MSR , msr);
     //ArgumentReg0 is initialized with 0xc00000 because in linux/system.cc
     //dtb is loaded at 0xc00000