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 cls->add(Attribute("upstream_target", "o|n",
68 "The PCIe upstream target to connect to.",
69 ATTR_CLS_VAR(C, simics_transaction_target_)));
70 cls->add(Attribute("address_id_mem_map", "[[[ii]i]*]",
71 "Internal. The map from MEM address range to"
72 " socket ID",
73 ATTR_GETTER(C, addressIdMemMap), nullptr));
74 cls->add(Attribute("address_id_io_map", "[[[ii]i]*]",
75 "Internal. The map from IO address range to"
76 " socket ID",
77 ATTR_GETTER(C, addressIdIoMap), nullptr));
78 cls->add(Attribute("enable_base_address_subtraction", "b",
79 "If set, MEM/IO transaction will receive only the"
80 " offset to the base address. Otherwise, it receives"
81 " the whole base address + offset. Default enabled",
82 ATTR_GETTER(C, enableBaseAddressSubtraction),
83 ATTR_SETTER(C, setEnableBaseAddressSubtraction)));
84 cls->add(pcie_device_simics_adapter);
85 cls->add(transaction_simics_adapter);
86 cls->add(signal_simics_adapter);
87
88 // Depends on the pcie_map_helper_cpp class
89 auto *map_helper = SIM_get_class("pcie_map_helper_cpp");
90 if (SIM_clear_exception() != SimExc_No_Exception) {
91 std::cerr << "ERROR: Simics class pcie_map_helper_cpp is not"
92 << " registered. Please build module"
93 << " pcie-map-helper-c++ first."
94 << std::endl;
95 }
96 assert(map_helper);
97 SIM_register_port(*cls, "port.mem", map_helper,
98 " The help object maps to the PCIe MEM space");
99 SIM_register_port(*cls, "port.io", map_helper,
100 "The help object maps to the PCIe IO space");
101 SIM_register_port(*cls, "port.msg", map_helper,
102 "The help object maps to the PCIe MSG space");
103 }
104
105 protected:
109 };
110};
111
116template<unsigned int BUSWIDTH = 32,
117 typename TYPES = tlm::tlm_base_protocol_types>
122 public:
124 : PcieDeviceGasketAdapter(&systemc_pcie_, simulation),
125 TransactionGasketAdapter(&systemc_transaction_, simulation),
126 SignalGasketAdapter(&systemc_signal_, simulation),
127 simulation_(simulation) {
128 if (simulation_->simics_object().object()) {
129 setPcieTypeAndForwardTarget(simulation_->simics_object());
130 }
131 }
132
134 simics::ConfObjectRef obj)
135 : PcieDeviceGasketAdapter(&systemc_pcie_, simulation),
136 TransactionGasketAdapter(&systemc_transaction_, simulation),
137 SignalGasketAdapter(&systemc_signal_, simulation),
138 simulation_(simulation),
139 obj_(obj) {
140 if (obj_.object()) {
141 setPcieTypeAndForwardTarget(obj_);
142 }
143 }
144
145 /*
146 * Intercepts PcieDeviceGasketAdapter to connect/disconnect the simics
147 * upstream target connector before pass it down to the IC
148 */
149 void connected(conf_object_t *port_obj, uint16_t id) override {
150 Context context(simulation_);
151
152 if (port_obj == nullptr) {
153 SIM_LOG_ERROR(simulation_->simics_object(), 0,
154 "can't connect to NULL");
155 return;
156 }
157
159 if (simics_transaction_target_ != port_obj) {
160 SIM_LOG_ERROR(
161 simulation_->simics_object(), 0,
162 "can't connect to '%s', currently connected to '%s'",
163 SIM_object_name(port_obj),
164 SIM_object_name(simics_transaction_target_));
165 return;
166 }
167 }
168
169 simics_transaction_target_.set(port_obj);
170 // The device_id should use 0 as the function number (F part of B:D:F)
171 interconnect_.connected(id & ~0x7);
172 }
173
174 void disconnected(conf_object_t *port_obj, uint16_t id) override {
175 Context context(simulation_);
176
177 if (port_obj == nullptr) {
178 SIM_LOG_ERROR(simulation_->simics_object(), 0,
179 "can't disconnect from NULL");
180 return;
181 }
182
183 if (simics_transaction_target_ != port_obj) {
184 SIM_LOG_ERROR(simulation_->simics_object(), 0,
185 "can't disconnect from '%s', currently connected"
186 " to '%s'",
187 SIM_object_name(port_obj),
188 SIM_object_name(simics_transaction_target_));
189 return;
190 }
191
193 // Delete mapping
194 // The device_id should use 0 as the function number
195 // (F part of B:D:F)
196 interconnect_.disconnected(id & ~0x7);
197 simics_transaction_target_.set(nullptr);
198 }
199 }
200
201 void hot_reset() override {
202 Context context(simulation_);
203 interconnect_.hotReset();
204 }
205
206 // NOTE: By using the TPciDevice as method parameter, the compiler can
207 // deduce the template parameter.
208 template<typename TPcieDevice>
209 void connect(TPcieDevice *device) {
210 auto o = simulation_->simics_object();
211
212 // Connect IC's pcie_device target socket
213 // No payload is sent to the socket since PcieDevice is completely
214 // handled here
215 systemc_pcie_.set_gasket(
216 simics2tlm::createGasket(
217 &interconnect_.pcie_device_target_socket, o));
218
219 // Connect IC's transaction target socket (snooping)
220 systemc_transaction_.set_gasket(
221 simics2tlm::createGasket(
222 &interconnect_.transaction_target_socket, o));
223 systemc_transaction_.set_deferrable(true);
224
225 // Connect IC's warm reset target socket
226 systemc_signal_.set_pin(&interconnect_.warm_reset_pin, false, o);
227
228 // Connect IC's pcie_map initiator socket to the pcie upstream target
229 simics_transaction_target_->set_gasket(
230 tlm2simics::createMultiGasket(
231 &interconnect_.pcie_map_initiator_socket, o));
232 simics_pcie_map_target_->set_gasket(
233 tlm2simics::createMultiGasket(
234 &interconnect_.pcie_map_initiator_socket, o));
235
236 // Retrieve the required information from the device to configure
237 // the IC to prepare the connection with the device
238 interconnect_.connect(
239 dynamic_cast<iface::PcieDeviceQueryInterface *>(device),
241 device),
242 dynamic_cast<iface::PcieResetInterface *>(device),
243 obj_ ? obj_ : o);
244 }
245
246 // Return the current map from address range to socket ID (Memory)
247 std::map<std::pair<size_t, size_t>, size_t> addressIdMemMap() const {
248 return interconnect_.addressIdMemMap();
249 }
250 // Return the current map from address range to socket ID (IO)
251 std::map<std::pair<size_t, size_t>, size_t> addressIdIoMap() const {
252 return interconnect_.addressIdIoMap();
253 }
254
256 return interconnect_.enable_base_address_subtraction;
257 }
258 void setEnableBaseAddressSubtraction(const bool &val) {
259 interconnect_.enable_base_address_subtraction = val;
260 }
261
262 // Create map helpers which are mapped on the cfg space. It contains
263 // PCI information like PCIe type and function id which is used to
264 // route the transaction to the right TLM2 socket
266 interconnect_.createCfgMapHelper();
267 }
268
269 private:
270 void setPcieTypeAndForwardTarget(ConfObjectRef obj) {
271 SIM_set_attribute_default(
272 SIM_object_descendant(obj, "port.mem"), "pcie_type",
273 SIM_make_attr_int64(types::PCIE_Type_Mem));
274 SIM_set_attribute_default(
275 SIM_object_descendant(obj, "port.mem"), "forward_target",
276 SIM_make_attr_object(obj));
277 SIM_set_attribute_default(
278 SIM_object_descendant(obj, "port.io"), "pcie_type",
279 SIM_make_attr_int64(types::PCIE_Type_IO));
280 SIM_set_attribute_default(
281 SIM_object_descendant(obj, "port.io"), "forward_target",
282 SIM_make_attr_object(obj));
283 SIM_set_attribute_default(
284 SIM_object_descendant(obj, "port.msg"), "pcie_type",
285 SIM_make_attr_int64(types::PCIE_Type_Msg));
286 SIM_set_attribute_default(
287 SIM_object_descendant(obj, "port.msg"), "forward_target",
288 SIM_make_attr_object(obj));
289 }
290
291 iface::SimulationInterface *simulation_;
292
293 // Snoop PCI transactions and handle Simics mappings
294 PcieMappingInterconnect<BUSWIDTH, TYPES> interconnect_;
295
296 // Gaskets required for wrapping a PCIe device
297 simics2tlm::PcieDevice systemc_pcie_;
298 simics2tlm::PcieTransaction systemc_transaction_;
299 simics2systemc::Signal systemc_signal_;
300
301 simics::ConfObjectRef obj_;
302};
303
304} // namespace composite
305
306template <class T>
307void SCLCompositePcieInit(typename T::is_composite_pcie_gasket,
308 ConfClass *cls) {
309 composite::PcieGasketBase::initClassInternal<T>(cls);
310}
311
312} // namespace systemc
313} // namespace simics
314
315#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:106
PcieGasketBase * is_composite_pcie_gasket
Definition: pcie_gasket.h:61
ConnectorProxy< tlm2simics::PcieMap > simics_pcie_map_target_
Definition: pcie_gasket.h:107
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:121
void hot_reset() override
Definition: pcie_gasket.h:201
void createCfgMapHelper()
Definition: pcie_gasket.h:265
void disconnected(conf_object_t *port_obj, uint16_t id) override
Definition: pcie_gasket.h:174
bool enableBaseAddressSubtraction() const
Definition: pcie_gasket.h:255
std::map< std::pair< size_t, size_t >, size_t > addressIdMemMap() const
Definition: pcie_gasket.h:247
void connected(conf_object_t *port_obj, uint16_t id) override
Definition: pcie_gasket.h:149
void connect(TPcieDevice *device)
Definition: pcie_gasket.h:209
PcieGasket(iface::SimulationInterface *simulation, simics::ConfObjectRef obj)
Definition: pcie_gasket.h:133
PcieGasket(iface::SimulationInterface *simulation)
Definition: pcie_gasket.h:123
void setEnableBaseAddressSubtraction(const bool &val)
Definition: pcie_gasket.h:258
std::map< std::pair< size_t, size_t >, size_t > addressIdIoMap() const
Definition: pcie_gasket.h:251
Interface that allows the Simics glue to perform snooping and automatic connection of the device's ta...
Definition: pcie_device_query_interface.h:50
Interface required from a SystemC PCIe device in order to connect to Simics.
Definition: pcie_device_query_interface.h:29
Adapter for Simics pcie_device interface.
Definition: pcie_device_simics_adapter.h:32
Definition: pcie_device_query_interface.h:92
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
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