Switch the inferior too in switch_to_program_space_and_thread
[deliverable/binutils-gdb.git] / sim / common / sim-core.c
CommitLineData
b85e4829
AC
1/* The common simulator framework for GDB, the GNU Debugger.
2
b811d2c2 3 Copyright 2002-2020 Free Software Foundation, Inc.
b85e4829
AC
4
5 Contributed by Andrew Cagney and Red Hat.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
4744ac1b 11 the Free Software Foundation; either version 3 of the License, or
b85e4829
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
4744ac1b 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22
23#ifndef SIM_CORE_C
24#define SIM_CORE_C
25
26#include "sim-main.h"
27#include "sim-assert.h"
28
29#if (WITH_HW)
30#include "sim-hw.h"
31#endif
32
c906108c
SS
33/* "core" module install handler.
34
35 This is called via sim_module_install to install the "core"
36 subsystem into the simulator. */
37
38#if EXTERN_SIM_CORE_P
39static MODULE_INIT_FN sim_core_init;
40static MODULE_UNINSTALL_FN sim_core_uninstall;
41#endif
42
43#if EXTERN_SIM_CORE_P
44SIM_RC
45sim_core_install (SIM_DESC sd)
46{
47 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
48
49 /* establish the other handlers */
50 sim_module_add_uninstall_fn (sd, sim_core_uninstall);
51 sim_module_add_init_fn (sd, sim_core_init);
52
53 /* establish any initial data structures - none */
54 return SIM_RC_OK;
55}
56#endif
57
58
59/* Uninstall the "core" subsystem from the simulator. */
60
61#if EXTERN_SIM_CORE_P
62static void
63sim_core_uninstall (SIM_DESC sd)
64{
34b47c38 65 sim_core *core = STATE_CORE (sd);
c906108c
SS
66 unsigned map;
67 /* blow away any mappings */
68 for (map = 0; map < nr_maps; map++) {
69 sim_core_mapping *curr = core->common.map[map].first;
70 while (curr != NULL) {
71 sim_core_mapping *tbd = curr;
72 curr = curr->next;
73 if (tbd->free_buffer != NULL) {
34b47c38
MF
74 SIM_ASSERT (tbd->buffer != NULL);
75 free (tbd->free_buffer);
c906108c 76 }
34b47c38 77 free (tbd);
c906108c
SS
78 }
79 core->common.map[map].first = NULL;
80 }
81}
82#endif
83
84
85#if EXTERN_SIM_CORE_P
86static SIM_RC
87sim_core_init (SIM_DESC sd)
88{
89 /* Nothing to do */
90 return SIM_RC_OK;
91}
92#endif
93
94
95
96#ifndef SIM_CORE_SIGNAL
97#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
98sim_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
99#endif
100
101#if EXTERN_SIM_CORE_P
102void
103sim_core_signal (SIM_DESC sd,
104 sim_cpu *cpu,
105 sim_cia cia,
106 unsigned map,
107 int nr_bytes,
108 address_word addr,
109 transfer_type transfer,
110 sim_core_signals sig)
111{
112 const char *copy = (transfer == read_transfer ? "read" : "write");
113 address_word ip = CIA_ADDR (cia);
114 switch (sig)
115 {
116 case sim_core_unmapped_signal:
117 sim_io_eprintf (sd, "core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
118 nr_bytes, copy, (unsigned long) addr, (unsigned long) ip);
119 sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGSEGV);
120 break;
121 case sim_core_unaligned_signal:
122 sim_io_eprintf (sd, "core: %d byte misaligned %s to address 0x%lx at 0x%lx\n",
123 nr_bytes, copy, (unsigned long) addr, (unsigned long) ip);
124 sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGBUS);
125 break;
126 default:
127 sim_engine_abort (sd, cpu, cia,
128 "sim_core_signal - internal error - bad switch");
129 }
130}
131#endif
132
133
134#if EXTERN_SIM_CORE_P
135static sim_core_mapping *
136new_sim_core_mapping (SIM_DESC sd,
137 int level,
138 int space,
139 address_word addr,
140 address_word nr_bytes,
141 unsigned modulo,
c906108c 142 struct hw *device,
c906108c
SS
143 void *buffer,
144 void *free_buffer)
145{
34b47c38 146 sim_core_mapping *new_mapping = ZALLOC (sim_core_mapping);
c906108c
SS
147 /* common */
148 new_mapping->level = level;
149 new_mapping->space = space;
150 new_mapping->base = addr;
151 new_mapping->nr_bytes = nr_bytes;
152 new_mapping->bound = addr + (nr_bytes - 1);
cdf850e9 153 new_mapping->mask = modulo - 1;
c906108c
SS
154 new_mapping->buffer = buffer;
155 new_mapping->free_buffer = free_buffer;
156 new_mapping->device = device;
157 return new_mapping;
158}
159#endif
160
161
162#if EXTERN_SIM_CORE_P
163static void
164sim_core_map_attach (SIM_DESC sd,
165 sim_core_map *access_map,
166 int level,
167 int space,
168 address_word addr,
169 address_word nr_bytes,
170 unsigned modulo,
c906108c 171 struct hw *client, /*callback/default*/
c906108c
SS
172 void *buffer, /*raw_memory*/
173 void *free_buffer) /*raw_memory*/
174{
175 /* find the insertion point for this additional mapping and then
176 insert */
177 sim_core_mapping *next_mapping;
178 sim_core_mapping **last_mapping;
179
180 SIM_ASSERT ((client == NULL) != (buffer == NULL));
181 SIM_ASSERT ((client == NULL) >= (free_buffer != NULL));
182
183 /* actually do occasionally get a zero size map */
184 if (nr_bytes == 0)
185 {
c906108c
SS
186#if (WITH_HW)
187 sim_hw_abort (sd, client, "called on sim_core_map_attach with size zero");
188#endif
189 sim_io_error (sd, "called on sim_core_map_attach with size zero");
190 }
191
192 /* find the insertion point (between last/next) */
193 next_mapping = access_map->first;
194 last_mapping = &access_map->first;
34b47c38 195 while (next_mapping != NULL
c906108c
SS
196 && (next_mapping->level < level
197 || (next_mapping->level == level
198 && next_mapping->bound < addr)))
199 {
200 /* provided levels are the same */
201 /* assert: next_mapping->base > all bases before next_mapping */
202 /* assert: next_mapping->bound >= all bounds before next_mapping */
203 last_mapping = &next_mapping->next;
204 next_mapping = next_mapping->next;
205 }
028f6515 206
c906108c
SS
207 /* check insertion point correct */
208 SIM_ASSERT (next_mapping == NULL || next_mapping->level >= level);
209 if (next_mapping != NULL && next_mapping->level == level
210 && next_mapping->base < (addr + (nr_bytes - 1)))
211 {
c906108c
SS
212#if WITH_HW
213 sim_hw_abort (sd, client, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
214 space,
215 (long) addr,
c906108c 216 (long) (addr + (nr_bytes - 1)),
35c20992 217 (long) nr_bytes,
c906108c
SS
218 next_mapping->space,
219 (long) next_mapping->base,
220 (long) next_mapping->bound,
221 (long) next_mapping->nr_bytes);
222#endif
223 sim_io_error (sd, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
224 space,
225 (long) addr,
c906108c 226 (long) (addr + (nr_bytes - 1)),
35c20992 227 (long) nr_bytes,
c906108c
SS
228 next_mapping->space,
229 (long) next_mapping->base,
230 (long) next_mapping->bound,
231 (long) next_mapping->nr_bytes);
232 }
233
234 /* create/insert the new mapping */
34b47c38
MF
235 *last_mapping = new_sim_core_mapping (sd,
236 level,
237 space, addr, nr_bytes, modulo,
238 client, buffer, free_buffer);
c906108c
SS
239 (*last_mapping)->next = next_mapping;
240}
241#endif
242
243
244/* Attach memory or a memory mapped device to the simulator.
245 See sim-core.h for a full description. */
246
247#if EXTERN_SIM_CORE_P
248void
249sim_core_attach (SIM_DESC sd,
250 sim_cpu *cpu,
251 int level,
252 unsigned mapmask,
253 int space,
254 address_word addr,
255 address_word nr_bytes,
256 unsigned modulo,
c906108c 257 struct hw *client,
c906108c
SS
258 void *optional_buffer)
259{
34b47c38 260 sim_core *memory = STATE_CORE (sd);
c906108c
SS
261 unsigned map;
262 void *buffer;
263 void *free_buffer;
264
265 /* check for for attempt to use unimplemented per-processor core map */
266 if (cpu != NULL)
267 sim_io_error (sd, "sim_core_map_attach - processor specific memory map not yet supported");
268
c906108c
SS
269 if (client != NULL && modulo != 0)
270 {
c906108c
SS
271#if (WITH_HW)
272 sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo and callback memory conflict");
273#endif
274 sim_io_error (sd, "sim_core_attach - internal error - modulo and callback memory conflict");
275 }
276 if (modulo != 0)
277 {
278 unsigned mask = modulo - 1;
279 /* any zero bits */
280 while (mask >= sizeof (unsigned64)) /* minimum modulo */
281 {
282 if ((mask & 1) == 0)
283 mask = 0;
284 else
285 mask >>= 1;
286 }
287 if (mask != sizeof (unsigned64) - 1)
288 {
c906108c
SS
289#if (WITH_HW)
290 sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
291#endif
292 sim_io_error (sd, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
293 }
294 }
295
296 /* verify consistency between device and buffer */
297 if (client != NULL && optional_buffer != NULL)
298 {
c906108c
SS
299#if (WITH_HW)
300 sim_hw_abort (sd, client, "sim_core_attach - internal error - conflicting buffer and attach arguments");
301#endif
302 sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments");
303 }
304 if (client == NULL)
305 {
306 if (optional_buffer == NULL)
307 {
308 int padding = (addr % sizeof (unsigned64));
309 unsigned long bytes = (modulo == 0 ? nr_bytes : modulo) + padding;
310 free_buffer = zalloc (bytes);
311 buffer = (char*) free_buffer + padding;
312 }
313 else
314 {
315 buffer = optional_buffer;
316 free_buffer = NULL;
317 }
318 }
319 else
320 {
321 /* a device */
322 buffer = NULL;
323 free_buffer = NULL;
324 }
325
326 /* attach the region to all applicable access maps */
028f6515 327 for (map = 0;
c906108c
SS
328 map < nr_maps;
329 map++)
330 {
331 if (mapmask & (1 << map))
332 {
333 sim_core_map_attach (sd, &memory->common.map[map],
334 level, space, addr, nr_bytes, modulo,
335 client, buffer, free_buffer);
336 free_buffer = NULL;
337 }
338 }
028f6515 339
c906108c
SS
340 /* Just copy this map to each of the processor specific data structures.
341 FIXME - later this will be replaced by true processor specific
342 maps. */
343 {
344 int i;
345 for (i = 0; i < MAX_NR_PROCESSORS; i++)
346 {
347 CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common;
348 }
349 }
350}
351#endif
352
353
354/* Remove any memory reference related to this address */
355#if EXTERN_SIM_CORE_P
356static void
357sim_core_map_detach (SIM_DESC sd,
358 sim_core_map *access_map,
359 int level,
360 int space,
361 address_word addr)
362{
363 sim_core_mapping **entry;
364 for (entry = &access_map->first;
365 (*entry) != NULL;
366 entry = &(*entry)->next)
367 {
368 if ((*entry)->base == addr
369 && (*entry)->level == level
370 && (*entry)->space == space)
371 {
372 sim_core_mapping *dead = (*entry);
373 (*entry) = dead->next;
374 if (dead->free_buffer != NULL)
d79fe0d6
MF
375 free (dead->free_buffer);
376 free (dead);
c906108c
SS
377 return;
378 }
379 }
380}
381#endif
382
383#if EXTERN_SIM_CORE_P
384void
385sim_core_detach (SIM_DESC sd,
386 sim_cpu *cpu,
387 int level,
388 int address_space,
389 address_word addr)
390{
391 sim_core *memory = STATE_CORE (sd);
392 unsigned map;
393 for (map = 0; map < nr_maps; map++)
394 {
395 sim_core_map_detach (sd, &memory->common.map[map],
396 level, address_space, addr);
397 }
398 /* Just copy this update to each of the processor specific data
399 structures. FIXME - later this will be replaced by true
400 processor specific maps. */
401 {
402 int i;
403 for (i = 0; i < MAX_NR_PROCESSORS; i++)
404 {
405 CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common;
406 }
407 }
408}
409#endif
410
411
412STATIC_INLINE_SIM_CORE\
413(sim_core_mapping *)
34b47c38
MF
414sim_core_find_mapping (sim_core_common *core,
415 unsigned map,
416 address_word addr,
417 unsigned nr_bytes,
418 transfer_type transfer,
419 int abort, /*either 0 or 1 - hint to inline/-O */
420 sim_cpu *cpu, /* abort => cpu != NULL */
421 sim_cia cia)
c906108c
SS
422{
423 sim_core_mapping *mapping = core->map[map].first;
424 ASSERT ((addr & (nr_bytes - 1)) == 0); /* must be aligned */
425 ASSERT ((addr + (nr_bytes - 1)) >= addr); /* must not wrap */
426 ASSERT (!abort || cpu != NULL); /* abort needs a non null CPU */
427 while (mapping != NULL)
428 {
429 if (addr >= mapping->base
430 && (addr + (nr_bytes - 1)) <= mapping->bound)
431 return mapping;
432 mapping = mapping->next;
433 }
434 if (abort)
435 {
436 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, nr_bytes, addr, transfer,
437 sim_core_unmapped_signal);
438 }
439 return NULL;
440}
441
442
443STATIC_INLINE_SIM_CORE\
444(void *)
445sim_core_translate (sim_core_mapping *mapping,
446 address_word addr)
447{
cdf850e9
MF
448 return (void *)((unsigned8 *) mapping->buffer
449 + ((addr - mapping->base) & mapping->mask));
c906108c
SS
450}
451
452
453#if EXTERN_SIM_CORE_P
454unsigned
455sim_core_read_buffer (SIM_DESC sd,
456 sim_cpu *cpu,
457 unsigned map,
458 void *buffer,
459 address_word addr,
460 unsigned len)
461{
462 sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
463 unsigned count = 0;
464 while (count < len)
465 {
6bf91687 466 address_word raddr = addr + count;
c906108c
SS
467 sim_core_mapping *mapping =
468 sim_core_find_mapping (core, map,
469 raddr, /*nr-bytes*/1,
470 read_transfer,
471 0 /*dont-abort*/, NULL, NULL_CIA);
472 if (mapping == NULL)
473 break;
c906108c
SS
474#if (WITH_HW)
475 if (mapping->device != NULL)
476 {
477 int nr_bytes = len - count;
478 if (raddr + nr_bytes - 1> mapping->bound)
479 nr_bytes = mapping->bound - raddr + 1;
dea10706
MF
480 /* If the access was initiated by a cpu, pass it down so errors can
481 be propagated properly. For other sources (e.g. GDB or DMA), we
482 can only signal errors via the return value. */
483 if (cpu)
484 {
485 sim_cia cia = cpu ? CPU_PC_GET (cpu) : NULL_CIA;
486 sim_cpu_hw_io_read_buffer (cpu, cia, mapping->device,
487 (unsigned_1*)buffer + count,
488 mapping->space,
489 raddr,
490 nr_bytes);
491 }
492 else if (sim_hw_io_read_buffer (sd, mapping->device,
493 (unsigned_1*)buffer + count,
494 mapping->space,
495 raddr,
496 nr_bytes) != nr_bytes)
c906108c
SS
497 break;
498 count += nr_bytes;
499 continue;
500 }
501#endif
502 ((unsigned_1*)buffer)[count] =
34b47c38 503 *(unsigned_1*)sim_core_translate (mapping, raddr);
c906108c
SS
504 count += 1;
505 }
506 return count;
507}
508#endif
509
510
511#if EXTERN_SIM_CORE_P
512unsigned
513sim_core_write_buffer (SIM_DESC sd,
514 sim_cpu *cpu,
515 unsigned map,
516 const void *buffer,
517 address_word addr,
518 unsigned len)
519{
520 sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
521 unsigned count = 0;
522 while (count < len)
523 {
6bf91687 524 address_word raddr = addr + count;
c906108c
SS
525 sim_core_mapping *mapping =
526 sim_core_find_mapping (core, map,
527 raddr, /*nr-bytes*/1,
528 write_transfer,
529 0 /*dont-abort*/, NULL, NULL_CIA);
530 if (mapping == NULL)
531 break;
c906108c 532#if (WITH_HW)
9e8e7dd9 533 if (mapping->device != NULL)
c906108c
SS
534 {
535 int nr_bytes = len - count;
536 if (raddr + nr_bytes - 1 > mapping->bound)
537 nr_bytes = mapping->bound - raddr + 1;
dea10706
MF
538 /* If the access was initiated by a cpu, pass it down so errors can
539 be propagated properly. For other sources (e.g. GDB or DMA), we
540 can only signal errors via the return value. */
541 if (cpu)
542 {
543 sim_cia cia = cpu ? CPU_PC_GET (cpu) : NULL_CIA;
544 sim_cpu_hw_io_write_buffer (cpu, cia, mapping->device,
545 (unsigned_1*)buffer + count,
546 mapping->space,
547 raddr,
548 nr_bytes);
549 }
550 else if (sim_hw_io_write_buffer (sd, mapping->device,
551 (unsigned_1*)buffer + count,
552 mapping->space,
553 raddr,
554 nr_bytes) != nr_bytes)
c906108c
SS
555 break;
556 count += nr_bytes;
557 continue;
558 }
559#endif
34b47c38 560 *(unsigned_1*)sim_core_translate (mapping, raddr) =
c906108c
SS
561 ((unsigned_1*)buffer)[count];
562 count += 1;
563 }
564 return count;
565}
566#endif
567
568
569#if EXTERN_SIM_CORE_P
570void
571sim_core_set_xor (SIM_DESC sd,
572 sim_cpu *cpu,
573 int is_xor)
574{
575 /* set up the XOR map if required. */
576 if (WITH_XOR_ENDIAN) {
577 {
578 sim_core *core = STATE_CORE (sd);
579 sim_cpu_core *cpu_core = (cpu != NULL ? CPU_CORE (cpu) : NULL);
580 if (cpu_core != NULL)
581 {
582 int i = 1;
583 unsigned mask;
584 if (is_xor)
585 mask = WITH_XOR_ENDIAN - 1;
586 else
587 mask = 0;
588 while (i - 1 < WITH_XOR_ENDIAN)
589 {
2283a210 590 cpu_core->byte_xor[i-1] = mask;
c906108c
SS
591 mask = (mask << 1) & (WITH_XOR_ENDIAN - 1);
592 i = (i << 1);
593 }
594 }
595 else
596 {
597 if (is_xor)
598 core->byte_xor = WITH_XOR_ENDIAN - 1;
599 else
600 core->byte_xor = 0;
028f6515 601 }
c906108c
SS
602 }
603 }
604 else {
605 if (is_xor)
606 sim_engine_abort (sd, NULL, NULL_CIA,
607 "Attempted to enable xor-endian mode when permenantly disabled.");
608 }
609}
610#endif
611
612
613#if EXTERN_SIM_CORE_P
614static void
615reverse_n (unsigned_1 *dest,
616 const unsigned_1 *src,
617 int nr_bytes)
618{
619 int i;
620 for (i = 0; i < nr_bytes; i++)
621 {
622 dest [nr_bytes - i - 1] = src [i];
623 }
624}
625#endif
626
627
628#if EXTERN_SIM_CORE_P
629unsigned
630sim_core_xor_read_buffer (SIM_DESC sd,
631 sim_cpu *cpu,
632 unsigned map,
633 void *buffer,
634 address_word addr,
635 unsigned nr_bytes)
636{
2283a210
КВО
637 address_word byte_xor
638 = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->byte_xor[0]);
c906108c
SS
639 if (!WITH_XOR_ENDIAN || !byte_xor)
640 return sim_core_read_buffer (sd, cpu, map, buffer, addr, nr_bytes);
641 else
642 /* only break up transfers when xor-endian is both selected and enabled */
643 {
644 unsigned_1 x[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero-sized array */
645 unsigned nr_transfered = 0;
646 address_word start = addr;
647 unsigned nr_this_transfer = (WITH_XOR_ENDIAN - (addr & ~(WITH_XOR_ENDIAN - 1)));
648 address_word stop;
649 /* initial and intermediate transfers are broken when they cross
650 an XOR endian boundary */
651 while (nr_transfered + nr_this_transfer < nr_bytes)
652 /* initial/intermediate transfers */
653 {
654 /* since xor-endian is enabled stop^xor defines the start
655 address of the transfer */
656 stop = start + nr_this_transfer - 1;
657 SIM_ASSERT (start <= stop);
658 SIM_ASSERT ((stop ^ byte_xor) <= (start ^ byte_xor));
659 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
660 != nr_this_transfer)
661 return nr_transfered;
662 reverse_n (&((unsigned_1*)buffer)[nr_transfered], x, nr_this_transfer);
663 nr_transfered += nr_this_transfer;
664 nr_this_transfer = WITH_XOR_ENDIAN;
665 start = stop + 1;
666 }
667 /* final transfer */
668 nr_this_transfer = nr_bytes - nr_transfered;
669 stop = start + nr_this_transfer - 1;
670 SIM_ASSERT (stop == (addr + nr_bytes - 1));
671 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
672 != nr_this_transfer)
673 return nr_transfered;
674 reverse_n (&((unsigned_1*)buffer)[nr_transfered], x, nr_this_transfer);
675 return nr_bytes;
676 }
677}
678#endif
028f6515
MF
679
680
c906108c
SS
681#if EXTERN_SIM_CORE_P
682unsigned
683sim_core_xor_write_buffer (SIM_DESC sd,
684 sim_cpu *cpu,
685 unsigned map,
686 const void *buffer,
687 address_word addr,
688 unsigned nr_bytes)
689{
2283a210
КВО
690 address_word byte_xor
691 = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->byte_xor[0]);
c906108c
SS
692 if (!WITH_XOR_ENDIAN || !byte_xor)
693 return sim_core_write_buffer (sd, cpu, map, buffer, addr, nr_bytes);
694 else
695 /* only break up transfers when xor-endian is both selected and enabled */
696 {
697 unsigned_1 x[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero sized array */
698 unsigned nr_transfered = 0;
699 address_word start = addr;
700 unsigned nr_this_transfer = (WITH_XOR_ENDIAN - (addr & ~(WITH_XOR_ENDIAN - 1)));
701 address_word stop;
702 /* initial and intermediate transfers are broken when they cross
703 an XOR endian boundary */
704 while (nr_transfered + nr_this_transfer < nr_bytes)
705 /* initial/intermediate transfers */
706 {
707 /* since xor-endian is enabled stop^xor defines the start
708 address of the transfer */
709 stop = start + nr_this_transfer - 1;
710 SIM_ASSERT (start <= stop);
711 SIM_ASSERT ((stop ^ byte_xor) <= (start ^ byte_xor));
712 reverse_n (x, &((unsigned_1*)buffer)[nr_transfered], nr_this_transfer);
713 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
714 != nr_this_transfer)
715 return nr_transfered;
716 nr_transfered += nr_this_transfer;
717 nr_this_transfer = WITH_XOR_ENDIAN;
718 start = stop + 1;
719 }
720 /* final transfer */
721 nr_this_transfer = nr_bytes - nr_transfered;
722 stop = start + nr_this_transfer - 1;
723 SIM_ASSERT (stop == (addr + nr_bytes - 1));
724 reverse_n (x, &((unsigned_1*)buffer)[nr_transfered], nr_this_transfer);
725 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
726 != nr_this_transfer)
727 return nr_transfered;
728 return nr_bytes;
729 }
730}
731#endif
732
6edf0760
NC
733#if EXTERN_SIM_CORE_P
734void *
735sim_core_trans_addr (SIM_DESC sd,
736 sim_cpu *cpu,
737 unsigned map,
738 address_word addr)
739{
740 sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
741 sim_core_mapping *mapping =
742 sim_core_find_mapping (core, map,
743 addr, /*nr-bytes*/1,
744 write_transfer,
745 0 /*dont-abort*/, NULL, NULL_CIA);
746 if (mapping == NULL)
747 return NULL;
34b47c38 748 return sim_core_translate (mapping, addr);
6edf0760
NC
749}
750#endif
751
c906108c
SS
752
753
754/* define the read/write 1/2/4/8/16/word functions */
755
756#define N 16
757#include "sim-n-core.h"
758
759#define N 8
760#include "sim-n-core.h"
761
762#define N 7
763#define M 8
764#include "sim-n-core.h"
765
766#define N 6
767#define M 8
768#include "sim-n-core.h"
769
770#define N 5
771#define M 8
772#include "sim-n-core.h"
773
774#define N 4
775#include "sim-n-core.h"
776
777#define N 3
778#define M 4
779#include "sim-n-core.h"
780
781#define N 2
782#include "sim-n-core.h"
783
784#define N 1
785#include "sim-n-core.h"
786
787#endif
This page took 0.994494 seconds and 4 git commands to generate.