arch-power: Add support for external interrupts
authorKajol Jain <kajoljain797@gmail.com>
Thu, 13 Jun 2019 08:42:02 +0000 (14:12 +0530)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 24 Jan 2021 04:24:48 +0000 (04:24 +0000)
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 aa1da38e510fc9faa629fd294e286042a0d0258a..535ee72aedd1473212c0e04d20e86e1376b60a33 100644 (file)
@@ -669,9 +669,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 1ea7c5487657b280eaec96d9b0e0995cac016864..4a891882c3d0845025cf0223548c493d3dc68920 100644 (file)
@@ -49,7 +49,8 @@ enum pcSet
     DataStoragePCSet = 0x300,
     InstrStoragePCSet = 0x400,
     PriDoorbellPCSet = 0xA00,
-    HypDoorbellPCSet = 0xe80
+    HypDoorbellPCSet = 0xe80,
+    DirectExternalPCSet = 0x500
 };
 
 extern long stdout_buf_addr;
@@ -150,6 +151,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 f1351b5cbbccc3fc32fa1b211b72a1604b98dc77..2454329b1ce6c9a959d503f720117b3214607056 100644 (file)
@@ -114,6 +114,8 @@ class Interrupts : public BaseInterrupts
          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;
@@ -140,6 +142,11 @@ class Interrupts : public BaseInterrupts
             clear(DirHypDoorbell,0);
             return std::make_shared<HypDoorbellInterrupt>();
         }
+        else if (interrupts[DirectExt]){
+            clear(DirectExt,0);
+            return std::make_shared<DirectExternalInterrupt>();
+        }
+
         else return NoFault;
     }
 
index edb4d5340712c6143f0a1c2de33b26c7db562444..3c0a4baa0d74911ad66c805cea908e7b49676cf7 100644 (file)
@@ -696,6 +696,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