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