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'
amba_m = AmbaInitiatorSocket(64, 'Memory initiator socket')
amba_s = AmbaTargetSocket(64, 'Memory target socket')
- redistributor = Gicv3CommsInitiatorSocket('GIC communication initiator')
+ redistributor = VectorGicv3CommsInitiatorSocket(
+ 'GIC communication initiator')
master port<AMBAPV> amba_m;
slave port<AMBAPV> amba_s;
- master port<GICv3Comms> redistributor;
+ master port<GICv3Comms> redistributor[256];
#define setPPI(C) \
case C: ppi_##C[num].setValue(state); \
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)
{
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
#include <amba_pv.h>
+#include <memory>
+
#include "arch/arm/fastmodel/amba_ports.hh"
#include "dev/arm/base_gic.hh"
#include "params/FastModelGIC.hh"
// 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> 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
{
AmbaInitiator ambaM;
AmbaTarget ambaS;
- TlmGicInitiator redistributor;
+ std::vector<std::unique_ptr<TlmGicInitiator>> redistributors;
SCGIC *scGIC;
#define __ARCH_ARM_FASTMODEL_COMMON_SIGNAL_RECEIVER_HH__
#include <amba_pv.h>
+
#include <functional>
namespace FastModel