ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
MemoryManipulationSystem.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2//
3// This file is part of ETISS. It is licensed under the BSD 3-Clause License; you may not use this file except in
4// compliance with the License. You should have received a copy of the license along with this project. If not, see the
5// LICENSE file.
16#include "etiss/fault/Action.h"
17#include "etiss/Misc.h"
18#include "elfio/elfio.hpp"
19#include <memory>
20#include <algorithm>
21
22using namespace etiss;
23using namespace ELFIO;
24
25std::shared_ptr<VirtualStruct> MemoryManipulationSystem::getStruct(void)
26{
27 if (!vsystem_)
28 {
30 }
31 return vsystem_;
32}
33
34void MemoryManipulationSystem::init_manipulation(std::shared_ptr<etiss::VirtualStructSupport> vs_parent)
35{
36 auto mount_successful = vs_parent->getStruct()->mountStruct(this->getName(), this->getStruct());
37
38 if (!mount_successful)
39 {
40 etiss::log(etiss::FATALERROR, std::string("Failed to mount ") + this->getName() +
41 std::string("'s VirtualStruct to ") + vs_parent->getName());
42 }
43 else
44 {
45 uint8_t arch_width = 0;
46
47 if (etiss::cfg().isSet("arch.cpu"))
48 {
49 auto cpu_arch_str = etiss::cfg().get<std::string>("arch.cpu", "");
50 arch_width = cpu_arch_str == "RISCV64" ? 64 : 32;
51 }
52 else
53 {
54 // get architecture automatically
55 std::string elf_file = etiss::cfg().get<std::string>("vp.elf_file", "");
56 ELFIO::elfio reader;
57 if (!reader.load(elf_file))
58 {
59 etiss::log(etiss::FATALERROR, "ELF reader could not process file");
60 }
61 arch_width = reader.get_class() == ELFCLASS64 ? 64 : 32;
62 }
63
64 etiss::log(etiss::VERBOSE, std::string("Mounted ") + this->getName() +
65 std::string("'s VirtualStruct to CPUCore ") + vs_parent->getName());
66
67 if (!etiss::cfg().isSet("vp.elf_file"))
68 {
69 etiss::log(etiss::FATALERROR, std::string("MemoryManipulationSystem::initialize_virtualstruct: Requires "
70 "\"vp.elf_file\" config to retrieve architecture bit-width."));
71 }
72
73 std::string elf_file = etiss::cfg().get<std::string>("vp.elf_file", "");
74
75 ELFIO::elfio reader;
76
77 if (!reader.load(elf_file))
78 {
79 etiss::log(etiss::FATALERROR, "ELF reader could not process file");
80 }
81
82 if (arch_width == 32)
83 {
84 auto read = [this](size_t address, etiss::int32 &return_code)
85 {
86 etiss::uint32 x;
87 return_code = dbus_access<false>(nullptr, static_cast<etiss::uint64>(address),
88 reinterpret_cast<etiss::uint8 *>(&x), sizeof(x));
89 return x;
90 };
91 auto write = [this](size_t address, etiss::uint32 word, etiss::int32 &return_code)
92 {
93 return_code = dbus_access<true>(nullptr, static_cast<etiss::uint64>(address),
94 reinterpret_cast<etiss::uint8 *>(&word), sizeof(word));
95 };
96 mem_manipulator_ = std::make_unique<MemoryWordManipulator<etiss::uint32>>(read, write);
97 }
98 else if (arch_width == 64)
99 {
100 auto read = [this](size_t address, etiss::int32 &return_code)
101 {
102 etiss::uint64 x;
103 return_code = dbus_access<false>(nullptr, static_cast<etiss::uint64>(address),
104 reinterpret_cast<etiss::uint8 *>(&x), sizeof(x));
105 return x;
106 };
107 auto write = [this](size_t address, etiss::uint64 word, etiss::int32 &return_code)
108 {
109 return_code = dbus_access<true>(nullptr, static_cast<etiss::uint64>(address),
110 reinterpret_cast<etiss::uint8 *>(&word), sizeof(word));
111 };
112 mem_manipulator_ = std::make_unique<MemoryWordManipulator<etiss::uint64>>(read, write);
113 }
114 else
115 {
117 std::string("Failed to initiliaze MemStack: Architecture bit width not set."));
118 }
119
120 getStruct()->applyCustomAction =
121 [this](const etiss::fault::Fault &fault, const etiss::fault::Action &action, std::string &errormsg)
122 {
123 auto cmd = action.getCommand();
124
125 size_t pos = 0;
126 std::vector<std::string> split_cmd;
127 while ((pos = cmd.find(" ")) != std::string::npos)
128 {
129 split_cmd.push_back(cmd.substr(0, pos));
130 cmd.erase(0, pos + 1);
131 }
132 split_cmd.push_back(cmd);
133 if (split_cmd.size() > 1)
134 {
135 etiss::uint64 dst_address;
136 etiss::int32 return_code;
137 dst_address = std::stoll(split_cmd[1], nullptr, 16);
138
139 std::transform(split_cmd[0].begin(), split_cmd[0].end(), split_cmd[0].begin(), ::toupper);
140 auto mem_manip_cmd = MemoryWordManipulatorBase::mem_manip_cmd_t::_from_string("UNDEF");
141 if (auto maybe = MemoryWordManipulatorBase::mem_manip_cmd_t::_from_string_nothrow(split_cmd[0].c_str()))
142 {
143 mem_manip_cmd = MemoryWordManipulatorBase::mem_manip_cmd_t::_from_integral(maybe);
144 }
145
146 switch (mem_manip_cmd)
147 {
148 case MemoryWordManipulatorBase::mem_manip_cmd_t::PUSH:
149 return_code = mem_manipulator_->push(dst_address);
150 break;
151 case MemoryWordManipulatorBase::mem_manip_cmd_t::POP:
152 return_code = mem_manipulator_->pop(dst_address);
153 break;
154 case MemoryWordManipulatorBase::mem_manip_cmd_t::RMW:
155 {
156 etiss::uint64 val;
157 val = std::stoll(split_cmd[3], nullptr, 16);
158 return_code =
159 mem_manipulator_->rmw(dst_address, MemoryWordManipulatorBase::MemOp(split_cmd[2]), val);
160 break;
161 }
162 case MemoryWordManipulatorBase::mem_manip_cmd_t::RRMW:
163 {
164 etiss::uint64 src2_addr;
165 src2_addr = std::stoll(split_cmd[3], nullptr, 16);
166 return_code =
167 mem_manipulator_->rrmw(dst_address, MemoryWordManipulatorBase::MemOp(split_cmd[2]), src2_addr);
168 break;
169 }
170 default: /* UNDEF */
172 std::string("MemoryManipulationSystem/VirtualStruct/applyCustomAction: \'") +
173 action.getCommand() +
174 std::string("\' unrecognized Action. Invalid memory manipulation command: ") +
175 split_cmd[0]);
176 return false;
177 }
178
179 if (return_code != etiss::RETURNCODE::NOERROR)
180 {
182 std::string("MemoryManipulationSystem/VirtualStruct/applyCustomAction: \'") +
183 action.getCommand() + std::string("\' memory access error"));
184 return false;
185 }
186
187 return true;
188 }
189
190 etiss::log(etiss::FATALERROR, std::string("MemoryManipulationSystem/VirtualStruct/applyCustomAction: \'") +
191 action.getCommand() + std::string("\' unrecognized Action"));
192 return false;
193 };
194 }
195}
196
198 : SimpleMemSystem(), name_(name), vsystem_(), mem_manipulator_()
199{
200}
contains an action class that describes actions associated with a fault
simple test system implementation with fault functionality
general configuration and logging
static __inline__ uint8_t
Definition arm_mve.h:323
T get(const std::string &key, T default_, bool *default_used=0)
template function to read the value of a configuration key.
Definition Misc.h:312
std::unique_ptr< etiss::MemoryWordManipulatorBase > mem_manipulator_
std::shared_ptr< etiss::VirtualStruct > vsystem_
MemoryManipulationSystem(const std::string &name="system")
Constructor takes name for reference of this class as a name Injector.
const std::string & getName()
get virtual struct associated name
std::shared_ptr< etiss::VirtualStruct > getStruct(void)
get virtual struct
void init_manipulation(std::shared_ptr< etiss::VirtualStructSupport > vs_parent)
initialize this virtual struct and mount it to cpu_core
simple etiss:System implementation for testing
a Field instance represents e.g.
static std::shared_ptr< VirtualStruct > allocate(void *structure, std::function< void(Field *)> delete_)
forwards: include/jit/*
Definition Benchmark.h:17
@ VERBOSE
Definition Misc.h:88
@ FATALERROR
Definition Misc.h:84
Configuration & cfg()
Definition Misc.cpp:548
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:94