From 54646f5cd201c6e5672d866d2836b86768b280be Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 16 Sep 2019 14:58:43 -0700 Subject: [PATCH] fastmodel: Expose all CPU communication ports from the GIC. The unconnected CPU ports/sockets still need to be connected for TLM to be happy, so this change also adds a terminator module which finds all unbound sockets, creates pair sockets for them to connect to, binds everything together, and implements the target interface with a dummy stub that will complain and crash gem5 if it ever gets called. This will allow us to use the same GIC model to connect an arbitrary number of cores, up to the architected limit of 256. Change-Id: Iaa83fe4f023217dc91a3734b31f764fc4176130e Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21500 Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini Tested-by: kokoro --- src/arch/arm/fastmodel/GIC/FastModelGIC.py | 8 ++- src/arch/arm/fastmodel/GIC/GIC.lisa | 2 +- src/arch/arm/fastmodel/GIC/gic.cc | 63 ++++++++++++++++--- src/arch/arm/fastmodel/GIC/gic.hh | 34 +++++++++- .../arm/fastmodel/common/signal_receiver.hh | 1 + 5 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/arch/arm/fastmodel/GIC/FastModelGIC.py b/src/arch/arm/fastmodel/GIC/FastModelGIC.py index 6390edff7..53b7e1a2d 100644 --- a/src/arch/arm/fastmodel/GIC/FastModelGIC.py +++ b/src/arch/arm/fastmodel/GIC/FastModelGIC.py @@ -47,6 +47,11 @@ class Gicv3CommsInitiatorSocket(Port): super(Gicv3CommsInitiatorSocket, self).__init__( GICV3_COMMS_TARGET_ROLE, desc, is_source=True) +class VectorGicv3CommsInitiatorSocket(VectorPort): + def __init__(self, desc): + super(VectorGicv3CommsInitiatorSocket, self).__init__( + GICV3_COMMS_TARGET_ROLE, desc, is_source=True) + class SCFastModelGIC(SystemC_ScModule): type = 'SCFastModelGIC' @@ -457,4 +462,5 @@ class FastModelGIC(BaseGic): amba_m = AmbaInitiatorSocket(64, 'Memory initiator socket') amba_s = AmbaTargetSocket(64, 'Memory target socket') - redistributor = Gicv3CommsInitiatorSocket('GIC communication initiator') + redistributor = VectorGicv3CommsInitiatorSocket( + 'GIC communication initiator') diff --git a/src/arch/arm/fastmodel/GIC/GIC.lisa b/src/arch/arm/fastmodel/GIC/GIC.lisa index 098b51d39..7f00d7509 100644 --- a/src/arch/arm/fastmodel/GIC/GIC.lisa +++ b/src/arch/arm/fastmodel/GIC/GIC.lisa @@ -325,7 +325,7 @@ component GIC master port amba_m; slave port amba_s; - master port redistributor; + master port redistributor[256]; #define setPPI(C) \ case C: ppi_##C[num].setValue(state); \ diff --git a/src/arch/arm/fastmodel/GIC/gic.cc b/src/arch/arm/fastmodel/GIC/gic.cc index ae9ce02d2..cb7752892 100644 --- a/src/arch/arm/fastmodel/GIC/gic.cc +++ b/src/arch/arm/fastmodel/GIC/gic.cc @@ -36,6 +36,39 @@ namespace FastModel { +int +SCGIC::Terminator::countUnbound(const Initiators &inits) +{ + int count = 0; + for (auto &init: inits) + if (!init.get_port_base().size()) + count++; + return count; +} + +SCGIC::Terminator::Terminator( + sc_core::sc_module_name _name, Initiators &inits) : + sc_core::sc_module(_name), + targets("targets", countUnbound(inits)) +{ + // For every unbound initiator socket, connected it to one + // terminator target socket. + int i = 0; + for (auto &init: inits) { + if (!init.get_port_base().size()) { + auto &term = targets.at(i++); + term.bind(*this); + term.bind(init); + } + } +} + +void +SCGIC::Terminator::sendTowardsCPU(uint8_t len, const uint8_t *data) +{ + panic("Call to terminated interface!"); +} + SCGIC::SCGIC(const SCFastModelGICParams ¶ms, sc_core::sc_module_name _name) : scx_evs_GIC(_name) { @@ -257,27 +290,39 @@ SCGIC::SCGIC(const SCFastModelGICParams ¶ms, set_parameter("gic.consolidators", params.consolidators); } +void +SCGIC::before_end_of_elaboration() +{ + scx_evs_GIC::before_end_of_elaboration(); + terminator.reset(new Terminator("terminator", redistributor)); +} + GIC::GIC(const FastModelGICParams ¶ms) : BaseGic(¶ms), ambaM(params.sc_gic->amba_m, params.name + ".amba_m", -1), ambaS(params.sc_gic->amba_s, params.name + ".amba_s", -1), - redistributor(params.sc_gic->redistributor, - params.name + ".redistributor", -1), + redistributors(params.port_redistributor_connection_count), scGIC(params.sc_gic) -{ -} +{} Port & GIC::getPort(const std::string &if_name, PortID idx) { - if (if_name == "amba_m") + if (if_name == "amba_m") { return ambaM; - else if (if_name == "amba_s") + } else if (if_name == "amba_s") { return ambaS; - else if (if_name == "redistributor") - return redistributor; - else + } else if (if_name == "redistributor") { + auto &ptr = redistributors.at(idx); + if (!ptr) { + ptr.reset(new TlmGicInitiator(scGIC->redistributor[idx], + csprintf("%s.redistributor[%d]", + name(), idx), idx)); + } + return *ptr; + } else { return BaseGic::getPort(if_name, idx); + } } void diff --git a/src/arch/arm/fastmodel/GIC/gic.hh b/src/arch/arm/fastmodel/GIC/gic.hh index de97f63fe..aadfa3aea 100644 --- a/src/arch/arm/fastmodel/GIC/gic.hh +++ b/src/arch/arm/fastmodel/GIC/gic.hh @@ -32,6 +32,8 @@ #include +#include + #include "arch/arm/fastmodel/amba_ports.hh" #include "dev/arm/base_gic.hh" #include "params/FastModelGIC.hh" @@ -50,11 +52,41 @@ namespace FastModel // the work. class SCGIC : public scx_evs_GIC { + private: + // The unconnected CPU ports/sockets still need to be connected for TLM to + // be happy, so this module finds all unbound sockets, creates pair + // sockets for them to connect to, binds everything together, and + // implements the target interface with a dummy stub that will complain + // and crash gem5 if it ever gets called. + class Terminator : public sc_core::sc_module, + public svp_gicv3_comms::gicv3_comms_fw_if + { + protected: + typedef sc_core::sc_vector< + svp_gicv3_comms::gicv3_comms_initiator_socket<>> Initiators; + typedef sc_core::sc_vector< + svp_gicv3_comms::gicv3_comms_target_socket<>> Targets; + + Targets targets; + + static int countUnbound(const Initiators &inits); + + public: + Terminator(sc_core::sc_module_name _name, Initiators &inits); + + // Stub out the terminated interface. + void sendTowardsCPU(uint8_t len, const uint8_t *data) override; + }; + + std::unique_ptr terminator; + public: SCGIC(const SCFastModelGICParams ¶ms, sc_core::sc_module_name _name); SignalInterruptInitiatorSocket signalInterrupt; + void before_end_of_elaboration() override; + void end_of_elaboration() override { @@ -77,7 +109,7 @@ class GIC : public BaseGic AmbaInitiator ambaM; AmbaTarget ambaS; - TlmGicInitiator redistributor; + std::vector> redistributors; SCGIC *scGIC; diff --git a/src/arch/arm/fastmodel/common/signal_receiver.hh b/src/arch/arm/fastmodel/common/signal_receiver.hh index c249c3aaf..b45598239 100644 --- a/src/arch/arm/fastmodel/common/signal_receiver.hh +++ b/src/arch/arm/fastmodel/common/signal_receiver.hh @@ -31,6 +31,7 @@ #define __ARCH_ARM_FASTMODEL_COMMON_SIGNAL_RECEIVER_HH__ #include + #include namespace FastModel -- 2.30.2