ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
MemoryDevice.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.
6
8#include "etiss/System.h"
9
10namespace etiss
11{
12namespace plugin
13{
14
15namespace
16{
17
19{
20
21 struct ETISS_System sys;
22
24
26
27 bool (*fastrule)(uint64_t addr, unsigned len);
28};
29
30bool empty_fastrule(uint64_t, unsigned)
31{
32 return false; // pass through directly
33}
34
36{
37 MapperSystem *lsys = ((MapperSystem *)handle);
38 if (lsys->fastrule(addr, length))
39 {
40 return lsys->this_->iread(lsys->orig, cpu, addr, length);
41 }
42 ETISS_System *sys = lsys->orig;
43 return sys->iread(sys->handle, cpu, addr, length);
44}
46{
47 MapperSystem *lsys = ((MapperSystem *)handle);
48 if (lsys->fastrule(addr, length))
49 {
50 return lsys->this_->iwrite(lsys->orig, cpu, addr, buffer, length);
51 }
52 ETISS_System *sys = lsys->orig;
53 return sys->iwrite(sys->handle, cpu, addr, buffer, length);
54}
55
57{
58 MapperSystem *lsys = ((MapperSystem *)handle);
59 if (lsys->fastrule(addr, length))
60 {
61 return lsys->this_->dread(lsys->orig, cpu, addr, buffer, length);
62 }
63 ETISS_System *sys = lsys->orig;
64 return sys->dread(sys->handle, cpu, addr, buffer, length);
65}
67{
68 MapperSystem *lsys = ((MapperSystem *)handle);
69 if (lsys->fastrule(addr, length))
70 {
71 return lsys->this_->dwrite(lsys->orig, cpu, addr, buffer, length);
72 }
73 ETISS_System *sys = lsys->orig;
74 return sys->dwrite(sys->handle, cpu, addr, buffer, length);
75}
76
78{
79 MapperSystem *lsys = ((MapperSystem *)handle);
80 if (lsys->fastrule(addr, length))
81 {
82 return lsys->this_->dbg_read(lsys->orig, addr, buffer, length);
83 }
84 ETISS_System *sys = lsys->orig;
85 return sys->dbg_read(sys->handle, addr, buffer, length);
86}
87
89{
90 MapperSystem *lsys = ((MapperSystem *)handle);
91 if (lsys->fastrule(addr, length))
92 {
93 return lsys->this_->dbg_write(lsys->orig, addr, buffer, length);
94 }
95 ETISS_System *sys = lsys->orig;
96 return sys->dbg_write(sys->handle, addr, buffer, length);
97}
98
99void syncTime_(void *handle, ETISS_CPU *cpu)
100{
101 MapperSystem *lsys = ((MapperSystem *)handle);
102 ETISS_System *sys = lsys->orig;
103 sys->syncTime(sys->handle, cpu);
104}
105
106} // namespace
107
108MemoryDeviceMapper::MemoryDeviceMapper(std::string name) : name_(name) {}
109
111
113{
114 MapperSystem *ret = new MapperSystem();
115
116 ret->sys.iread = &iread_;
117 ret->sys.iwrite = &iwrite_;
118 ret->sys.dread = &dread_;
119 ret->sys.dwrite = &dwrite_;
120 ret->sys.dbg_read = &dbg_read_;
121 ret->sys.dbg_write = &dbg_write_;
122 ret->sys.syncTime = &syncTime_;
123
124 ret->sys.handle = (void *)ret;
125
126 ret->this_ = this;
127
128 ret->orig = system;
129
130 ret->fastrule = &empty_fastrule;
131
132 return (ETISS_System *)ret;
133}
135{
136 ETISS_System *ret = ((MapperSystem *)system)->orig;
137
138 delete system;
139
140 return ret;
141}
142
143etiss::int32 MemoryDeviceMapper::iread(ETISS_System *sys, ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint32 len)
144{
145 while (true)
146 {
147 unsigned nlen = len;
148 int index = map(true, true, false, addr, 0, len, nlen);
149 if ((index < 0) || (index > (int)devices_.size()) || (devices_[index] == 0))
150 {
151 int32_t err = sys->iread(sys->handle, cpu, addr, len);
152 if (err)
153 return err;
154 }
155 else
156 {
157 int32_t err = devices_[index]->iread(cpu, addr, nlen);
158 if (err)
159 return err;
160 }
161 len = len - nlen;
162 if (len == 0)
163 return 0;
164 addr += nlen;
165 }
166}
167etiss::int32 MemoryDeviceMapper::iwrite(ETISS_System *sys, ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint8 *buf,
168 etiss::uint32 len)
169{
170 while (true)
171 {
172 unsigned nlen = len;
173 int index = map(true, false, false, addr, buf, len, nlen);
174 if ((index < 0) || (index > (int)devices_.size()) || (devices_[index] == 0))
175 {
176 int32_t err = sys->iwrite(sys->handle, cpu, addr, buf, len);
177 if (err)
178 return err;
179 }
180 else
181 {
182 int32_t err = devices_[index]->iwrite(cpu, addr, buf, nlen);
183 if (err)
184 return err;
185 }
186 len = len - nlen;
187 if (len == 0)
188 return 0;
189 buf += nlen;
190 addr += nlen;
191 }
192}
193etiss::int32 MemoryDeviceMapper::dread(ETISS_System *sys, ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint8 *buf,
194 etiss::uint32 len)
195{
196 while (true)
197 {
198 unsigned nlen = len;
199 int index = map(false, true, false, addr, buf, len, nlen);
200 if ((index < 0) || (index > (int)devices_.size()) || (devices_[index] == 0))
201 {
202 int32_t err = sys->dread(sys->handle, cpu, addr, buf, len);
203 if (err)
204 return err;
205 }
206 else
207 {
208 int32_t err = devices_[index]->dread(cpu, addr, buf, nlen);
209 if (err)
210 return err;
211 }
212 len = len - nlen;
213 if (len == 0)
214 return 0;
215 buf += nlen;
216 addr += nlen;
217 }
218}
219etiss::int32 MemoryDeviceMapper::dwrite(ETISS_System *sys, ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint8 *buf,
220 etiss::uint32 len)
221{
222 while (true)
223 {
224 unsigned nlen = len;
225 int index = map(false, false, false, addr, buf, len, nlen);
226 if ((index < 0) || (index > (int)devices_.size()) || (devices_[index] == 0))
227 {
228 int32_t err = sys->dwrite(sys->handle, cpu, addr, buf, len);
229 if (err)
230 return err;
231 }
232 else
233 {
234 int32_t err = devices_[index]->dwrite(cpu, addr, buf, nlen);
235 if (err)
236 return err;
237 }
238 len = len - nlen;
239 if (len == 0)
240 return 0;
241 buf += nlen;
242 addr += nlen;
243 }
244}
245etiss::int32 MemoryDeviceMapper::dbg_read(ETISS_System *sys, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len)
246{
247 while (true)
248 {
249 unsigned nlen = len;
250 int index = map(false, true, true, addr, buf, len, nlen);
251 if ((index < 0) || (index > (int)devices_.size()) || (devices_[index] == 0))
252 {
253 int32_t err = sys->dbg_read(sys->handle, addr, buf, len);
254 if (err)
255 return err;
256 }
257 else
258 {
259 int32_t err = devices_[index]->dbg_read(addr, buf, nlen);
260 if (err)
261 return err;
262 }
263 len = len - nlen;
264 if (len == 0)
265 return 0;
266 buf += nlen;
267 addr += nlen;
268 }
269}
270etiss::int32 MemoryDeviceMapper::dbg_write(ETISS_System *sys, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len)
271{
272 while (true)
273 {
274 unsigned nlen = len;
275 int index = map(false, true, true, addr, buf, len, nlen);
276 if ((index < 0) || (index > (int)devices_.size()) || (devices_[index] == 0))
277 {
278 int32_t err = sys->dbg_write(sys->handle, addr, buf, len);
279 if (err)
280 return err;
281 }
282 else
283 {
284 int32_t err = devices_[index]->dbg_write(addr, buf, nlen);
285 if (err)
286 return err;
287 }
288 len = len - nlen;
289 if (len == 0)
290 return 0;
291 buf += nlen;
292 addr += nlen;
293 }
294}
295
296int MemoryDeviceMapper::map(bool ibus, bool read, bool dbg, uint64_t addr, uint8_t *buf, unsigned len, unsigned &newlen)
297{
298 for (unsigned i = 0; i < mountPoints_.size(); i++)
299 {
300 std::pair<uint64_t, uint64_t> &mp = mountPoints_[i];
301 if ((addr & mp.first) == mp.second)
302 return (int)i;
303 }
304 return -1;
305}
306
308{
309 if (sys == 0)
310 return false;
311
312 devices_.push_back(sys);
313 mountPoints_.push_back(std::make_pair(mask, addr));
314
315 return true;
316}
317
318} // namespace plugin
319} // namespace etiss
static __inline__ uint64_t
Definition arm_cde.h:31
static __inline__ int32_t
Definition arm_mve.h:51
static __inline__ uint8_t
Definition arm_mve.h:323
uint64_t etiss_uint64
Definition types.h:58
uint32_t etiss_uint32
Definition types.h:55
uint8_t etiss_uint8
Definition types.h:49
int32_t etiss_int32
Definition types.h:54
System Interface for the basic system IO operations and time synchronization.
Definition System.h:38
std::vector< etiss::System * > devices_
etiss::int32 dread(ETISS_System *sys, ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len)
etiss::int32 dbg_read(ETISS_System *sys, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len)
virtual int map(bool ibus, bool read, bool dbg, uint64_t addr, uint8_t *buf, unsigned len, unsigned &newlen)
virtual bool mount(etiss::System *sys, uint64_t mask, uint64_t addr)
virtual ETISS_System * unwrap(ETISS_CPU *cpu, ETISS_System *system)
undo wrap function call this function will be called AFTER etiss::Plugin::cleanup
etiss::int32 dbg_write(ETISS_System *sys, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len)
std::vector< std::pair< uint64_t, uint64_t > > mountPoints_
etiss::int32 iwrite(ETISS_System *sys, ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len)
etiss::int32 iread(ETISS_System *sys, ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint32 len)
etiss::int32 dwrite(ETISS_System *sys, ETISS_CPU *cpu, etiss::uint64 addr, etiss::uint8 *buf, etiss::uint32 len)
virtual ETISS_System * wrap(ETISS_CPU *cpu, ETISS_System *system)
change/wrap the passed system structure.
conatins a convinience class that can be wrapped as a ETISS_System structure
etiss_int32 dread_(void *handle, ETISS_CPU *cpu, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
etiss_int32 dbg_write_(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
etiss_int32 iwrite_(void *handle, ETISS_CPU *cpu, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
etiss_int32 dbg_read_(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
etiss_int32 iread_(void *handle, ETISS_CPU *cpu, etiss_uint64 addr, etiss_uint32 length)
etiss_int32 dwrite_(void *handle, ETISS_CPU *cpu, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
void syncTime_(void *handle, ETISS_CPU *cpu)
forwards: include/jit/*
Definition Benchmark.h:17
float __ovld __cnfn length(float p)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
#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
etiss_int32(* dwrite)(void *handle, ETISS_CPU *cpu, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
write data
Definition System.h:59
etiss_int32(* iread)(void *handle, ETISS_CPU *cpu, etiss_uint64 addr, etiss_uint32 length)
used to simulate an instruction fetch.
Definition System.h:46
void * handle
custom handle that will be passed to the functions of this structure
Definition System.h:78
etiss_int32(* dbg_write)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug write
Definition System.h:70
etiss_int32(* dbg_read)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug read
Definition System.h:66
etiss_int32(* dread)(void *handle, ETISS_CPU *cpu, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
read data
Definition System.h:55
void(* syncTime)(void *handle, ETISS_CPU *cpu)
called after a block to synchronize the time
Definition System.h:76
etiss_int32(* iwrite)(void *handle, ETISS_CPU *cpu, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
write instruction data over instruction bus
Definition System.h:50