fastmodel: handling amba far atomic transaction

Change-Id: I360c2a2bd415524b2a76434a13920f94360afa0f
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/44646
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Yu-hsin Wang
2021-03-30 16:07:03 +08:00
parent da7d752679
commit 34c5d537af
3 changed files with 82 additions and 0 deletions

View File

@@ -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'),

View File

@@ -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<void *, std::size_t> u_data = user_ex->get_user_data();
far_atomic::FarAtomic *fa = static_cast<far_atomic::FarAtomic *>(
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<FarAtomicOpFunctor>(fa), false);
if (trans.has_mm())
trans.set_auto_extension(atomic_ex);
else
trans.set_extension(atomic_ex);
}
} // namespace FastModel
FastModel::AmbaToTlmBridge64 *

View File

@@ -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;