diff options
author | Gabe Black <gabeblack@google.com> | 2019-09-16 14:58:43 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2019-10-14 18:17:03 +0000 |
commit | 54646f5cd201c6e5672d866d2836b86768b280be (patch) | |
tree | 57f40969e440e586f70bbbc1b06be7a111562132 /src/arch/arm/fastmodel/GIC/gic.cc | |
parent | 953ff92638591406674680626283c3dfdf2a7b34 (diff) | |
download | gem5-54646f5cd201c6e5672d866d2836b86768b280be.tar.xz |
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 <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/arch/arm/fastmodel/GIC/gic.cc')
-rw-r--r-- | src/arch/arm/fastmodel/GIC/gic.cc | 63 |
1 files changed, 54 insertions, 9 deletions
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 |