From bd9fb891225bdcd6b2896303458c092ce3a92902 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 12 May 2020 13:09:23 -0700 Subject: [PATCH] arch,cpu: Change setCPU to setThreadContext in Interrupts. 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 Reviewed-by: Giacomo Travaglini Maintainer: Gabe Black Tested-by: kokoro --- src/arch/arm/interrupts.cc | 2 +- src/arch/arm/interrupts.hh | 40 ++++++++++++--------------------- src/arch/arm/isa/insts/misc.isa | 2 +- src/arch/generic/interrupts.hh | 10 ++++----- src/arch/mips/interrupts.cc | 40 +++++++++++++-------------------- src/arch/mips/interrupts.hh | 25 +++++++++------------ src/arch/power/interrupts.hh | 20 +++++------------ src/arch/riscv/interrupts.hh | 19 +++++++--------- src/arch/sparc/interrupts.hh | 18 +++++---------- src/arch/x86/interrupts.cc | 34 ++++++++++++++-------------- src/arch/x86/interrupts.hh | 13 +++++------ src/cpu/base.cc | 20 +++++++---------- src/cpu/base.hh | 4 ++-- src/cpu/intr_control.cc | 2 +- src/cpu/kvm/x86_cpu.cc | 6 ++--- src/cpu/minor/execute.cc | 8 +++---- src/cpu/o3/commit_impl.hh | 6 ++--- src/cpu/o3/cpu.cc | 4 ++-- src/cpu/simple/base.cc | 6 ++--- 19 files changed, 113 insertions(+), 166 deletions(-) diff --git a/src/arch/arm/interrupts.cc b/src/arch/arm/interrupts.cc index 02f1e6df3..ae1d4357d 100644 --- a/src/arch/arm/interrupts.cc +++ b/src/arch/arm/interrupts.cc @@ -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; diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index e365a00e5..814fd71a5 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -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(_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(); @@ -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); diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index cd4438733..e8935b842 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -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); diff --git a/src/arch/generic/interrupts.hh b/src/arch/generic/interrupts.hh index 3701db763..51dd8f53d 100644 --- a/src/arch/generic/interrupts.hh +++ b/src/arch/generic/interrupts.hh @@ -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 diff --git a/src/arch/mips/interrupts.cc b/src/arch/mips/interrupts.cc index ee4d00f6d..ad2692f72 100644 --- a/src/arch/mips/interrupts.cc +++ b/src/arch/mips/interrupts.cc @@ -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); diff --git a/src/arch/mips/interrupts.hh b/src/arch/mips/interrupts.hh index 17481a86d..f79a8dfa8 100644 --- a/src/arch/mips/interrupts.hh +++ b/src/arch/mips/interrupts.hh @@ -55,11 +55,7 @@ class Interrupts : public BaseInterrupts return dynamic_cast(_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 diff --git a/src/arch/power/interrupts.hh b/src/arch/power/interrupts.hh index 6435e0e4e..29e665cae 100644 --- a/src/arch/power/interrupts.hh +++ b/src/arch/power/interrupts.hh @@ -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(_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"); } diff --git a/src/arch/riscv/interrupts.hh b/src/arch/riscv/interrupts.hh index 5fa6d782a..bf9f2a369 100644 --- a/src/arch/riscv/interrupts.hh +++ b/src/arch/riscv/interrupts.hh @@ -53,7 +53,6 @@ namespace RiscvISA { class Interrupts : public BaseInterrupts { private: - BaseCPU * cpu; std::bitset ip; std::bitset ie; @@ -66,12 +65,10 @@ class Interrupts : public BaseInterrupts return dynamic_cast(_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 - 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 mask = globalMask(tc); + assert(checkInterrupts()); + std::bitset mask = globalMask(); for (int c = 0; c < NumInterruptTypes; c++) if (checkInterrupt(c) && mask[c]) return std::make_shared(c); return NoFault; } - void updateIntrInfo(ThreadContext *tc) {} + void updateIntrInfo() {} void post(int int_num, int index) diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 4f1086acb..d32f5af4d 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -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(_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) diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index c81cf62c5..2be0746b1 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -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"); diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 32ca48950..c1b256559 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -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. diff --git a/src/cpu/base.cc b/src/cpu/base.cc index dc3cbf051..2e8d73871 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -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(); diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 810f2672c..b9456a926 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -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(); diff --git a/src/cpu/intr_control.cc b/src/cpu/intr_control.cc index 9b4a352c1..293b21143 100644 --- a/src/cpu/intr_control.cc +++ b/src/cpu/intr_control.cc @@ -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 * diff --git a/src/cpu/kvm/x86_cpu.cc b/src/cpu/kvm/x86_cpu.cc index 16b75f4cb..6c44af0d1 100644 --- a/src/cpu/kvm/x86_cpu.cc +++ b/src/cpu/kvm/x86_cpu.cc @@ -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(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"); diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc index ddb8db3cf..d311d1457 100644 --- a/src/cpu/minor/execute.cc +++ b/src/cpu/minor/execute.cc @@ -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()); diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 0f65e7168..667f42b2e 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -733,7 +733,7 @@ void DefaultCommit::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::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::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 " diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 5230ee944..befd162fb 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -891,7 +891,7 @@ Fault FullO3CPU::getInterrupts() { // Check if there are any outstanding interrupts - return this->interrupts[0]->getInterrupt(this->threadContexts[0]); + return this->interrupts[0]->getInterrupt(); } template @@ -905,7 +905,7 @@ FullO3CPU::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); diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 8f23babfe..2a7b00aca 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -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(); } -- 2.30.2