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/* -*- mode: C++; c-file-style: "virtutech-c++" -*-
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 // The device_id should use 0 as the function number (F part of B:D:F)
177 interconnect_.connected(id & ~0x7);
178 }
179
180 void disconnected(conf_object_t *port_obj, uint16_t id) override {
181 Context context(simulation_);
182
183 if (port_obj == nullptr) {
184 SIM_LOG_ERROR(simulation_->simics_object(), 0,
185 "can't disconnect from NULL");
186 return;
187 }
188
189 if (simics_transaction_target_ != port_obj) {
190 SIM_LOG_ERROR(simulation_->simics_object(), 0,
191 "can't disconnect from '%s', currently connected"
192 " to '%s'",
193 SIM_object_name(port_obj),
194 SIM_object_name(simics_transaction_target_));
195 return;
196 }
197
199 // Delete mapping
200 // The device_id should use 0 as the function number
201 // (F part of B:D:F)
202 interconnect_.disconnected(id & ~0x7);
203 simics_transaction_target_.set(nullptr);
204 }
205 }
206
207 void hot_reset() override {
208 Context context(simulation_);
209 interconnect_.hotReset();
210 }
211
212 // NOTE: By using the TPciDevice as method parameter, the compiler can
213 // deduce the template parameter.
214 template<typename TPcieDevice>
215 void connect(TPcieDevice *device) {
216 auto o = simulation_->simics_object();
217
218 // Connect IC's pcie_device target socket
219 // No payload is sent to the socket since PcieDevice is completely
220 // handled here
221 systemc_pcie_.set_gasket(
222 simics2tlm::createGasket(
223 &interconnect_.pcie_device_target_socket, o));
224
225 // Connect IC's transaction target socket (snooping)
226 systemc_transaction_.set_gasket(
227 simics2tlm::createGasket(
228 &interconnect_.transaction_target_socket, o));
229 systemc_transaction_.set_deferrable(true);
230
231 // Connect IC's warm reset target socket
232 systemc_signal_.set_pin(&interconnect_.warm_reset_pin, false, o);
233
234 // Connect IC's pcie_map initiator socket to the pcie upstream target
235 simics_transaction_target_->set_gasket(
236 tlm2simics::createMultiGasket(
237 &interconnect_.pcie_map_initiator_socket, o));
238 simics_pcie_map_target_->set_gasket(
239 tlm2simics::createMultiGasket(
240 &interconnect_.pcie_map_initiator_socket, o));
241
242 // Retrieve the required information from the device to configure
243 // the IC to prepare the connection with the device
244 interconnect_.connect(
245 dynamic_cast<iface::PcieDeviceQueryInterface *>(device),
247 device),
248 dynamic_cast<iface::PcieResetInterface *>(device),
249 obj_ ? obj_ : o,
250 dynamic_cast<iface::PcieSriovQueryInterface *>(device));
251 }
252
253 // Return the current map from address range to socket ID (Memory)
254 std::map<std::pair<size_t, size_t>, size_t> addressIdMemMap() const {
255 return interconnect_.addressIdMemMap();
256 }
257 // Return the current map from address range to socket ID (IO)
258 std::map<std::pair<size_t, size_t>, size_t> addressIdIoMap() const {
259 return interconnect_.addressIdIoMap();
260 }
261
263 return interconnect_.enable_base_address_subtraction;
264 }
265 void setEnableBaseAddressSubtraction(const bool &val) {
266 interconnect_.enable_base_address_subtraction = val;
267 }
268
269 // Create map helpers which are mapped on the cfg space. It contains
270 // PCI information like PCIe type and function id which is used to
271 // route the transaction to the right TLM2 socket
273 interconnect_.createCfgMapHelper();
274 }
275
276 private:
277 void setPcieTypeAndForwardTarget(ConfObjectRef obj) {
278 SIM_set_attribute_default(
279 SIM_object_descendant(obj, "port.mem"), "pcie_type",
280 SIM_make_attr_int64(types::PCIE_Type_Mem));
281 SIM_set_attribute_default(
282 SIM_object_descendant(obj, "port.mem"), "forward_target",
283 SIM_make_attr_object(obj));
284 SIM_set_attribute_default(
285 SIM_object_descendant(obj, "port.io"), "pcie_type",
286 SIM_make_attr_int64(types::PCIE_Type_IO));
287 SIM_set_attribute_default(
288 SIM_object_descendant(obj, "port.io"), "forward_target",
289 SIM_make_attr_object(obj));
290 SIM_set_attribute_default(
291 SIM_object_descendant(obj, "port.msg"), "pcie_type",
292 SIM_make_attr_int64(types::PCIE_Type_Msg));
293 SIM_set_attribute_default(
294 SIM_object_descendant(obj, "port.msg"), "forward_target",
295 SIM_make_attr_object(obj));
296 }
297
298 iface::SimulationInterface *simulation_;
299
300 // Snoop PCI transactions and handle Simics mappings
301 PcieMappingInterconnect<BUSWIDTH, TYPES> interconnect_;
302
303 // Gaskets required for wrapping a PCIe device
304 simics2tlm::PcieDevice systemc_pcie_;
305 simics2tlm::PcieTransaction systemc_transaction_;
306 simics2systemc::Signal systemc_signal_;
307
308 simics::ConfObjectRef obj_;
309};
310
311} // namespace composite
312
313template <class T>
314void SCLCompositePcieInit(typename T::is_composite_pcie_gasket,
315 ConfClass *cls) {
316 composite::PcieGasketBase::initClassInternal<T>(cls);
317}
318
319} // namespace systemc
320} // namespace simics
321
322#endif
Definition: connector.h:76
Provides get/set functionality for a connector attribute, typically registered by using the Connector...
Definition: connector.h:41
Utility class that handles the context switching, using RAII methodology.
Definition: context.h:33
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:207
void createCfgMapHelper()
Definition: pcie_gasket.h:272
void disconnected(conf_object_t *port_obj, uint16_t id) override
Definition: pcie_gasket.h:180
bool enableBaseAddressSubtraction() const
Definition: pcie_gasket.h:262
std::map< std::pair< size_t, size_t >, size_t > addressIdMemMap() const
Definition: pcie_gasket.h:254
void connected(conf_object_t *port_obj, uint16_t id) override
Definition: pcie_gasket.h:155
void connect(TPcieDevice *device)
Definition: pcie_gasket.h:215
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:265
std::map< std::pair< size_t, size_t >, size_t > addressIdIoMap() const
Definition: pcie_gasket.h:258
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:32
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:32
Interface to the SystemC simulation.
Definition: simulation_interface.h:27
virtual ConfObjectRef simics_object() const =0
Adapter for Simics signal interface.
Definition: transaction_simics_adapter.h:32
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:35
SignalGasketAdapter(SignalInterface *signal, iface::SimulationInterface *simulation)
Definition: signal_gasket_adapter.h:37
void set_gasket(GasketInterface::Ptr gasketInterface)
Definition: gasket_owner.h:39
Adapter for PcieDevice gasket.
Definition: pcie_device_gasket_adapter.h:33
PcieDeviceGasketAdapter(PcieDeviceInterface *pcie_device, iface::SimulationInterface *simulation)
Definition: pcie_device_gasket_adapter.h:35
Class that implements the Simics pcie_device interface and translates it into a TLM transaction.
Definition: pcie_device.h:33
Definition: pcie_transaction.h:36
Adapter for Transaction gasket.
Definition: transaction_gasket_adapter.h:33
TransactionGasketAdapter(TransactionInterface *transaction, iface::SimulationInterface *simulation)
Definition: transaction_gasket_adapter.h:35
void set_deferrable(bool enable)
Toggle code paths for deferred transactions.
Definition: transaction.h:57
void bindUnmappedSimicsAdapters(conf_class_t *conf_class)
Bind all adapters that are still pending mapping to a conf_class.
Definition: simics_adapter.h:186
conf_class_t * SIM_get_class(const char *NOTNULL name)
void SCLCompositePcieInit(...)
Definition: class_decorator.h:34
@ PCIE_Type_Mem
Definition: pcie_type.h:24
@ PCIE_Type_Msg
Definition: pcie_type.h:27
@ PCIE_Type_IO
Definition: pcie_type.h:25
Definition: adapter.h:81