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 mapes 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()) {
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()) {
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 interconnect_.connected(id);
171 }
172
173 void disconnected(conf_object_t *port_obj, uint16_t id) override {
174 Context context(simulation_);
175
176 if (port_obj == nullptr) {
177 SIM_LOG_ERROR(simulation_->simics_object(), 0,
178 "can't disconnect from NULL");
179 return;
180 }
181
182 if (simics_transaction_target_ != port_obj) {
183 SIM_LOG_ERROR(simulation_->simics_object(), 0,
184 "can't disconnect from '%s', currently connected"
185 " to '%s'",
186 SIM_object_name(port_obj),
187 SIM_object_name(simics_transaction_target_));
188 return;
189 }
190
192 // Delete mapping
193 interconnect_.disconnected(id);
194 simics_transaction_target_.set(nullptr);
195 }
196 }
197
198 void hot_reset() override {
199 Context context(simulation_);
200 interconnect_.hotReset();
201 }
202
203 // NOTE: By using the TPciDevice as method parameter, the compiler can
204 // deduce the template parameter.
205 template<typename TPcieDevice>
206 void connect(TPcieDevice *device) {
207 auto o = simulation_->simics_object();
208
209 // Connect IC's pcie_device target socket
210 // No payload is sent to the socket since PcieDevice is completely
211 // handled here
212 systemc_pcie_.set_gasket(
213 simics2tlm::createGasket(
214 &interconnect_.pcie_device_target_socket, o));
215
216 // Connect IC's transaction target socket (snooping)
217 systemc_transaction_.set_gasket(
218 simics2tlm::createGasket(
219 &interconnect_.transaction_target_socket, o));
220
221 // Connect IC's warm reset target socket
222 systemc_signal_.set_pin(&interconnect_.warm_reset_pin, false, o);
223
224 // Connect IC's pcie_map initiator socket to the pcie upstream target
225 simics_transaction_target_->set_gasket(
226 tlm2simics::createMultiGasket(
227 &interconnect_.pcie_map_initiator_socket, o));
228 simics_pcie_map_target_->set_gasket(
229 tlm2simics::createMultiGasket(
230 &interconnect_.pcie_map_initiator_socket, o));
231
232 // Retrieve the required information from the device to configure
233 // the IC to prepare the connection with the device
234 interconnect_.connect(
235 dynamic_cast<iface::PcieDeviceQueryInterface *>(device),
237 device),
238 dynamic_cast<iface::PcieResetInterface *>(device),
239 obj_ ? obj_ : o);
240 }
241
242 // Return the current map from address range to socket ID (Memory)
243 std::map<std::pair<size_t, size_t>, size_t> addressIdMemMap() const {
244 return interconnect_.addressIdMemMap();
245 }
246 // Return the current map from address range to socket ID (IO)
247 std::map<std::pair<size_t, size_t>, size_t> addressIdIoMap() const {
248 return interconnect_.addressIdIoMap();
249 }
250
252 return interconnect_.enable_base_address_subtraction;
253 }
254 void setEnableBaseAddressSubtraction(const bool &val) {
255 interconnect_.enable_base_address_subtraction = val;
256 }
257 void setPcieTypeAndForwardTarget(ConfObjectRef obj) {
258 SIM_set_attribute_default(
259 SIM_object_descendant(obj, "port.mem"), "pcie_type",
260 SIM_make_attr_int64(types::PCIE_Type_Mem));
261 SIM_set_attribute_default(
262 SIM_object_descendant(obj, "port.mem"), "forward_target",
263 SIM_make_attr_object(obj));
264 SIM_set_attribute_default(
265 SIM_object_descendant(obj, "port.io"), "pcie_type",
266 SIM_make_attr_int64(types::PCIE_Type_IO));
267 SIM_set_attribute_default(
268 SIM_object_descendant(obj, "port.io"), "forward_target",
269 SIM_make_attr_object(obj));
270 SIM_set_attribute_default(
271 SIM_object_descendant(obj, "port.msg"), "pcie_type",
272 SIM_make_attr_int64(types::PCIE_Type_Msg));
273 SIM_set_attribute_default(
274 SIM_object_descendant(obj, "port.msg"), "forward_target",
275 SIM_make_attr_object(obj));
276 }
277
278 // Create map helpers which are mapped on the cfg space. It contains
279 // PCI information like PCIe type and function id which is used to
280 // route the transaction to the right TLM2 socket
282 interconnect_.createCfgMapHelper();
283 }
284
285 private:
286 iface::SimulationInterface *simulation_;
287
288 // Snoop PCI transactions and handle Simics mappings
290
291 // Gaskets required for wrapping a PCIe device
292 simics2tlm::PcieDevice systemc_pcie_;
293 simics2tlm::PcieTransaction systemc_transaction_;
294 simics2systemc::Signal systemc_signal_;
295
296 simics::ConfObjectRef obj_;
297};
298
299} // namespace composite
300
301template <class T>
302void SCLCompositePcieInit(typename T::is_composite_pcie_gasket,
303 ConfClass *cls) {
304 composite::PcieGasketBase::initClassInternal<T>(cls);
305}
306
307} // namespace systemc
308} // namespace simics
309
310#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:198
void createCfgMapHelper()
Definition: pcie_gasket.h:281
void disconnected(conf_object_t *port_obj, uint16_t id) override
Definition: pcie_gasket.h:173
bool enableBaseAddressSubtraction() const
Definition: pcie_gasket.h:251
std::map< std::pair< size_t, size_t >, size_t > addressIdMemMap() const
Definition: pcie_gasket.h:243
void connected(conf_object_t *port_obj, uint16_t id) override
Definition: pcie_gasket.h:149
void connect(TPcieDevice *device)
Definition: pcie_gasket.h:206
PcieGasket(iface::SimulationInterface *simulation, simics::ConfObjectRef obj)
Definition: pcie_gasket.h:133
PcieGasket(iface::SimulationInterface *simulation)
Definition: pcie_gasket.h:123
void setPcieTypeAndForwardTarget(ConfObjectRef obj)
Definition: pcie_gasket.h:257
void setEnableBaseAddressSubtraction(const bool &val)
Definition: pcie_gasket.h:254
std::map< std::pair< size_t, size_t >, size_t > addressIdIoMap() const
Definition: pcie_gasket.h:247
Definition: pcie_mapping_interconnect.h:106
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
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:80