fastmodel: Expose all CPU communication ports from the GIC.
authorGabe Black <gabeblack@google.com>
Mon, 16 Sep 2019 21:58:43 +0000 (14:58 -0700)
committerGabe Black <gabeblack@google.com>
Mon, 14 Oct 2019 18:17:03 +0000 (18:17 +0000)
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>
src/arch/arm/fastmodel/GIC/FastModelGIC.py
src/arch/arm/fastmodel/GIC/GIC.lisa
src/arch/arm/fastmodel/GIC/gic.cc
src/arch/arm/fastmodel/GIC/gic.hh
src/arch/arm/fastmodel/common/signal_receiver.hh

index 6390edff7e10c13a4c618cbab321527eec1293e3..53b7e1a2da661b02321115ea95d7bd6ec4e427ac 100644 (file)
@@ -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')
index 098b51d3994ccdb436ae98cf79486497448ad9d0..7f00d750944aa1fa59f16ce9b61af232bcc6f960 100644 (file)
@@ -325,7 +325,7 @@ component GIC
     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); \
index ae9ce02d295d94b2c4ee0b6c0688b85fcd1881ed..cb7752892fa96e131b9db9bbbe7e021f33d8e7e5 100644 (file)
 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 &params,
              sc_core::sc_module_name _name) : scx_evs_GIC(_name)
 {
@@ -257,27 +290,39 @@ SCGIC::SCGIC(const SCFastModelGICParams &params,
     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 &params) :
     BaseGic(&params),
     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
index de97f63fea9aa0c33d9abc01eb73e6f3c4f85836..aadfa3aea9a0cac4da7baf39b33d0b20e0894fa5 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <amba_pv.h>
 
+#include <memory>
+
 #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> terminator;
+
   public:
     SCGIC(const SCFastModelGICParams &params, 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<std::unique_ptr<TlmGicInitiator>> redistributors;
 
     SCGIC *scGIC;
 
index c249c3aaf347f25c268c489d7e5f4bde0822f192..b4559823928cfbef4ea5c7b9ee8fd082d8726624 100644 (file)
@@ -31,6 +31,7 @@
 #define __ARCH_ARM_FASTMODEL_COMMON_SIGNAL_RECEIVER_HH__
 
 #include <amba_pv.h>
+
 #include <functional>
 
 namespace FastModel