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// -*- mode: C++; c-file-style: "virtutech-c++" -*-
2
3/*
4 © 2015 Intel Corporation
5
6 This software and the related documents are Intel copyrighted materials, and
7 your use of them is governed by the express license under which they were
8 provided to you ("License"). Unless the License provides otherwise, you may
9 not use, modify, copy, publish, distribute, disclose or transmit this software
10 or the related documents without Intel's prior written permission.
11
12 This software and the related documents are provided as is, with no express or
13 implied warranties, other than those that are expressly stated in the License.
14*/
15
16#ifndef SIMICS_SYSTEMC_IFACE_SIMICS_ADAPTER_H
17#define SIMICS_SYSTEMC_IFACE_SIMICS_ADAPTER_H
18
19#include <simics/iface/interface-info.h>
20#include <simics/devs/io-memory.h>
25
26#include <string>
27#include <vector>
28
29namespace simics {
30namespace systemc {
31namespace iface {
32
45template<typename TSimicsInterface>
46class SimicsAdapter : public simics::iface::InterfaceInfo,
47 public Registrant<SimicsAdapterInterface> {
48 public:
49 SimicsAdapter(const char *name, TSimicsInterface iface)
50 : name_(name),
51 iface_(iface),
52 conf_class_(NULL),
53 map_adapter_(true) {
54 }
55
56 // simics::iface::InterfaceInfo
57 std::string name() const override {
58 return name_;
59 }
60 const interface_t *cstruct() const override {
61 return &iface_;
62 }
63
64 void set_simics_class(conf_class_t *conf_class) override {
65 if (!conf_class_)
66 conf_class_ = conf_class;
67 }
68 conf_class_t *simics_class() const override {
69 return conf_class_;
70 }
71 void set_map_adapter(bool map) override {
72 map_adapter_ = map;
73 }
74 bool map_adapter() const override {
75 return map_adapter_;
76 }
77
78 protected:
79 template<typename TBase, typename TInterface>
80 static TInterface *adapterWithoutLocking(conf_object_t *obj) {
81 FATAL_ERROR_IF(!obj, "NULL object passed to Simics interface");
82 TBase *so = simics::from_obj<TBase>(obj);
83 TInterface *adapter = dynamic_cast<TInterface*>(so);
84 FATAL_ERROR_IF(adapter == NULL, "Unable to locate GasketAdapter");
85 return adapter;
86 }
87 // This version is mainly used by the tool_simics_adapter that the lock
88 // is not implemented on obj but on the provider/connection object.
89 template<typename TBase, typename TInterface>
90 static SimicsLock<TInterface> adapter(conf_object_t *obj,
91 conf_object_t *obj_lock) {
92 SimulationInterface *simulation = cached_simulation_;
93 if (obj_lock != cached_obj_lock_
94 || cached_obj_id_ != SIM_object_id(obj_lock)) {
95 ConfObject *lock_base =
96 simics::from_obj<ConfObject>(obj_lock);
97 simulation = dynamic_cast<SimulationInterface*>(lock_base);
98 if (simulation == nullptr) {
99 conf_object_t *parent = SIM_port_object_parent(obj_lock);
100 if (parent) {
101 // Check port's parent
102 lock_base = simics::from_obj<ConfObject>(parent);
103 simulation = dynamic_cast<SimulationInterface*>(lock_base);
104 }
105 }
106 FATAL_ERROR_IF(simulation == NULL, "Unable to locate Simulation");
107 cached_obj_lock_ = obj_lock;
108 cached_obj_id_ = SIM_object_id(obj_lock);
109 cached_simulation_ = simulation;
110 }
111 return {simulation, adapterWithoutLocking<TBase, TInterface>(obj)};
112 }
113 template<typename TBase, typename TInterface>
114 static SimicsLock<TInterface> adapter(conf_object_t *obj) {
115 return adapter<TBase, TInterface>(obj, obj);
116 }
117 template<typename TBase, typename TInterface>
118 std::vector<std::string> descriptionBase(conf_object_t *obj,
119 DescriptionType type) {
120 if (SIM_object_class(obj) != conf_class_ )
121 return {};
122
123 TInterface *iface = adapterWithoutLocking<TBase, TInterface>(obj);
124 auto *adapter = dynamic_cast<DescriptionInterface<TInterface> *>(iface);
125 if (!adapter)
126 return {};
127
128 std::vector<std::string> description = adapter->description(type);
129 if (description.empty())
130 return {};
131
132 description.insert(description.begin(), name_);
133 description.insert(description.begin(), SIM_object_name(obj));
134 return description;
135 }
136
137 private:
138 std::string name_;
139 TSimicsInterface iface_;
140 conf_class_t *conf_class_;
141 bool map_adapter_;
142 // Under extreme scenarios (100M consecutive interface calls) the
143 // dynamic_cast within adapter() becomes a problem. By caching the
144 // result, this is avoided. This was highlighted (and verified) by VTune
145 static conf_object_t *cached_obj_lock_;
146 // A char pointer cannot be safely used to cache the object ID, as the same
147 // object ID pointer may be reused for a different object.
148 // Use std::string for cached_obj_id_ instead.
149 static std::string cached_obj_id_;
150 static SimulationInterface* cached_simulation_;
151};
152
153template<typename TSimicsInterface> conf_object_t*
154SimicsAdapter<TSimicsInterface>::cached_obj_lock_ = nullptr;
155template<typename TSimicsInterface> std::string
156SimicsAdapter<TSimicsInterface>::cached_obj_id_ = "";
157template<typename TSimicsInterface> SimulationInterface*
158SimicsAdapter<TSimicsInterface>::cached_simulation_ = nullptr;
159
162
173template <typename InterfaceSimicsAdapter>
174InterfaceSimicsAdapter& createAdapter() {
175 static InterfaceSimicsAdapter adapter;
176 return adapter;
177}
178
186inline void bindUnmappedSimicsAdapters(conf_class_t *conf_class) {
187 struct Binder {
188 bool operator()(SimicsAdapterInterface *adapter) {
189 if (adapter->map_adapter()) {
190 adapter->set_simics_class(conf_class_);
191 adapter->set_map_adapter(false);
192 }
193 return false;
194 }
195 conf_class_t *conf_class_;
196 };
197 Binder binder{conf_class};
199}
200
202
203} // namespace iface
204} // namespace systemc
205} // namespace simics
206
207#endif
Definition: description_interface.h:34
Definition: registry.h:89
static Registry< T > * instance()
Definition: registry.h:70
Definition: simics_lock.h:27
Definition: simics_adapter_interface.h:29
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:47
static TInterface * adapterWithoutLocking(conf_object_t *obj)
Definition: simics_adapter.h:80
const interface_t * cstruct() const override
Definition: simics_adapter.h:60
void set_map_adapter(bool map) override
Definition: simics_adapter.h:71
conf_class_t * simics_class() const override
Definition: simics_adapter.h:68
static SimicsLock< TInterface > adapter(conf_object_t *obj)
Definition: simics_adapter.h:114
SimicsAdapter(const char *name, TSimicsInterface iface)
Definition: simics_adapter.h:49
std::vector< std::string > descriptionBase(conf_object_t *obj, DescriptionType type)
Definition: simics_adapter.h:118
static SimicsLock< TInterface > adapter(conf_object_t *obj, conf_object_t *obj_lock)
Definition: simics_adapter.h:90
void set_simics_class(conf_class_t *conf_class) override
Definition: simics_adapter.h:64
std::string name() const override
Definition: simics_adapter.h:57
bool map_adapter() const override
Definition: simics_adapter.h:74
Interface to the SystemC simulation.
Definition: simulation_interface.h:27
void bindUnmappedSimicsAdapters(conf_class_t *conf_class)
Bind all adapters that are still pending mapping to a conf_class.
Definition: simics_adapter.h:186
InterfaceSimicsAdapter & createAdapter()
Create a SimicsAdapter that can be registered with a ConfClass.
Definition: simics_adapter.h:174
DescriptionType
Definition: description_interface.h:25
Definition: adapter.h:81