13#ifndef ETISS_PLUGIN_VIRTUALSTRUCT_H_
14#define ETISS_PLUGIN_VIRTUALSTRUCT_H_
15#include "etiss/CVirtualStruct.h"
129 const std::pair<
Listener *, std::shared_ptr<Listener>> &rhs)
const
131 return lhs.first < rhs.first;
151 static const int R = 1;
152 static const int W = 2;
154 static const int L = 4;
156 static const int F = 8;
157 static const int A = 16;
158 static const int P = 32;
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,
172 size_t bitwidth = 0);
196 std::string &errormsg);
237 bool addListener(Listener *listener, std::shared_ptr<Listener> ref =
nullptr);
242 void removeListener(Listener *listener, std::shared_ptr<Listener> ref =
nullptr);
249 template <
typename structT,
typename retT, retT structT::*field>
252 static_assert(
sizeof(retT) <=
sizeof(
uint64_t),
253 "Cannot use etiss::VirtualStruct::FieldT for a field larger than uint64_t");
257 :
Field(parent, name, prettyname, 0, sizeof(retT))
265 VirtualStruct(
void *structure, std::function<
void(Field *)> dtor = [](Field *f) {
delete f; });
270 bool addField(Field *f,
bool noerrorprint =
false);
272 template <
typename structT,
typename retT, retT structT::*field>
274 bool addField(
const std::string &name,
const std::string &prettyname =
"",
bool noerrorprint =
false)
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)
297 if (supportsListener)
300 *
this, name, prettyname, flags,
sizeof(T),
false, [read]() {
return (
uint64_t)read(); },
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);
312 bool mountStruct(
const std::string &name,
const std::shared_ptr<VirtualStruct> vs);
313 std::shared_ptr<VirtualStruct>
findStruct(
const std::string &name);
323 virtual std::shared_ptr<etiss::fault::Injector>
getSubInjector(
const std::string &name);
330 virtual bool readField(
void *fastfieldaccessptr,
uint64_t &val, std::string &errormsg);
332 std::string &errormsg);
357 static std::shared_ptr<VirtualStruct>
allocate(
void *structure, std::function<
void(
Field *)> delete_);
360 static std::shared_ptr<VirtualStruct>
root();
364 std::shared_ptr<VirtualStruct::Field>
getResolvedField(
const std::string &path);
375 std::function<
void(
void *handle)> cleanup);
389 static std::recursive_mutex &
mutex();
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);
418#define ETISS_VIRTUALSTRUCT_ADDFIELD(VIRTUALSTRUCT, STRUCT, FIELD, NAME, PRETTYNAME) \
419 (VIRTUALSTRUCT).addField<STRUCT, decltype(((STRUCT *)0)->FIELD), &STRUCT::FIELD>(NAME, PRETTYNAME);
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
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 ~VirtualStructSupport()
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
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
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.
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