From ae390c629f2a10fd6a1c2eb50b7d3510d6e091da Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 2 Sep 2019 21:26:12 -0700 Subject: [PATCH] arch: Make a base class for Interrupts. That abstracts the ISA further from the CPU, getting us a small step closer to being able to build in more than one ISA at a time. Change-Id: Ibf7e26a3df411ffe994ac1e11d2a53b656863223 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20831 Tested-by: kokoro Reviewed-by: Jason Lowe-Power Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg --- src/arch/alpha/AlphaInterrupts.py | 4 +- src/arch/alpha/interrupts.hh | 6 +- src/arch/alpha/isa/decoder.isa | 2 +- src/arch/arm/ArmInterrupts.py | 4 +- src/arch/arm/interrupts.hh | 6 +- src/arch/arm/isa.cc | 27 +++++--- src/arch/arm/isa/includes.isa | 1 + src/arch/arm/isa/insts/misc.isa | 5 +- src/arch/generic/BaseInterrupts.py | 34 +++++++++++ src/arch/generic/SConscript | 1 + src/arch/generic/interrupts.hh | 98 ++++++++++++++++++++++++++++++ src/arch/mips/MipsInterrupts.py | 4 +- src/arch/mips/interrupts.cc | 2 +- src/arch/mips/interrupts.hh | 8 +-- src/arch/power/PowerInterrupts.py | 4 +- src/arch/power/interrupts.hh | 6 +- src/arch/riscv/RiscvInterrupts.py | 4 +- src/arch/riscv/interrupts.hh | 7 ++- src/arch/riscv/isa.cc | 31 +++++++--- src/arch/sparc/SparcInterrupts.py | 4 +- src/arch/sparc/interrupts.hh | 5 +- src/arch/sparc/isa.cc | 1 + src/arch/x86/X86LocalApic.py | 3 +- src/arch/x86/interrupts.cc | 2 +- src/arch/x86/interrupts.hh | 7 ++- src/arch/x86/pagetable_walker.cc | 1 + src/cpu/BaseCPU.py | 9 +-- src/cpu/base.hh | 6 +- src/cpu/kvm/base.hh | 1 + src/cpu/kvm/x86_cpu.cc | 10 ++- src/dev/x86/i82094aa.cc | 3 +- 31 files changed, 236 insertions(+), 70 deletions(-) create mode 100644 src/arch/generic/BaseInterrupts.py create mode 100644 src/arch/generic/interrupts.hh diff --git a/src/arch/alpha/AlphaInterrupts.py b/src/arch/alpha/AlphaInterrupts.py index a75b11fc0..7bab9b0ca 100644 --- a/src/arch/alpha/AlphaInterrupts.py +++ b/src/arch/alpha/AlphaInterrupts.py @@ -26,9 +26,9 @@ # # Authors: Gabe Black -from m5.SimObject import SimObject +from m5.objects.BaseInterrupts import BaseInterrupts -class AlphaInterrupts(SimObject): +class AlphaInterrupts(BaseInterrupts): type = 'AlphaInterrupts' cxx_class = 'AlphaISA::Interrupts' cxx_header = "arch/alpha/interrupts.hh" diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 61ac6c968..e054b4389 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -36,17 +36,17 @@ #include "arch/alpha/faults.hh" #include "arch/alpha/isa_traits.hh" +#include "arch/generic/interrupts.hh" #include "base/compiler.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" #include "debug/Flow.hh" #include "debug/Interrupt.hh" #include "params/AlphaInterrupts.hh" -#include "sim/sim_object.hh" namespace AlphaISA { -class Interrupts : public SimObject +class Interrupts : public BaseInterrupts { private: bool newInfoSet; @@ -67,7 +67,7 @@ class Interrupts : public SimObject return dynamic_cast(_params); } - Interrupts(Params * p) : SimObject(p), cpu(NULL) + Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL) { memset(interrupts, 0, sizeof(interrupts)); intstatus = 0; diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 8732d70ba..020e43359 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -982,7 +982,7 @@ decode OPCODE default Unknown::unknown() { }}, IsNonSpeculative); 0x01: quiesce({{ // Don't sleep if (unmasked) interrupts are pending - Interrupts* interrupts = + BaseInterrupts* interrupts = xc->tcBase()->getCpuPtr()->getInterruptController(0); if (interrupts->checkInterrupts(xc->tcBase())) { PseudoInst::quiesceSkip(xc->tcBase()); diff --git a/src/arch/arm/ArmInterrupts.py b/src/arch/arm/ArmInterrupts.py index 68a58958d..9a6b546a5 100644 --- a/src/arch/arm/ArmInterrupts.py +++ b/src/arch/arm/ArmInterrupts.py @@ -26,9 +26,9 @@ # # Authors: Ali Saidi -from m5.SimObject import SimObject +from m5.objects.BaseInterrupts import BaseInterrupts -class ArmInterrupts(SimObject): +class ArmInterrupts(BaseInterrupts): type = 'ArmInterrupts' cxx_class = 'ArmISA::Interrupts' cxx_header = "arch/arm/interrupts.hh" diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index 8d0cb49ea..1f8e321cd 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -48,15 +48,15 @@ #include "arch/arm/miscregs.hh" #include "arch/arm/registers.hh" #include "arch/arm/utility.hh" +#include "arch/generic/interrupts.hh" #include "cpu/thread_context.hh" #include "debug/Interrupt.hh" #include "params/ArmInterrupts.hh" -#include "sim/sim_object.hh" namespace ArmISA { -class Interrupts : public SimObject +class Interrupts : public BaseInterrupts { private: BaseCPU * cpu; @@ -80,7 +80,7 @@ class Interrupts : public SimObject return dynamic_cast(_params); } - Interrupts(Params * p) : SimObject(p), cpu(NULL) + Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL) { clearAll(); } diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 6e65102b6..712b43040 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -39,6 +39,9 @@ */ #include "arch/arm/isa.hh" + +#include "arch/arm/faults.hh" +#include "arch/arm/interrupts.hh" #include "arch/arm/pmu.hh" #include "arch/arm/system.hh" #include "arch/arm/tlb.hh" @@ -672,15 +675,23 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc) case MISCREG_DBGDSCRint: return 0; case MISCREG_ISR: - return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR( - readMiscRegNoEffect(MISCREG_HCR), - readMiscRegNoEffect(MISCREG_CPSR), - readMiscRegNoEffect(MISCREG_SCR)); + { + auto ic = dynamic_cast( + tc->getCpuPtr()->getInterruptController(tc->threadId())); + return ic->getISR( + readMiscRegNoEffect(MISCREG_HCR), + readMiscRegNoEffect(MISCREG_CPSR), + readMiscRegNoEffect(MISCREG_SCR)); + } case MISCREG_ISR_EL1: - return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR( - readMiscRegNoEffect(MISCREG_HCR_EL2), - readMiscRegNoEffect(MISCREG_CPSR), - readMiscRegNoEffect(MISCREG_SCR_EL3)); + { + auto ic = dynamic_cast( + tc->getCpuPtr()->getInterruptController(tc->threadId())); + return ic->getISR( + readMiscRegNoEffect(MISCREG_HCR_EL2), + readMiscRegNoEffect(MISCREG_CPSR), + readMiscRegNoEffect(MISCREG_SCR_EL3)); + } case MISCREG_DCZID_EL0: return 0x04; // DC ZVA clear 64-byte chunks case MISCREG_HCPTR: diff --git a/src/arch/arm/isa/includes.isa b/src/arch/arm/isa/includes.isa index f054bc862..d584d8225 100644 --- a/src/arch/arm/isa/includes.isa +++ b/src/arch/arm/isa/includes.isa @@ -96,6 +96,7 @@ output exec {{ #include #include "arch/arm/faults.hh" +#include "arch/arm/interrupts.hh" #include "arch/arm/isa.hh" #include "arch/arm/isa_traits.hh" #include "arch/arm/utility.hh" diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index ecf09aab5..b2dc2f6d8 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -756,8 +756,9 @@ let {{ // WFI doesn't sleep if interrupts are pending (masked or not) ThreadContext *tc = xc->tcBase(); - if (tc->getCpuPtr()->getInterruptController( - tc->threadId())->checkWfiWake(hcr, cpsr, scr)) { + auto *ic = dynamic_cast( + tc->getCpuPtr()->getInterruptController(tc->threadId())); + if (ic->checkWfiWake(hcr, cpsr, scr)) { PseudoInst::quiesceSkip(tc); } else { fault = trapWFx(tc, cpsr, scr, false); diff --git a/src/arch/generic/BaseInterrupts.py b/src/arch/generic/BaseInterrupts.py new file mode 100644 index 000000000..b373d80bc --- /dev/null +++ b/src/arch/generic/BaseInterrupts.py @@ -0,0 +1,34 @@ +# Copyright 2019 Google, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.params import * +from m5.SimObject import SimObject + +class BaseInterrupts(SimObject): + type = 'BaseInterrupts' + abstract = True + cxx_header = "arch/generic/interrupts.hh" diff --git a/src/arch/generic/SConscript b/src/arch/generic/SConscript index 0fc5e7402..61034bfe9 100644 --- a/src/arch/generic/SConscript +++ b/src/arch/generic/SConscript @@ -46,6 +46,7 @@ if env['TARGET_ISA'] == 'null': Source('decode_cache.cc') Source('mmapped_ipr.cc') +SimObject('BaseInterrupts.py') SimObject('BaseTLB.py') SimObject('ISACommon.py') diff --git a/src/arch/generic/interrupts.hh b/src/arch/generic/interrupts.hh new file mode 100644 index 000000000..cae2d0911 --- /dev/null +++ b/src/arch/generic/interrupts.hh @@ -0,0 +1,98 @@ +/* + * Copyright 2019 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_GENERIC_INTERRUPTS_HH__ +#define __ARCH_GENERIC_INTERRUPTS_HH__ + +#include "params/BaseInterrupts.hh" +#include "sim/sim_object.hh" + +class ThreadContext; +class BaseCPU; + +class BaseInterrupts : public SimObject +{ + protected: + BaseCPU *cpu; + + public: + typedef BaseInterruptsParams Params; + + BaseInterrupts(Params *p) : SimObject(p) {} + + virtual void setCPU(BaseCPU * newCPU) = 0; + + const Params * + params() const + { + return dynamic_cast(_params); + } + + /* + * Functions for retrieving interrupts for the CPU to handle. + */ + + /* + * Return whether there are any interrupts waiting to be recognized. + */ + virtual bool checkInterrupts(ThreadContext *tc) const = 0; + /* + * Return an interrupt to process. This should return an interrupt exactly + * when checkInterrupts returns true. + */ + virtual Fault getInterrupt(ThreadContext *tc) = 0; + /* + * Update interrupt related state after an interrupt has been processed. + */ + virtual void updateIntrInfo(ThreadContext *tc) = 0; + + /* + * Old functions needed for compatability but which will be phased out + * eventually. + */ + virtual void + post(int int_num, int index) + { + panic("Interrupts::post unimplemented!\n"); + } + + virtual void + clear(int int_num, int index) + { + panic("Interrupts::clear unimplemented!\n"); + } + + virtual void + clearAll() + { + panic("Interrupts::clearAll unimplemented!\n"); + } +}; + +#endif // __ARCH_GENERIC_INTERRUPTS_HH__ diff --git a/src/arch/mips/MipsInterrupts.py b/src/arch/mips/MipsInterrupts.py index 9cde5daef..106570171 100644 --- a/src/arch/mips/MipsInterrupts.py +++ b/src/arch/mips/MipsInterrupts.py @@ -26,9 +26,9 @@ # # Authors: Gabe Black -from m5.SimObject import SimObject +from m5.objects.BaseInterrupts import BaseInterrupts -class MipsInterrupts(SimObject): +class MipsInterrupts(BaseInterrupts): type = 'MipsInterrupts' cxx_class = 'MipsISA::Interrupts' cxx_header = 'arch/mips/interrupts.hh' diff --git a/src/arch/mips/interrupts.cc b/src/arch/mips/interrupts.cc index a8c94169d..94d0535ca 100644 --- a/src/arch/mips/interrupts.cc +++ b/src/arch/mips/interrupts.cc @@ -153,7 +153,7 @@ Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const } void -Interrupts::updateIntrInfo(ThreadContext *tc) const +Interrupts::updateIntrInfo(ThreadContext *tc) { //Nothing needs to be done. } diff --git a/src/arch/mips/interrupts.hh b/src/arch/mips/interrupts.hh index ce9e0e4a3..02927ef2a 100644 --- a/src/arch/mips/interrupts.hh +++ b/src/arch/mips/interrupts.hh @@ -33,12 +33,12 @@ #include +#include "arch/generic/interrupts.hh" #include "arch/mips/faults.hh" #include "base/compiler.hh" #include "base/logging.hh" #include "params/MipsInterrupts.hh" #include "sim/serialize.hh" -#include "sim/sim_object.hh" class BaseCPU; class Checkpoint; @@ -46,7 +46,7 @@ class Checkpoint; namespace MipsISA { -class Interrupts : public SimObject +class Interrupts : public BaseInterrupts { public: typedef MipsInterruptsParams Params; @@ -57,7 +57,7 @@ class Interrupts : public SimObject return dynamic_cast(_params); } - Interrupts(Params * p) : SimObject(p) + Interrupts(Params * p) : BaseInterrupts(p) { } @@ -104,7 +104,7 @@ class Interrupts : public SimObject // MIPS cause register with the instatus variable. instatus // is essentially a copy of the MIPS cause[IP7:IP0] // - void updateIntrInfo(ThreadContext *tc) const; + void updateIntrInfo(ThreadContext *tc); bool interruptsPending(ThreadContext *tc) const; bool onCpuTimerInterrupt(ThreadContext *tc) const; bool checkInterrupts(ThreadContext *tc) const; diff --git a/src/arch/power/PowerInterrupts.py b/src/arch/power/PowerInterrupts.py index 2c6a5c2c3..f7e7e57bb 100644 --- a/src/arch/power/PowerInterrupts.py +++ b/src/arch/power/PowerInterrupts.py @@ -26,9 +26,9 @@ # # Authors: Gabe Black -from m5.SimObject import SimObject +from m5.objects.BaseInterrupts import BaseInterrupts -class PowerInterrupts(SimObject): +class PowerInterrupts(BaseInterrupts): type = 'PowerInterrupts' cxx_class = 'PowerISA::Interrupts' cxx_header = 'arch/power/interrupts.hh' diff --git a/src/arch/power/interrupts.hh b/src/arch/power/interrupts.hh index f89959863..b68cf8742 100644 --- a/src/arch/power/interrupts.hh +++ b/src/arch/power/interrupts.hh @@ -31,16 +31,16 @@ #ifndef __ARCH_POWER_INTERRUPT_HH__ #define __ARCH_POWER_INTERRUPT_HH__ +#include "arch/generic/interrupts.hh" #include "base/logging.hh" #include "params/PowerInterrupts.hh" -#include "sim/sim_object.hh" class BaseCPU; class ThreadContext; namespace PowerISA { -class Interrupts : public SimObject +class Interrupts : public BaseInterrupts { private: BaseCPU * cpu; @@ -54,7 +54,7 @@ class Interrupts : public SimObject return dynamic_cast(_params); } - Interrupts(Params * p) : SimObject(p), cpu(NULL) + Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL) {} void diff --git a/src/arch/riscv/RiscvInterrupts.py b/src/arch/riscv/RiscvInterrupts.py index 57b29b4ca..7e63dedea 100644 --- a/src/arch/riscv/RiscvInterrupts.py +++ b/src/arch/riscv/RiscvInterrupts.py @@ -31,9 +31,9 @@ # Sven Karlsson # Alec Roelke -from m5.SimObject import SimObject +from m5.objects.BaseInterrupts import BaseInterrupts -class RiscvInterrupts(SimObject): +class RiscvInterrupts(BaseInterrupts): type = 'RiscvInterrupts' cxx_class = 'RiscvISA::Interrupts' cxx_header = 'arch/riscv/interrupts.hh' diff --git a/src/arch/riscv/interrupts.hh b/src/arch/riscv/interrupts.hh index ed946879b..509b48391 100644 --- a/src/arch/riscv/interrupts.hh +++ b/src/arch/riscv/interrupts.hh @@ -34,6 +34,7 @@ #include #include +#include "arch/generic/interrupts.hh" #include "arch/riscv/faults.hh" #include "arch/riscv/registers.hh" #include "base/logging.hh" @@ -51,7 +52,7 @@ namespace RiscvISA { * This is based on version 1.10 of the RISC-V privileged ISA reference, * chapter 3.1.14. */ -class Interrupts : public SimObject +class Interrupts : public BaseInterrupts { private: BaseCPU * cpu; @@ -67,7 +68,7 @@ class Interrupts : public SimObject return dynamic_cast(_params); } - Interrupts(Params * p) : SimObject(p), cpu(nullptr), ip(0), ie(0) {} + Interrupts(Params * p) : BaseInterrupts(p), cpu(nullptr), ip(0), ie(0) {} void setCPU(BaseCPU * _cpu) { cpu = _cpu; } @@ -92,7 +93,7 @@ class Interrupts : public SimObject } Fault - getInterrupt(ThreadContext *tc) const + getInterrupt(ThreadContext *tc) { assert(checkInterrupts(tc)); std::bitset mask = globalMask(tc); diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index cc86752ab..0fa730533 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -34,6 +34,7 @@ #include #include +#include "arch/riscv/interrupts.hh" #include "arch/riscv/registers.hh" #include "base/bitfield.hh" #include "cpu/base.hh" @@ -142,11 +143,17 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc) return 0; } case MISCREG_IP: - return tc->getCpuPtr()->getInterruptController(tc->threadId()) - ->readIP(); + { + auto ic = dynamic_cast( + tc->getCpuPtr()->getInterruptController(tc->threadId())); + return ic->readIP(); + } case MISCREG_IE: - return tc->getCpuPtr()->getInterruptController(tc->threadId()) - ->readIE(); + { + auto ic = dynamic_cast( + tc->getCpuPtr()->getInterruptController(tc->threadId())); + return ic->readIE(); + } default: // Try reading HPM counters // As a placeholder, all HPM counters are just cycle counters @@ -185,11 +192,19 @@ ISA::setMiscReg(int misc_reg, RegVal val, ThreadContext *tc) } else { switch (misc_reg) { case MISCREG_IP: - return tc->getCpuPtr()->getInterruptController(tc->threadId()) - ->setIP(val); + { + auto ic = dynamic_cast( + tc->getCpuPtr()->getInterruptController(tc->threadId())); + ic->setIP(val); + } + break; case MISCREG_IE: - return tc->getCpuPtr()->getInterruptController(tc->threadId()) - ->setIE(val); + { + auto ic = dynamic_cast( + tc->getCpuPtr()->getInterruptController(tc->threadId())); + ic->setIE(val); + } + break; default: setMiscRegNoEffect(misc_reg, val); } diff --git a/src/arch/sparc/SparcInterrupts.py b/src/arch/sparc/SparcInterrupts.py index c11176164..04979ad09 100644 --- a/src/arch/sparc/SparcInterrupts.py +++ b/src/arch/sparc/SparcInterrupts.py @@ -26,9 +26,9 @@ # # Authors: Gabe Black -from m5.SimObject import SimObject +from m5.objects.BaseInterrupts import BaseInterrupts -class SparcInterrupts(SimObject): +class SparcInterrupts(BaseInterrupts): type = 'SparcInterrupts' cxx_class = 'SparcISA::Interrupts' cxx_header = 'arch/sparc/interrupts.hh' diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index abc899efb..58c701477 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -32,6 +32,7 @@ #ifndef __ARCH_SPARC_INTERRUPT_HH__ #define __ARCH_SPARC_INTERRUPT_HH__ +#include "arch/generic/interrupts.hh" #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" #include "arch/sparc/registers.hh" @@ -55,7 +56,7 @@ enum InterruptTypes NumInterruptTypes }; -class Interrupts : public SimObject +class Interrupts : public BaseInterrupts { private: BaseCPU * cpu; @@ -79,7 +80,7 @@ class Interrupts : public SimObject return dynamic_cast(_params); } - Interrupts(Params * p) : SimObject(p), cpu(NULL) + Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL) { clearAll(); } diff --git a/src/arch/sparc/isa.cc b/src/arch/sparc/isa.cc index f75d00645..b89f46550 100644 --- a/src/arch/sparc/isa.cc +++ b/src/arch/sparc/isa.cc @@ -32,6 +32,7 @@ #include "arch/sparc/asi.hh" #include "arch/sparc/decoder.hh" +#include "arch/sparc/interrupts.hh" #include "base/bitfield.hh" #include "base/trace.hh" #include "cpu/base.hh" diff --git a/src/arch/x86/X86LocalApic.py b/src/arch/x86/X86LocalApic.py index 914f29766..b7ab7bc6d 100644 --- a/src/arch/x86/X86LocalApic.py +++ b/src/arch/x86/X86LocalApic.py @@ -42,10 +42,11 @@ from m5.defines import buildEnv from m5.params import * from m5.proxy import * +from m5.objects.BaseInterrupts import BaseInterrupts from m5.objects.ClockDomain import DerivedClockDomain from m5.SimObject import SimObject -class X86LocalApic(SimObject): +class X86LocalApic(BaseInterrupts): type = 'X86LocalApic' cxx_class = 'X86ISA::Interrupts' cxx_header = 'arch/x86/interrupts.hh' diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index d237366ab..80d2650ef 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -596,7 +596,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) X86ISA::Interrupts::Interrupts(Params * p) - : SimObject(p), sys(p->system), clockDomain(*p->clk_domain), + : BaseInterrupts(p), sys(p->system), clockDomain(*p->clk_domain), apicTimerEvent([this]{ processApicTimerEvent(); }, name()), pendingSmi(false), smiVector(0), pendingNmi(false), nmiVector(0), diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 519d9f10e..3c383ab92 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -53,13 +53,14 @@ #ifndef __ARCH_X86_INTERRUPTS_HH__ #define __ARCH_X86_INTERRUPTS_HH__ -#include "arch/x86/regs/apic.hh" +#include "arch/generic/interrupts.hh" #include "arch/x86/faults.hh" #include "arch/x86/intmessage.hh" +#include "arch/x86/regs/apic.hh" #include "base/bitfield.hh" #include "cpu/thread_context.hh" -#include "dev/x86/intdev.hh" #include "dev/io_device.hh" +#include "dev/x86/intdev.hh" #include "params/X86LocalApic.hh" #include "sim/eventq.hh" @@ -72,7 +73,7 @@ namespace X86ISA { ApicRegIndex decodeAddr(Addr paddr); -class Interrupts : public SimObject +class Interrupts : public BaseInterrupts { protected: System *sys; diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index 86f140fdc..aab0a7118 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -53,6 +53,7 @@ #include +#include "arch/x86/faults.hh" #include "arch/x86/pagetable.hh" #include "arch/x86/tlb.hh" #include "arch/x86/vtophys.hh" diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 143ee9224..e17e26a11 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -66,44 +66,37 @@ if buildEnv['TARGET_ISA'] == 'alpha': from m5.objects.AlphaTLB import AlphaDTB as ArchDTB, AlphaITB as ArchITB from m5.objects.AlphaInterrupts import AlphaInterrupts as ArchInterrupts from m5.objects.AlphaISA import AlphaISA as ArchISA - ArchInterruptsParam = VectorParam.AlphaInterrupts ArchISAsParam = VectorParam.AlphaISA elif buildEnv['TARGET_ISA'] == 'sparc': from m5.objects.SparcTLB import SparcTLB as ArchDTB, SparcTLB as ArchITB from m5.objects.SparcInterrupts import SparcInterrupts as ArchInterrupts from m5.objects.SparcISA import SparcISA as ArchISA - ArchInterruptsParam = VectorParam.SparcInterrupts ArchISAsParam = VectorParam.SparcISA elif buildEnv['TARGET_ISA'] == 'x86': from m5.objects.X86TLB import X86TLB as ArchDTB, X86TLB as ArchITB from m5.objects.X86LocalApic import X86LocalApic as ArchInterrupts from m5.objects.X86ISA import X86ISA as ArchISA - ArchInterruptsParam = VectorParam.X86LocalApic ArchISAsParam = VectorParam.X86ISA elif buildEnv['TARGET_ISA'] == 'mips': from m5.objects.MipsTLB import MipsTLB as ArchDTB, MipsTLB as ArchITB from m5.objects.MipsInterrupts import MipsInterrupts as ArchInterrupts from m5.objects.MipsISA import MipsISA as ArchISA - ArchInterruptsParam = VectorParam.MipsInterrupts ArchISAsParam = VectorParam.MipsISA elif buildEnv['TARGET_ISA'] == 'arm': from m5.objects.ArmTLB import ArmTLB as ArchDTB, ArmTLB as ArchITB from m5.objects.ArmTLB import ArmStage2IMMU, ArmStage2DMMU from m5.objects.ArmInterrupts import ArmInterrupts as ArchInterrupts from m5.objects.ArmISA import ArmISA as ArchISA - ArchInterruptsParam = VectorParam.ArmInterrupts ArchISAsParam = VectorParam.ArmISA elif buildEnv['TARGET_ISA'] == 'power': from m5.objects.PowerTLB import PowerTLB as ArchDTB, PowerTLB as ArchITB from m5.objects.PowerInterrupts import PowerInterrupts as ArchInterrupts from m5.objects.PowerISA import PowerISA as ArchISA - ArchInterruptsParam = VectorParam.PowerInterrupts ArchISAsParam = VectorParam.PowerISA elif buildEnv['TARGET_ISA'] == 'riscv': from m5.objects.RiscvTLB import RiscvTLB as ArchDTB, RiscvTLB as ArchITB from m5.objects.RiscvInterrupts import RiscvInterrupts as ArchInterrupts from m5.objects.RiscvISA import RiscvISA as ArchISA - ArchInterruptsParam = VectorParam.RiscvInterrupts ArchISAsParam = VectorParam.RiscvISA else: print("Don't know what object types to use for ISA %s" % @@ -186,7 +179,7 @@ class BaseCPU(ClockedObject): dstage2_mmu = ArmStage2DMMU() elif buildEnv['TARGET_ISA'] == 'power': UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?") - interrupts = ArchInterruptsParam([], "Interrupt Controller") + interrupts = VectorParam.BaseInterrupts([], "Interrupt Controller") isa = ArchISAsParam([], "ISA instance") max_insts_all_threads = Param.Counter(0, diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 383ae8185..cb23cb1ba 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -54,7 +54,7 @@ #if THE_ISA == NULL_ISA #include "arch/null/cpu_dummy.hh" #else -#include "arch/interrupts.hh" +#include "arch/generic/interrupts.hh" #include "arch/isa_traits.hh" #include "arch/microcode_rom.hh" #include "base/statistics.hh" @@ -219,10 +219,10 @@ class BaseCPU : public ClockedObject TheISA::MicrocodeRom microcodeRom; protected: - std::vector interrupts; + std::vector interrupts; public: - TheISA::Interrupts * + BaseInterrupts * getInterruptController(ThreadID tid) { if (interrupts.empty()) diff --git a/src/cpu/kvm/base.hh b/src/cpu/kvm/base.hh index 7bf518f04..8d1258b4c 100644 --- a/src/cpu/kvm/base.hh +++ b/src/cpu/kvm/base.hh @@ -52,6 +52,7 @@ #include "cpu/kvm/vm.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" +#include "sim/faults.hh" /** Signal to use to trigger exits from KVM */ #define KVM_KICK_SIGNAL SIGRTMIN diff --git a/src/cpu/kvm/x86_cpu.cc b/src/cpu/kvm/x86_cpu.cc index 681e14200..5d2250dae 100644 --- a/src/cpu/kvm/x86_cpu.cc +++ b/src/cpu/kvm/x86_cpu.cc @@ -38,6 +38,8 @@ #include "arch/registers.hh" #include "arch/x86/cpuid.hh" +#include "arch/x86/faults.hh" +#include "arch/x86/interrupts.hh" #include "arch/x86/regs/msr.hh" #include "arch/x86/utility.hh" #include "cpu/kvm/base.hh" @@ -1185,8 +1187,10 @@ X86KvmCPU::kvmRun(Tick ticks) { struct kvm_run &kvm_run(*getKvmRunState()); - if (interrupts[0]->checkInterruptsRaw()) { - if (interrupts[0]->hasPendingUnmaskable()) { + auto *lapic = dynamic_cast(interrupts[0]); + + if (lapic->checkInterruptsRaw()) { + if (lapic->hasPendingUnmaskable()) { DPRINTF(KvmInt, "Delivering unmaskable interrupt.\n"); syncThreadContext(); @@ -1198,7 +1202,7 @@ X86KvmCPU::kvmRun(Tick ticks) // the thread context and check if there are /really/ // interrupts that should be delivered now. syncThreadContext(); - if (interrupts[0]->checkInterrupts(tc)) { + if (lapic->checkInterrupts(tc)) { DPRINTF(KvmInt, "M5 has pending interrupts, delivering interrupt.\n"); diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc index d6742a780..ba50ad57f 100644 --- a/src/dev/x86/i82094aa.cc +++ b/src/dev/x86/i82094aa.cc @@ -216,8 +216,9 @@ X86ISA::I82094AA::signalInterrupt(int line) } } else { for (int i = 0; i < numContexts; i++) { - Interrupts *localApic = sys->getThreadContext(i)-> + BaseInterrupts *base_int = sys->getThreadContext(i)-> getCpuPtr()->getInterruptController(0); + auto *localApic = dynamic_cast(base_int); if ((localApic->readReg(APIC_LOGICAL_DESTINATION) >> 24) & message.destination) { apics.push_back(localApic->getInitialApicId()); -- 2.30.2