]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/sim-core.c
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / sim / common / sim-core.c
CommitLineData
b85e4829
AC
1/* The common simulator framework for GDB, the GNU Debugger.
2
8acc9f48 3 Copyright 2002-2013 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"
81c641e7
MF
31#define device_error(client, ...) device_error ((device *)(client), __VA_ARGS__)
32#define device_io_read_buffer(client, ...) device_io_read_buffer ((device *)(client), __VA_ARGS__)
33#define device_io_write_buffer(client, ...) device_io_write_buffer ((device *)(client), __VA_ARGS__)
c906108c
SS
34#endif
35
c906108c
SS
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
42static MODULE_INIT_FN sim_core_init;
43static MODULE_UNINSTALL_FN sim_core_uninstall;
44#endif
45
46#if EXTERN_SIM_CORE_P
47SIM_RC
48sim_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
65static void
66sim_core_uninstall (SIM_DESC sd)
67{
34b47c38 68 sim_core *core = STATE_CORE (sd);
c906108c
SS
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) {
34b47c38
MF
77 SIM_ASSERT (tbd->buffer != NULL);
78 free (tbd->free_buffer);
c906108c 79 }
34b47c38 80 free (tbd);
c906108c
SS
81 }
82 core->common.map[map].first = NULL;
83 }
84}
85#endif
86
87
88#if EXTERN_SIM_CORE_P
89static SIM_RC
90sim_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) \
101sim_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
102#endif
103
104#if EXTERN_SIM_CORE_P
105void
106sim_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
138static sim_core_mapping *
139new_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#if WITH_HW
146 struct hw *device,
147#else
148 device *device,
149#endif
150 void *buffer,
151 void *free_buffer)
152{
34b47c38 153 sim_core_mapping *new_mapping = ZALLOC (sim_core_mapping);
c906108c
SS
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 if (modulo == 0)
161 new_mapping->mask = (unsigned) 0 - 1;
162 else
163 new_mapping->mask = modulo - 1;
164 new_mapping->buffer = buffer;
165 new_mapping->free_buffer = free_buffer;
166 new_mapping->device = device;
167 return new_mapping;
168}
169#endif
170
171
172#if EXTERN_SIM_CORE_P
173static void
174sim_core_map_attach (SIM_DESC sd,
175 sim_core_map *access_map,
176 int level,
177 int space,
178 address_word addr,
179 address_word nr_bytes,
180 unsigned modulo,
181#if WITH_HW
182 struct hw *client, /*callback/default*/
183#else
184 device *client, /*callback/default*/
185#endif
186 void *buffer, /*raw_memory*/
187 void *free_buffer) /*raw_memory*/
188{
189 /* find the insertion point for this additional mapping and then
190 insert */
191 sim_core_mapping *next_mapping;
192 sim_core_mapping **last_mapping;
193
194 SIM_ASSERT ((client == NULL) != (buffer == NULL));
195 SIM_ASSERT ((client == NULL) >= (free_buffer != NULL));
196
197 /* actually do occasionally get a zero size map */
198 if (nr_bytes == 0)
199 {
200#if (WITH_DEVICES)
34b47c38 201 device_error (client, "called on sim_core_map_attach with size zero");
c906108c
SS
202#endif
203#if (WITH_HW)
204 sim_hw_abort (sd, client, "called on sim_core_map_attach with size zero");
205#endif
206 sim_io_error (sd, "called on sim_core_map_attach with size zero");
207 }
208
209 /* find the insertion point (between last/next) */
210 next_mapping = access_map->first;
211 last_mapping = &access_map->first;
34b47c38 212 while (next_mapping != NULL
c906108c
SS
213 && (next_mapping->level < level
214 || (next_mapping->level == level
215 && next_mapping->bound < addr)))
216 {
217 /* provided levels are the same */
218 /* assert: next_mapping->base > all bases before next_mapping */
219 /* assert: next_mapping->bound >= all bounds before next_mapping */
220 last_mapping = &next_mapping->next;
221 next_mapping = next_mapping->next;
222 }
028f6515 223
c906108c
SS
224 /* check insertion point correct */
225 SIM_ASSERT (next_mapping == NULL || next_mapping->level >= level);
226 if (next_mapping != NULL && next_mapping->level == level
227 && next_mapping->base < (addr + (nr_bytes - 1)))
228 {
229#if (WITH_DEVICES)
230 device_error (client, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
231 space,
232 (long) addr,
35c20992 233 (long) (addr + nr_bytes - 1),
c906108c 234 (long) nr_bytes,
c906108c
SS
235 next_mapping->space,
236 (long) next_mapping->base,
237 (long) next_mapping->bound,
238 (long) next_mapping->nr_bytes);
239#endif
240#if WITH_HW
241 sim_hw_abort (sd, client, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
242 space,
243 (long) addr,
c906108c 244 (long) (addr + (nr_bytes - 1)),
35c20992 245 (long) nr_bytes,
c906108c
SS
246 next_mapping->space,
247 (long) next_mapping->base,
248 (long) next_mapping->bound,
249 (long) next_mapping->nr_bytes);
250#endif
251 sim_io_error (sd, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
252 space,
253 (long) addr,
c906108c 254 (long) (addr + (nr_bytes - 1)),
35c20992 255 (long) nr_bytes,
c906108c
SS
256 next_mapping->space,
257 (long) next_mapping->base,
258 (long) next_mapping->bound,
259 (long) next_mapping->nr_bytes);
260 }
261
262 /* create/insert the new mapping */
34b47c38
MF
263 *last_mapping = new_sim_core_mapping (sd,
264 level,
265 space, addr, nr_bytes, modulo,
266 client, buffer, free_buffer);
c906108c
SS
267 (*last_mapping)->next = next_mapping;
268}
269#endif
270
271
272/* Attach memory or a memory mapped device to the simulator.
273 See sim-core.h for a full description. */
274
275#if EXTERN_SIM_CORE_P
276void
277sim_core_attach (SIM_DESC sd,
278 sim_cpu *cpu,
279 int level,
280 unsigned mapmask,
281 int space,
282 address_word addr,
283 address_word nr_bytes,
284 unsigned modulo,
285#if WITH_HW
286 struct hw *client,
287#else
288 device *client,
289#endif
290 void *optional_buffer)
291{
34b47c38 292 sim_core *memory = STATE_CORE (sd);
c906108c
SS
293 unsigned map;
294 void *buffer;
295 void *free_buffer;
296
297 /* check for for attempt to use unimplemented per-processor core map */
298 if (cpu != NULL)
299 sim_io_error (sd, "sim_core_map_attach - processor specific memory map not yet supported");
300
301 /* verify modulo memory */
302 if (!WITH_MODULO_MEMORY && modulo != 0)
303 {
304#if (WITH_DEVICES)
305 device_error (client, "sim_core_attach - internal error - modulo memory disabled");
306#endif
307#if (WITH_HW)
308 sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo memory disabled");
309#endif
310 sim_io_error (sd, "sim_core_attach - internal error - modulo memory disabled");
311 }
312 if (client != NULL && modulo != 0)
313 {
314#if (WITH_DEVICES)
315 device_error (client, "sim_core_attach - internal error - modulo and callback memory conflict");
316#endif
317#if (WITH_HW)
318 sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo and callback memory conflict");
319#endif
320 sim_io_error (sd, "sim_core_attach - internal error - modulo and callback memory conflict");
321 }
322 if (modulo != 0)
323 {
324 unsigned mask = modulo - 1;
325 /* any zero bits */
326 while (mask >= sizeof (unsigned64)) /* minimum modulo */
327 {
328 if ((mask & 1) == 0)
329 mask = 0;
330 else
331 mask >>= 1;
332 }
333 if (mask != sizeof (unsigned64) - 1)
334 {
335#if (WITH_DEVICES)
336 device_error (client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
337#endif
338#if (WITH_HW)
339 sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
340#endif
341 sim_io_error (sd, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
342 }
343 }
344
345 /* verify consistency between device and buffer */
346 if (client != NULL && optional_buffer != NULL)
347 {
348#if (WITH_DEVICES)
349 device_error (client, "sim_core_attach - internal error - conflicting buffer and attach arguments");
350#endif
351#if (WITH_HW)
352 sim_hw_abort (sd, client, "sim_core_attach - internal error - conflicting buffer and attach arguments");
353#endif
354 sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments");
355 }
356 if (client == NULL)
357 {
358 if (optional_buffer == NULL)
359 {
360 int padding = (addr % sizeof (unsigned64));
361 unsigned long bytes = (modulo == 0 ? nr_bytes : modulo) + padding;
362 free_buffer = zalloc (bytes);
363 buffer = (char*) free_buffer + padding;
364 }
365 else
366 {
367 buffer = optional_buffer;
368 free_buffer = NULL;
369 }
370 }
371 else
372 {
373 /* a device */
374 buffer = NULL;
375 free_buffer = NULL;
376 }
377
378 /* attach the region to all applicable access maps */
028f6515 379 for (map = 0;
c906108c
SS
380 map < nr_maps;
381 map++)
382 {
383 if (mapmask & (1 << map))
384 {
385 sim_core_map_attach (sd, &memory->common.map[map],
386 level, space, addr, nr_bytes, modulo,
387 client, buffer, free_buffer);
388 free_buffer = NULL;
389 }
390 }
028f6515 391
c906108c
SS
392 /* Just copy this map to each of the processor specific data structures.
393 FIXME - later this will be replaced by true processor specific
394 maps. */
395 {
396 int i;
397 for (i = 0; i < MAX_NR_PROCESSORS; i++)
398 {
399 CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common;
400 }
401 }
402}
403#endif
404
405
406/* Remove any memory reference related to this address */
407#if EXTERN_SIM_CORE_P
408static void
409sim_core_map_detach (SIM_DESC sd,
410 sim_core_map *access_map,
411 int level,
412 int space,
413 address_word addr)
414{
415 sim_core_mapping **entry;
416 for (entry = &access_map->first;
417 (*entry) != NULL;
418 entry = &(*entry)->next)
419 {
420 if ((*entry)->base == addr
421 && (*entry)->level == level
422 && (*entry)->space == space)
423 {
424 sim_core_mapping *dead = (*entry);
425 (*entry) = dead->next;
426 if (dead->free_buffer != NULL)
d79fe0d6
MF
427 free (dead->free_buffer);
428 free (dead);
c906108c
SS
429 return;
430 }
431 }
432}
433#endif
434
435#if EXTERN_SIM_CORE_P
436void
437sim_core_detach (SIM_DESC sd,
438 sim_cpu *cpu,
439 int level,
440 int address_space,
441 address_word addr)
442{
443 sim_core *memory = STATE_CORE (sd);
444 unsigned map;
445 for (map = 0; map < nr_maps; map++)
446 {
447 sim_core_map_detach (sd, &memory->common.map[map],
448 level, address_space, addr);
449 }
450 /* Just copy this update to each of the processor specific data
451 structures. FIXME - later this will be replaced by true
452 processor specific maps. */
453 {
454 int i;
455 for (i = 0; i < MAX_NR_PROCESSORS; i++)
456 {
457 CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common;
458 }
459 }
460}
461#endif
462
463
464STATIC_INLINE_SIM_CORE\
465(sim_core_mapping *)
34b47c38
MF
466sim_core_find_mapping (sim_core_common *core,
467 unsigned map,
468 address_word addr,
469 unsigned nr_bytes,
470 transfer_type transfer,
471 int abort, /*either 0 or 1 - hint to inline/-O */
472 sim_cpu *cpu, /* abort => cpu != NULL */
473 sim_cia cia)
c906108c
SS
474{
475 sim_core_mapping *mapping = core->map[map].first;
476 ASSERT ((addr & (nr_bytes - 1)) == 0); /* must be aligned */
477 ASSERT ((addr + (nr_bytes - 1)) >= addr); /* must not wrap */
478 ASSERT (!abort || cpu != NULL); /* abort needs a non null CPU */
479 while (mapping != NULL)
480 {
481 if (addr >= mapping->base
482 && (addr + (nr_bytes - 1)) <= mapping->bound)
483 return mapping;
484 mapping = mapping->next;
485 }
486 if (abort)
487 {
488 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, nr_bytes, addr, transfer,
489 sim_core_unmapped_signal);
490 }
491 return NULL;
492}
493
494
495STATIC_INLINE_SIM_CORE\
496(void *)
497sim_core_translate (sim_core_mapping *mapping,
498 address_word addr)
499{
500 if (WITH_MODULO_MEMORY)
501 return (void *)((unsigned8 *) mapping->buffer
502 + ((addr - mapping->base) & mapping->mask));
503 else
504 return (void *)((unsigned8 *) mapping->buffer
505 + addr - mapping->base);
506}
507
508
509#if EXTERN_SIM_CORE_P
510unsigned
511sim_core_read_buffer (SIM_DESC sd,
512 sim_cpu *cpu,
513 unsigned map,
514 void *buffer,
515 address_word addr,
516 unsigned len)
517{
518 sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
519 unsigned count = 0;
520 while (count < len)
521 {
6bf91687 522 address_word raddr = addr + count;
c906108c
SS
523 sim_core_mapping *mapping =
524 sim_core_find_mapping (core, map,
525 raddr, /*nr-bytes*/1,
526 read_transfer,
527 0 /*dont-abort*/, NULL, NULL_CIA);
528 if (mapping == NULL)
529 break;
530#if (WITH_DEVICES)
531 if (mapping->device != NULL)
532 {
533 int nr_bytes = len - count;
7a292a7a 534 sim_cia cia = cpu ? CIA_GET (cpu) : NULL_CIA;
c906108c
SS
535 if (raddr + nr_bytes - 1> mapping->bound)
536 nr_bytes = mapping->bound - raddr + 1;
537 if (device_io_read_buffer (mapping->device,
538 (unsigned_1*)buffer + count,
539 mapping->space,
540 raddr,
028f6515 541 nr_bytes,
7a292a7a 542 sd,
028f6515 543 cpu,
7a292a7a 544 cia) != nr_bytes)
c906108c
SS
545 break;
546 count += nr_bytes;
547 continue;
548 }
549#endif
550#if (WITH_HW)
551 if (mapping->device != NULL)
552 {
553 int nr_bytes = len - count;
554 if (raddr + nr_bytes - 1> mapping->bound)
555 nr_bytes = mapping->bound - raddr + 1;
556 if (sim_hw_io_read_buffer (sd, mapping->device,
557 (unsigned_1*)buffer + count,
558 mapping->space,
559 raddr,
560 nr_bytes) != nr_bytes)
561 break;
562 count += nr_bytes;
563 continue;
564 }
565#endif
566 ((unsigned_1*)buffer)[count] =
34b47c38 567 *(unsigned_1*)sim_core_translate (mapping, raddr);
c906108c
SS
568 count += 1;
569 }
570 return count;
571}
572#endif
573
574
575#if EXTERN_SIM_CORE_P
576unsigned
577sim_core_write_buffer (SIM_DESC sd,
578 sim_cpu *cpu,
579 unsigned map,
580 const void *buffer,
581 address_word addr,
582 unsigned len)
583{
584 sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
585 unsigned count = 0;
586 while (count < len)
587 {
6bf91687 588 address_word raddr = addr + count;
c906108c
SS
589 sim_core_mapping *mapping =
590 sim_core_find_mapping (core, map,
591 raddr, /*nr-bytes*/1,
592 write_transfer,
593 0 /*dont-abort*/, NULL, NULL_CIA);
594 if (mapping == NULL)
595 break;
596#if (WITH_DEVICES)
597 if (WITH_CALLBACK_MEMORY
598 && mapping->device != NULL)
599 {
600 int nr_bytes = len - count;
7a292a7a 601 sim_cia cia = cpu ? CIA_GET (cpu) : NULL_CIA;
c906108c
SS
602 if (raddr + nr_bytes - 1 > mapping->bound)
603 nr_bytes = mapping->bound - raddr + 1;
604 if (device_io_write_buffer (mapping->device,
605 (unsigned_1*)buffer + count,
606 mapping->space,
607 raddr,
608 nr_bytes,
7a292a7a 609 sd,
028f6515 610 cpu,
7a292a7a 611 cia) != nr_bytes)
c906108c
SS
612 break;
613 count += nr_bytes;
614 continue;
615 }
616#endif
617#if (WITH_HW)
618 if (WITH_CALLBACK_MEMORY
619 && mapping->device != NULL)
620 {
621 int nr_bytes = len - count;
622 if (raddr + nr_bytes - 1 > mapping->bound)
623 nr_bytes = mapping->bound - raddr + 1;
624 if (sim_hw_io_write_buffer (sd, mapping->device,
625 (unsigned_1*)buffer + count,
626 mapping->space,
627 raddr,
628 nr_bytes) != nr_bytes)
629 break;
630 count += nr_bytes;
631 continue;
632 }
633#endif
34b47c38 634 *(unsigned_1*)sim_core_translate (mapping, raddr) =
c906108c
SS
635 ((unsigned_1*)buffer)[count];
636 count += 1;
637 }
638 return count;
639}
640#endif
641
642
643#if EXTERN_SIM_CORE_P
644void
645sim_core_set_xor (SIM_DESC sd,
646 sim_cpu *cpu,
647 int is_xor)
648{
649 /* set up the XOR map if required. */
650 if (WITH_XOR_ENDIAN) {
651 {
652 sim_core *core = STATE_CORE (sd);
653 sim_cpu_core *cpu_core = (cpu != NULL ? CPU_CORE (cpu) : NULL);
654 if (cpu_core != NULL)
655 {
656 int i = 1;
657 unsigned mask;
658 if (is_xor)
659 mask = WITH_XOR_ENDIAN - 1;
660 else
661 mask = 0;
662 while (i - 1 < WITH_XOR_ENDIAN)
663 {
664 cpu_core->xor[i-1] = mask;
665 mask = (mask << 1) & (WITH_XOR_ENDIAN - 1);
666 i = (i << 1);
667 }
668 }
669 else
670 {
671 if (is_xor)
672 core->byte_xor = WITH_XOR_ENDIAN - 1;
673 else
674 core->byte_xor = 0;
028f6515 675 }
c906108c
SS
676 }
677 }
678 else {
679 if (is_xor)
680 sim_engine_abort (sd, NULL, NULL_CIA,
681 "Attempted to enable xor-endian mode when permenantly disabled.");
682 }
683}
684#endif
685
686
687#if EXTERN_SIM_CORE_P
688static void
689reverse_n (unsigned_1 *dest,
690 const unsigned_1 *src,
691 int nr_bytes)
692{
693 int i;
694 for (i = 0; i < nr_bytes; i++)
695 {
696 dest [nr_bytes - i - 1] = src [i];
697 }
698}
699#endif
700
701
702#if EXTERN_SIM_CORE_P
703unsigned
704sim_core_xor_read_buffer (SIM_DESC sd,
705 sim_cpu *cpu,
706 unsigned map,
707 void *buffer,
708 address_word addr,
709 unsigned nr_bytes)
710{
711 address_word byte_xor = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->xor[0]);
712 if (!WITH_XOR_ENDIAN || !byte_xor)
713 return sim_core_read_buffer (sd, cpu, map, buffer, addr, nr_bytes);
714 else
715 /* only break up transfers when xor-endian is both selected and enabled */
716 {
717 unsigned_1 x[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero-sized array */
718 unsigned nr_transfered = 0;
719 address_word start = addr;
720 unsigned nr_this_transfer = (WITH_XOR_ENDIAN - (addr & ~(WITH_XOR_ENDIAN - 1)));
721 address_word stop;
722 /* initial and intermediate transfers are broken when they cross
723 an XOR endian boundary */
724 while (nr_transfered + nr_this_transfer < nr_bytes)
725 /* initial/intermediate transfers */
726 {
727 /* since xor-endian is enabled stop^xor defines the start
728 address of the transfer */
729 stop = start + nr_this_transfer - 1;
730 SIM_ASSERT (start <= stop);
731 SIM_ASSERT ((stop ^ byte_xor) <= (start ^ byte_xor));
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 nr_transfered += nr_this_transfer;
737 nr_this_transfer = WITH_XOR_ENDIAN;
738 start = stop + 1;
739 }
740 /* final transfer */
741 nr_this_transfer = nr_bytes - nr_transfered;
742 stop = start + nr_this_transfer - 1;
743 SIM_ASSERT (stop == (addr + nr_bytes - 1));
744 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
745 != nr_this_transfer)
746 return nr_transfered;
747 reverse_n (&((unsigned_1*)buffer)[nr_transfered], x, nr_this_transfer);
748 return nr_bytes;
749 }
750}
751#endif
028f6515
MF
752
753
c906108c
SS
754#if EXTERN_SIM_CORE_P
755unsigned
756sim_core_xor_write_buffer (SIM_DESC sd,
757 sim_cpu *cpu,
758 unsigned map,
759 const void *buffer,
760 address_word addr,
761 unsigned nr_bytes)
762{
763 address_word byte_xor = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->xor[0]);
764 if (!WITH_XOR_ENDIAN || !byte_xor)
765 return sim_core_write_buffer (sd, cpu, map, buffer, addr, nr_bytes);
766 else
767 /* only break up transfers when xor-endian is both selected and enabled */
768 {
769 unsigned_1 x[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero sized array */
770 unsigned nr_transfered = 0;
771 address_word start = addr;
772 unsigned nr_this_transfer = (WITH_XOR_ENDIAN - (addr & ~(WITH_XOR_ENDIAN - 1)));
773 address_word stop;
774 /* initial and intermediate transfers are broken when they cross
775 an XOR endian boundary */
776 while (nr_transfered + nr_this_transfer < nr_bytes)
777 /* initial/intermediate transfers */
778 {
779 /* since xor-endian is enabled stop^xor defines the start
780 address of the transfer */
781 stop = start + nr_this_transfer - 1;
782 SIM_ASSERT (start <= stop);
783 SIM_ASSERT ((stop ^ byte_xor) <= (start ^ byte_xor));
784 reverse_n (x, &((unsigned_1*)buffer)[nr_transfered], nr_this_transfer);
785 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
786 != nr_this_transfer)
787 return nr_transfered;
788 nr_transfered += nr_this_transfer;
789 nr_this_transfer = WITH_XOR_ENDIAN;
790 start = stop + 1;
791 }
792 /* final transfer */
793 nr_this_transfer = nr_bytes - nr_transfered;
794 stop = start + nr_this_transfer - 1;
795 SIM_ASSERT (stop == (addr + nr_bytes - 1));
796 reverse_n (x, &((unsigned_1*)buffer)[nr_transfered], nr_this_transfer);
797 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
798 != nr_this_transfer)
799 return nr_transfered;
800 return nr_bytes;
801 }
802}
803#endif
804
6edf0760
NC
805#if EXTERN_SIM_CORE_P
806void *
807sim_core_trans_addr (SIM_DESC sd,
808 sim_cpu *cpu,
809 unsigned map,
810 address_word addr)
811{
812 sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
813 sim_core_mapping *mapping =
814 sim_core_find_mapping (core, map,
815 addr, /*nr-bytes*/1,
816 write_transfer,
817 0 /*dont-abort*/, NULL, NULL_CIA);
818 if (mapping == NULL)
819 return NULL;
34b47c38 820 return sim_core_translate (mapping, addr);
6edf0760
NC
821}
822#endif
823
c906108c
SS
824
825
826/* define the read/write 1/2/4/8/16/word functions */
827
828#define N 16
829#include "sim-n-core.h"
830
831#define N 8
832#include "sim-n-core.h"
833
834#define N 7
835#define M 8
836#include "sim-n-core.h"
837
838#define N 6
839#define M 8
840#include "sim-n-core.h"
841
842#define N 5
843#define M 8
844#include "sim-n-core.h"
845
846#define N 4
847#include "sim-n-core.h"
848
849#define N 3
850#define M 4
851#include "sim-n-core.h"
852
853#define N 2
854#include "sim-n-core.h"
855
856#define N 1
857#include "sim-n-core.h"
858
859#endif