From 7e30bea9036697afbe759f5f62a9332e4ba2ce3a Mon Sep 17 00:00:00 2001 From: Kajol Jain Date: Thu, 13 Jun 2019 14:12:02 +0530 Subject: [PATCH] arch-power: Add support for external interrupts Change-Id: Ib6f0b12064498483b87d7030ca7551829766fe5b Signed-off-by: Kajol Jain --- configs/common/FSConfig.py | 7 +++++-- src/arch/power/PowerSystem.py | 4 ++++ src/arch/power/faults.hh | 36 +++++++++++++++++++++++++++++++++- src/arch/power/interrupts.hh | 7 +++++++ src/arch/power/isa/decoder.isa | 1 + src/arch/power/system.cc | 6 ++++-- 6 files changed, 56 insertions(+), 5 deletions(-) diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index aa1da38e5..535ee72ae 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -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; diff --git a/src/arch/power/PowerSystem.py b/src/arch/power/PowerSystem.py index 67ab7d73a..eb1ab6d7d 100644 --- a/src/arch/power/PowerSystem.py +++ b/src/arch/power/PowerSystem.py @@ -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") diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh index 1ea7c5487..4a891882c 100644 --- a/src/arch/power/faults.hh +++ b/src/arch/power/faults.hh @@ -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: diff --git a/src/arch/power/interrupts.hh b/src/arch/power/interrupts.hh index f1351b5cb..2454329b1 100644 --- a/src/arch/power/interrupts.hh +++ b/src/arch/power/interrupts.hh @@ -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(); } + else if (interrupts[DirectExt]){ + clear(DirectExt,0); + return std::make_shared(); + } + else return NoFault; } diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index edb4d5340..3c0a4baa0 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -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 ]); diff --git a/src/arch/power/system.cc b/src/arch/power/system.cc index db44eb58f..2acee2695 100644 --- a/src/arch/power/system.cc +++ b/src/arch/power/system.cc @@ -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 -- 2.30.2