ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
VirtualStruct.h
Go to the documentation of this file.
1
52#ifndef ETISS_PLUGIN_VIRTUALSTRUCT_H_
53#define ETISS_PLUGIN_VIRTUALSTRUCT_H_
54#include "etiss/CVirtualStruct.h"
55#include "etiss/Misc.h"
57
58#include <cstddef>
59
60#include <memory>
61
62namespace etiss
63{
64
65class VSSync;
66
139class VirtualStruct : public std::enable_shared_from_this<VirtualStruct>, public etiss::fault::Injector
140{
141 friend class VSSync;
142
143 public:
148 class Field
149 {
150 public:
158 {
159 public:
160 virtual ~Listener();
161 virtual void write(etiss::VirtualStruct::Field &field, uint64_t val) = 0;
162 };
163
164 private:
166 {
167 bool operator()(const std::pair<Listener *, std::shared_ptr<Listener>> &lhs,
168 const std::pair<Listener *, std::shared_ptr<Listener>> &rhs) const
169 {
170 return lhs.first < rhs.first;
171 }
172 };
173
174 public:
188
189 public: // flags
190 static const int R = 1;
191 static const int W = 2;
192 static const int RW = R | W;
193 static const int L = 4;
195 static const int F = 8;
196 static const int A = 16;
197 static const int P = 32;
199
200 public: // constructor
207 Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags, size_t width,
208 size_t bitwidth = 0);
209 Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags, size_t width,
210 bool virtual_enabled, std::function<uint64_t()> lread, std::function<void(uint64_t)> lwrite,
211 size_t bitwidth = 0);
212 virtual ~Field();
213
214 public: // fields
216 const std::string name_;
218 const std::string prettyname_;
220 const int flags_;
221 const size_t width_;
222 const size_t bitwidth_;
224
225 public: // read write
226 uint64_t read()
227 const;
230 void write(uint64_t);
233 bool applyBitflip(unsigned position, uint64_t fault_id);
235 std::string &errormsg);
236 void signalWrite();
239 protected: // read write implementation
241 virtual uint64_t _read() const;
244 virtual void _write(uint64_t);
246 virtual bool _applyBitflip(unsigned position, uint64_t fault_id);
248 virtual bool _applyAction(const etiss::fault::Fault &f, const etiss::fault::Action &a, std::string &errormsg);
250 std::function<uint64_t()> lread;
253 std::function<void(uint64_t)> lwrite;
254
255 public:
257 std::function<bool(unsigned position, uint64_t fault_id)> lapplyBitflip;
258
259 public:
260 std::function<void(Field *)> delete_;
261 inline Field *setDeleteP(std::function<void(Field *)> del)
262 {
263 delete_ = del;
264 return this;
265 }
266 inline Field &setDelete(std::function<void(Field *)> del)
267 {
268 delete_ = del;
269 return *this;
270 }
271
272 public:
276 bool addListener(Listener *listener, std::shared_ptr<Listener> ref = nullptr);
281 void removeListener(Listener *listener, std::shared_ptr<Listener> ref = nullptr);
282
283 private:
284 std::set<std::pair<Listener *, std::shared_ptr<Listener>>, listener_pair_compare> listeners;
285 };
286
287 private:
288 template <typename structT, typename retT, retT structT::*field>
290 {
291 static_assert(sizeof(retT) <= sizeof(uint64_t),
292 "Cannot use etiss::VirtualStruct::FieldT for a field larger than uint64_t");
293
294 protected:
295 FieldT(VirtualStruct &parent, const std::string &name, const std::string &prettyname)
296 : Field(parent, name, prettyname, 0, sizeof(retT))
297 {
298 }
299 virtual uint64_t _read() const { return (uint64_t)((const structT *)parent_.structure_)->*field; }
300 virtual void _write(uint64_t val) { ((structT *)parent_.structure_)->*field = (retT)val; }
301 };
302
303 private:
304 VirtualStruct(void *structure, std::function<void(Field *)> dtor = [](Field *f) { delete f; });
305
306 public:
307 virtual ~VirtualStruct();
308
309 bool addField(Field *f, bool noerrorprint = false);
310
311 template <typename structT, typename retT, retT structT::*field>
313 bool addField(const std::string &name, const std::string &prettyname = "", bool noerrorprint = false)
314 {
315
316 Field *ret = new FieldT<structT, retT, field>(*this, name, prettyname);
317
318 if (!addField(ret, noerrorprint))
319 {
320 delete ret;
321 return false;
322 }
323
324 return true;
325 }
326
327 template <typename T>
328 bool addField(const std::string &name, const std::string &prettyname, std::function<T()> read,
329 std::function<void(T)> write, bool supportsListener = false, bool noerrorprint = false)
330 {
331 int flags = 0;
332 if (read)
333 flags |= Field::R;
334 if (write)
335 flags |= Field::W;
336 if (supportsListener)
337 flags |= Field::L;
338 Field *f = new Field(*this, name, prettyname, flags, sizeof(T), false, [read]() { return (uint64_t)read(); },
339 [write](uint64_t v) { write((T)v); });
340 if (addField(f, noerrorprint))
341 return true;
342 delete f;
343 return false;
344 }
345
346 std::shared_ptr<Field> findName(const std::string &name) const;
347 std::shared_ptr<Field> findPrettyName(const std::string &name) const;
348 void foreachField(const std::function<void(std::shared_ptr<Field>)> &func);
349
350 bool mountStruct(const std::string &name, const std::shared_ptr<VirtualStruct> vs);
351 std::shared_ptr<VirtualStruct> findStruct(const std::string &name);
352 void foreachStruct(const std::function<void(const std::string &name, VirtualStruct &vs)> &func);
353
354 void close();
355 bool isClosed();
356
357 public: // inherited from etiss::fault::Injector
358 virtual std::list<std::string> listFields();
359 virtual std::list<std::string> listSubInjectors();
360
361 virtual std::shared_ptr<etiss::fault::Injector> getSubInjector(const std::string &name);
362 virtual std::shared_ptr<etiss::fault::Injector> getParentInjector();
363
364 virtual bool acceleratedTrigger(const etiss::fault::Trigger &, int32_t fault_id);
365
366 protected: // inherited from etiss::fault::Injector
367 virtual void *fastFieldAccessPtr(const std::string &name, std::string &errormsg);
368 virtual bool readField(void *fastfieldaccessptr, uint64_t &val, std::string &errormsg);
369 virtual bool applyAction(const etiss::fault::Fault &fault, const etiss::fault::Action &action,
370 std::string &errormsg);
371
372 public:
375 std::function<bool(const etiss::fault::Fault &, const etiss::fault::Action &, std::string & /*errormsg*/)>
377
378 public:
379 void *const structure_;
381
382 private:
383 std::list<Field *> fields_;
384 std::map<std::string, Field *> fieldNames_;
385 std::map<std::string, Field *> fieldPrettyNames_;
386 std::map<std::string, std::weak_ptr<VirtualStruct>> subStructs_;
387 std::function<void(Field *)> dtor_;
388 bool closed;
389
390 private:
391 std::shared_ptr<VirtualStruct> parent_;
392
393 public:
394 static std::shared_ptr<VirtualStruct> allocate(void *structure, std::function<void(Field *)> delete_);
395
396 public: // name resolving an root VirtualStruct
397 static std::shared_ptr<VirtualStruct> root();
398
399 std::shared_ptr<VirtualStruct> getVirtualStruct(const std::string &path);
400
401 std::shared_ptr<VirtualStruct::Field> getResolvedField(const std::string &path);
402
403 public: // C interface
407 static std::shared_ptr<VirtualStruct> allocateFromC(void *handle, VirtualStruct_names names,
408 VirtualStruct_prettyNames prettyNames_optional,
409 VirtualStruct_read read_recommended,
410 VirtualStruct_write write_optional,
411 VirtualStruct_setListenerCallback setListenerCallback_optional,
412 std::function<void(void *handle)> cleanup);
413};
414
420{
421 public:
422 VSSync();
423 ~VSSync();
424
425 private:
426 static std::recursive_mutex &mutex();
427};
428
438void copy(VirtualStruct &dst, VirtualStruct &src, std::list<std::shared_ptr<VirtualStruct::Field>> &dst_notPresent,
439 std::list<std::shared_ptr<VirtualStruct::Field>> &dst_notWriteable,
440 std::list<std::shared_ptr<VirtualStruct::Field>> dst_unknown, bool pretend = false,
441 std::list<std::shared_ptr<VirtualStruct::Field>> *src_private = 0,
442 std::list<std::shared_ptr<VirtualStruct::Field>> *dst_private = 0);
443
445{
446 public:
447 virtual inline ~VirtualStructSupport() {}
451 virtual std::shared_ptr<VirtualStruct> getStruct() = 0;
452};
453
454#define ETISS_VIRTUALSTRUCT_ADDFIELD(VIRTUALSTRUCT, STRUCT, FIELD, NAME, PRETTYNAME) \
455 (VIRTUALSTRUCT).addField<STRUCT, decltype(((STRUCT *)0)->FIELD), &STRUCT::FIELD>(NAME, PRETTYNAME);
456
457} // namespace etiss
458
459#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 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
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
const int flags_
read write flags as specified by the static const int parameters of Field: R,W,L
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).
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.
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition Benchmark.h:53
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