arch,cpu: Change setCPU to setThreadContext in Interrupts.
authorGabe Black <gabeblack@google.com>
Tue, 12 May 2020 20:09:23 +0000 (13:09 -0700)
committerGabe Black <gabeblack@google.com>
Thu, 11 Jun 2020 23:42:54 +0000 (23:42 +0000)
The ThreadContext can be used to access the cpu if needed, and is a
more representative interface to various pieces of state than the CPU
itself. Also convert some of the methods in Interupts to use the
locally stored ThreadContext pointer instead of taking one as an
argument. This makes calling those methods simpler and less error
prone.

Change-Id: I740bd99f92e54e052a618a4ae2927ea1c4ece193
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28988
Reviewed-by: Gabe Black <gabeblack@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
19 files changed:
src/arch/arm/interrupts.cc
src/arch/arm/interrupts.hh
src/arch/arm/isa/insts/misc.isa
src/arch/generic/interrupts.hh
src/arch/mips/interrupts.cc
src/arch/mips/interrupts.hh
src/arch/power/interrupts.hh
src/arch/riscv/interrupts.hh
src/arch/sparc/interrupts.hh
src/arch/x86/interrupts.cc
src/arch/x86/interrupts.hh
src/cpu/base.cc
src/cpu/base.hh
src/cpu/intr_control.cc
src/cpu/kvm/x86_cpu.cc
src/cpu/minor/execute.cc
src/cpu/o3/commit_impl.hh
src/cpu/o3/cpu.cc
src/cpu/simple/base.cc

index 02f1e6df384c91ffb0640a05c04aa8d195c11148..ae1d4357dc8b8ab47aebdf37a3bc8eb01dabac6f 100644 (file)
@@ -46,7 +46,7 @@ ArmInterruptsParams::create()
 }
 
 bool
-ArmISA::Interrupts::takeInt(ThreadContext *tc, InterruptTypes int_type) const
+ArmISA::Interrupts::takeInt(InterruptTypes int_type) const
 {
     // Table G1-17~19 of ARM V8 ARM
     InterruptMask mask;
index e365a00e5b3af7f263ac508604f73c3f12b32f4f..814fd71a513633031d6b1fe0e20261e3b9e323ed 100644 (file)
@@ -57,19 +57,11 @@ namespace ArmISA
 class Interrupts : public BaseInterrupts
 {
   private:
-    BaseCPU * cpu;
-
     bool interrupts[NumInterruptTypes];
     uint64_t intStatus;
 
   public:
 
-    void
-    setCPU(BaseCPU * _cpu)
-    {
-        cpu = _cpu;
-    }
-
     typedef ArmInterruptsParams Params;
 
     const Params *
@@ -78,7 +70,7 @@ class Interrupts : public BaseInterrupts
         return dynamic_cast<const Params *>(_params);
     }
 
-    Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
+    Interrupts(Params * p) : BaseInterrupts(p)
     {
         clearAll();
     }
@@ -128,10 +120,10 @@ class Interrupts : public BaseInterrupts
         INT_MASK_P  // pending
     };
 
-    bool takeInt(ThreadContext *tc, InterruptTypes int_type) const;
+    bool takeInt(InterruptTypes int_type) const;
 
     bool
-    checkInterrupts(ThreadContext *tc) const
+    checkInterrupts() const
     {
         HCR  hcr  = tc->readMiscReg(MISCREG_HCR);
 
@@ -150,9 +142,9 @@ class Interrupts : public BaseInterrupts
                (hcr.va && allowVAbort)) )
             return false;
 
-        bool take_irq = takeInt(tc, INT_IRQ);
-        bool take_fiq = takeInt(tc, INT_FIQ);
-        bool take_ea =  takeInt(tc, INT_ABT);
+        bool take_irq = takeInt(INT_IRQ);
+        bool take_fiq = takeInt(INT_FIQ);
+        bool take_ea =  takeInt(INT_ABT);
 
         return ((interrupts[INT_IRQ] && take_irq)                   ||
                 (interrupts[INT_FIQ] && take_fiq)                   ||
@@ -220,9 +212,9 @@ class Interrupts : public BaseInterrupts
     }
 
     Fault
-    getInterrupt(ThreadContext *tc)
+    getInterrupt() override
     {
-        assert(checkInterrupts(tc));
+        assert(checkInterrupts());
 
         HCR  hcr  = tc->readMiscReg(MISCREG_HCR);
         CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
@@ -236,9 +228,9 @@ class Interrupts : public BaseInterrupts
         bool allowVFiq   = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
         bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
 
-        bool take_irq = takeInt(tc, INT_IRQ);
-        bool take_fiq = takeInt(tc, INT_FIQ);
-        bool take_ea =  takeInt(tc, INT_ABT);
+        bool take_irq = takeInt(INT_IRQ);
+        bool take_fiq = takeInt(INT_FIQ);
+        bool take_ea =  takeInt(INT_ABT);
 
         if (interrupts[INT_IRQ] && take_irq)
             return std::make_shared<Interrupt>();
@@ -262,21 +254,17 @@ class Interrupts : public BaseInterrupts
         panic("intStatus and interrupts not in sync\n");
     }
 
-    void
-    updateIntrInfo(ThreadContext *tc)
-    {
-        ; // nothing to do
-    }
+    void updateIntrInfo() override {} // nothing to do
 
     void
-    serialize(CheckpointOut &cp) const
+    serialize(CheckpointOut &cp) const override
     {
         SERIALIZE_ARRAY(interrupts, NumInterruptTypes);
         SERIALIZE_SCALAR(intStatus);
     }
 
     void
-    unserialize(CheckpointIn &cp)
+    unserialize(CheckpointIn &cp) override
     {
         UNSERIALIZE_ARRAY(interrupts, NumInterruptTypes);
         UNSERIALIZE_SCALAR(intStatus);
index cd44387337e01fe10d7b989eb522a3bdfdafb7ef..e8935b842777cd6d2a8fe631a635b4509df9acf5 100644 (file)
@@ -721,7 +721,7 @@ let {{
         SevMailbox = 0;
         PseudoInst::quiesceSkip(tc);
     } else if (tc->getCpuPtr()->getInterruptController(
-                tc->threadId())->checkInterrupts(tc)) {
+                tc->threadId())->checkInterrupts()) {
         PseudoInst::quiesceSkip(tc);
     } else {
         fault = trapWFx(tc, cpsr, scr, true);
index 3701db763fecca0cdabf4e07780449d39557eb6a..51dd8f53d4a64d458d72fda155001533e54d4089 100644 (file)
@@ -37,14 +37,14 @@ class BaseCPU;
 class BaseInterrupts : public SimObject
 {
   protected:
-    BaseCPU *cpu;
+    ThreadContext *tc = nullptr;
 
   public:
     typedef BaseInterruptsParams Params;
 
     BaseInterrupts(Params *p) : SimObject(p) {}
 
-    virtual void setCPU(BaseCPU * newCPU) = 0;
+    virtual void setThreadContext(ThreadContext *_tc) { tc = _tc; }
 
     const Params *
     params() const
@@ -59,16 +59,16 @@ class BaseInterrupts : public SimObject
     /*
      * Return whether there are any interrupts waiting to be recognized.
      */
-    virtual bool checkInterrupts(ThreadContext *tc) const = 0;
+    virtual bool checkInterrupts() const = 0;
     /*
      * Return an interrupt to process. This should return an interrupt exactly
      * when checkInterrupts returns true.
      */
-    virtual Fault getInterrupt(ThreadContext *tc) = 0;
+    virtual Fault getInterrupt() = 0;
     /*
      * Update interrupt related state after an interrupt has been processed.
      */
-    virtual void updateIntrInfo(ThreadContext *tc) = 0;
+    virtual void updateIntrInfo() = 0;
 
     /*
      * Old functions needed for compatability but which will be phased out
index ee4d00f6d8a0237a2a62d67c60a0928abf60b238..ad2692f7221e907d36c97d6d00bda0015c9196d9 100644 (file)
@@ -39,20 +39,22 @@ namespace MipsISA
 {
 
 static inline uint8_t
-getCauseIP(ThreadContext *tc) {
+getCauseIP(ThreadContext *tc)
+{
     CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
     return cause.ip;
 }
 
 static inline void
-setCauseIP(ThreadContext *tc, uint8_t val) {
+setCauseIP(ThreadContext *tc, uint8_t val)
+{
     CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
     cause.ip = val;
     tc->setMiscRegNoEffect(MISCREG_CAUSE, cause);
 }
 
 void
-Interrupts::post(int int_num, ThreadContext* tc)
+Interrupts::post(int int_num)
 {
     DPRINTF(Interrupt, "Interrupt %d posted\n", int_num);
     if (int_num < 0 || int_num >= NumInterruptLevels)
@@ -70,7 +72,7 @@ Interrupts::post(int int_num, int index)
 }
 
 void
-Interrupts::clear(int int_num, ThreadContext* tc)
+Interrupts::clear(int int_num)
 {
     DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num);
     if (int_num < 0 || int_num >= NumInterruptLevels)
@@ -88,24 +90,18 @@ Interrupts::clear(int int_num, int index)
 }
 
 void
-Interrupts::clearAll(ThreadContext *tc)
+Interrupts::clearAll()
 {
     DPRINTF(Interrupt, "Interrupts all cleared\n");
     uint8_t intstatus = 0;
     setCauseIP(tc, intstatus);
 }
 
-void
-Interrupts::clearAll()
-{
-    fatal("Must use Thread Context when clearing MIPS Interrupts in M5");
-}
-
 
 bool
-Interrupts::checkInterrupts(ThreadContext *tc) const
+Interrupts::checkInterrupts() const
 {
-    if (!interruptsPending(tc))
+    if (!interruptsPending())
         return false;
 
     //Check if there are any outstanding interrupts
@@ -126,9 +122,9 @@ Interrupts::checkInterrupts(ThreadContext *tc) const
 }
 
 Fault
-Interrupts::getInterrupt(ThreadContext * tc)
+Interrupts::getInterrupt()
 {
-    assert(checkInterrupts(tc));
+    assert(checkInterrupts());
 
     StatusReg M5_VAR_USED status = tc->readMiscRegNoEffect(MISCREG_STATUS);
     CauseReg M5_VAR_USED cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
@@ -139,7 +135,7 @@ Interrupts::getInterrupt(ThreadContext * tc)
 }
 
 bool
-Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const
+Interrupts::onCpuTimerInterrupt() const
 {
     RegVal compare = tc->readMiscRegNoEffect(MISCREG_COMPARE);
     RegVal count = tc->readMiscRegNoEffect(MISCREG_COUNT);
@@ -148,19 +144,15 @@ Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const
     return false;
 }
 
-void
-Interrupts::updateIntrInfo(ThreadContext *tc)
-{
-    //Nothing needs to be done.
-}
+void Interrupts::updateIntrInfo() {} // Nothing needs to be done.
 
 bool
-Interrupts::interruptsPending(ThreadContext *tc) const
+Interrupts::interruptsPending() const
 {
     //if there is a on cpu timer interrupt (i.e. Compare == Count)
     //update CauseIP before proceeding to interrupt
-    if (onCpuTimerInterrupt(tc)) {
-        DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc) == true\n");
+    if (onCpuTimerInterrupt()) {
+        DPRINTF(Interrupt, "Interrupts OnCpuTimerInterrupt() == true\n");
         //determine timer interrupt IP #
         IntCtlReg intCtl = tc->readMiscRegNoEffect(MISCREG_INTCTL);
         uint8_t intStatus = getCauseIP(tc);
index 17481a86dbc83f950460adedb1ccf129f9036edb..f79a8dfa852d923fb473ba1c64edd83485197fd2 100644 (file)
@@ -55,11 +55,7 @@ class Interrupts : public BaseInterrupts
         return dynamic_cast<const Params *>(_params);
     }
 
-    Interrupts(Params * p) : BaseInterrupts(p)
-    {
-    }
-
-    void setCPU(BaseCPU *_cpu) override {}
+    Interrupts(Params * p) : BaseInterrupts(p) {}
 
     //  post(int int_num, int index) is responsible
     //  for posting an interrupt. It sets a bit
@@ -67,7 +63,7 @@ class Interrupts : public BaseInterrupts
     //  MIPS register Cause is updated by updateIntrInfo
     //  which is called by checkInterrupts
     //
-    void post(int int_num, ThreadContext *tc);
+    void post(int int_num);
     void post(int int_num, int index) override;
 
     // clear(int int_num, int index) is responsible
@@ -76,7 +72,7 @@ class Interrupts : public BaseInterrupts
     //  MIPS register Cause is updated by updateIntrInfo
     //  which is called by checkInterrupts
     //
-    void clear(int int_num, ThreadContext* tc);
+    void clear(int int_num);
     void clear(int int_num, int index) override;
 
     //  clearAll() is responsible
@@ -85,25 +81,24 @@ class Interrupts : public BaseInterrupts
     //  MIPS register Cause is updated by updateIntrInfo
     //  which is called by checkInterrupts
     //
-    void clearAll(ThreadContext *tc);
     void clearAll() override;
 
-    // getInterrupt(ThreadContext * tc) checks if an interrupt
+    // getInterrupt() checks if an interrupt
     //  should be returned. It ands the interrupt mask and
     //  and interrupt pending bits to see if one exists. It
     //  also makes sure interrupts are enabled (IE) and
     //  that ERL and ERX are not set
     //
-    Fault getInterrupt(ThreadContext *tc) override;
+    Fault getInterrupt() override;
 
-    // updateIntrInfo(ThreadContext *tc) const syncs the
+    // updateIntrInfo() const syncs the
     //  MIPS cause register with the instatus variable. instatus
     //  is essentially a copy of the MIPS cause[IP7:IP0]
     //
-    void updateIntrInfo(ThreadContext *tc) override;
-    bool interruptsPending(ThreadContext *tc) const;
-    bool onCpuTimerInterrupt(ThreadContext *tc) const;
-    bool checkInterrupts(ThreadContext *tc) const override;
+    void updateIntrInfo() override;
+    bool interruptsPending() const;
+    bool onCpuTimerInterrupt() const;
+    bool checkInterrupts() const override;
 
     void
     serialize(CheckpointOut &cp) const override
index 6435e0e4e5de6f5f34a9066aefa9f5c3c2cd4b3f..29e665cae82dca256a1d13cea1f531edcedc7f89 100644 (file)
@@ -40,9 +40,6 @@ namespace PowerISA {
 
 class Interrupts : public BaseInterrupts
 {
-  private:
-    BaseCPU * cpu;
-
   public:
     typedef PowerInterruptsParams Params;
 
@@ -52,14 +49,7 @@ class Interrupts : public BaseInterrupts
         return dynamic_cast<const Params *>(_params);
     }
 
-    Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
-    {}
-
-    void
-    setCPU(BaseCPU * _cpu)
-    {
-        cpu = _cpu;
-    }
+    Interrupts(Params *p) : BaseInterrupts(p) {}
 
     void
     post(int int_num, int index)
@@ -80,20 +70,20 @@ class Interrupts : public BaseInterrupts
     }
 
     bool
-    checkInterrupts(ThreadContext *tc) const
+    checkInterrupts() const
     {
         panic("Interrupts::checkInterrupts not implemented.\n");
     }
 
     Fault
-    getInterrupt(ThreadContext *tc)
+    getInterrupt()
     {
-        assert(checkInterrupts(tc));
+        assert(checkInterrupts());
         panic("Interrupts::getInterrupt not implemented.\n");
     }
 
     void
-    updateIntrInfo(ThreadContext *tc)
+    updateIntrInfo()
     {
         panic("Interrupts::updateIntrInfo not implemented.\n");
     }
index 5fa6d782a8a62db4977fde2c775a0943af05c2a5..bf9f2a369a849be04b9881b590af6509447945da 100644 (file)
@@ -53,7 +53,6 @@ namespace RiscvISA {
 class Interrupts : public BaseInterrupts
 {
   private:
-    BaseCPU * cpu;
     std::bitset<NumInterruptTypes> ip;
     std::bitset<NumInterruptTypes> ie;
 
@@ -66,12 +65,10 @@ class Interrupts : public BaseInterrupts
         return dynamic_cast<const Params *>(_params);
     }
 
-    Interrupts(Params * p) : BaseInterrupts(p), cpu(nullptr), ip(0), ie(0) {}
-
-    void setCPU(BaseCPU * _cpu) { cpu = _cpu; }
+    Interrupts(Params * p) : BaseInterrupts(p), ip(0), ie(0) {}
 
     std::bitset<NumInterruptTypes>
-    globalMask(ThreadContext *tc) const
+    globalMask() const
     {
         INTERRUPT mask = 0;
         STATUS status = tc->readMiscReg(MISCREG_STATUS);
@@ -85,23 +82,23 @@ class Interrupts : public BaseInterrupts
     }
 
     bool checkInterrupt(int num) const { return ip[num] && ie[num]; }
-    bool checkInterrupts(ThreadContext *tc) const
+    bool checkInterrupts() const
     {
-        return (ip & ie & globalMask(tc)).any();
+        return (ip & ie & globalMask()).any();
     }
 
     Fault
-    getInterrupt(ThreadContext *tc)
+    getInterrupt()
     {
-        assert(checkInterrupts(tc));
-        std::bitset<NumInterruptTypes> mask = globalMask(tc);
+        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);
         return NoFault;
     }
 
-    void updateIntrInfo(ThreadContext *tc) {}
+    void updateIntrInfo() {}
 
     void
     post(int int_num, int index)
index 4f1086acbd1e041894755b31f211a7dbced8156b..d32f5af4dbd50d7198dbf88d9a736b7076b0c947 100644 (file)
@@ -56,19 +56,11 @@ enum InterruptTypes
 class Interrupts : public BaseInterrupts
 {
   private:
-    BaseCPU * cpu;
-
     uint64_t interrupts[NumInterruptTypes];
     uint64_t intStatus;
 
   public:
 
-    void
-    setCPU(BaseCPU * _cpu) override
-    {
-        cpu = _cpu;
-    }
-
     typedef SparcInterruptsParams Params;
 
     const Params *
@@ -77,7 +69,7 @@ class Interrupts : public BaseInterrupts
         return dynamic_cast<const Params *>(_params);
     }
 
-    Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
+    Interrupts(Params * p) : BaseInterrupts(p)
     {
         clearAll();
     }
@@ -129,7 +121,7 @@ class Interrupts : public BaseInterrupts
     }
 
     bool
-    checkInterrupts(ThreadContext *tc) const override
+    checkInterrupts() const override
     {
         if (!intStatus)
             return false;
@@ -187,9 +179,9 @@ class Interrupts : public BaseInterrupts
     }
 
     Fault
-    getInterrupt(ThreadContext *tc) override
+    getInterrupt() override
     {
-        assert(checkInterrupts(tc));
+        assert(checkInterrupts());
 
         HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
         PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
@@ -243,7 +235,7 @@ class Interrupts : public BaseInterrupts
         return NoFault;
     }
 
-    void updateIntrInfo(ThreadContext *tc) override {}
+    void updateIntrInfo() override {}
 
     uint64_t
     get_vec(int int_num)
index c81cf62c5eaf18fdf2026afdfb3de0dc038984aa..2be0746b1cfb5be973f28cfc59430f62c7c0f84d 100644 (file)
@@ -266,20 +266,20 @@ X86ISA::Interrupts::requestInterrupt(uint8_t vector,
         }
     }
     if (FullSystem)
-        cpu->wakeup(0);
+        tc->getCpuPtr()->wakeup(0);
 }
 
 
 void
-X86ISA::Interrupts::setCPU(BaseCPU * newCPU)
+X86ISA::Interrupts::setThreadContext(ThreadContext *_tc)
 {
-    assert(newCPU);
-    if (cpu != NULL && cpu->cpuId() != newCPU->cpuId()) {
-        panic("Local APICs can't be moved between CPUs"
-                " with different IDs.\n");
-    }
-    cpu = newCPU;
-    initialApicId = cpu->cpuId();
+    assert(_tc);
+    panic_if(tc != NULL && tc->cpuId() != _tc->cpuId(),
+             "Local APICs can't be moved between CPUs with different IDs.");
+
+    BaseInterrupts::setThreadContext(_tc);
+
+    initialApicId = tc->cpuId();
     regs[APIC_ID] = (initialApicId << 24);
     pioAddr = x86LocalAPICAddress(initialApicId, 0);
 }
@@ -343,7 +343,7 @@ X86ISA::Interrupts::completeIPI(PacketPtr pkt)
 AddrRangeList
 X86ISA::Interrupts::getAddrRanges() const
 {
-    assert(cpu);
+    assert(tc);
     AddrRangeList ranges;
     ranges.push_back(RangeSize(pioAddr, PageBytes));
     return ranges;
@@ -593,7 +593,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
 }
 
 
-X86ISA::Interrupts::Interrupts(Params * p)
+X86ISA::Interrupts::Interrupts(Params *p)
     : BaseInterrupts(p), sys(p->system), clockDomain(*p->clk_domain),
       apicTimerEvent([this]{ processApicTimerEvent(); }, name()),
       pendingSmi(false), smiVector(0),
@@ -602,7 +602,7 @@ X86ISA::Interrupts::Interrupts(Params * p)
       pendingInit(false), initVector(0),
       pendingStartup(false), startupVector(0),
       startedUp(false), pendingUnmaskableInt(false),
-      pendingIPIs(0), cpu(NULL),
+      pendingIPIs(0),
       intSlavePort(name() + ".int_slave", this, this),
       intMasterPort(name() + ".int_master", this, this, p->int_latency),
       pioPort(this), pioDelay(p->pio_latency)
@@ -618,7 +618,7 @@ X86ISA::Interrupts::Interrupts(Params * p)
 
 
 bool
-X86ISA::Interrupts::checkInterrupts(ThreadContext *tc) const
+X86ISA::Interrupts::checkInterrupts() const
 {
     RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS);
     if (pendingUnmaskableInt) {
@@ -648,9 +648,9 @@ X86ISA::Interrupts::checkInterruptsRaw() const
 }
 
 Fault
-X86ISA::Interrupts::getInterrupt(ThreadContext *tc)
+X86ISA::Interrupts::getInterrupt()
 {
-    assert(checkInterrupts(tc));
+    assert(checkInterrupts());
     // These are all probably fairly uncommon, so we'll make them easier to
     // check for.
     if (pendingUnmaskableInt) {
@@ -682,9 +682,9 @@ X86ISA::Interrupts::getInterrupt(ThreadContext *tc)
 }
 
 void
-X86ISA::Interrupts::updateIntrInfo(ThreadContext *tc)
+X86ISA::Interrupts::updateIntrInfo()
 {
-    assert(checkInterrupts(tc));
+    assert(checkInterrupts());
     if (pendingUnmaskableInt) {
         if (pendingSmi) {
             DPRINTF(LocalApic, "SMI sent to core.\n");
index 32ca489501cc749c640e3e1d8e386e3fb9dc865b..c1b256559088e52712736ee61c8e69cbc5b360d8 100644 (file)
@@ -66,7 +66,8 @@ class BaseCPU;
 
 int divideFromConf(uint32_t conf);
 
-namespace X86ISA {
+namespace X86ISA
+{
 
 ApicRegIndex decodeAddr(Addr paddr);
 
@@ -170,8 +171,6 @@ class Interrupts : public BaseInterrupts
 
     void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level);
 
-    BaseCPU *cpu;
-
     int initialApicId;
 
     // Ports for interrupts.
@@ -193,7 +192,7 @@ class Interrupts : public BaseInterrupts
      */
     typedef X86LocalApicParams Params;
 
-    void setCPU(BaseCPU * newCPU) override;
+    void setThreadContext(ThreadContext *_tc) override;
 
     const Params *
     params() const
@@ -261,7 +260,7 @@ class Interrupts : public BaseInterrupts
      * Functions for retrieving interrupts for the CPU to handle.
      */
 
-    bool checkInterrupts(ThreadContext *tc) const override;
+    bool checkInterrupts() const override;
     /**
      * Check if there are pending interrupts without ignoring the
      * interrupts disabled flag.
@@ -275,8 +274,8 @@ class Interrupts : public BaseInterrupts
      * @return true there are unmaskable interrupts pending.
      */
     bool hasPendingUnmaskable() const { return pendingUnmaskableInt; }
-    Fault getInterrupt(ThreadContext *tc) override;
-    void updateIntrInfo(ThreadContext *tc) override;
+    Fault getInterrupt() override;
+    void updateIntrInfo() override;
 
     /*
      * Serialization.
index dc3cbf051c826577ce907ff7562ce2610e45e064..2e8d7387100acf1e7e87385ba802014e121c5aec 100644 (file)
@@ -170,17 +170,6 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
         }
     }
 
-    // The interrupts should always be present unless this CPU is
-    // switched in later or in case it is a checker CPU
-    if (!params()->switched_out && !is_checker) {
-        fatal_if(interrupts.size() != numThreads,
-                 "CPU %s has %i interrupt controllers, but is expecting one "
-                 "per thread (%i)\n",
-                 name(), interrupts.size(), numThreads);
-        for (ThreadID tid = 0; tid < numThreads; tid++)
-            interrupts[tid]->setCPU(this);
-    }
-
     if (FullSystem) {
         if (params()->profile)
             profileEvent = new EventFunctionWrapper(
@@ -432,6 +421,11 @@ BaseCPU::registerThreadContexts()
 {
     assert(system->multiThread || numThreads == 1);
 
+    fatal_if(interrupts.size() != numThreads,
+             "CPU %s has %i interrupt controllers, but is expecting one "
+             "per thread (%i)\n",
+             name(), interrupts.size(), numThreads);
+
     ThreadID size = threadContexts.size();
     for (ThreadID tid = 0; tid < size; ++tid) {
         ThreadContext *tc = threadContexts[tid];
@@ -444,6 +438,8 @@ BaseCPU::registerThreadContexts()
 
         if (!FullSystem)
             tc->getProcessPtr()->assignThreadContext(tc->contextId());
+
+        interrupts[tid]->setThreadContext(tc);
     }
 }
 
@@ -628,7 +624,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
 
     interrupts = oldCPU->interrupts;
     for (ThreadID tid = 0; tid < numThreads; tid++) {
-        interrupts[tid]->setCPU(this);
+        interrupts[tid]->setThreadContext(threadContexts[tid]);
     }
     oldCPU->interrupts.clear();
 
index 810f2672c08e0ee2588a1c473b747127e1fd11c0..b9456a92644bf3df211c08507a4d9ed460cb6cff 100644 (file)
@@ -252,9 +252,9 @@ class BaseCPU : public ClockedObject
     }
 
     bool
-    checkInterrupts(ThreadContext *tc) const
+    checkInterrupts(ThreadID tid) const
     {
-        return FullSystem && interrupts[tc->threadId()]->checkInterrupts(tc);
+        return FullSystem && interrupts[tid]->checkInterrupts();
     }
 
     void processProfileEvent();
index 9b4a352c1f58ea8720a7414e8e5b41ecf7ea3156..293b211433ea5479ca0301068383612900a0ecde 100644 (file)
@@ -72,7 +72,7 @@ IntrControl::havePosted(int cpu_id) const
 {
     DPRINTF(IntrControl, "Check pending interrupts for CPU %d\n", cpu_id);
     auto *tc = sys->threads[cpu_id];
-    return tc->getCpuPtr()->checkInterrupts(tc);
+    return tc->getCpuPtr()->checkInterrupts(tc->threadId());
 }
 
 IntrControl *
index 16b75f4cb616024fc32c4b2191f9f20974ac85dc..6c44af0d1ec41f7a4d3008e2ec7b679e657498f5 100644 (file)
@@ -1141,8 +1141,8 @@ X86KvmCPU::deliverInterrupts()
         // they are getInterrupt() and updateIntrInfo() are called
         // atomically.
         EventQueue::ScopedMigration migrate(interrupts[0]->eventQueue());
-        fault = interrupts[0]->getInterrupt(tc);
-        interrupts[0]->updateIntrInfo(tc);
+        fault = interrupts[0]->getInterrupt();
+        interrupts[0]->updateIntrInfo();
     }
 
     X86Interrupt *x86int(dynamic_cast<X86Interrupt *>(fault.get()));
@@ -1200,7 +1200,7 @@ X86KvmCPU::kvmRun(Tick ticks)
             // the thread context and check if there are /really/
             // interrupts that should be delivered now.
             syncThreadContext();
-            if (lapic->checkInterrupts(tc)) {
+            if (lapic->checkInterrupts()) {
                 DPRINTF(KvmInt,
                         "M5 has pending interrupts, delivering interrupt.\n");
 
index ddb8db3cf04399f8a265f7ac12e39c01ecb882d9..d311d145730debd59a7bf075d9057eb7e78a8a9c 100644 (file)
@@ -409,7 +409,7 @@ Execute::handleMemResponse(MinorDynInstPtr inst,
 bool
 Execute::isInterrupted(ThreadID thread_id) const
 {
-    return cpu.checkInterrupts(cpu.getContext(thread_id));
+    return cpu.checkInterrupts(thread_id);
 }
 
 bool
@@ -418,13 +418,11 @@ Execute::takeInterrupt(ThreadID thread_id, BranchData &branch)
     DPRINTF(MinorInterrupt, "Considering interrupt status from PC: %s\n",
         cpu.getContext(thread_id)->pcState());
 
-    Fault interrupt = cpu.getInterruptController(thread_id)->getInterrupt
-        (cpu.getContext(thread_id));
+    Fault interrupt = cpu.getInterruptController(thread_id)->getInterrupt();
 
     if (interrupt != NoFault) {
         /* The interrupt *must* set pcState */
-        cpu.getInterruptController(thread_id)->updateIntrInfo
-            (cpu.getContext(thread_id));
+        cpu.getInterruptController(thread_id)->updateIntrInfo();
         interrupt->invoke(cpu.getContext(thread_id));
 
         assert(!lsq.accessesInFlight());
index 0f65e71689a16ea1afdba0cfcefe59ded5547de4..667f42b2eedbc02e0c8ea4ed74ba69b2b7a7b1aa 100644 (file)
@@ -733,7 +733,7 @@ void
 DefaultCommit<Impl>::handleInterrupt()
 {
     // Verify that we still have an interrupt to handle
-    if (!cpu->checkInterrupts(cpu->tcBase(0))) {
+    if (!cpu->checkInterrupts(0)) {
         DPRINTF(Commit, "Pending interrupt is cleared by master before "
                 "it got handled. Restart fetching from the orig path.\n");
         toIEW->commitInfo[0].clearInterrupt = true;
@@ -813,7 +813,7 @@ DefaultCommit<Impl>::commit()
 {
     if (FullSystem) {
         // Check if we have a interrupt and get read to handle it
-        if (cpu->checkInterrupts(cpu->tcBase(0)))
+        if (cpu->checkInterrupts(0))
             propagateInterrupt();
     }
 
@@ -1125,7 +1125,7 @@ DefaultCommit<Impl>::commitInsts()
                 //
                 // If we don't do this, we might end up in a live lock situation
                 if (!interrupt && avoidQuiesceLiveLock &&
-                    onInstBoundary && cpu->checkInterrupts(cpu->tcBase(0)))
+                    onInstBoundary && cpu->checkInterrupts(0))
                     squashAfter(tid, head_inst);
             } else {
                 DPRINTF(Commit, "Unable to commit head instruction PC:%s "
index 5230ee944ba8ef752f511e2485316dac570df08e..befd162fb11973b8e4004c8cd6abd13ee51214ca 100644 (file)
@@ -891,7 +891,7 @@ Fault
 FullO3CPU<Impl>::getInterrupts()
 {
     // Check if there are any outstanding interrupts
-    return this->interrupts[0]->getInterrupt(this->threadContexts[0]);
+    return this->interrupts[0]->getInterrupt();
 }
 
 template <class Impl>
@@ -905,7 +905,7 @@ FullO3CPU<Impl>::processInterrupts(const Fault &interrupt)
     // @todo: Allow other threads to handle interrupts.
 
     assert(interrupt != NoFault);
-    this->interrupts[0]->updateIntrInfo(this->threadContexts[0]);
+    this->interrupts[0]->updateIntrInfo();
 
     DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
     this->trap(interrupt, 0, nullptr);
index 8f23babfebea7274c70454e509b5ebf841ef448a..2a7b00aca7ef3829cc0ff7d216b70383ea370c3f 100644 (file)
@@ -439,12 +439,12 @@ BaseSimpleCPU::checkForInterrupts()
     SimpleThread* thread = t_info.thread;
     ThreadContext* tc = thread->getTC();
 
-    if (checkInterrupts(tc)) {
-        Fault interrupt = interrupts[curThread]->getInterrupt(tc);
+    if (checkInterrupts(curThread)) {
+        Fault interrupt = interrupts[curThread]->getInterrupt();
 
         if (interrupt != NoFault) {
             t_info.fetchOffset = 0;
-            interrupts[curThread]->updateIntrInfo(tc);
+            interrupts[curThread]->updateIntrInfo();
             interrupt->invoke(tc);
             thread->decoder.reset();
         }