SystemC Library API Reference Manual
Reference documentation for the Simics SystemC Library.
 
Loading...
Searching...
No Matches
simics_adapter.h
Go to the documentation of this file.
1/*
2 © 2015 Intel Corporation
3
4 This software and the related documents are Intel copyrighted materials, and
5 your use of them is governed by the express license under which they were
6 provided to you ("License"). Unless the License provides otherwise, you may
7 not use, modify, copy, publish, distribute, disclose or transmit this software
8 or the related documents without Intel's prior written permission.
9
10 This software and the related documents are provided as is, with no express or
11 implied warranties, other than those that are expressly stated in the License.
12*/
13
14#ifndef SIMICS_SYSTEMC_IFACE_SIMICS_ADAPTER_H
15#define SIMICS_SYSTEMC_IFACE_SIMICS_ADAPTER_H
16
17#include <simics/iface/interface-info.h>
18#include <simics/devs/io-memory.h>
23
24#include <string>
25#include <vector>
26
27namespace simics {
28namespace systemc {
29namespace iface {
30
43template<typename TSimicsInterface>
44class SimicsAdapter : public simics::iface::InterfaceInfo,
45 public Registrant<SimicsAdapterInterface> {
46 public:
47 SimicsAdapter(const char *name, TSimicsInterface iface)
48 : name_(name),
49 iface_(iface),
50 conf_class_(NULL),
51 map_adapter_(true) {
52 }
53
54 // simics::iface::InterfaceInfo
55 std::string name() const override {
56 return name_;
57 }
58 const interface_t *cstruct() const override {
59 return &iface_;
60 }
61
62 void set_simics_class(conf_class_t *conf_class) override {
63 if (!conf_class_)
64 conf_class_ = conf_class;
65 }
66 conf_class_t *simics_class() const override {
67 return conf_class_;
68 }
69 void set_map_adapter(bool map) override {
70 map_adapter_ = map;
71 }
72 bool map_adapter() const override {
73 return map_adapter_;
74 }
75
76 protected:
77 template<typename TBase, typename TInterface>
78 static TInterface *adapterWithoutLocking(conf_object_t *obj) {
79 FATAL_ERROR_IF(!obj, "NULL object passed to Simics interface");
80 TBase *so = simics::from_obj<TBase>(obj);
81 TInterface *adapter = dynamic_cast<TInterface*>(so);
82 FATAL_ERROR_IF(adapter == NULL, "Unable to locate GasketAdapter");
83 return adapter;
84 }
85 // This version is mainly used by the tool_simics_adapter that the lock
86 // is not implemented on obj but on the provider/connection object.
87 template<typename TBase, typename TInterface>
88 static SimicsLock<TInterface> adapter(conf_object_t *obj,
89 conf_object_t *obj_lock) {
90 // Cache the SimulationInterface* to avoid repeated dynamic_cast under
91 // extreme call rates (highlighted by VTune at 100M+ consecutive calls).
92 ConfObject *lock_base = simics::from_obj<ConfObject>(obj_lock);
93 SimulationInterface *simulation = cached_simulation_;
94 if (lock_base != cached_lock_base_) {
95 simulation = dynamic_cast<SimulationInterface*>(lock_base);
96 if (simulation == nullptr) {
97 conf_object_t *parent = SIM_port_object_parent(obj_lock);
98 if (parent) {
99 // Check port's parent
100 lock_base = simics::from_obj<ConfObject>(parent);
101 simulation = dynamic_cast<SimulationInterface*>(lock_base);
102 }
103 }
104 FATAL_ERROR_IF(simulation == NULL, "Unable to locate Simulation");
105 cached_lock_base_ = lock_base;
106 cached_simulation_ = simulation;
107 }
108 return {simulation, adapterWithoutLocking<TBase, TInterface>(obj)};
109 }
110 template<typename TBase, typename TInterface>
111 static SimicsLock<TInterface> adapter(conf_object_t *obj) {
112 return adapter<TBase, TInterface>(obj, obj);
113 }
114 template<typename TBase, typename TInterface>
115 std::vector<std::string> descriptionBase(conf_object_t *obj,
116 DescriptionType type) {
117 if (SIM_object_class(obj) != conf_class_ )
118 return {};
119
120 TInterface *iface = adapterWithoutLocking<TBase, TInterface>(obj);
121 auto *adapter = dynamic_cast<DescriptionInterface<TInterface> *>(iface);
122 if (!adapter)
123 return {};
124
125 std::vector<std::string> description = adapter->description(type);
126 if (description.empty())
127 return {};
128
129 description.insert(description.begin(), name_);
130 description.insert(description.begin(), SIM_object_name(obj));
131 return description;
132 }
133
134 private:
135 std::string name_;
136 TSimicsInterface iface_;
137 conf_class_t *conf_class_;
138 bool map_adapter_;
139 // Cache the ConfObject* and SimulationInterface* to avoid expensive
140 // dynamic_cast operations during high-frequency interface calls.
141 // dynamic_cast is O(n) in the inheritance hierarchy depth and can
142 // dominate performance at extreme call rates (100M+ consecutive calls).
143 // We use ConfObject* as the cache key because it identifies the
144 // underlying C++ instance associated with the cached lock object for
145 // these calls, allowing fast pointer-equality cache checks without
146 // string allocation or comparison overhead.
147 static ConfObject *cached_lock_base_;
148 static SimulationInterface *cached_simulation_;
149};
150
151
152
153template<typename TSimicsInterface> ConfObject*
154SimicsAdapter<TSimicsInterface>::cached_lock_base_ = nullptr;
155template<typename TSimicsInterface> SimulationInterface*
156SimicsAdapter<TSimicsInterface>::cached_simulation_ = nullptr;
157
160
171template <typename InterfaceSimicsAdapter>
172InterfaceSimicsAdapter& createAdapter() {
173 static InterfaceSimicsAdapter adapter;
174 return adapter;
175}
176
184inline void bindUnmappedSimicsAdapters(conf_class_t *conf_class) {
185 struct Binder {
186 bool operator()(SimicsAdapterInterface *adapter) {
187 if (adapter->map_adapter()) {
188 adapter->set_simics_class(conf_class_);
189 adapter->set_map_adapter(false);
190 }
191 return false;
192 }
193 conf_class_t *conf_class_;
194 };
195 Binder binder{conf_class};
197}
198
200
201} // namespace iface
202} // namespace systemc
203} // namespace simics
204
205#endif
Definition: description_interface.h:32
Definition: registry.h:86
static Registry< T > * instance()
Definition: registry.h:67
Definition: simics_lock.h:25
Definition: simics_adapter_interface.h:27
virtual void set_simics_class(conf_class_t *conf_class)=0
Base class for mapping Simics interface to a C++ interface.
Definition: simics_adapter.h:45
static TInterface * adapterWithoutLocking(conf_object_t *obj)
Definition: simics_adapter.h:78
const interface_t * cstruct() const override
Definition: simics_adapter.h:58
void set_map_adapter(bool map) override
Definition: simics_adapter.h:69
conf_class_t * simics_class() const override
Definition: simics_adapter.h:66
static SimicsLock< TInterface > adapter(conf_object_t *obj)
Definition: simics_adapter.h:111
SimicsAdapter(const char *name, TSimicsInterface iface)
Definition: simics_adapter.h:47
std::vector< std::string > descriptionBase(conf_object_t *obj, DescriptionType type)
Definition: simics_adapter.h:115
static SimicsLock< TInterface > adapter(conf_object_t *obj, conf_object_t *obj_lock)
Definition: simics_adapter.h:88
void set_simics_class(conf_class_t *conf_class) override
Definition: simics_adapter.h:62
std::string name() const override
Definition: simics_adapter.h:55
bool map_adapter() const override
Definition: simics_adapter.h:72
Interface to the SystemC simulation.
Definition: simulation_interface.h:25
void bindUnmappedSimicsAdapters(conf_class_t *conf_class)
Bind all adapters that are still pending mapping to a conf_class.
Definition: simics_adapter.h:184
InterfaceSimicsAdapter & createAdapter()
Create a SimicsAdapter that can be registered with a ConfClass.
Definition: simics_adapter.h:172
DescriptionType
Definition: description_interface.h:23
Definition: adapter.h:79