51 size_t width,
size_t bitwidth)
57 ,
bitwidth_(bitwidth ? bitwidth : width * 8)
63 size_t width,
bool virtual_enabled, std::function<
uint64_t()> lread,
64 std::function<
void(
uint64_t)> lwrite,
size_t bitwidth)
67 , prettyname_(prettyname)
70 , bitwidth_(bitwidth ? bitwidth : width * 8)
83 std::runtime_error(
"VirtualStruct::Field::write called but the write flag is not set");
95 throw std::runtime_error(
96 "VirtualStruct is configured to use lambda expressions but no read function was provided.");
109 throw std::runtime_error(
"invalid enum value");
119 throw std::runtime_error(
"VirtualStruct::Field::write called but the write flag is not set");
121 if (accessMode_ == LAMBDA && !lwrite)
122 throw std::runtime_error(
123 "VirtualStruct is configured to use lambda expressions but no read function was provided.");
154 for (
auto l : listeners)
158 l.first->write(*
this, read());
173 return _applyBitflip(position, fault_id);
179 std::string &errormsg)
183 errormsg =
"field doesn't support advanced action handling";
186 return _applyAction(f, a, errormsg);
191 throw std::runtime_error(
"VirtualStruct::Field::_read called but not implemented");
195 throw std::runtime_error(
"VirtualStruct::Field::_write called but not implemented");
202 return lapplyBitflip(position, fault_id);
203 if ((flags_ & RW) != RW)
207 errval = val ^ errval;
209 std::stringstream ss;
210 ss <<
"Injected bitflip in " << name_ <<
" 0x" << std::hex << val <<
"->0x" << errval << std::dec;
215 std::string &errormsg)
224 listeners.insert(std::pair<
Listener *, std::shared_ptr<Listener>>(listener, ref));
229 listeners.erase(std::pair<
Listener *, std::shared_ptr<Listener>>(listener, ref));
243 if ((*iter)->delete_)
245 std::function<void(
Field *)> del_ = (*iter)->delete_;
257 "likely result in a memory leak.");
274 if (f->
name_.empty())
312 std::shared_ptr<const VirtualStruct> pref = shared_from_this();
315 return std::shared_ptr<VirtualStruct::Field>();
325 std::shared_ptr<const VirtualStruct> pref = shared_from_this();
335 std::shared_ptr<const VirtualStruct> pref = shared_from_this();
362 if (find->second.lock())
370 vs->parent_ = shared_from_this();
371 subStructs_.insert(std::pair<std::string, std::weak_ptr<VirtualStruct>>(name, vs));
379 return find->second.lock();
380 return std::shared_ptr<VirtualStruct>();
387 auto sp = e.second.lock();
410 std::list<std::string> ret;
413 ret.push_back(f->name_);
419 std::list<std::string> ret;
453 errormsg =
"No such field";
458 errormsg =
"No read access";
465 std::string &errormsg)
474 ": VirtualStruct::applyCustomAction function not set. cannot handle custom actions.";
530 static std::recursive_mutex mu;
535 std::list<std::shared_ptr<VirtualStruct::Field>> ¬Writeable,
536 std::list<std::shared_ptr<VirtualStruct::Field>> unknown,
bool pretend,
537 std::list<std::shared_ptr<VirtualStruct::Field>> *src_private,
538 std::list<std::shared_ptr<VirtualStruct::Field>> *dst_private)
543 std::set<std::shared_ptr<VirtualStruct::Field>> dst_known;
545 src.
foreachField([&](std::shared_ptr<VirtualStruct::Field> srcf) {
549 src_private->push_back(srcf);
553 auto dstf = dst.
findName(srcf->name_);
556 notPresent.push_back(srcf);
562 notPresent.push_back(srcf);
566 dst_known.insert(dstf);
570 notWriteable.push_back(dstf);
575 dstf->write(srcf->read());
578 dst.
foreachField([&](std::shared_ptr<VirtualStruct::Field> dstf) {
579 if (dst_known.find(dstf) == dst_known.end())
585 dst_private->push_back(dstf);
590 unknown.push_back(dstf);
600 return std::shared_ptr<VirtualStruct>(ret, [](
VirtualStruct *vs) {
delete vs; });
605 static std::shared_ptr<VirtualStruct> r =
allocate(0, [](
Field *) {});
612 return shared_from_this();
613 std::shared_ptr<VirtualStruct> ret;
614 if (path.find_first_of(
".") != std::string::npos)
619 auto pp1 = path.find(
"::");
624 auto prev = shared_from_this();
630 return prev->getVirtualStruct(path.substr(pp1 + 2));
635 auto find =
subStructs_.find((pp1 == std::string::npos) ? path : path.substr(0, pp1));
638 ret = find->second.lock();
645 if (pp1 == std::string::npos)
651 return ret->getVirtualStruct(path.substr(pp1 + 2));
657 return std::shared_ptr<etiss::fault::Injector>(
VirtualStruct::root()->getVirtualStruct(path));
662 auto pp1 = path.find_first_of(
".");
663 if (pp1 == std::string::npos)
664 return std::shared_ptr<VirtualStruct::Field>();
668 return std::shared_ptr<VirtualStruct::Field>();
670 auto ret = m->findName(path.substr(pp1 + 1));
672 ret = m->findPrettyName(path.substr(pp1 + 1));
static __inline__ uint64_t
static __inline__ int32_t
used for synchronization of the tree of virtual structs.
static std::recursive_mutex & mutex()
NOTE: etiss::CPUArch should implement support for Listeners by either using the etiss::VirtualStruct:...
a Field instance represents e.g.
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)
@ 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
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
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.
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
const size_t bitwidth_
width in bits
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)
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
virtual bool applyAction(const etiss::fault::Fault &fault, const etiss::fault::Action &action, std::string &errormsg)
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.
@ BITFLIP
applies a bit flip to a bit in a specified field
@ COMMAND
commands are targetet at Injectors, not fields.
const std::string & getTargetField() const
BITFLIP only.
unsigned getTargetBit() const
BITFLIP only.
virtual std::string getInjectorPath()
returns the path of the current object.
static ptr get(const std::string &injectorPath)
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.
void log(Verbosity level, std::string msg)
write log message at the given level.