SystemC Library API Reference Manual
Reference documentation for the Simics SystemC Library.
 
Loading...
Searching...
No Matches
gasket_dispatcher.h
Go to the documentation of this file.
1// -*- mode: C++; c-file-style: "virtutech-c++" -*-
2
3/*
4 © 2020 Intel Corporation
5
6 This software and the related documents are Intel copyrighted materials, and
7 your use of them is governed by the express license under which they were
8 provided to you ("License"). Unless the License provides otherwise, you may
9 not use, modify, copy, publish, distribute, disclose or transmit this software
10 or the related documents without Intel's prior written permission.
11
12 This software and the related documents are provided as is, with no express or
13 implied warranties, other than those that are expressly stated in the License.
14*/
15
16#ifndef SIMICS_SYSTEMC_TLM2SIMICS_GASKET_DISPATCHER_H
17#define SIMICS_SYSTEMC_TLM2SIMICS_GASKET_DISPATCHER_H
18
19
21
22#include <tlm>
23#include <tlm_utils/multi_passthrough_initiator_socket.h>
24#include <tlm_utils/simple_target_socket.h>
25
26#include <map>
27#include <utility>
28#include <vector>
29
30namespace simics {
31namespace systemc {
32namespace tlm2simics {
33
35 public:
37 context_.insert(
38 std::make_pair(sc_core::sc_get_curr_simcontext(), this));
39 }
41 static void cleanCache() {
42 auto range = context_.equal_range(sc_core::sc_get_curr_simcontext());
43 for (auto it = range.first; it != range.second; ++it)
44 delete it->second;
45
46 context_.erase(sc_core::sc_get_curr_simcontext());
47 }
48
49 private:
50 static std::multimap<sc_core::sc_simcontext *,
51 GasketDispatcherBase *> context_;
52};
53
54template <unsigned int BUSWIDTH = 32,
55 typename TYPES = tlm::tlm_base_protocol_types,
56 int N = 1,
57 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
59 : public sc_core::sc_module, public GasketDispatcherBase {
60 public:
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);
74 }
76 tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL> *socket,
77 const char *name,
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;
86 }
87
88 dispatcher = dispatchers_[socket];
89 assert(dispatcher);
91 name, simics_obj);
92
93 dispatcher->receivers_.push_back(
94 std::make_pair(dispatcher->receivers_.size(),
95 gasket));
96 gasket->bind(dispatcher->multi_initiator_);
97 return GasketInterface::Ptr(gasket);
98 }
100 for (auto it = dispatchers_.begin(); it != dispatchers_.end(); ++it) {
101 if (it->second == this) {
102 dispatchers_.erase(it);
103 return;
104 }
105 }
106 }
107
108 private:
109 tlm::tlm_sync_enum nb_transport_fw(
110 tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, // NOLINT
111 sc_core::sc_time &local_time) { // NOLINT
112 int idx = index(&trans);
113 if (idx >= 0)
114 return multi_initiator_[idx]->nb_transport_fw(trans, phase,
115 local_time);
116
117 return tlm::TLM_COMPLETED;
118 }
119 tlm::tlm_sync_enum nb_transport_bw(
120 int idx, tlm::tlm_generic_payload &trans, // NOLINT
121 tlm::tlm_phase &phase, sc_core::sc_time &local_time) { // NOLINT
122 return target_socket_->nb_transport_bw(trans, phase, local_time);
123 }
124 void b_transport(
125 tlm::tlm_generic_payload &trans, sc_core::sc_time &local_time) { // NOLINT
126 int idx = index(&trans);
127 if (idx >= 0)
128 multi_initiator_[idx]->b_transport(trans, local_time);
129 }
130 unsigned int transport_dbg(tlm::tlm_generic_payload &trans) { // NOLINT
131 int idx = index(&trans);
132 if (idx >= 0)
133 return multi_initiator_[idx]->transport_dbg(trans);
134
135 return 0;
136 }
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);
140 }
141
142 bool get_direct_mem_ptr(
143 tlm::tlm_generic_payload &trans, tlm::tlm_dmi &dmi) { // NOLINT
144 int idx = index(&trans);
145 if (idx >= 0)
146 return multi_initiator_[idx]->get_direct_mem_ptr(trans, dmi);
147
148 return false;
149 }
150
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");
157 return -1;
158 }
159
160 if (receivers_.size() <= 0) {
161 SIM_LOG_ERROR(simics_obj_, 0, "b_transport called without "
162 "bound socket");
163 return -1;
164 }
165
166 if (receivers_.size() > 1) {
167 for (auto it = receivers_.begin(); it != receivers_.end(); ++it) {
168 TransactionHandlerInterface *handler =
169 it->second->transaction_handler();
171 handler->receiver();
172 if (receiver && receiver->probe(trans)) {
173 return it->first;
174 }
175 }
176 }
177
178 // Use first gasket as default for transactions without extensions
179 return 0;
180 }
181
182 static std::map<sc_core::sc_object*,
183 GasketDispatcher<BUSWIDTH, TYPES, N, POL> *> dispatchers_;
184
185 std::vector<std::pair<size_t, GasketInterface *> > receivers_;
186 tlm_utils::multi_passthrough_initiator_socket<
187 GasketDispatcher,
188 BUSWIDTH,
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_;
194};
195
196template <unsigned int BUSWIDTH,
197 typename TYPES,
198 int N,
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_;
203
204} // namespace tlm2simics
205} // namespace systemc
206} // namespace simics
207
208#endif
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