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