fastmodel: Export GICV3Comms directly.

This lets us avoid having to have two levels of bridging and twice as
many ports on both the CPU and GIC side. The direct communication ports
can be instantiated and connected using array syntax, where the bridges
require instantiating each bridge individually and wiring them up one
at a time with a lot of boilerplate/duplicate code.

Change-Id: I815ee47bcd19994e46a5220e0c23e89c497d7aa5
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21050
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chun-Chen TK Hsu <chunchenhsu@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
diff --git a/src/arch/arm/fastmodel/CortexA76x1/CortexA76x1.lisa b/src/arch/arm/fastmodel/CortexA76x1/CortexA76x1.lisa
index 28c0bd9..695ae9e 100644
--- a/src/arch/arm/fastmodel/CortexA76x1/CortexA76x1.lisa
+++ b/src/arch/arm/fastmodel/CortexA76x1/CortexA76x1.lisa
@@ -36,9 +36,6 @@
 
         // Bridges for the core.
         ambaBridge : PVBus2AMBAPV();
-        gic_pv2gic : PVBusGICv3Comms();
-        gic_pv2amba : PVBus2AMBAPV();
-        gic_amba2pv : AMBAPV2PVBus();
 
         // Adapters for CPU-to-GIC signals
         CNTHPIRQ : SGSignal2AMBAPVSignal();
@@ -64,14 +61,7 @@
         ambaBridge.amba_pv_m => self.amba;
 
         // Connection to the GIC.
-        self.redistributor_s => gic_amba2pv.amba_pv_s;
-        // Bridges coming in.
-        gic_amba2pv.pvbus_m => gic_pv2gic.pvbus_s;
-        // Bridge to GICV3Comms.
-        gic_pv2gic.distributor_m[0] => core.gicv3_redistributor_s[0];
-        // Bridges going out.
-        gic_pv2gic.pvbus_m => gic_pv2amba.pvbus_s;
-        gic_pv2amba.amba_pv_m => self.redistributor_m;
+        self.redistributor =>core.gicv3_redistributor_s[0];
 
         // Connections from CPU to adapters
         core.CNTHPIRQ[0] => CNTHPIRQ.sg_signal_s;
@@ -113,8 +103,7 @@
             clockDiv.rate.set64(mul, div);
         }
     }
-    slave port<AMBAPV> redistributor_s;
-    master port<AMBAPV> redistributor_m;
+    slave port<GICv3Comms> redistributor;
 
     // External ports for CPU-to-GIC signals
     master port<AMBAPVSignal> cnthpirq;
diff --git a/src/arch/arm/fastmodel/CortexA76x1/FastModelCortexA76x1.py b/src/arch/arm/fastmodel/CortexA76x1/FastModelCortexA76x1.py
index 215189f..055223f 100644
--- a/src/arch/arm/fastmodel/CortexA76x1/FastModelCortexA76x1.py
+++ b/src/arch/arm/fastmodel/CortexA76x1/FastModelCortexA76x1.py
@@ -71,8 +71,7 @@
             "Non-secure physical timer event")
 
     amba = AmbaInitiatorSocket(64, 'AMBA initiator socket')
-    redistributor_m = Gicv3CommsInitiatorSocket('GIC communication initiator')
-    redistributor_s = Gicv3CommsTargetSocket('GIC communication target')
+    redistributor = Gicv3CommsTargetSocket('GIC communication target')
 
     # 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 15021e7..50d5417 100644
--- a/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.cc
+++ b/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.cc
@@ -50,8 +50,8 @@
         const FastModelCortexA76x1Params &p)
     : scx_evs_CortexA76x1(mod_name),
       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),
+      redistributor(scx_evs_CortexA76x1::redistributor,
+              p.name + ".redistributor", -1),
       cnthpirq("cnthpirq"),
       cnthvirq("cnthvirq"),
       cntpsirq("cntpsirq"),
@@ -264,10 +264,8 @@
 {
     if (if_name == "amba")
         return amba;
-    else if (if_name == "redistributor_m")
-        return redistributorM;
-    else if (if_name == "redistributor_s")
-        return redistributorS;
+    else if (if_name == "redistributor")
+        return redistributor;
     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 73f04ea..c4ea983 100644
--- a/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh
+++ b/src/arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh
@@ -54,9 +54,13 @@
   private:
     SC_HAS_PROCESS(CortexA76x1);
 
+    typedef sc_gem5::TlmTargetBaseWrapper<
+        64, svp_gicv3_comms::gicv3_comms_fw_if,
+        svp_gicv3_comms::gicv3_comms_bw_if, 1,
+        sc_core::SC_ONE_OR_MORE_BOUND> TlmGicTarget;
+
     AmbaInitiator amba;
-    AmbaInitiator redistributorM;
-    AmbaTarget redistributorS;
+    TlmGicTarget redistributor;
 
     ClockRateControlInitiatorSocket clockRateControl;
 
diff --git a/src/arch/arm/fastmodel/GIC/FastModelGIC.py b/src/arch/arm/fastmodel/GIC/FastModelGIC.py
index 82f2d28..6390edf 100644
--- a/src/arch/arm/fastmodel/GIC/FastModelGIC.py
+++ b/src/arch/arm/fastmodel/GIC/FastModelGIC.py
@@ -457,5 +457,4 @@
     amba_m = AmbaInitiatorSocket(64, 'Memory initiator socket')
     amba_s = AmbaTargetSocket(64, 'Memory target socket')
 
-    redistributor_m = Gicv3CommsInitiatorSocket('GIC communication initiator')
-    redistributor_s = Gicv3CommsTargetSocket('GIC communication target')
+    redistributor = Gicv3CommsInitiatorSocket('GIC communication initiator')
diff --git a/src/arch/arm/fastmodel/GIC/GIC.lisa b/src/arch/arm/fastmodel/GIC/GIC.lisa
index f691b26..098b51d 100644
--- a/src/arch/arm/fastmodel/GIC/GIC.lisa
+++ b/src/arch/arm/fastmodel/GIC/GIC.lisa
@@ -54,11 +54,7 @@
         mem_in.pvbus_m => gic.pvbus_s;
 
         // For the CPU interface.
-        gic.redistributor_m => gic_gic2pv.distributor_s;
-        gic_gic2pv.pvbus_m => gic_pv2amba.pvbus_s;
-        gic_pv2amba.amba_pv_m => self.redistributor_m;
-        self.redistributor_s => gic_amba2pv.amba_pv_s;
-        gic_amba2pv.pvbus_m => gic_gic2pv.pvbus_s;
+        gic.redistributor_m => self.redistributor;
 
         // Internal ports for PPI and SPI programmatic access.
         self.ppi_0 => gic.ppi_in_0;
@@ -329,8 +325,7 @@
     master port<AMBAPV> amba_m;
     slave port<AMBAPV> amba_s;
 
-    slave port<AMBAPV> redistributor_s;
-    master port<AMBAPV> redistributor_m;
+    master port<GICv3Comms> redistributor;
 
     #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 62a82b2..ae9ce02 100644
--- a/src/arch/arm/fastmodel/GIC/gic.cc
+++ b/src/arch/arm/fastmodel/GIC/gic.cc
@@ -261,10 +261,8 @@
     BaseGic(&params),
     ambaM(params.sc_gic->amba_m, params.name + ".amba_m", -1),
     ambaS(params.sc_gic->amba_s, params.name + ".amba_s", -1),
-    redistributorM(params.sc_gic->redistributor_m,
-                   params.name + ".redistributor_m", -1),
-    redistributorS(params.sc_gic->redistributor_s,
-                   params.name + ".redistributor_s", -1),
+    redistributor(params.sc_gic->redistributor,
+                  params.name + ".redistributor", -1),
     scGIC(params.sc_gic)
 {
 }
@@ -276,10 +274,8 @@
         return ambaM;
     else if (if_name == "amba_s")
         return ambaS;
-    else if (if_name == "redistributor_m")
-        return redistributorM;
-    else if (if_name == "redistributor_s")
-        return redistributorS;
+    else if (if_name == "redistributor")
+        return redistributor;
     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 11209ab..de97f63 100644
--- a/src/arch/arm/fastmodel/GIC/gic.hh
+++ b/src/arch/arm/fastmodel/GIC/gic.hh
@@ -70,10 +70,14 @@
 class GIC : public BaseGic
 {
   private:
+    typedef sc_gem5::TlmInitiatorBaseWrapper<
+        64, svp_gicv3_comms::gicv3_comms_fw_if,
+        svp_gicv3_comms::gicv3_comms_bw_if, 1,
+        sc_core::SC_ONE_OR_MORE_BOUND> TlmGicInitiator;
+
     AmbaInitiator ambaM;
     AmbaTarget ambaS;
-    AmbaInitiator redistributorM;
-    AmbaTarget redistributorS;
+    TlmGicInitiator redistributor;
 
     SCGIC *scGIC;
 
diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript
index 17d931f..e4c9590 100644
--- a/src/arch/arm/fastmodel/SConscript
+++ b/src/arch/arm/fastmodel/SConscript
@@ -366,3 +366,26 @@
 SimObject('FastModel.py')
 Source('amba_to_tlm_bridge.cc')
 Source('amba_from_tlm_bridge.cc')
+
+# HACK: Make sure the gic protocol headers are somewhere we can find them.
+# These should start out alongside other headers fast model provides which we
+# are already able to include, but unfortunately they're in the examples
+# directory.
+gicv3_comms_headers = (
+        'gicv3_comms_base.h', 'gicv3_comms_if.h', 'gicv3_comms_sockets.h')
+examples_common_dir = pvlib_home.Dir('examples/SystemCExport/Common')
+gic_protocol_path = 'Protocols/GICv3Comms'
+gic_protocol_dest = Dir(env['BUILDDIR']).Dir(gic_protocol_path)
+gic_protocol_src = examples_common_dir.Dir(gic_protocol_path)
+
+for header in gicv3_comms_headers:
+    Command(gic_protocol_dest.File(header), gic_protocol_src.File(header),
+            Copy('${TARGET}', '${SOURCE}'))
+
+lisa_protocol_types_header_path = 'include/lisa_protocol_types.h'
+lisa_protocol_types_header_target = \
+    gic_protocol_dest.File(lisa_protocol_types_header_path)
+lisa_protocol_types_header_src = \
+    examples_common_dir.File(lisa_protocol_types_header_path)
+Command(lisa_protocol_types_header_target, lisa_protocol_types_header_src,
+        Copy('${TARGET}', '${SOURCE}'))