fastmodel: correct the control signal for AmbaFromTlmBridge

In AmbaToTlmBridge we copy the control signal from amba extension to
SystemC extension. This makes gem5 models can proceed the correct
control signals. We need to make the same thing in AmbaToTlmBridge for
fastmodel can proceed the correct control signals.

A practical example is given a request is generated by fastmodel CPU,
translated by gem5 MMU, and routed to a fastmodel target. The secure bit
may be changed by MMU according to the PTE. We need to update the amba
extension in AmbaFromTlmBridge to make the target get the correct
information.

Change-Id: I600be7ba21368f00c05426ac1db3c28efd6ca2ea
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/63773
Maintainer: Gabe Black <gabe.black@gmail.com>
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/arch/arm/fastmodel/amba_from_tlm_bridge.cc b/src/arch/arm/fastmodel/amba_from_tlm_bridge.cc
index 4005355..f84e581 100644
--- a/src/arch/arm/fastmodel/amba_from_tlm_bridge.cc
+++ b/src/arch/arm/fastmodel/amba_from_tlm_bridge.cc
@@ -28,6 +28,8 @@
 #include "arch/arm/fastmodel/amba_from_tlm_bridge.hh"
 
 #include "params/AmbaFromTlmBridge64.hh"
+#include "pv_userpayload_extension.h"
+#include "systemc/tlm_bridge/sc_ext.hh"
 
 namespace gem5
 {
@@ -36,11 +38,21 @@
 namespace fastmodel
 {
 
-AmbaFromTlmBridge64::AmbaFromTlmBridge64(const char *name) :
+AmbaFromTlmBridge64::AmbaFromTlmBridge64(const sc_core::sc_module_name& name) :
     amba_pv::amba_pv_from_tlm_bridge<64>(name),
-    ambaWrapper(amba_pv_m, std::string(name) + ".amba", -1),
-    tlmWrapper(tlm_s, std::string(name) + ".tlm", -1)
-{}
+    targetProxy("target_proxy"),
+    initiatorProxy("initiator_proxy"),
+    tlmWrapper(targetProxy, std::string(name) + ".tlm", -1),
+    ambaWrapper(amba_pv_m, std::string(name) + ".amba", -1)
+{
+    targetProxy.register_b_transport(this, &AmbaFromTlmBridge64::bTransport);
+    targetProxy.register_get_direct_mem_ptr(
+        this, &AmbaFromTlmBridge64::getDirectMemPtr);
+    targetProxy.register_transport_dbg(this, &AmbaFromTlmBridge64::transportDbg);
+    initiatorProxy.register_invalidate_direct_mem_ptr(
+        this, &AmbaFromTlmBridge64::invalidateDirectMemPtr);
+    initiatorProxy(tlm_s);
+}
 
 Port &
 AmbaFromTlmBridge64::gem5_getPort(const std::string &if_name, int idx)
@@ -55,6 +67,55 @@
     }
 }
 
+void
+AmbaFromTlmBridge64::bTransport(amba_pv::amba_pv_transaction &trans,
+                                sc_core::sc_time &t)
+{
+    syncControlExtension(trans);
+    return initiatorProxy->b_transport(trans, t);
+}
+
+bool
+AmbaFromTlmBridge64::getDirectMemPtr(amba_pv::amba_pv_transaction &trans,
+                                   tlm::tlm_dmi &dmi_data)
+{
+    return initiatorProxy->get_direct_mem_ptr(trans, dmi_data);
+}
+
+unsigned int
+AmbaFromTlmBridge64::transportDbg(amba_pv::amba_pv_transaction &trans)
+{
+    syncControlExtension(trans);
+    return initiatorProxy->transport_dbg(trans);
+}
+
+void
+AmbaFromTlmBridge64::invalidateDirectMemPtr(sc_dt::uint64 start_range,
+                                          sc_dt::uint64 end_range)
+{
+    targetProxy->invalidate_direct_mem_ptr(start_range, end_range);
+}
+
+void
+AmbaFromTlmBridge64::syncControlExtension(amba_pv::amba_pv_transaction &trans)
+{
+    Gem5SystemC::ControlExtension *control_ex = nullptr;
+    trans.get_extension(control_ex);
+    if (!control_ex) {
+        return;
+    }
+
+    amba_pv::amba_pv_extension *amba_ex = nullptr;
+    trans.get_extension(amba_ex);
+    if (!amba_ex) {
+        return;
+    }
+
+    amba_ex->set_privileged(control_ex->isPrivileged());
+    amba_ex->set_non_secure(!control_ex->isSecure());
+    amba_ex->set_instruction(control_ex->isInstruction());
+}
+
 } // namespace fastmodel
 
 fastmodel::AmbaFromTlmBridge64 *
diff --git a/src/arch/arm/fastmodel/amba_from_tlm_bridge.hh b/src/arch/arm/fastmodel/amba_from_tlm_bridge.hh
index a54617d..4484ea9 100644
--- a/src/arch/arm/fastmodel/amba_from_tlm_bridge.hh
+++ b/src/arch/arm/fastmodel/amba_from_tlm_bridge.hh
@@ -47,13 +47,25 @@
 class AmbaFromTlmBridge64 : public amba_pv::amba_pv_from_tlm_bridge<64>
 {
   public:
-    AmbaFromTlmBridge64(const char *name);
+    AmbaFromTlmBridge64(const sc_core::sc_module_name &name);
 
     gem5::Port &gem5_getPort(const std::string &if_name, int idx=-1) override;
 
   private:
-    AmbaInitiator ambaWrapper;
+    void bTransport(amba_pv::amba_pv_transaction &trans, sc_core::sc_time &t);
+    bool getDirectMemPtr(amba_pv::amba_pv_transaction &trans,
+                         tlm::tlm_dmi &dmi_data);
+    unsigned int transportDbg(amba_pv::amba_pv_transaction &trans);
+    void invalidateDirectMemPtr(sc_dt::uint64 start_range,
+                                sc_dt::uint64 end_range);
+    void syncControlExtension(amba_pv::amba_pv_transaction &trans);
+
+    tlm_utils::simple_target_socket<
+        AmbaFromTlmBridge64, 64, tlm::tlm_base_protocol_types> targetProxy;
+    tlm_utils::simple_initiator_socket<
+        AmbaFromTlmBridge64, 64, tlm::tlm_base_protocol_types> initiatorProxy;
     sc_gem5::TlmTargetWrapper<64> tlmWrapper;
+    AmbaInitiator ambaWrapper;
 };
 
 } // namespace fastmodel