From 8329f4bb658e4681f4d39fbd5d053114504f1403 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 28 Aug 2019 15:16:05 -0700 Subject: [PATCH] fastmodel: Make CortexA76x1's interrupts use gem5's mechanisms. This makes it easier to wire up CPUs to the interrupt controller, and makes things more modular. Change-Id: I8d3ab26e4bb588b8efb198ed145d0f58b7ee04cb Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21049 Reviewed-by: Chun-Chen TK Hsu Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini Tested-by: kokoro --- .../CortexA76x1/FastModelCortexA76x1.py | 28 +++--- .../arm/fastmodel/CortexA76x1/cortex_a76x1.cc | 88 ++++++++++++------- .../arm/fastmodel/CortexA76x1/cortex_a76x1.hh | 33 ++++--- src/arch/arm/fastmodel/GIC/FastModelGIC.py | 11 --- src/arch/arm/fastmodel/GIC/GIC.lisa | 42 --------- src/arch/arm/fastmodel/GIC/gic.cc | 29 +----- src/arch/arm/fastmodel/GIC/gic.hh | 15 ---- 7 files changed, 90 insertions(+), 156 deletions(-) diff --git a/src/arch/arm/fastmodel/CortexA76x1/FastModelCortexA76x1.py b/src/arch/arm/fastmodel/CortexA76x1/FastModelCortexA76x1.py index 925e3eef1..215189f21 100644 --- a/src/arch/arm/fastmodel/CortexA76x1/FastModelCortexA76x1.py +++ b/src/arch/arm/fastmodel/CortexA76x1/FastModelCortexA76x1.py @@ -31,10 +31,10 @@ from m5.SimObject import SimObject from m5.objects.ArmInterrupts import ArmInterrupts from m5.objects.ArmISA import ArmISA from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket -from m5.objects.FastModel import ScMasterPort from m5.objects.FastModelArch import FastModelArmCPU from m5.objects.FastModelGIC import Gicv3CommsInitiatorSocket from m5.objects.FastModelGIC import Gicv3CommsTargetSocket +from m5.objects.Gic import ArmPPI from m5.objects.SystemC import SystemC_ScModule class FastModelCortexA76x1(SystemC_ScModule): @@ -53,18 +53,26 @@ class FastModelCortexA76x1(SystemC_ScModule): isa = [ ArmISA() ], ) + cnthpirq = Param.ArmInterruptPin(ArmPPI(num=10), + "EL2 physical timer event") + cnthvirq = Param.ArmInterruptPin(ArmPPI(num=12), "EL2 virtual timer event") + cntpsirq = Param.ArmInterruptPin(ArmPPI(num=13), + "EL1 Secure physical timer event") + cntvirq = Param.ArmInterruptPin(ArmPPI(num=11), "Virtual timer event") + commirq = Param.ArmInterruptPin(ArmPPI(num=6), + "Interrupt signal from debug communications channel") + ctidbgirq = Param.ArmInterruptPin(ArmPPI(num=8), + "Cross Trigger Interface (CTI) interrupt trigger output") + pmuirq = Param.ArmInterruptPin(ArmPPI(num=7), + "Interrupt from performance monitoring unit") + vcpumntirq = Param.ArmInterruptPin(ArmPPI(num=9), + "Interrupt signal for virtual CPU maintenance IRQ") + cntpnsirq = Param.ArmInterruptPin(ArmPPI(num=14), + "Non-secure physical timer event") + amba = AmbaInitiatorSocket(64, 'AMBA initiator socket') redistributor_m = Gicv3CommsInitiatorSocket('GIC communication initiator') redistributor_s = Gicv3CommsTargetSocket('GIC communication target') - cnthpirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") - cnthvirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") - cntpsirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") - cntvirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") - commirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") - ctidbgirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") - pmuirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") - vcpumntirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") - cntpnsirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool") # These parameters are described in "Fast Models Reference Manual" section # 3.4.19, "ARMCortexA7x1CT". diff --git a/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.cc b/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.cc index 1ac0acb31..15021e71d 100644 --- a/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.cc +++ b/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.cc @@ -29,8 +29,10 @@ #include "arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh" +#include "arch/arm/fastmodel/arm/cpu.hh" #include "arch/arm/fastmodel/iris/cpu.hh" #include "base/logging.hh" +#include "dev/arm/base_gic.hh" #include "params/FastModelCortexA76x1.hh" #include "sim/core.hh" #include "systemc/tlm_bridge/gem5_to_tlm.hh" @@ -45,24 +47,25 @@ CortexA76x1::clockChangeHandler() } CortexA76x1::CortexA76x1(const sc_core::sc_module_name &mod_name, - const FastModelCortexA76x1Params ¶ms) + const FastModelCortexA76x1Params &p) : scx_evs_CortexA76x1(mod_name), - amba(scx_evs_CortexA76x1::amba, params.name + ".amba", -1), - redistributorM(redistributor_m, params.name + ".redistributor_m", -1), - redistributorS(redistributor_s, params.name + ".redistributor_s", -1), - cnthpirqWrapper(cnthpirq, params.name + ".cnthpirq", -1), - cnthvirqWrapper(cnthvirq, params.name + ".cnthvirq", -1), - cntpsirqWrapper(cntpsirq, params.name + ".cntpsirq", -1), - cntvirqWrapper(cntvirq, params.name + ".cntvirq", -1), - commirqWrapper(commirq, params.name + ".commirq", -1), - ctidbgirqWrapper(ctidbgirq, params.name + ".ctidbgirq", -1), - pmuirqWrapper(pmuirq, params.name + ".pmuirq", -1), - vcpumntirqWrapper(vcpumntirq, params.name + ".vcpumntirq", -1), - cntpnsirqWrapper(cntpnsirq, params.name + ".cntpnsirq", -1), + amba(scx_evs_CortexA76x1::amba, p.name + ".amba", -1), + redistributorM(redistributor_m, p.name + ".redistributor_m", -1), + redistributorS(redistributor_s, p.name + ".redistributor_s", -1), + cnthpirq("cnthpirq"), + cnthvirq("cnthvirq"), + cntpsirq("cntpsirq"), + cntvirq("cntvirq"), + commirq("commirq"), + ctidbgirq("ctidbgirq"), + pmuirq("pmuirq"), + vcpumntirq("vcpumntirq"), + cntpnsirq("cntpnsirq"), clockChanged(Iris::ClockEventName.c_str()), clockPeriod(Iris::PeriodAttributeName.c_str()), gem5Cpu(Iris::Gem5CpuAttributeName.c_str()), - sendFunctional(Iris::SendFunctionalAttributeName.c_str()) + sendFunctional(Iris::SendFunctionalAttributeName.c_str()), + params(p) { clockRateControl.bind(clock_rate_s); @@ -206,6 +209,16 @@ CortexA76x1::CortexA76x1(const sc_core::sc_module_name &mod_name, sendFunctional.value = [this](PacketPtr pkt) { sendFunc(pkt); }; add_attribute(sendFunctional); + + scx_evs_CortexA76x1::cnthpirq.bind(cnthpirq.signal_in); + scx_evs_CortexA76x1::cnthvirq.bind(cnthvirq.signal_in); + scx_evs_CortexA76x1::cntpsirq.bind(cntpsirq.signal_in); + scx_evs_CortexA76x1::cntvirq.bind(cntvirq.signal_in); + scx_evs_CortexA76x1::commirq.bind(commirq.signal_in); + scx_evs_CortexA76x1::ctidbgirq.bind(ctidbgirq.signal_in); + scx_evs_CortexA76x1::pmuirq.bind(pmuirq.signal_in); + scx_evs_CortexA76x1::vcpumntirq.bind(vcpumntirq.signal_in); + scx_evs_CortexA76x1::cntpnsirq.bind(cntpnsirq.signal_in); } void @@ -217,6 +230,35 @@ CortexA76x1::sendFunc(PacketPtr pkt) trans->release(); } +void +CortexA76x1::before_end_of_elaboration() +{ + scx_evs_CortexA76x1::before_end_of_elaboration(); + + auto *gem5_cpu = gem5Cpu.value; + auto set_on_change = [gem5_cpu](SignalReceiver &recv, + ArmInterruptPinGen *gen, + int ctx_num) + { + auto *pin = gen->get(gem5_cpu->getContext(ctx_num)); + auto handler = [pin](bool status) + { + status ? pin->raise() : pin->clear(); + }; + recv.onChange(handler); + }; + + set_on_change(cnthpirq, params.cnthpirq, 0); + set_on_change(cnthvirq, params.cnthvirq, 0); + set_on_change(cntpsirq, params.cntpsirq, 0); + set_on_change(cntvirq, params.cntvirq, 0); + set_on_change(commirq, params.commirq, 0); + set_on_change(ctidbgirq, params.ctidbgirq, 0); + set_on_change(pmuirq, params.pmuirq, 0); + set_on_change(vcpumntirq, params.vcpumntirq, 0); + set_on_change(cntpnsirq, params.cntpnsirq, 0); +} + Port & CortexA76x1::gem5_getPort(const std::string &if_name, int idx) { @@ -226,24 +268,6 @@ CortexA76x1::gem5_getPort(const std::string &if_name, int idx) return redistributorM; else if (if_name == "redistributor_s") return redistributorS; - else if (if_name == "cnthpirq") - return cnthpirqWrapper; - else if (if_name == "cnthvirq") - return cnthvirqWrapper; - else if (if_name == "cntpsirq") - return cntpsirqWrapper; - else if (if_name == "cntvirq") - return cntvirqWrapper; - else if (if_name == "commirq") - return commirqWrapper; - else if (if_name == "ctidbgirq") - return ctidbgirqWrapper; - else if (if_name == "pmuirq") - return pmuirqWrapper; - else if (if_name == "vcpumntirq") - return vcpumntirqWrapper; - else if (if_name == "cntpnsirq") - return cntpnsirqWrapper; else return scx_evs_CortexA76x1::gem5_getPort(if_name, idx); } diff --git a/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh b/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh index 0d204798e..73f04ea86 100644 --- a/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh +++ b/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh @@ -30,24 +30,17 @@ #ifndef __ARCH_ARM_FASTMODEL_CORTEXA76X1_CORETEX_A76X1_HH__ #define __ARCH_ARM_FASTMODEL_CORTEXA76X1_CORETEX_A76X1_HH__ -#include - #include "arch/arm/fastmodel/amba_ports.hh" +#include "arch/arm/fastmodel/common/signal_receiver.hh" #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh" #include "mem/port_proxy.hh" #include "params/FastModelCortexA76x1.hh" #include "scx_evs_CortexA76x1.h" #include "systemc/ext/core/sc_event.hh" #include "systemc/ext/core/sc_module.hh" -#include "systemc/sc_port_wrapper.hh" class BaseCPU; -// This macro is to get the type IF of a sc_export variable x. It relies on -// the fact that the "operator->()" function returns the "IF*" type and -// std::decay to remove cv-qualifiers and reference. -#define IFACE_TYPE(x) std::decay())>::type - namespace FastModel { @@ -67,15 +60,15 @@ class CortexA76x1 : public scx_evs_CortexA76x1 ClockRateControlInitiatorSocket clockRateControl; - sc_gem5::ScPortWrapper cnthpirqWrapper; - sc_gem5::ScPortWrapper cnthvirqWrapper; - sc_gem5::ScPortWrapper cntpsirqWrapper; - sc_gem5::ScPortWrapper cntvirqWrapper; - sc_gem5::ScPortWrapper commirqWrapper; - sc_gem5::ScPortWrapper ctidbgirqWrapper; - sc_gem5::ScPortWrapper pmuirqWrapper; - sc_gem5::ScPortWrapper vcpumntirqWrapper; - sc_gem5::ScPortWrapper cntpnsirqWrapper; + SignalReceiver cnthpirq; + SignalReceiver cnthvirq; + SignalReceiver cntpsirq; + SignalReceiver cntvirq; + SignalReceiver commirq; + SignalReceiver ctidbgirq; + SignalReceiver pmuirq; + SignalReceiver vcpumntirq; + SignalReceiver cntpnsirq; sc_core::sc_event clockChanged; sc_core::sc_attribute clockPeriod; @@ -86,12 +79,16 @@ class CortexA76x1 : public scx_evs_CortexA76x1 void clockChangeHandler(); + const FastModelCortexA76x1Params ¶ms; + public: CortexA76x1(const sc_core::sc_module_name &mod_name, - const FastModelCortexA76x1Params ¶ms); + const FastModelCortexA76x1Params &p); Port &gem5_getPort(const std::string &if_name, int idx=-1) override; + void before_end_of_elaboration() override; + void end_of_elaboration() override { diff --git a/src/arch/arm/fastmodel/GIC/FastModelGIC.py b/src/arch/arm/fastmodel/GIC/FastModelGIC.py index 79c6d48e0..82f2d281a 100644 --- a/src/arch/arm/fastmodel/GIC/FastModelGIC.py +++ b/src/arch/arm/fastmodel/GIC/FastModelGIC.py @@ -29,7 +29,6 @@ from m5.params import * from m5.SimObject import SimObject from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket -from m5.objects.FastModel import ScSlavePort from m5.objects.Gic import BaseGic from m5.objects.SystemC import SystemC_ScModule @@ -460,13 +459,3 @@ class FastModelGIC(BaseGic): redistributor_m = Gicv3CommsInitiatorSocket('GIC communication initiator') redistributor_s = Gicv3CommsTargetSocket('GIC communication target') - - cnthpirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") - cnthvirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") - cntpsirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") - cntvirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") - commirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") - ctidbgirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") - pmuirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") - vcpumntirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") - cntpnsirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool") diff --git a/src/arch/arm/fastmodel/GIC/GIC.lisa b/src/arch/arm/fastmodel/GIC/GIC.lisa index bb1e5649c..f691b261a 100644 --- a/src/arch/arm/fastmodel/GIC/GIC.lisa +++ b/src/arch/arm/fastmodel/GIC/GIC.lisa @@ -43,17 +43,6 @@ component GIC gic_gic2pv : GICv3CommsPVBus(); gic_pv2amba : PVBus2AMBAPV(); gic_amba2pv : AMBAPV2PVBus(); - - // Adapters for CPU-to-GIC signals - cnthpirqBridge : AMBAPVSignal2SGSignal(); - cnthvirqBridge : AMBAPVSignal2SGSignal(); - cntpnsirqBridge : AMBAPVSignal2SGSignal(); - cntpsirqBridge : AMBAPVSignal2SGSignal(); - cntvirqBridge : AMBAPVSignal2SGSignal(); - commirqBridge : AMBAPVSignal2SGSignal(); - ctidbgirqBridge : AMBAPVSignal2SGSignal(); - pmuirqBridge : AMBAPVSignal2SGSignal(); - vcpumntirqBridge : AMBAPVSignal2SGSignal(); } connection @@ -330,26 +319,6 @@ component GIC self.ppi_255 => gic.ppi_in_255; self.spi => gic.spi_in; - - // Connections from CPU - self.cnthpirq => cnthpirqBridge.amba_pv_signal_s; - cnthpirqBridge.sg_signal_m => gic.ppi_in_0[10]; - self.cnthvirq => cnthvirqBridge.amba_pv_signal_s; - cnthvirqBridge.sg_signal_m => gic.ppi_in_0[12]; - self.cntpnsirq => cntpnsirqBridge.amba_pv_signal_s; - cntpnsirqBridge.sg_signal_m => gic.ppi_in_0[14]; - self.cntpsirq => cntpsirqBridge.amba_pv_signal_s; - cntpsirqBridge.sg_signal_m => gic.ppi_in_0[13]; - self.cntvirq => cntvirqBridge.amba_pv_signal_s; - cntvirqBridge.sg_signal_m => gic.ppi_in_0[11]; - self.commirq => commirqBridge.amba_pv_signal_s; - commirqBridge.sg_signal_m => gic.ppi_in_0[6]; - self.ctidbgirq => ctidbgirqBridge.amba_pv_signal_s; - ctidbgirqBridge.sg_signal_m => gic.ppi_in_0[8]; - self.pmuirq => pmuirqBridge.amba_pv_signal_s; - pmuirqBridge.sg_signal_m => gic.ppi_in_0[7]; - self.vcpumntirq => vcpumntirqBridge.amba_pv_signal_s; - vcpumntirqBridge.sg_signal_m => gic.ppi_in_0[9]; } properties @@ -439,17 +408,6 @@ component GIC } } - // CPU-side connections - slave port cnthpirq; - slave port cnthvirq; - slave port cntpnsirq; - slave port cntpsirq; - slave port cntvirq; - slave port commirq; - slave port ctidbgirq; - slave port pmuirq; - slave port vcpumntirq; - internal slave port spi[988]; internal slave port ppi_0[16]; diff --git a/src/arch/arm/fastmodel/GIC/gic.cc b/src/arch/arm/fastmodel/GIC/gic.cc index cd332c62b..62a82b262 100644 --- a/src/arch/arm/fastmodel/GIC/gic.cc +++ b/src/arch/arm/fastmodel/GIC/gic.cc @@ -37,16 +37,7 @@ namespace FastModel { SCGIC::SCGIC(const SCFastModelGICParams ¶ms, - sc_core::sc_module_name _name) : scx_evs_GIC(_name), - cnthpirqWrapper(cnthpirq, params.name + ".cnthpirq", -1), - cnthvirqWrapper(cnthvirq, params.name + ".cnthvirq", -1), - cntpnsirqWrapper(cntpnsirq, params.name + ".cntpnsirq", -1), - cntpsirqWrapper(cntpsirq, params.name + ".cntpsirq", -1), - cntvirqWrapper(cntvirq, params.name + ".cntvirq", -1), - commirqWrapper(commirq, params.name + ".commirq", -1), - ctidbgirqWrapper(ctidbgirq, params.name + ".ctidbgirq", -1), - pmuirqWrapper(pmuirq, params.name + ".pmuirq", -1), - vcpumntirqWrapper(vcpumntirq, params.name + ".vcpumntirq", -1) + sc_core::sc_module_name _name) : scx_evs_GIC(_name) { signalInterrupt.bind(signal_interrupt); @@ -289,24 +280,6 @@ GIC::getPort(const std::string &if_name, PortID idx) return redistributorM; else if (if_name == "redistributor_s") return redistributorS; - else if (if_name == "cnthpirq") - return scGIC->cnthpirqWrapper; - else if (if_name == "cnthvirq") - return scGIC->cnthvirqWrapper; - else if (if_name == "cntpnsirq") - return scGIC->cntpnsirqWrapper; - else if (if_name == "cntpsirq") - return scGIC->cntpsirqWrapper; - else if (if_name == "cntvirq") - return scGIC->cntvirqWrapper; - else if (if_name == "commirq") - return scGIC->commirqWrapper; - else if (if_name == "ctidbgirq") - return scGIC->ctidbgirqWrapper; - else if (if_name == "pmuirq") - return scGIC->pmuirqWrapper; - else if (if_name == "vcpumntirq") - return scGIC->vcpumntirqWrapper; else return BaseGic::getPort(if_name, idx); } diff --git a/src/arch/arm/fastmodel/GIC/gic.hh b/src/arch/arm/fastmodel/GIC/gic.hh index b5d37c42d..11209ab27 100644 --- a/src/arch/arm/fastmodel/GIC/gic.hh +++ b/src/arch/arm/fastmodel/GIC/gic.hh @@ -40,11 +40,6 @@ #include "systemc/ext/core/sc_module_name.hh" #include "systemc/sc_port_wrapper.hh" -// This macro is to get the type IF of a sc_export variable x. It relies on -// the fact that the "operator->()" function returns the "IF*" type and -// std::decay to remove cv-qualifiers and reference. -#define IFACE_TYPE(x) std::decay())>::type - namespace FastModel { @@ -60,16 +55,6 @@ class SCGIC : public scx_evs_GIC SignalInterruptInitiatorSocket signalInterrupt; - sc_gem5::ScInterfaceWrapper cnthpirqWrapper; - sc_gem5::ScInterfaceWrapper cnthvirqWrapper; - sc_gem5::ScInterfaceWrapper cntpnsirqWrapper; - sc_gem5::ScInterfaceWrapper cntpsirqWrapper; - sc_gem5::ScInterfaceWrapper cntvirqWrapper; - sc_gem5::ScInterfaceWrapper commirqWrapper; - sc_gem5::ScInterfaceWrapper ctidbgirqWrapper; - sc_gem5::ScInterfaceWrapper pmuirqWrapper; - sc_gem5::ScInterfaceWrapper vcpumntirqWrapper; - void end_of_elaboration() override { -- 2.30.2