SystemC Library API Reference Manual
Reference documentation for the Simics SystemC Library.
 
Loading...
Searching...
No Matches
pcie_gasket.h
Go to the documentation of this file.
1/*
2
3 © 2024 Intel Corporation
4
5 This software and the related documents are Intel copyrighted materials, and
6 your use of them is governed by the express license under which they were
7 provided to you ("License"). Unless the License provides otherwise, you may
8 not use, modify, copy, publish, distribute, disclose or transmit this software
9 or the related documents without Intel's prior written permission.
10
11 This software and the related documents are provided as is, with no express or
12 implied warranties, other than those that are expressly stated in the License.
13*/
14
15/*
16 * Used by device that simulates a PCIe endpoint/multifunciton endpoint with
17 * a Type 0 header.
18 * It implements the following Simics interfaces:
19 * - `pcie_device` interface which handles the PCIe connection
20 * - `pcie_transaction` interface which receives PCIe transactions
21 * - `signal` interface which receives warm reset
22 * It implements the following Simics connectors:
23 * - `pcie_map` connector which controls the map/unmap bar memory, and
24 * enable/disable PCI functions
25 * - `pcie_transaction` connector which sends PCIe transactions
26 */
27
28#ifndef SIMICS_SYSTEMC_COMPOSITE_PCIE_GASKET_H
29#define SIMICS_SYSTEMC_COMPOSITE_PCIE_GASKET_H
30
31#include <tlm>
32
33#include <simics/cc-api.h> // Attribute
50
51#include <iostream>
52#include <map>
53#include <utility>
54
55namespace simics {
56namespace systemc {
57namespace composite {
58
60 public:
62 template <typename C>
63 static void initClassInternal(ConfClass *cls) {
64 static iface::PcieDeviceSimicsAdapter<C> pcie_device_simics_adapter;
65 static iface::TransactionSimicsAdapter<C> transaction_simics_adapter;
66 static iface::SignalSimicsAdapter<C> signal_simics_adapter;
67 // Bind all currently unmapped adapters (i.e. the ones just created
68 // above) to this gasket class before a subsequent device class's
69 // initClassInternal calls bindUnmappedSimicsAdapters for the device
70 // class.
72
73 cls->add(Attribute("upstream_target", "o|n",
74 "The PCIe upstream target to connect to.",
75 ATTR_CLS_VAR(C, simics_transaction_target_)));
76 cls->add(Attribute("address_id_mem_map", "[[[ii]i]*]",
77 "Internal. The map from MEM address range to"
78 " socket ID",
79 ATTR_GETTER(C, addressIdMemMap), nullptr));
80 cls->add(Attribute("address_id_io_map", "[[[ii]i]*]",
81 "Internal. The map from IO address range to"
82 " socket ID",
83 ATTR_GETTER(C, addressIdIoMap), nullptr));
84 cls->add(Attribute("enable_base_address_subtraction", "b",
85 "If set, MEM/IO transaction will receive only the"
86 " offset to the base address. Otherwise, it receives"
87 " the whole base address + offset. Default enabled",
88 ATTR_GETTER(C, enableBaseAddressSubtraction),
89 ATTR_SETTER(C, setEnableBaseAddressSubtraction)));
90 cls->add(pcie_device_simics_adapter);
91 cls->add(transaction_simics_adapter);
92 cls->add(signal_simics_adapter);
93
94 // Depends on the pcie_map_helper_cpp class
95 auto *map_helper = SIM_get_class("pcie_map_helper_cpp");
96 if (SIM_clear_exception() != SimExc_No_Exception) {
97 std::cerr << "ERROR: Simics class pcie_map_helper_cpp is not"
98 << " registered. Please build module"
99 << " pcie-map-helper-c++ first."
100 << std::endl;
101 }
102 assert(map_helper);
103 SIM_register_port(*cls, "port.mem", map_helper,
104 " The help object maps to the PCIe MEM space");
105 SIM_register_port(*cls, "port.io", map_helper,
106 "The help object maps to the PCIe IO space");
107 SIM_register_port(*cls, "port.msg", map_helper,
108 "The help object maps to the PCIe MSG space");
109 }
110
111 protected:
115 };
116};
117
122template<unsigned int BUSWIDTH = 32,
123 typename TYPES = tlm::tlm_base_protocol_types>
128 public:
130 : PcieDeviceGasketAdapter(&systemc_pcie_, simulation),
131 TransactionGasketAdapter(&systemc_transaction_, simulation),
132 SignalGasketAdapter(&systemc_signal_, simulation),
133 simulation_(simulation) {
134 if (simulation_->simics_object().object()) {
135 setPcieTypeAndForwardTarget(simulation_->simics_object());
136 }
137 }
138
140 simics::ConfObjectRef obj)
141 : PcieDeviceGasketAdapter(&systemc_pcie_, simulation),
142 TransactionGasketAdapter(&systemc_transaction_, simulation),
143 SignalGasketAdapter(&systemc_signal_, simulation),
144 simulation_(simulation),
145 obj_(obj) {
146 if (obj_.object()) {
147 setPcieTypeAndForwardTarget(obj_);
148 }
149 }
150
151 /*
152 * Intercepts PcieDeviceGasketAdapter to connect/disconnect the simics
153 * upstream target connector before pass it down to the IC
154 */
155 void connected(conf_object_t *port_obj, uint16_t id) override {
156 Context context(simulation_);
157
158 if (port_obj == nullptr) {
159 SIM_LOG_ERROR(simulation_->simics_object(), 0,
160 "can't connect to NULL");
161 return;
162 }
163
165 if (simics_transaction_target_ != port_obj) {
166 SIM_LOG_ERROR(
167 simulation_->simics_object(), 0,
168 "can't connect to '%s', currently connected to '%s'",
169 SIM_object_name(port_obj),
170 SIM_object_name(simics_transaction_target_));
171 return;
172 }
173 }
174
175 simics_transaction_target_.set(port_obj);
176 interconnect_.connected(id);
177 }
178
179 void disconnected(conf_object_t *port_obj, uint16_t id) override {
180 Context context(simulation_);
181
182 if (port_obj == nullptr) {
183 SIM_LOG_ERROR(simulation_->simics_object(), 0,
184 "can't disconnect from NULL");
185 return;
186 }
187
188 if (simics_transaction_target_ != port_obj) {
189 SIM_LOG_ERROR(simulation_->simics_object(), 0,
190 "can't disconnect from '%s', currently connected"
191 " to '%s'",
192 SIM_object_name(port_obj),
193 SIM_object_name(simics_transaction_target_));
194 return;
195 }
196
198 // Delete mapping
199 interconnect_.disconnected(id);
200 simics_transaction_target_.set(nullptr);
201 }
202 }
203
204 void hot_reset() override {
205 Context context(simulation_);
206 interconnect_.hotReset();
207 }
208
209 // NOTE: By using the TPciDevice as method parameter, the compiler can
210 // deduce the template parameter.
211 template<typename TPcieDevice>
212 void connect(TPcieDevice *device) {
213 auto o = simulation_->simics_object();
214
215 // Connect IC's pcie_device target socket
216 // No payload is sent to the socket since PcieDevice is completely
217 // handled here
218 systemc_pcie_.set_gasket(
219 simics2tlm::createGasket(
220 &interconnect_.pcie_device_target_socket, o));
221
222 // Connect IC's transaction target socket (snooping)
223 systemc_transaction_.set_gasket(
224 simics2tlm::createGasket(
225 &interconnect_.transaction_target_socket, o));
226 systemc_transaction_.set_deferrable(true);
227
228 // Connect IC's warm reset target socket
229 systemc_signal_.set_pin(&interconnect_.warm_reset_pin, false, o);
230
231 // Connect IC's pcie_map initiator socket to the pcie upstream target
232 simics_transaction_target_->set_gasket(
233 tlm2simics::createMultiGasket(
234 &interconnect_.pcie_map_initiator_socket, o));
235 simics_pcie_map_target_->set_gasket(
236 tlm2simics::createMultiGasket(
237 &interconnect_.pcie_map_initiator_socket, o));
238
239 // Retrieve the required information from the device to configure
240 // the IC to prepare the connection with the device
241 interconnect_.connect(
242 dynamic_cast<iface::PcieDeviceQueryInterface *>(device),
244 device),
245 dynamic_cast<iface::PcieResetInterface *>(device),
246 obj_ ? obj_ : o,
247 dynamic_cast<iface::PcieSriovQueryInterface *>(device));
248 }
249
250 // Return the current map from address range to socket ID (Memory)
251 std::map<std::pair<size_t, size_t>, size_t> addressIdMemMap() const {
252 return interconnect_.addressIdMemMap();
253 }
254 // Return the current map from address range to socket ID (IO)
255 std::map<std::pair<size_t, size_t>, size_t> addressIdIoMap() const {
256 return interconnect_.addressIdIoMap();
257 }
258
260 return interconnect_.enable_base_address_subtraction;
261 }
262 void setEnableBaseAddressSubtraction(const bool &val) {
263 interconnect_.enable_base_address_subtraction = val;
264 }
265
266 // Create map helpers which are mapped on the cfg space. It contains
267 // PCI information like PCIe type and function id which is used to
268 // route the transaction to the right TLM2 socket
270 interconnect_.createCfgMapHelper();
271 }
272
273 private:
274 void setPcieTypeAndForwardTarget(ConfObjectRef obj) {
275 SIM_set_attribute_default(
276 SIM_object_descendant(obj, "port.mem"), "pcie_type",
277 SIM_make_attr_int64(types::PCIE_Type_Mem));
278 SIM_set_attribute_default(
279 SIM_object_descendant(obj, "port.mem"), "forward_target",
280 SIM_make_attr_object(obj));
281 SIM_set_attribute_default(
282 SIM_object_descendant(obj, "port.io"), "pcie_type",
283 SIM_make_attr_int64(types::PCIE_Type_IO));
284 SIM_set_attribute_default(
285 SIM_object_descendant(obj, "port.io"), "forward_target",
286 SIM_make_attr_object(obj));
287 SIM_set_attribute_default(
288 SIM_object_descendant(obj, "port.msg"), "pcie_type",
289 SIM_make_attr_int64(types::PCIE_Type_Msg));
290 SIM_set_attribute_default(
291 SIM_object_descendant(obj, "port.msg"), "forward_target",
292 SIM_make_attr_object(obj));
293 }
294
295 iface::SimulationInterface *simulation_;
296
297 // Snoop PCI transactions and handle Simics mappings
298 PcieMappingInterconnect<BUSWIDTH, TYPES> interconnect_;
299
300 // Gaskets required for wrapping a PCIe device
301 simics2tlm::PcieDevice systemc_pcie_;
302 simics2tlm::PcieTransaction systemc_transaction_;
303 simics2systemc::Signal systemc_signal_;
304
305 simics::ConfObjectRef obj_;
306};
307
308} // namespace composite
309
310template <class T>
311void SCLCompositePcieInit(typename T::is_composite_pcie_gasket,
312 ConfClass *cls) {
313 composite::PcieGasketBase::initClassInternal<T>(cls);
314}
315
316} // namespace systemc
317} // namespace simics
318
319#endif
Definition: connector.h:74
Provides get/set functionality for a connector attribute, typically registered by using the Connector...
Definition: connector.h:39
Utility class that handles the context switching, using RAII methodology.
Definition: context.h:31
Definition: pcie_gasket.h:59
Connector< tlm2simics::PcieTransaction > simics_transaction_target_
Definition: pcie_gasket.h:112
PcieGasketBase * is_composite_pcie_gasket
Definition: pcie_gasket.h:61
ConnectorProxy< tlm2simics::PcieMap > simics_pcie_map_target_
Definition: pcie_gasket.h:113
static void initClassInternal(ConfClass *cls)
Definition: pcie_gasket.h:63
Composite Pcie Gasket to help the wrapping of a SystemC PCIe (multifunction) endpoint in Simics.
Definition: pcie_gasket.h:127
void hot_reset() override
Definition: pcie_gasket.h:204
void createCfgMapHelper()
Definition: pcie_gasket.h:269
void disconnected(conf_object_t *port_obj, uint16_t id) override
Definition: pcie_gasket.h:179
bool enableBaseAddressSubtraction() const
Definition: pcie_gasket.h:259
std::map< std::pair< size_t, size_t >, size_t > addressIdMemMap() const
Definition: pcie_gasket.h:251
void connected(conf_object_t *port_obj, uint16_t id) override
Definition: pcie_gasket.h:155
void connect(TPcieDevice *device)
Definition: pcie_gasket.h:212
PcieGasket(iface::SimulationInterface *simulation, simics::ConfObjectRef obj)
Definition: pcie_gasket.h:139
PcieGasket(iface::SimulationInterface *simulation)
Definition: pcie_gasket.h:129
void setEnableBaseAddressSubtraction(const bool &val)
Definition: pcie_gasket.h:262
std::map< std::pair< size_t, size_t >, size_t > addressIdIoMap() const
Definition: pcie_gasket.h:255
Interface that allows the Simics glue to perform snooping and automatic connection of the device's ta...
Definition: pcie_device_query_interface.h:51
Interface required from a SystemC PCIe device in order to connect to Simics.
Definition: pcie_device_query_interface.h:30
Adapter for Simics pcie_device interface.
Definition: pcie_device_simics_adapter.h:30
Definition: pcie_device_query_interface.h:93
Interface providing static SR-IOV configuration to the PcieMappingInterconnect.
Definition: pcie_device_query_interface.h:124
Adapter for Simics signal interface.
Definition: signal_simics_adapter.h:30
Interface to the SystemC simulation.
Definition: simulation_interface.h:25
virtual ConfObjectRef simics_object() const =0
Adapter for Simics signal interface.
Definition: transaction_simics_adapter.h:30
void set_pin(sc_core::sc_in< bool > *target_pin, bool initial_level, const ConfObjectRef &obj)
Adapter for Signal gasket.
Definition: signal_gasket_adapter.h:33
SignalGasketAdapter(SignalInterface *signal, iface::SimulationInterface *simulation)
Definition: signal_gasket_adapter.h:35
void set_gasket(GasketInterface::Ptr gasketInterface)
Definition: gasket_owner.h:39
Adapter for PcieDevice gasket.
Definition: pcie_device_gasket_adapter.h:31
PcieDeviceGasketAdapter(PcieDeviceInterface *pcie_device, iface::SimulationInterface *simulation)
Definition: pcie_device_gasket_adapter.h:33
Class that implements the Simics pcie_device interface and translates it into a TLM transaction.
Definition: pcie_device.h:31
Definition: pcie_transaction.h:34
Adapter for Transaction gasket.
Definition: transaction_gasket_adapter.h:31
TransactionGasketAdapter(TransactionInterface *transaction, iface::SimulationInterface *simulation)
Definition: transaction_gasket_adapter.h:33
void set_deferrable(bool enable)
Toggle code paths for deferred transactions.
Definition: transaction.h:55
void bindUnmappedSimicsAdapters(conf_class_t *conf_class)
Bind all adapters that are still pending mapping to a conf_class.
Definition: simics_adapter.h:184
conf_class_t * SIM_get_class(const char *NOTNULL name)
void SCLCompositePcieInit(...)
Definition: class_decorator.h:34
@ PCIE_Type_Mem
Definition: pcie_type.h:22
@ PCIE_Type_Msg
Definition: pcie_type.h:25
@ PCIE_Type_IO
Definition: pcie_type.h:23
Definition: adapter.h:79