Skip to content

Commit

Permalink
Merge branch 'rev_faultinjection' into rebaser
Browse files Browse the repository at this point in the history
  • Loading branch information
JoGei authored Feb 23, 2023
2 parents d1bebd3 + a25a699 commit d225750
Show file tree
Hide file tree
Showing 36 changed files with 2,350 additions and 13,249 deletions.
33 changes: 31 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,35 @@ target_include_directories(simpleini PUBLIC
)
install(TARGETS simpleini
PUBLIC_HEADER DESTINATION include/simpleini

FetchContent_Declare(pugixml_srcs
GIT_REPOSITORY https://github.com/zeux/pugixml.git
GIT_TAG v1.11.4
)
if(NOT pugixml_srcs_POPULATED)
FetchContent_Populate(pugixml_srcs)
FetchContent_GetProperties(pugixml_srcs)
endif()
add_subdirectory(${pugixml_srcs_SOURCE_DIR} ${pugixml_srcs_BINARY_DIR} EXCLUDE_FROM_ALL)

FetchContent_Declare(betterenums_srcs
GIT_REPOSITORY https://github.com/aantron/better-enums.git
GIT_TAG 0.11.3
)
if(NOT betterenums_srcs_POPULATED)
FetchContent_Populate(betterenums_srcs)
FetchContent_GetProperties(betterenums_srcs)
endif()
add_library(betterenums INTERFACE)
set_target_properties(betterenums PROPERTIES
PUBLIC_HEADER "${betterenums_srcs_SOURCE_DIR}/enum.h"
)
target_include_directories(betterenums INTERFACE
$<BUILD_INTERFACE:${betterenums_srcs_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
install(TARGETS betterenums
PUBLIC_HEADER DESTINATION include
)

### Doxyfile
Expand Down Expand Up @@ -361,7 +390,7 @@ set_target_properties(ETISS PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/
)
IF(UNIX)
TARGET_LINK_LIBRARIES(ETISS PUBLIC ${Boost_LIBRARIES})
TARGET_LINK_LIBRARIES(ETISS PUBLIC Boost::filesystem Boost::system Boost::program_options)
ELSE(UNIX)
TARGET_LINK_LIBRARIES(ETISS PUBLIC Boost::boost Threads::Threads)
ENDIF()
Expand All @@ -384,7 +413,7 @@ TARGET_INCLUDE_DIRECTORIES(ETISS PUBLIC
${INCGEN_INC_DIR}
${elfio_srcs_SOURCE_DIR}
)
TARGET_LINK_LIBRARIES(ETISS PUBLIC simpleini)
TARGET_LINK_LIBRARIES(ETISS PUBLIC simpleini pugixml betterenums)

GENERATE_EXPORT_HEADER(ETISS
BASE_NAME ETISS_PLUGIN
Expand Down
21 changes: 21 additions & 0 deletions include/etiss/ETISS.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,27 @@ void initialize(std::vector<std::string>& args);
*/
std::shared_ptr<etiss::JIT> getDefaultJIT();

/**
* @brief Initialize and configure etiss::VirtualStruct root with etiss::CPUCore
* \p cpu_core.
*
* @detail This function also initializes configured faults which require a
* mounted \p core etiss::VirtualStruct. Add the virtual structure of the cpu to
* the VirtualStruct root. This allows to access the field of the cpu from a
* global context. See etiss::VirtualStruct::getVirtualStruct() and
* etiss::VirtualStruct::getResolvedField(). In this case e.g. the
* instructionPointer can be read from a global context by calling
* etiss::VirtualStruct::root()->getResolvedField("core0.instructionPointer")
* ->read().
*/
void initialize_virtualstruct(std::shared_ptr<etiss::CPUCore> cpu_core);
/**
* @brief Extension of etiss::initialize_virtualstruct(
* std::shared_ptr<etiss::CPUCore>) to allow direct setting of custom action for
* \p cpu_core etiss::VirtualStruct with \p fcustom_action.
*/
void initialize_virtualstruct(std::shared_ptr<etiss::CPUCore> cpu_core, std::function<bool(const etiss::fault::Fault&, const etiss::fault::Action&, std::string& /*errormsg*/)> const & fcustom_action);

/**
* @brief Shutdown ETISS
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class InstructionAccurateCallback : public etiss::TranslationPlugin
virtual std::string _getPluginName() const;

public:
void call();
etiss_int32 call_on_entry();
};

} // namespace plugin
Expand Down
250 changes: 250 additions & 0 deletions include/etiss/IntegratedLibrary/fault/MemoryManipulationSystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
/**
@copyright
<pre>
Copyright 2018 Infineon Technologies AG
This file is part of ETISS tool, see <https://github.com/tum-ei-eda/etiss>.
The initial version of this software has been created with the funding support by the German Federal
Ministry of Education and Research (BMBF) in the project EffektiV under grant 01IS13022.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
</pre>
@author Chair of Electronic Design Automation, TUM
@date November 16, 2021
@version 0.1
*/
/**
@file
@brief simple test system implementation with fault functionality
*/

#ifndef ETISS_INCLUDE_INTEGRATEDLIBRARY_FAULT_MEMORYMANIPULATIONSYSTEM_H_
#define ETISS_INCLUDE_INTEGRATEDLIBRARY_FAULT_MEMORYMANIPULATIONSYSTEM_H_
#include "etiss/System.h"
#include "etiss/make_unique.h"
#include <fstream>

#include "etiss/SimpleMemSystem.h"

#include "etiss/VirtualStruct.h"

#include <memory>
#include <map>
#include <stack>

#include <functional>

#include "etiss/fault/Misc.h"
#include "enum.h"

namespace etiss
{

BETTER_ENUM(MM_MemOpType, char, UNDEF = 0, COPY, AND, OR, XOR, NAND, NOR)
BETTER_ENUM(MM_MemManipCmd, char, UNDEF = 0, PUSH, POP, OR, RMW, RRMW)

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Memory word faulter base class
class MemoryWordManipulatorBase
{
public:
typedef MM_MemOpType mem_op_t;
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Memory operation class
class MemOp : mem_op_t
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
/// \brief executes memory operation with operands \p src1 and \p src2 and returns result
template <typename word_t>
word_t operator()(word_t src1, word_t src2) const;
////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Constructor takes string encoded memory operation \ref MemOpType
MemOp(const std::string &memop_str) : mem_op_t(mem_op_t::_from_string(memop_str.c_str())) {}
} /* class MemOp */;

////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Memory operation type code
typedef MM_MemManipCmd mem_manip_cmd_t;

virtual etiss::int32 push(size_t address) = 0;
virtual etiss::int32 pop(size_t address) = 0;
virtual etiss::int32 rmw(size_t address, MemOp op, etiss::uint64 mod_val) = 0;
virtual etiss::int32 rrmw(size_t dstsrc1_address, MemOp op, size_t src2_address) = 0;
} /* class MemoryWordManipulatorBase */;

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Memory word faulter class template \p word_t
template <typename word_t>
class MemoryWordManipulator : public MemoryWordManipulatorBase
{
private:
std::function<word_t(size_t address, etiss::int32 &return_code)> mem_read_word_;
///< function to read a single word from memory
std::function<void(size_t address, word_t val, etiss::int32 &return_code)> mem_write_word_;
///< function to write a single word to memory
std::stack<word_t> memstack_{};
///< memory stack to allow read modify write manipulations to memory

public:
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief pop the last added element from the memory stack and write it to memory \p address
/// \return etiss::RETURNCODE encoded via \ref MemoryManipulationSystem::dbus_access
virtual etiss::int32 pop(size_t address);
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief read memory from \p address and push it to memory stack
/// \return etiss::RETURNCODE encoded via \ref MemoryManipulationSystem::dbus_access
virtual etiss::int32 push(size_t address);
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief read-modify-write memory word at \p address with \p mod_val by bit-wise operation \p op
/// \p mod_val is type casted to \p word_t
/// \return etiss::RETURNCODE encoded via \ref MemoryManipulationSystem::dbus_access
virtual etiss::int32 rmw(size_t address, MemOp op, etiss::uint64 mod_val);
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief read-readmodify-write memory word at \p dstsrc1_address with memory word at
/// \p src2_address by bit-wise operation \p op
/// \return etiss::RETURNCODE encoded via \ref MemoryManipulationSystem::dbus_access
virtual etiss::int32 rrmw(size_t dstsrc1_address, MemOp op, size_t src2_address);
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Constructor taking \p mem_read_word and \p mem_write_word functions for memory
/// fault action
MemoryWordManipulator(
std::function<word_t(size_t address, etiss::int32 &return_code)> const &mem_read_word,
std::function<void(size_t address, word_t val, etiss::int32 &return_code)> const &mem_write_word);
} /* class MemoryWordManipulator */;

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Simple etiss:System implementation for testing
class MemoryManipulationSystem : public VirtualStructSupport, public SimpleMemSystem
{
public:
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Constructor takes \p name for reference of this class as a name \ref Injector
MemoryManipulationSystem(const std::string &name = "system");
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief get virtual struct associated name
inline const std::string &getName() { return name_; }
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief get virtual struct
std::shared_ptr<etiss::VirtualStruct> getStruct(void);
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief initialize this virtual struct and mount it to \p cpu_core
void init_manipulation(std::shared_ptr<etiss::VirtualStructSupport> vs_parent);

private:
std::string name_;
etiss::uint8 arch_width_;
std::shared_ptr<etiss::VirtualStruct> vsystem_;
std::unique_ptr<etiss::MemoryWordManipulatorBase> mem_manipulator_;
};

/* template "implemenations" */
template <typename word_t>
word_t MemoryWordManipulatorBase::MemOp::operator()(word_t src1, word_t src2) const
{
switch (*this)
{
case MM_MemOpType::COPY:
return src2;
case MM_MemOpType::AND:
return (src1 & src2);
case MM_MemOpType::OR:
return (src1 | src2);
case MM_MemOpType::XOR:
return (src1 ^ src2);
case MM_MemOpType::NAND:
return ~(src1 & src2);
case MM_MemOpType::NOR:
return ~(src1 | src2);
default:
break;
}
return src1;
}

template <typename word_t>
etiss::int32 MemoryWordManipulator<word_t>::pop(size_t address)
{
etiss::int32 return_code;
mem_write_word_(address, memstack_.top(), return_code);
memstack_.pop();
return return_code;
}

template <typename word_t>
etiss::int32 MemoryWordManipulator<word_t>::push(size_t address)
{
etiss::int32 return_code;
memstack_.push(mem_read_word_(address, return_code));
return return_code;
}

template <typename word_t>
etiss::int32 MemoryWordManipulator<word_t>::rmw(size_t address, MemOp op, etiss::uint64 mod_val)
{
etiss::int32 return_code;
word_t mem_val = mem_read_word_(address, return_code);
if (return_code == RETURNCODE::NOERROR)
{
mem_val = op(mem_val, static_cast<word_t>(mod_val));
mem_write_word_(address, mem_val, return_code);
}
return return_code;
}
template <typename word_t>
etiss::int32 MemoryWordManipulator<word_t>::rrmw(size_t dstsrc1_address, MemOp op, size_t src2_address)
{
etiss::int32 return_code;
word_t src1mem_val = mem_read_word_(dstsrc1_address, return_code);
if (return_code == RETURNCODE::NOERROR)
{
word_t src2mem_val = mem_read_word_(src2_address, return_code);
if (return_code == RETURNCODE::NOERROR)
{
src1mem_val = op(src1mem_val, src2mem_val);
mem_write_word_(dstsrc1_address, src1mem_val, return_code);
}
}
return return_code;
}
template <typename word_t>
MemoryWordManipulator<word_t>::MemoryWordManipulator(
std::function<word_t(size_t address, etiss::int32 &return_code)> const &mem_read_word,
std::function<void(size_t address, word_t val, etiss::int32 &return_code)> const &mem_write_word)
: mem_read_word_(mem_read_word), mem_write_word_(mem_write_word)
{
}

} // namespace etiss

#endif // ETISS_INCLUDE_INTEGRATEDLIBRARY_FAULT_MEMORYMANIPULATIONSYSTEM_H_
7 changes: 5 additions & 2 deletions include/etiss/SimpleMemSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,13 @@ class SimpleMemSystem : public System
etiss::uint64 get_startaddr(void) { return (start_addr_); }
void add_memsegment(std::unique_ptr<MemSegment>& mseg, const void *raw_data, size_t file_size_bytes);

protected:
template <bool write>
etiss::int32 dbus_access(ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len);

private:
std::vector<std::unique_ptr<MemSegment>> msegs_{};

template <bool write>
etiss::int32 dbus_access(ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len);

etiss::uint64 start_addr_{ 0 };

Expand All @@ -193,4 +195,5 @@ class SimpleMemSystem : public System

} // namespace etiss

void access_error(ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint32 len, std::string error, etiss::Verbosity verbosity);
#endif
Loading

0 comments on commit d225750

Please sign in to comment.