16#ifndef SIMICS_SYSTEMC_TLM2SIMICS_GASKET_DISPATCHER_H
17#define SIMICS_SYSTEMC_TLM2SIMICS_GASKET_DISPATCHER_H
23#include <tlm_utils/multi_passthrough_initiator_socket.h>
24#include <tlm_utils/simple_target_socket.h>
38 std::make_pair(sc_core::sc_get_curr_simcontext(),
this));
42 auto range = context_.equal_range(sc_core::sc_get_curr_simcontext());
43 for (
auto it = range.first; it != range.second; ++it)
46 context_.erase(sc_core::sc_get_curr_simcontext());
50 static std::multimap<sc_core::sc_simcontext *,
54template <
unsigned int BUSWIDTH = 32,
55 typename TYPES = tlm::tlm_base_protocol_types,
57 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
62 target_socket_.register_nb_transport_fw(
63 this, &GasketDispatcher::nb_transport_fw);
64 target_socket_.register_b_transport(
65 this, &GasketDispatcher::b_transport);
66 target_socket_.register_transport_dbg(
67 this, &GasketDispatcher::transport_dbg);
68 target_socket_.register_get_direct_mem_ptr(
69 this, &GasketDispatcher::get_direct_mem_ptr);
70 multi_initiator_.register_invalidate_direct_mem_ptr(
71 this, &GasketDispatcher::invalidate_direct_mem_ptr);
72 multi_initiator_.register_nb_transport_bw(
73 this, &GasketDispatcher::nb_transport_bw);
76 tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL> *socket,
78 const simics::ConfObjectRef &simics_obj) {
80 if (dispatchers_.find(socket) == dispatchers_.end()) {
82 sc_core::sc_gen_unique_name(
"GasketDispatcher"));
83 dispatchers_[socket] = dispatcher;
84 (*socket)(dispatcher->target_socket_);
85 dispatcher->simics_obj_ = simics_obj;
88 dispatcher = dispatchers_[socket];
93 dispatcher->receivers_.push_back(
94 std::make_pair(dispatcher->receivers_.size(),
96 gasket->
bind(dispatcher->multi_initiator_);
100 for (
auto it = dispatchers_.begin(); it != dispatchers_.end(); ++it) {
101 if (it->second ==
this) {
102 dispatchers_.erase(it);
109 tlm::tlm_sync_enum nb_transport_fw(
110 tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase,
111 sc_core::sc_time &local_time) {
112 int idx = index(&trans);
114 return multi_initiator_[idx]->nb_transport_fw(trans, phase,
117 return tlm::TLM_COMPLETED;
119 tlm::tlm_sync_enum nb_transport_bw(
120 int idx, tlm::tlm_generic_payload &trans,
121 tlm::tlm_phase &phase, sc_core::sc_time &local_time) {
122 return target_socket_->nb_transport_bw(trans, phase, local_time);
125 tlm::tlm_generic_payload &trans, sc_core::sc_time &local_time) {
126 int idx = index(&trans);
128 multi_initiator_[idx]->b_transport(trans, local_time);
130 unsigned int transport_dbg(tlm::tlm_generic_payload &trans) {
131 int idx = index(&trans);
133 return multi_initiator_[idx]->transport_dbg(trans);
137 void invalidate_direct_mem_ptr(
int idx, sc_dt::uint64 start_range,
138 sc_dt::uint64 end_range) {
139 target_socket_->invalidate_direct_mem_ptr(start_range, end_range);
142 bool get_direct_mem_ptr(
143 tlm::tlm_generic_payload &trans, tlm::tlm_dmi &dmi) {
144 int idx = index(&trans);
146 return multi_initiator_[idx]->get_direct_mem_ptr(trans, dmi);
151 int index(tlm::tlm_generic_payload *trans) {
152 if ((sc_core::SC_ELABORATION |
153 sc_core::SC_BEFORE_END_OF_ELABORATION |
154 sc_core::SC_END_OF_ELABORATION) & sc_core::sc_get_status()) {
155 SIM_LOG_ERROR(simics_obj_, 0,
"b_transport called before "
156 "completion of SystemC SC_END_OF_ELABORATION");
160 if (receivers_.size() <= 0) {
161 SIM_LOG_ERROR(simics_obj_, 0,
"b_transport called without "
166 if (receivers_.size() > 1) {
167 for (
auto it = receivers_.begin(); it != receivers_.end(); ++it) {
168 TransactionHandlerInterface *handler =
169 it->second->transaction_handler();
172 if (receiver && receiver->
probe(trans)) {
182 static std::map<sc_core::sc_object*,
183 GasketDispatcher<BUSWIDTH, TYPES, N, POL> *> dispatchers_;
185 std::vector<std::pair<size_t, GasketInterface *> > receivers_;
186 tlm_utils::multi_passthrough_initiator_socket<
189 TYPES> multi_initiator_;
190 tlm_utils::simple_target_socket<
191 GasketDispatcher<BUSWIDTH, TYPES, N, POL>,
192 BUSWIDTH, TYPES> target_socket_;
193 simics::ConfObjectRef simics_obj_;
196template <
unsigned int BUSWIDTH,
199 sc_core::sc_port_policy POL>
200std::map<sc_core::sc_object*,
201 GasketDispatcher<BUSWIDTH, TYPES, N, POL> *>
202GasketDispatcher<BUSWIDTH, TYPES, N, POL>::dispatchers_;
Interface implemented by the ExtensionReceiver class, used by the ExtensionDispatcher.
Definition: receiver_interface.h:29
virtual bool probe(tlm::tlm_generic_payload *payload)=0
Definition: gasket_dispatcher.h:34
GasketDispatcherBase()
Definition: gasket_dispatcher.h:36
virtual ~GasketDispatcherBase()
Definition: gasket_dispatcher.h:40
static void cleanCache()
Definition: gasket_dispatcher.h:41
Definition: gasket_dispatcher.h:59
static GasketInterface::Ptr bind(tlm::tlm_initiator_socket< BUSWIDTH, TYPES, N, POL > *socket, const char *name, const simics::ConfObjectRef &simics_obj)
Definition: gasket_dispatcher.h:75
SC_CTOR(GasketDispatcher)
Definition: gasket_dispatcher.h:61
virtual ~GasketDispatcher()
Definition: gasket_dispatcher.h:99
std::shared_ptr< GasketInterface > Ptr
Definition: gasket_interface.h:32
Implements core functionality for receiving a TLM2 transaction over a socket.
Definition: gasket.h:63
void bind(Socket &sock)
Definition: gasket.h:90
Definition: pci_bus_interface.h:24