ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
VirtualStruct.h
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2//
3// This file is part of ETISS. It is licensed under the BSD 3-Clause License; you may not use this file except in
4// compliance with the License. You should have received a copy of the license along with this project. If not, see the
5// LICENSE file.
13#ifndef ETISS_PLUGIN_VIRTUALSTRUCT_H_
14#define ETISS_PLUGIN_VIRTUALSTRUCT_H_
15#include "etiss/CVirtualStruct.h"
16#include "etiss/Misc.h"
18
19#include <cstddef>
20
21#include <memory>
22
23namespace etiss
24{
25
26class VSSync;
27
100class VirtualStruct : public std::enable_shared_from_this<VirtualStruct>, public etiss::fault::Injector
101{
102 friend class VSSync;
103
104 public:
109 class Field
110 {
111 public:
119 {
120 public:
121 virtual ~Listener();
122 virtual void write(etiss::VirtualStruct::Field &field, uint64_t val) = 0;
123 };
124
125 private:
127 {
128 bool operator()(const std::pair<Listener *, std::shared_ptr<Listener>> &lhs,
129 const std::pair<Listener *, std::shared_ptr<Listener>> &rhs) const
130 {
131 return lhs.first < rhs.first;
132 }
133 };
134
135 public:
149
150 public: // flags
151 static const int R = 1;
152 static const int W = 2;
153 static const int RW = R | W;
154 static const int L = 4;
156 static const int F = 8;
157 static const int A = 16;
158 static const int P = 32;
160
161 public: // constructor
168 Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags, size_t width,
169 size_t bitwidth = 0);
170 Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags, size_t width,
171 bool virtual_enabled, std::function<uint64_t()> lread, std::function<void(uint64_t)> lwrite,
172 size_t bitwidth = 0);
173 virtual ~Field();
174
175 public: // fields
177 const std::string name_;
179 const std::string prettyname_;
181 int flags_;
182 const size_t width_;
183 const size_t bitwidth_;
185
186 public: // read write
187 uint64_t read()
188 const;
191 void write(uint64_t);
194 bool applyBitflip(unsigned position, uint64_t fault_id);
196 std::string &errormsg);
197 void signalWrite();
200 protected: // read write implementation
202 virtual uint64_t _read() const;
205 virtual void _write(uint64_t);
207 virtual bool _applyBitflip(unsigned position, uint64_t fault_id);
209 virtual bool _applyAction(const etiss::fault::Fault &f, const etiss::fault::Action &a, std::string &errormsg);
211 std::function<uint64_t()> lread;
214 std::function<void(uint64_t)> lwrite;
215
216 public:
218 std::function<bool(unsigned position, uint64_t fault_id)> lapplyBitflip;
219
220 public:
221 std::function<void(Field *)> delete_;
222 inline Field *setDeleteP(std::function<void(Field *)> del)
223 {
224 delete_ = del;
225 return this;
226 }
227 inline Field &setDelete(std::function<void(Field *)> del)
228 {
229 delete_ = del;
230 return *this;
231 }
232
233 public:
237 bool addListener(Listener *listener, std::shared_ptr<Listener> ref = nullptr);
242 void removeListener(Listener *listener, std::shared_ptr<Listener> ref = nullptr);
243
244 private:
245 std::set<std::pair<Listener *, std::shared_ptr<Listener>>, listener_pair_compare> listeners;
246 };
247
248 private:
249 template <typename structT, typename retT, retT structT::*field>
251 {
252 static_assert(sizeof(retT) <= sizeof(uint64_t),
253 "Cannot use etiss::VirtualStruct::FieldT for a field larger than uint64_t");
254
255 protected:
256 FieldT(VirtualStruct &parent, const std::string &name, const std::string &prettyname)
257 : Field(parent, name, prettyname, 0, sizeof(retT))
258 {
259 }
260 virtual uint64_t _read() const { return (uint64_t)((const structT *)parent_.structure_)->*field; }
261 virtual void _write(uint64_t val) { ((structT *)parent_.structure_)->*field = (retT)val; }
262 };
263
264 protected:
265 VirtualStruct(void *structure, std::function<void(Field *)> dtor = [](Field *f) { delete f; });
266
267 public:
268 virtual ~VirtualStruct();
269
270 bool addField(Field *f, bool noerrorprint = false);
271
272 template <typename structT, typename retT, retT structT::*field>
274 bool addField(const std::string &name, const std::string &prettyname = "", bool noerrorprint = false)
275 {
276
277 Field *ret = new FieldT<structT, retT, field>(*this, name, prettyname);
278
279 if (!addField(ret, noerrorprint))
280 {
281 delete ret;
282 return false;
283 }
284
285 return true;
286 }
287
288 template <typename T>
289 bool addField(const std::string &name, const std::string &prettyname, std::function<T()> read,
290 std::function<void(T)> write, bool supportsListener = false, bool noerrorprint = false)
291 {
292 int flags = 0;
293 if (read)
294 flags |= Field::R;
295 if (write)
296 flags |= Field::W;
297 if (supportsListener)
298 flags |= Field::L;
299 Field *f = new Field(
300 *this, name, prettyname, flags, sizeof(T), false, [read]() { return (uint64_t)read(); },
301 [write](uint64_t v) { write((T)v); });
302 if (addField(f, noerrorprint))
303 return true;
304 delete f;
305 return false;
306 }
307
308 std::shared_ptr<Field> findName(const std::string &name) const;
309 std::shared_ptr<Field> findPrettyName(const std::string &name) const;
310 void foreachField(const std::function<void(std::shared_ptr<Field>)> &func);
311
312 bool mountStruct(const std::string &name, const std::shared_ptr<VirtualStruct> vs);
313 std::shared_ptr<VirtualStruct> findStruct(const std::string &name);
314 void foreachStruct(const std::function<void(const std::string &name, VirtualStruct &vs)> &func);
315
316 void close();
317 bool isClosed();
318
319 public: // inherited from etiss::fault::Injector
320 virtual std::list<std::string> listFields();
321 virtual std::list<std::string> listSubInjectors();
322
323 virtual std::shared_ptr<etiss::fault::Injector> getSubInjector(const std::string &name);
324 virtual std::shared_ptr<etiss::fault::Injector> getParentInjector();
325
326 virtual bool acceleratedTrigger(const etiss::fault::Trigger &, int32_t fault_id);
327
328 protected: // inherited from etiss::fault::Injector
329 virtual void *fastFieldAccessPtr(const std::string &name, std::string &errormsg);
330 virtual bool readField(void *fastfieldaccessptr, uint64_t &val, std::string &errormsg);
331 virtual bool applyAction(const etiss::fault::Fault &fault, const etiss::fault::Action &action,
332 std::string &errormsg);
333 virtual bool update_field_access_rights(const etiss::fault::Action &action, std::string &errormsg);
334
335 public:
338 std::function<bool(const etiss::fault::Fault &, const etiss::fault::Action &, std::string & /*errormsg*/)>
340
341 public:
342 void *const structure_;
344
345 private:
346 std::list<Field *> fields_;
347 std::map<std::string, Field *> fieldNames_;
348 std::map<std::string, Field *> fieldPrettyNames_;
349 std::map<std::string, std::weak_ptr<VirtualStruct>> subStructs_;
350 std::function<void(Field *)> dtor_;
351 bool closed;
352
353 private:
354 std::shared_ptr<VirtualStruct> parent_;
355
356 public:
357 static std::shared_ptr<VirtualStruct> allocate(void *structure, std::function<void(Field *)> delete_);
358
359 public: // name resolving an root VirtualStruct
360 static std::shared_ptr<VirtualStruct> root();
361
362 std::shared_ptr<VirtualStruct> getVirtualStruct(const std::string &path);
363
364 std::shared_ptr<VirtualStruct::Field> getResolvedField(const std::string &path);
365
366 public: // C interface
370 static std::shared_ptr<VirtualStruct> allocateFromC(void *handle, VirtualStruct_names names,
371 VirtualStruct_prettyNames prettyNames_optional,
372 VirtualStruct_read read_recommended,
373 VirtualStruct_write write_optional,
374 VirtualStruct_setListenerCallback setListenerCallback_optional,
375 std::function<void(void *handle)> cleanup);
376};
377
383{
384 public:
385 VSSync();
386 ~VSSync();
387
388 private:
389 static std::recursive_mutex &mutex();
390};
391
401void copy(VirtualStruct &dst, VirtualStruct &src, std::list<std::shared_ptr<VirtualStruct::Field>> &dst_notPresent,
402 std::list<std::shared_ptr<VirtualStruct::Field>> &dst_notWriteable,
403 std::list<std::shared_ptr<VirtualStruct::Field>> dst_unknown, bool pretend = false,
404 std::list<std::shared_ptr<VirtualStruct::Field>> *src_private = 0,
405 std::list<std::shared_ptr<VirtualStruct::Field>> *dst_private = 0);
406
408{
409 public:
410 virtual inline ~VirtualStructSupport() {}
414 virtual std::shared_ptr<VirtualStruct> getStruct() = 0;
415 virtual const std::string &getName() = 0;
416};
417
418#define ETISS_VIRTUALSTRUCT_ADDFIELD(VIRTUALSTRUCT, STRUCT, FIELD, NAME, PRETTYNAME) \
419 (VIRTUALSTRUCT).addField<STRUCT, decltype(((STRUCT *)0)->FIELD), &STRUCT::FIELD>(NAME, PRETTYNAME);
420
421} // namespace etiss
422
423#endif
contains the fault injector interface class.
general configuration and logging
do v
Definition arm_acle.h:76
static __inline__ uint64_t
Definition arm_cde.h:31
static __inline__ int32_t
Definition arm_mve.h:51
uint64_t(* VirtualStruct_read)(void *handle, uint32_t index)
read the value of the field at the given index
void(* VirtualStruct_setListenerCallback)(void *handle, void *callbackHandle, void(*callback)(void *handle, void *callbackHandle, uint32_t index))
setter function to register the callback handle for listener supported fields.
void(* VirtualStruct_write)(void *handle, uint32_t index)
write the value of the field at the given index
const char *const *(* VirtualStruct_names)(void *handle)
must return an array of zero terminated strings.
const char *const *(* VirtualStruct_prettyNames)(void *handle)
similar to above array but with human readable/alternative field names (see etiss::VirtualStruct)
used for synchronization of the tree of virtual structs.
static std::recursive_mutex & mutex()
virtual std::shared_ptr< VirtualStruct > getStruct()=0
virtual const std::string & getName()=0
virtual void _write(uint64_t val)
override this function to implement writes in case of AccessMode::VIRTUAL / AccessMode::PREFER_LAMBDA
FieldT(VirtualStruct &parent, const std::string &name, const std::string &prettyname)
virtual uint64_t _read() const
override this function to implement reads in case of AccessMode::VIRTUAL / AccessMode::PREFER_LAMBDA
NOTE: etiss::CPUArch should implement support for Listeners by either using the etiss::VirtualStruct:...
virtual void write(etiss::VirtualStruct::Field &field, uint64_t val)=0
a Field instance represents e.g.
Field & setDelete(std::function< void(Field *)> del)
std::function< uint64_t()> lread
set this function for reads in case of AccessMode::LAMBDA / AccessMode::PREFER_LAMBDA
static const int W
write flag
Field * setDeleteP(std::function< void(Field *)> del)
AccessMode
defines how a field should perform reads/writes.
@ PREFER_LAMBDA
tries to use the lread,lwrite functions and falls back to virtual functions
@ LAMBDA
uses the lread,lwrite functions
@ VIRTUAL
uses the virtual _read() / _write functions
bool applyAction(const etiss::fault::Fault &f, const etiss::fault::Action &a, std::string &errormsg)
advanced fault injection. Field must have the A flag to use this.
static const int A
supports advanced fault injection/tracing with the applyAction function
const std::string name_
name of the field.
virtual bool _applyBitflip(unsigned position, uint64_t fault_id)
override this function to implement bitflip applying to a field
static const int RW
flags to signal that a field supports read and write operations
const size_t width_
width in bytes (rounded up if neccessary)
void signalWrite()
this function should be called if the listener flag is set and the field changed without using the wr...
void removeListener(Listener *listener, std::shared_ptr< Listener > ref=nullptr)
static const int L
supports listener plugins; used for etiss::RegisterDevicePlugins to determine access to a variable/fi...
virtual uint64_t _read() const
override this function to implement reads in case of AccessMode::VIRTUAL / AccessMode::PREFER_LAMBDA
VirtualStruct & parent_
reference to parent virtual struct
int flags_
read write flags as specified by the static const int parameters of Field: R,W,L
bool addListener(Listener *listener, std::shared_ptr< Listener > ref=nullptr)
void write(uint64_t)
function to write bits/a value to the Field.
static const int P
private field: this flag indicates that this field is an implementation specific field that e....
bool applyBitflip(unsigned position, uint64_t fault_id)
function to write a bitflip to a field
std::function< bool(unsigned position, uint64_t fault_id)> lapplyBitflip
if this function is set the the default implementation of applyBitflip will use it
static const int R
read flag
static const int F
supports fault injection/tracing
uint64_t read() const
function to read bits/a value from the Field.
const std::string prettyname_
alternative/human readable name of the field.
std::function< void(uint64_t)> lwrite
set this function for writes in case of AccessMode::LAMBDA / AccessMode::PREFER_LAMBDA
virtual bool _applyAction(const etiss::fault::Fault &f, const etiss::fault::Action &a, std::string &errormsg)
override this function to implement advanced action handling
std::set< std::pair< Listener *, std::shared_ptr< Listener > >, listener_pair_compare > listeners
const size_t bitwidth_
width in bits
std::function< void(Field *)> delete_
virtual void _write(uint64_t)
override this function to implement writes in case of AccessMode::VIRTUAL / AccessMode::PREFER_LAMBDA
abstract representation of an module of a simulation which could be a embedded device of the cpu of a...
virtual bool readField(void *fastfieldaccessptr, uint64_t &val, std::string &errormsg)
read the value of a field
std::map< std::string, Field * > fieldNames_
std::map< std::string, Field * > fieldPrettyNames_
void foreachStruct(const std::function< void(const std::string &name, VirtualStruct &vs)> &func)
bool mountStruct(const std::string &name, const std::shared_ptr< VirtualStruct > vs)
std::shared_ptr< VirtualStruct > getVirtualStruct(const std::string &path)
bool addField(const std::string &name, const std::string &prettyname, std::function< T()> read, std::function< void(T)> write, bool supportsListener=false, bool noerrorprint=false)
virtual bool acceleratedTrigger(const etiss::fault::Trigger &, int32_t fault_id)
std::list< Field * > fields_
std::shared_ptr< Field > findName(const std::string &name) const
static std::shared_ptr< VirtualStruct > allocateFromC(void *handle, VirtualStruct_names names, VirtualStruct_prettyNames prettyNames_optional, VirtualStruct_read read_recommended, VirtualStruct_write write_optional, VirtualStruct_setListenerCallback setListenerCallback_optional, std::function< void(void *handle)> cleanup)
implemented in CVirtualStruct.cpp
virtual bool applyAction(const etiss::fault::Fault &fault, const etiss::fault::Action &action, std::string &errormsg)
bool addField(const std::string &name, const std::string &prettyname="", bool noerrorprint=false)
add a structure field to this VirtualStructure
static std::shared_ptr< VirtualStruct > root()
std::map< std::string, std::weak_ptr< VirtualStruct > > subStructs_
bool addField(Field *f, bool noerrorprint=false)
static std::shared_ptr< VirtualStruct > allocate(void *structure, std::function< void(Field *)> delete_)
virtual std::list< std::string > listSubInjectors()
list all sub injectors.
virtual std::list< std::string > listFields()
list all fields directly reachable by this injector
std::function< void(Field *)> dtor_
virtual void * fastFieldAccessPtr(const std::string &name, std::string &errormsg)
void foreachField(const std::function< void(std::shared_ptr< Field >)> &func)
std::shared_ptr< VirtualStruct > parent_
std::shared_ptr< VirtualStruct::Field > getResolvedField(const std::string &path)
std::function< bool(const etiss::fault::Trigger &, int32_t)> acceleratedTrigger_
virtual std::shared_ptr< etiss::fault::Injector > getParentInjector()
get a the parent injector (root returns 0).
virtual bool update_field_access_rights(const etiss::fault::Action &action, std::string &errormsg)
Update the field of injector with access rights to allow action (used to get type of action).
std::shared_ptr< Field > findPrettyName(const std::string &name) const
std::function< bool(const etiss::fault::Fault &, const etiss::fault::Action &, std::string &)> applyCustomAction
set this function to handle custom commands passed by etiss::fault::Action of the type etiss::fault::...
std::shared_ptr< VirtualStruct > findStruct(const std::string &name)
virtual std::shared_ptr< etiss::fault::Injector > getSubInjector(const std::string &name)
get a sub injector.
forwards: include/jit/*
Definition Benchmark.h:17
void copy(VirtualStruct &dst, VirtualStruct &src, std::list< std::shared_ptr< VirtualStruct::Field > > &dst_notPresent, std::list< std::shared_ptr< VirtualStruct::Field > > &dst_notWriteable, std::list< std::shared_ptr< VirtualStruct::Field > > dst_unknown, bool pretend=false, std::list< std::shared_ptr< VirtualStruct::Field > > *src_private=0, std::list< std::shared_ptr< VirtualStruct::Field > > *dst_private=0)
copies all fields with the same name from the source to the destination structure.
#define bool
Definition stdbool.h:15
bool operator()(const std::pair< Listener *, std::shared_ptr< Listener > > &lhs, const std::pair< Listener *, std::shared_ptr< Listener > > &rhs) const