52 #ifndef ETISS_PLUGIN_VIRTUALSTRUCT_H_
53 #define ETISS_PLUGIN_VIRTUALSTRUCT_H_
54 #include "etiss/CVirtualStruct.h"
168 const std::pair<
Listener *, std::shared_ptr<Listener>> &rhs)
const
170 return lhs.first < rhs.first;
190 static const int R = 1;
191 static const int W = 2;
193 static const int L = 4;
195 static const int F = 8;
196 static const int A = 16;
197 static const int P = 32;
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,
211 size_t bitwidth = 0);
235 std::string &errormsg);
276 bool addListener(Listener *listener, std::shared_ptr<Listener> ref =
nullptr);
281 void removeListener(Listener *listener, std::shared_ptr<Listener> ref =
nullptr);
288 template <
typename structT,
typename retT, retT structT::*field>
292 "Cannot use etiss::VirtualStruct::FieldT for a field larger than uint64_t");
296 :
Field(parent, name, prettyname, 0, sizeof(retT))
304 VirtualStruct(
void *structure, std::function<
void(Field *)> dtor = [](Field *f) {
delete f; });
309 bool addField(Field *f,
bool noerrorprint =
false);
311 template <
typename structT,
typename retT, retT structT::*field>
313 bool addField(
const std::string &name,
const std::string &prettyname =
"",
bool noerrorprint =
false)
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)
336 if (supportsListener)
338 Field *f =
new Field(*
this, name, prettyname, flags,
sizeof(T),
false, [read]() {
return (
uint64_t)read(); },
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);
350 bool mountStruct(
const std::string &name,
const std::shared_ptr<VirtualStruct> vs);
351 std::shared_ptr<VirtualStruct>
findStruct(
const std::string &name);
361 virtual std::shared_ptr<etiss::fault::Injector>
getSubInjector(
const std::string &name);
368 virtual bool readField(
void *fastfieldaccessptr,
uint64_t &val, std::string &errormsg);
370 std::string &errormsg);
394 static std::shared_ptr<VirtualStruct>
allocate(
void *structure, std::function<
void(
Field *)> delete_);
397 static std::shared_ptr<VirtualStruct>
root();
401 std::shared_ptr<VirtualStruct::Field>
getResolvedField(
const std::string &path);
412 std::function<
void(
void *handle)> cleanup);
426 static std::recursive_mutex &
mutex();
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);
454 #define ETISS_VIRTUALSTRUCT_ADDFIELD(VIRTUALSTRUCT, STRUCT, FIELD, NAME, PRETTYNAME) \
455 (VIRTUALSTRUCT).addField<STRUCT, decltype(((STRUCT *)0)->FIELD), &STRUCT::FIELD>(NAME, PRETTYNAME);
#define static_assert(x, y)
contains the fault injector interface class.
general configuration and logging
static __inline__ uint64_t
static __inline__ int32_t
uint64_t(* VirtualStruct_read)(void *handle, uint32_t index)
read the value of the field at the given index
const char *const *(* VirtualStruct_prettyNames)(void *handle)
similar to above array but with human readable/alternative field names (see etiss::VirtualStruct)
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.
used for synchronization of the tree of virtual structs.
static std::recursive_mutex & mutex()
virtual std::shared_ptr< VirtualStruct > getStruct()=0
virtual ~VirtualStructSupport()
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.
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(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags, size_t width, size_t bitwidth=0)
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
Field & setDelete(std::function< void(Field *)> del)
Field * setDeleteP(std::function< void(Field *)> del)
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
const AccessMode accessMode_
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)
VirtualStruct(void *structure, std::function< void(Field *)> dtor=[](Field *f) { delete f;})
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.
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.
bool operator()(const std::pair< Listener *, std::shared_ptr< Listener >> &lhs, const std::pair< Listener *, std::shared_ptr< Listener >> &rhs) const