ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
Delegate.h
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.
14#ifndef ETISS_INTERFACES_DELEGATE_H
15#define ETISS_INTERFACES_DELEGATE_H
16
17#include "etiss/Misc.h"
18#include "etiss/jit/ReturnCode.h"
19
20namespace etiss
21{
22namespace interfaces
23{
24
25template <typename T, unsigned align>
27
28template <>
30{
31 return ((((((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1)) & 0xcccccccc) >> 2) |
32 (((((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1)) & 0x33333333)
33 << 2)); // heavily requires compiler optimization. cannot be implemented smarter since a constexpr function
34 // may only have a return statement
35}
36
38{
39 private:
42
43 public:
45
46 void syncTime(uint64_t time_ps);
47
51 etiss::int32 read(bool ibus, uint64_t &time_ps, uint64_t addr, uint8_t *buf, unsigned len);
52
56 etiss::int32 write(bool ibus, uint64_t &time_ps, uint64_t addr, uint8_t *buf, unsigned len);
57
58 private:
59 public:
61 std::function<etiss::int32(bool /*ibus*/, uint64_t & /*time_ps*/, uint64_t /*addr*/, uint8_t * /*buf*/,
62 unsigned /*len*/, bool & /*continue*/, bool & /*handleNormal*/)>
64 std::function<etiss::int32(bool /*ibus*/, uint64_t & /*time_ps*/, uint64_t /*addr*/, uint8_t * /*buf*/,
65 unsigned /*len*/, bool & /*continue*/, bool & /*handleNormal*/)>
67
68 std::function<void(bool injected, const uint64_t &time_ps, uint64_t addr, const uint8_t *buf, unsigned len)>
70};
71
72template <typename T, bool (Delegate::*rwop)(bool ibus, uint64_t &time_ps, uint64_t addr, uint8_t *buf, unsigned len),
73 unsigned bytewidth, bool swapBitOrder_ = false>
78bool sel_rwop(Delegate &delg, bool ibus, uint64_t &time_ps, uint64_t addr, uint8_t *buf, T sel_i)
79{
80 static_assert(std::is_integral<T>::value, "sel_rwop needs an integral type for the select signal");
81 static_assert(bytewidth > 0, "bytewidth cannot be 0");
82 if (unlikely(sel_i == 0))
83 {
84 return (delg.*rwop)(ibus, time_ps, addr, buf, 0);
85 }
86 // if (swapBitOrder_)
87 // sel_i = swapBitOrder<T,bytewidth>(sel_i);
88 // handle common cases quickly
89 if (likely(sel_i == ((1 << bytewidth) - 1)))
90 { // all bits are selected
91 return (delg.*rwop)(ibus, time_ps, addr, buf, bytewidth);
92 }
93 else
94 {
95 // std::cout << "sel_i = " << sel_i << std::endl;
96 if (!swapBitOrder_)
97 { // guessing common values
98 if ((sel_i == ((1 << (bytewidth >> 1)) - 1)) && (bytewidth > 1))
99 { // halve of the bits are selected
100 return (delg.*rwop)(ibus, time_ps, addr, buf, bytewidth >> 1);
101 }
102 else if ((sel_i == ((1 << (bytewidth >> 2)) - 1)) && (bytewidth > 3))
103 { // one bit is selected
104 return (delg.*rwop)(ibus, time_ps, addr, buf, bytewidth >> 2);
105 }
106 }
107 else
108 {
109 if ((sel_i == ((1 << (bytewidth >> 1)) - 1)) && (bytewidth > 1))
110 { // halve of the bits are selected
111 return (delg.*rwop)(ibus, time_ps, addr, buf, bytewidth >> 1);
112 }
113 else if ((sel_i == ((1 << (bytewidth >> 2)) - 1)) && (bytewidth > 3))
114 {
115 return (delg.*rwop)(ibus, time_ps, addr, buf, bytewidth >> 2);
116 }
117 }
118 }
119 etiss::log(etiss::FATALERROR, "not implemented", ETISS_SRCLOC, sel_i);
120 return false;
121}
122
123template <typename T>
125{
126 static_assert(std::is_pod<T>::value, "SimpleInstructionInjector<T> requires T to be a pod type");
127
128 public:
129 SimpleInstructionInjector(bool useRefetchCompensation = true)
130 : logInjectionAddresses_(false), useRefetchCompensation_(useRefetchCompensation)
131 {
132 }
133
134 void append(T val) { buffer.push_back(val); }
135
136 template <class InputIt>
137 void append(InputIt first, InputIt last)
138 {
139 buffer.insert(buffer.end(), first, last);
140 }
141
147 void setHelper(unsigned index, std::function<std::list<T>(T)> func)
148 {
149 genHelpers.insert(std::make_pair(index, func));
150 }
151
152 bool appendWithHelper(unsigned helper, T val)
153 {
154 auto fnc = genHelpers.find(helper);
155 if (fnc == genHelpers.end())
156 return false;
157
158 std::list<T> tmp = fnc->second(val);
159
160 append(tmp.begin(), tmp.end());
161
162 return true;
163 }
164
165 void appendRepetitions(unsigned count)
166 {
167 std::list<T> oldbuf = buffer;
168 for (unsigned i = 0; i < count; i++)
169 {
170 buffer.insert(buffer.end(), oldbuf.begin(), oldbuf.end());
171 }
172 }
173
177 std::function<etiss::int32(bool, uint64_t &, uint64_t, uint8_t *, unsigned, bool &, bool &)> toFunction()
178 {
179 std::map<uint64_t, T> refetchcompensation;
180 return [refetchcompensation, this](bool ibus, uint64_t &time_ps, uint64_t addr, uint8_t *buf, unsigned len,
181 bool &continu, bool &handleNormal) mutable
182 {
183 continu = true;
184 handleNormal = false;
185
186 if (!ibus)
187 {
188 handleNormal = true;
189 return etiss::RETURNCODE::GENERALERROR; // X Read bus can not handle instruction injection.
190 }
191
192 if (len != sizeof(T))
193 {
195 "SimpleInstructionInjector detected an instruction read access of invalid length");
196 return etiss::RETURNCODE::IBUS_READ_ERROR;
197 }
198
199 // if data is fetched from the same address again then inject the same data again
200 // is a size limited form of this compensation usefull? e.g. execute from address 4,8,12,16,4 where the
201 // instructions at address 4 should differ -> size limit needs to be 3
203 {
204 auto refetch = refetchcompensation.find(addr);
205 if (refetch != refetchcompensation.end())
206 {
207 *((T *)buf) = refetch->second;
208 return etiss::RETURNCODE::NOERROR;
209 }
210 }
211
212 // note the injected sequence must guarantee that there is no refetch that
213 // would require instructions from this function. in case of an or1k
214 // processor this can be achieved by adding l.nop operations at the end
215 if (buffer.size() == 0)
216 {
217 continu = false;
218 handleNormal = true;
219 return etiss::RETURNCODE::IBUS_READ_ERROR; // X
220 }
221
222 *((T *)buf) = buffer.front();
224 refetchcompensation.insert(std::pair<uint64_t, T>(addr, buffer.front()));
225 buffer.pop_front();
226
227 continu = buffer.size() != 0;
228
230 {
231 // std::cout << "push_back(0x" << std::hex << addr << std::dec << ")" << std::endl;
232 injectionAddresses_.push_back(addr);
233 }
234
235 // std::cout << "Pending: " << buffer.size() << std::endl;
236
237 return etiss::RETURNCODE::NOERROR;
238 };
239 }
240
245 {
246 for (auto iter = buffer.begin(); iter != buffer.end(); iter++)
247 {
248 T tmp = *iter;
249 for (size_t i = 0; i < (sizeof(T) >> 1); i++)
250 {
251 ((char *)&(*iter))[i] = ((char *)&tmp)[sizeof(T) - 1 - i];
252 ((char *)&(*iter))[sizeof(T) - 1 - i] = ((char *)&tmp)[i];
253 }
254 }
255 }
256
257 inline bool injectionFinished() { return buffer.empty(); }
258
260 inline void logInjectionAddresses(bool val) { logInjectionAddresses_ = val; }
261 inline std::list<uint64_t> &injectionAddresses() { return injectionAddresses_; }
262
263 private:
264 std::list<T> buffer;
265
266 std::map<unsigned, std::function<std::list<T>(T)>> genHelpers;
267
270 std::list<uint64_t> injectionAddresses_;
271};
272
273} // namespace interfaces
274} // namespace etiss
275
276#endif // ETISS_INTERFACES_DELEGATE_H
general configuration and logging
#define ETISS_SRCLOC
Definition Misc.h:202
static __inline__ uint32_t
Definition arm_cde.h:25
static __inline__ uint64_t
Definition arm_cde.h:31
static __inline__ uint8_t
Definition arm_mve.h:323
#define likely(x)
Definition types.h:35
#define unlikely(x)
Definition types.h:36
std::function< etiss::int32(bool, uint64_t &, uint64_t, uint8_t *, unsigned, bool &, bool &)> injectedRead
if valid then this function will be called by read() instead of performing any action itself
Definition Delegate.h:63
void syncTime(uint64_t time_ps)
Definition Delegate.cpp:17
etiss::int32 read(bool ibus, uint64_t &time_ps, uint64_t addr, uint8_t *buf, unsigned len)
handles read operations.
Definition Delegate.cpp:31
ETISS_System & system
Definition Delegate.h:40
etiss::int32 write(bool ibus, uint64_t &time_ps, uint64_t addr, uint8_t *buf, unsigned len)
handles write operations.
Definition Delegate.cpp:89
std::function< etiss::int32(bool, uint64_t &, uint64_t, uint8_t *, unsigned, bool &, bool &)> redirectedWrite
Definition Delegate.h:66
std::function< void(bool injected, const uint64_t &time_ps, uint64_t addr, const uint8_t *buf, unsigned len)> snoopRead
Definition Delegate.h:69
bool appendWithHelper(unsigned helper, T val)
Definition Delegate.h:152
void swapEndianness()
swaps the endianness of all stored buffer values
Definition Delegate.h:244
SimpleInstructionInjector(bool useRefetchCompensation=true)
Definition Delegate.h:129
std::map< unsigned, std::function< std::list< T >(T)> > genHelpers
Definition Delegate.h:266
std::function< etiss::int32(bool, uint64_t &, uint64_t, uint8_t *, unsigned, bool &, bool &)> toFunction()
Definition Delegate.h:177
void setHelper(unsigned index, std::function< std::list< T >(T)> func)
Adds a function with an unique ID to the SimpleInstructionInjector.
Definition Delegate.h:147
void append(InputIt first, InputIt last)
Definition Delegate.h:137
std::list< uint64_t > & injectionAddresses()
Definition Delegate.h:261
#define CONSTEXPR
Definition config.h:53
CONSTEXPR uint32_t swapBitOrder< uint32_t, 4 >(uint32_t t)
Definition Delegate.h:29
bool sel_rwop(Delegate &delg, bool ibus, uint64_t &time_ps, uint64_t addr, uint8_t *buf, T sel_i)
this function handles read writes in case of busses that have a fixed output with and a select signal...
Definition Delegate.h:78
CONSTEXPR T swapBitOrder(T t)
forwards: include/jit/*
Definition Benchmark.h:17
@ ERROR
Definition Misc.h:85
@ FATALERROR
Definition Misc.h:84
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:94
#define false
Definition stdbool.h:17
#define bool
Definition stdbool.h:15
basic cpu state structure needed for execution of any cpu architecture.
Definition CPU.h:51
memory access and time synchronization functions.
Definition System.h:40