13#include "etiss/jit/ReturnCode.h"
32 throw "wrong action type";
37 return ((
type_ == +type_t::BITFLIP ||
type_ == +type_t::MASK) ?
true :
false);
56 std::string(
", command=") + command + std::string(
") called. "));
63 std::string(
", field=") + field + std::string(
", bit=") + std::to_string(bit) +
64 std::string(
") called. "));
72 , mask_value_(mask_value)
75 std::string(
", field=") + field + std::string(
", mask_op=") +
mask_op_._to_string() +
76 std::string(
", mask_value=") + std::to_string(mask_value) +
77 std::string(
") called. "));
83 std::string(
") called. "));
107 case type_t::COMMAND:
111 case type_t::EJECTION:
113 case type_t::INJECTION:
127#if CXX0X_UP_SUPPORTED
146 if (!(
type_ == +type_t::BITFLIP ||
type_ == +type_t::MASK ||
type_ == +type_t::COMMAND))
150 "etiss::fault::Action::TypeStruct::getInjectorAddress(): Requested Action::Type is not Injector"));
157 if (
type_ != +type_t::COMMAND)
159 std::string(
"etiss::fault::Action::getCommand(): Requested Action::Type is not Command"));
166 if (!(
type_ == +type_t::BITFLIP ||
type_ == +type_t::MASK))
168 std::string(
"etiss::fault::Action::getTargetField(): Requested Action::Type is not TargetField"));
175 if (
type_ != +type_t::BITFLIP)
177 std::string(
"etiss::fault::Action::getTargetBit(): Requested Action::Type is not TargetBit"));
183 if (!((
type_ == +type_t::INJECTION) || (
type_ == +type_t::EJECTION)))
185 std::string(
"etiss::fault::Action::getFault(): Requested Action::Type is not injectable Fault"));
191 if (
type_ != +type_t::MASK)
193 std::string(
"etiss::fault::Action::getMaskOp(): Requested Action::Type is not Mask"));
199 if (
type_ != +type_t::MASK)
201 std::string(
"etiss::fault::Action::getMaskValue(): Requested Action::Type is not Mask"));
208 if (
type_ != +type_t::EVENT)
210 std::string(
"etiss::fault::Action::getEvent(): Requested Action::Type is not Event"));
217 pugi::xml_document doc;
218 doc.load_string(
"<?xml version=\"1.0\"?>");
220 xml::Diagnostics diag;
222 xml::write<etiss::fault::Action>(doc.append_child(
"action"), *
this, diag);
224 std::stringstream ss;
235bool parse<Action>(pugi::xml_node node,
Action &f, Diagnostics &diag)
238 std::string(
", Diagnostics) called. "));
241 if (!parse_attr(node,
"type", type_s, diag))
243 diag.unexpectedNode(node,
"Failed to parse type of action");
246 if (!Action::type_t::_from_string_nothrow(type_s.c_str()))
248 diag.unexpectedNode(node, std::string(
"There is no Action type ") + type_s);
251 auto type = Action::type_t::_from_string(type_s.c_str());
255 case Action::type_t::NOP:
261 case Action::type_t::BITFLIP:
264 if (!
etiss::cfg().get<bool>(
"faultInjection::allowBitFlip",
true))
266 if (!parse<InjectorAddress>(findSingleNode(node,
"injector", diag), inj, diag))
268 diag.unexpectedNode(node,
"Failed to parse target <injector>");
272 if (!parse<std::string>(findSingleNode(node,
"field", diag), field, diag))
274 diag.unexpectedNode(node,
"Failed to parse target <field>");
279 if (!parse<unsigned>(findSingleNode(node,
"bit", diag), bit, diag))
281 diag.unexpectedNode(node,
"Failed to parse target <bit>");
284 f = Action(inj, field, bit);
288 case Action::type_t::COMMAND:
291 if (!parse<InjectorAddress>(findSingleNode(node,
"injector", diag), inj, diag))
293 diag.unexpectedNode(node,
"Failed to parse target <injector>");
297 if (!parse<std::string>(findSingleNode(node,
"command", diag), command, diag))
299 diag.unexpectedNode(node,
"Failed to parse target <command>");
302 f = Action(inj, command);
306 case Action::type_t::INJECTION:
308 case Action::type_t::EJECTION:
311 if (!parse<FaultRef>(findSingleNode(node,
"fault_ref", diag), fault_ref, diag))
313 diag.unexpectedNode(node,
"Failed to parse <fault_ref> to inject");
316 f = Action(fault_ref, type);
320 case Action::type_t::MASK:
323 if (!parse<InjectorAddress>(findSingleNode(node,
"injector", diag), inj, diag))
325 diag.unexpectedNode(node,
"Failed to parse target <injector>");
329 if (!parse<std::string>(findSingleNode(node,
"field", diag), field, diag))
331 diag.unexpectedNode(node,
"Failed to parse target <field>");
336 if (!parse<std::string>(findSingleNode(node,
"op", diag), op_str, diag))
338 diag.unexpectedNode(node,
"Failed to parse mask operation <op>");
342 if (!(etiss::fault::Action::mask_op_t::_from_string_nothrow(op_str.c_str())))
344 diag.unexpectedNode(node,
"Failed to parse mask operation <op>");
348 if (!parse_hex(findSingleNode(node,
"value", diag), value, diag))
350 diag.unexpectedNode(node,
"Failed to parse mask operation <value>");
353 f = Action(inj, field, Action::mask_op_t::_from_string(op_str.c_str()), value);
358 case Action::type_t::EVENT:
360 std::string event_str;
362 if (!parse<std::string>(findSingleNode(node,
"cause", diag), event_str, diag))
364 diag.unexpectedNode(node,
"Failed to parse node of event type: <cause>");
369 diag.unexpectedNode(node,
"Failed to parse event <cause>. Supported values: {NOERROR, RELOADBLOCKS, "
370 "RELOADCURRENTBLOCK, CPUFINISHED, EXCEPTION:[cause(hex)]}");
378 diag.unexpectedNode(node, std::string(
"Unknown type of action: ") +
type._to_string());
385bool write<Action>(pugi::xml_node node,
const Action &f, Diagnostics &diag)
388 std::string(
", Diagnostics) called. "));
392 case Action::type_t::NOP:
393 return write_attr<std::string>(node,
"type",
"NOP", diag);
395 case Action::type_t::BITFLIP:
396 ok = ok & write_attr<std::string>(node,
"type",
"BITFLIP", diag);
397 ok = ok & write(node.append_child(
"injector"), f.getInjectorAddress(), diag);
398 ok = ok & write<std::string>(node.append_child(
"field"), f.getTargetField(), diag);
399 ok = ok & write<unsigned>(node.append_child(
"bit"), f.getTargetBit(), diag);
401 case Action::type_t::COMMAND:
402 ok = ok & write_attr<std::string>(node,
"type",
"COMMAND", diag);
403 ok = ok & write<std::string>(node.append_child(
"command"), f.getCommand(), diag);
405 case Action::type_t::INJECTION:
406 ok = ok & write_attr<std::string>(node,
"type",
"INJECTION", diag);
407 ok = ok & write<FaultRef>(node.append_child(
"fault_ref"), f.getFaultRef(), diag);
409 case Action::type_t::EJECTION:
410 ok = ok & write_attr<std::string>(node,
"type",
"EJECTION", diag);
411 ok = ok & write<FaultRef>(node.append_child(
"fault_ref"), f.getFaultRef(), diag);
413 case Action::type_t::MASK:
414 ok = ok & write_attr<std::string>(node,
"type",
"MASK", diag);
415 ok = ok & write(node.append_child(
"injector"), f.getInjectorAddress(), diag);
416 ok = ok & write<std::string>(node.append_child(
"field"), f.getTargetField(), diag);
417 ok = ok & write<std::string>(node.append_child(
"op"), f.getMaskOp()._to_string(), diag);
418 ok = ok & write<uint64_t>(node.append_child(
"value"), f.getMaskValue(), diag);
421 case Action::type_t::EVENT:
422 ok = ok & write_attr<std::string>(node,
"type",
"EVENT", diag);
429 std::string(
", Diagnostics) failed. "));
439 if ((in ==
"NOERROR") || (in ==
"RETURNCODE::NOERROR"))
441 out = etiss::RETURNCODE::NOERROR;
443 else if ((in ==
"RELOADBLOCKS") || (in ==
"RETURNCODE::RELOADBLOCKS"))
445 out = etiss::RETURNCODE::RELOADBLOCKS;
447 else if ((in ==
"RELOADCURRENTBLOCK") || (in ==
"RETURNCODE::RELOADCURRENTBLOCK"))
449 out = etiss::RETURNCODE::RELOADCURRENTBLOCK;
451 else if ((in ==
"CPUFINISHED") || (in ==
"RETURNCODE::CPUFINISHED"))
453 out = etiss::RETURNCODE::CPUFINISHED;
455 else if ((in ==
"DBUS_WRITE_ERROR") || (in ==
"RETURNCODE::DBUS_WRITE_ERROR"))
457 out = etiss::RETURNCODE::DBUS_WRITE_ERROR;
459 else if ((in ==
"IBUS_READ_ERROR") || (in ==
"RETURNCODE::IBUS_READ_ERROR"))
461 out = etiss::RETURNCODE::IBUS_READ_ERROR;
463 else if ((in ==
"IBUS_WRITE_ERROR") || (in ==
"RETURNCODE::IBUS_WRITE_ERROR"))
465 out = etiss::RETURNCODE::IBUS_WRITE_ERROR;
467 else if ((in ==
"INTERRUPT") || (in ==
"RETURNCODE::INTERRUPT"))
469 out = etiss::RETURNCODE::INTERRUPT;
471 else if ((in ==
"RESET") || (in ==
"RETURNCODE::RESET"))
473 out = etiss::RETURNCODE::RESET;
475 else if ((in ==
"ILLEGALINSTRUCTION") || (in ==
"RETURNCODE::ILLEGALINSTRUCTION"))
477 out = etiss::RETURNCODE::ILLEGALINSTRUCTION;
479 else if ((in ==
"ILLEGALJUMP") || (in ==
"RETURNCODE::ILLEGALJUMP"))
481 out = etiss::RETURNCODE::ILLEGALJUMP;
483 else if ((in ==
"INSTR_PAGEFAULT") || in == (
"RETURNCODE::INSTR_PAGEFAULT"))
485 out = etiss::RETURNCODE::INSTR_PAGEFAULT;
487 else if ((in ==
"LOAD_PAGEFAULT") || (in ==
"RETURNCODE::LOAD_PAGEFAULT"))
489 out = etiss::RETURNCODE::LOAD_PAGEFAULT;
491 else if ((in ==
"STORE_PAGEFAULT") || (in ==
"RETURNCODE::STORE_PAGEFAULT"))
493 out = etiss::RETURNCODE::STORE_PAGEFAULT;
495 else if ((in ==
"SYSCALL") || (in ==
"RETURNCODE::SYSCALL"))
497 out = etiss::RETURNCODE::SYSCALL;
499 else if ((in ==
"PAGEFAULT") || (in ==
"RETURNCODE::PAGEFAULT"))
501 out = etiss::RETURNCODE::PAGEFAULT;
503 else if ((in ==
"BREAKPOINT") || (in ==
"RETURNCODE::BREAKPOINT"))
505 out = etiss::RETURNCODE::BREAKPOINT;
518 case etiss::RETURNCODE::NOERROR:
520 case etiss::RETURNCODE::RELOADBLOCKS:
521 return "RELOADBLOCKS";
522 case etiss::RETURNCODE::RELOADCURRENTBLOCK:
523 return "RELOADCURRENTBLOCK";
524 case etiss::RETURNCODE::INTERRUPT:
526 case etiss::RETURNCODE::DBUS_WRITE_ERROR:
527 return "DBUS_WRITE_ERROR";
528 case etiss::RETURNCODE::IBUS_READ_ERROR:
529 return "IBUS_READ_ERROR";
530 case etiss::RETURNCODE::IBUS_WRITE_ERROR:
531 return "IBUS_WRITE_ERROR";
532 case etiss::RETURNCODE::RESET:
534 case etiss::RETURNCODE::ILLEGALINSTRUCTION:
535 return "ILLEGALINSTRUCTION";
536 case etiss::RETURNCODE::ILLEGALJUMP:
537 return "ILLEGALJUMP";
538 case etiss::RETURNCODE::INSTR_PAGEFAULT:
539 return "INSTR_PAGEFAULT";
540 case etiss::RETURNCODE::LOAD_PAGEFAULT:
541 return "LOAD_PAGEFAULT";
542 case etiss::RETURNCODE::STORE_PAGEFAULT:
543 return "STORE_PAGEFAULT";
544 case etiss::RETURNCODE::SYSCALL:
546 case etiss::RETURNCODE::PAGEFAULT:
548 case etiss::RETURNCODE::BREAKPOINT:
550 case etiss::RETURNCODE::CPUFINISHED:
551 return "CPUFINISHED";
553 std::stringstream ss;
554 ss <<
"EXCEPTION:" << std::hex << in;
contains an action class that describes actions associated with a fault
contains the fault container class that stores triggers and actions for fault injection
contains a simple class that represents and resolves injector addresses as used by triggers (
contains the Trigger class that defines conditions under which actions of a Fault need to be applied.
contains XML related functions.
static __inline__ uint64_t
static __inline__ int32_t
const mask_op_t & getMaskOp() const
MASK only.
const InjectorAddress & getInjectorAddress() const
bool is_action_on_field(void) const
returns true if type_ is an action on a Field
unsigned bit_
concerning Bit (for fault injection)
std::string toString() const
operator<< can be used.
const FaultRef & getFaultRef() const
INJECTION and EJECTION only.
uint64_t getMaskValue() const
std::string command_
command e.g. for booting OR1KVCPU
std::unique_ptr< InjectorAddress > inj_
Address of Injector.
std::unique_ptr< FaultRef > fault_ref_
for fault injection
const std::string & getCommand() const
COMMAND only.
const std::string & getTargetField() const
BITFLIP only.
std::string field_
concerning Field (for fault injection)
mask_op_t mask_op_
mask operation (for mask injection)
int32_t event_
exception, or rather etiss::RETURNCODE to to be injected into the simulation loop
const type_t & getType() const
uint64_t mask_value_
mask value (for mask injection)
Action & operator=(const Action &cpy)
unsigned getTargetBit() const
BITFLIP only.
type_t type_
type of the Attribute
std::string toString() const
operator<< can be used.
const std::string & getInjectorPath() const
void setCoreName(std::string &str)
bool returncode_fromstring(int32_t &out, const std::string &in)
decode etiss::RETURNCODE from string
std::string returncode_tostring(int32_t in)
encode etiss::RETURNCODE to string
void log(Verbosity level, std::string msg)
write log message at the given level.