From 34c5d537aff74321bc23a66820c6580aa169bef5 Mon Sep 17 00:00:00 2001 From: Yu-hsin Wang Date: Tue, 30 Mar 2021 16:07:03 +0800 Subject: [PATCH] fastmodel: handling amba far atomic transaction Change-Id: I360c2a2bd415524b2a76434a13920f94360afa0f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/44646 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- src/arch/arm/fastmodel/SConscript | 2 + src/arch/arm/fastmodel/amba_to_tlm_bridge.cc | 79 ++++++++++++++++++++ src/arch/arm/fastmodel/amba_to_tlm_bridge.hh | 1 + 3 files changed, 82 insertions(+) diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index c659434b48..257c001531 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -104,6 +104,8 @@ def staticify(env, name): env.Append(CCFLAGS='-pthread') cpppaths = ( + pvlib_home.Dir('examples/SystemCExport/Common/include'), + pvlib_home.Dir('include'), pvlib_home.Dir('include/fmruntime'), pvlib_home.Dir('include/fmruntime/eslapi'), pvlib_home.Dir('Iris/include'), diff --git a/src/arch/arm/fastmodel/amba_to_tlm_bridge.cc b/src/arch/arm/fastmodel/amba_to_tlm_bridge.cc index 82f84d80cb..8826f3e815 100644 --- a/src/arch/arm/fastmodel/amba_to_tlm_bridge.cc +++ b/src/arch/arm/fastmodel/amba_to_tlm_bridge.cc @@ -27,7 +27,43 @@ #include "arch/arm/fastmodel/amba_to_tlm_bridge.hh" +#include "base/amo.hh" #include "params/AmbaToTlmBridge64.hh" +#include "pv/FarAtomicService.h" +#include "pv_userpayload_extension.h" +#include "systemc/tlm_bridge/sc_ext.hh" + +namespace { + +// According to AbstractMemory::access in mem/abstract_mem.cc, the gem5 memory +// model would set original data into the packet buffer. However, the TLM +// request with atomic operation doesn't carry a valid buffer because the +// resource is all allocated in atomic extension. Preventing from segmentation +// fault, we allocate a random buffer and share it with all atomic transactions +// since we don't really care about the content of it. +uint8_t dummy_buffer[64] = {}; + +struct FarAtomicOpFunctor : public AtomicOpFunctor +{ + FarAtomicOpFunctor(far_atomic::FarAtomic *_fa) : fa(_fa) {} + + void + operator() (uint8_t *p) override + { + fa->serviceWasFound(); + fa->doAtomicOperation(p); + } + + AtomicOpFunctor * + clone() override + { + return new FarAtomicOpFunctor(*this); + } + + far_atomic::FarAtomic *fa; +}; + +} namespace FastModel { @@ -63,6 +99,7 @@ void AmbaToTlmBridge64::bTransport(amba_pv::amba_pv_transaction &trans, sc_core::sc_time &t) { + maybeSetupAtomicExtension(trans); return initiatorProxy->b_transport(trans, t); } @@ -86,6 +123,48 @@ AmbaToTlmBridge64::invalidateDirectMemPtr(sc_dt::uint64 start_range, targetProxy->invalidate_direct_mem_ptr(start_range, end_range); } +void +AmbaToTlmBridge64::maybeSetupAtomicExtension( + amba_pv::amba_pv_transaction &trans) +{ + Gem5SystemC::AtomicExtension *atomic_ex = nullptr; + trans.get_extension(atomic_ex); + if (atomic_ex) + return; + + pv_userpayload_extension *user_ex = nullptr; + trans.get_extension(user_ex); + if (!user_ex) + return; + + pv::UserPayloadBase *upb = user_ex->get_user_payload(); + uint32_t appid = upb->get_appID(); + if (appid != pv::UserPayloadBase::SERVICE_REQUEST) + return; + + std::pair u_data = user_ex->get_user_data(); + far_atomic::FarAtomic *fa = static_cast( + u_data.first); + + // Correct the request size manually and give it a dummy buffer preventing + // from segmentation fault. + fatal_if( + fa->getDataValueSizeInBytes() > sizeof(dummy_buffer), + "atomic operation(%d) is larger than dummy buffer(%d)", + fa->getDataValueSizeInBytes(), sizeof(dummy_buffer)); + trans.set_data_length(fa->getDataValueSizeInBytes()); + trans.set_data_ptr(dummy_buffer); + + // The return value would store in the extension. We don't need to specify + // need_return here. + atomic_ex = new Gem5SystemC::AtomicExtension( + std::make_shared(fa), false); + if (trans.has_mm()) + trans.set_auto_extension(atomic_ex); + else + trans.set_extension(atomic_ex); +} + } // namespace FastModel FastModel::AmbaToTlmBridge64 * diff --git a/src/arch/arm/fastmodel/amba_to_tlm_bridge.hh b/src/arch/arm/fastmodel/amba_to_tlm_bridge.hh index d0e52d00cd..0bb4c20f2b 100644 --- a/src/arch/arm/fastmodel/amba_to_tlm_bridge.hh +++ b/src/arch/arm/fastmodel/amba_to_tlm_bridge.hh @@ -54,6 +54,7 @@ class AmbaToTlmBridge64 : public amba_pv::amba_pv_to_tlm_bridge<64> unsigned int transportDbg(amba_pv::amba_pv_transaction &trans); void invalidateDirectMemPtr(sc_dt::uint64 start_range, sc_dt::uint64 end_range); + void maybeSetupAtomicExtension(amba_pv::amba_pv_transaction &trans); tlm_utils::simple_target_socket< AmbaToTlmBridge64, 64, tlm::tlm_base_protocol_types> targetProxy;