1 /* The common simulator framework for GDB, the GNU Debugger.
3 Copyright 2002-2024 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney and Red Hat.
7 This file is part of GDB.
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.
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.
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/>. */
26 /* This must come before any other includes. */
31 #include "libiberty.h"
34 #include "sim-assert.h"
35 #include "sim-signal.h"
41 /* "core" module install handler.
43 This is called via sim_module_install to install the "core"
44 subsystem into the simulator. */
47 static MODULE_INIT_FN sim_core_init
;
48 static MODULE_UNINSTALL_FN sim_core_uninstall
;
53 sim_core_install (SIM_DESC sd
)
55 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
57 /* establish the other handlers */
58 sim_module_add_uninstall_fn (sd
, sim_core_uninstall
);
59 sim_module_add_init_fn (sd
, sim_core_init
);
61 /* establish any initial data structures - none */
67 /* Uninstall the "core" subsystem from the simulator. */
71 sim_core_uninstall (SIM_DESC sd
)
73 sim_core
*core
= STATE_CORE (sd
);
75 /* blow away any mappings */
76 for (map
= 0; map
< nr_maps
; map
++) {
77 sim_core_mapping
*curr
= core
->common
.map
[map
].first
;
78 while (curr
!= NULL
) {
79 sim_core_mapping
*tbd
= curr
;
81 if (tbd
->free_buffer
!= NULL
) {
82 SIM_ASSERT (tbd
->buffer
!= NULL
);
83 free (tbd
->free_buffer
);
87 core
->common
.map
[map
].first
= NULL
;
95 sim_core_init (SIM_DESC sd
)
104 #ifndef SIM_CORE_SIGNAL
105 #define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
106 sim_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
109 #if EXTERN_SIM_CORE_P
111 sim_core_signal (SIM_DESC sd
,
117 transfer_type transfer
,
118 sim_core_signals sig
)
120 const char *copy
= (transfer
== read_transfer
? "read" : "write");
121 address_word ip
= CIA_ADDR (cia
);
124 case sim_core_unmapped_signal
:
125 sim_io_eprintf (sd
, "core: %d byte %s to unmapped 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_SIGSEGV
);
129 case sim_core_unaligned_signal
:
130 sim_io_eprintf (sd
, "core: %d byte misaligned %s to address 0x%lx at 0x%lx\n",
131 nr_bytes
, copy
, (unsigned long) addr
, (unsigned long) ip
);
132 sim_engine_halt (sd
, cpu
, NULL
, cia
, sim_stopped
, SIM_SIGBUS
);
135 sim_engine_abort (sd
, cpu
, cia
,
136 "sim_core_signal - internal error - bad switch");
142 #if EXTERN_SIM_CORE_P
143 static sim_core_mapping
*
144 new_sim_core_mapping (SIM_DESC sd
,
148 address_word nr_bytes
,
154 sim_core_mapping
*new_mapping
= ZALLOC (sim_core_mapping
);
156 new_mapping
->level
= level
;
157 new_mapping
->space
= space
;
158 new_mapping
->base
= addr
;
159 new_mapping
->nr_bytes
= nr_bytes
;
160 new_mapping
->bound
= addr
+ (nr_bytes
- 1);
161 new_mapping
->mask
= modulo
- 1;
162 new_mapping
->buffer
= buffer
;
163 new_mapping
->free_buffer
= free_buffer
;
164 new_mapping
->device
= device
;
170 #if EXTERN_SIM_CORE_P
172 sim_core_map_attach (SIM_DESC sd
,
173 sim_core_map
*access_map
,
177 address_word nr_bytes
,
179 struct hw
*client
, /*callback/default*/
180 void *buffer
, /*raw_memory*/
181 void *free_buffer
) /*raw_memory*/
183 /* find the insertion point for this additional mapping and then
185 sim_core_mapping
*next_mapping
;
186 sim_core_mapping
**last_mapping
;
188 SIM_ASSERT ((client
== NULL
) != (buffer
== NULL
));
189 SIM_ASSERT ((client
== NULL
) >= (free_buffer
!= NULL
));
191 /* actually do occasionally get a zero size map */
195 sim_hw_abort (sd
, client
, "called on sim_core_map_attach with size zero");
197 sim_io_error (sd
, "called on sim_core_map_attach with size zero");
200 /* find the insertion point (between last/next) */
201 next_mapping
= access_map
->first
;
202 last_mapping
= &access_map
->first
;
203 while (next_mapping
!= NULL
204 && (next_mapping
->level
< level
205 || (next_mapping
->level
== level
206 && next_mapping
->bound
< addr
)))
208 /* provided levels are the same */
209 /* assert: next_mapping->base > all bases before next_mapping */
210 /* assert: next_mapping->bound >= all bounds before next_mapping */
211 last_mapping
= &next_mapping
->next
;
212 next_mapping
= next_mapping
->next
;
215 /* check insertion point correct */
216 SIM_ASSERT (next_mapping
== NULL
|| next_mapping
->level
>= level
);
217 if (next_mapping
!= NULL
&& next_mapping
->level
== level
218 && next_mapping
->base
< (addr
+ (nr_bytes
- 1)))
221 sim_hw_abort (sd
, client
, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
224 (long) (addr
+ (nr_bytes
- 1)),
227 (long) next_mapping
->base
,
228 (long) next_mapping
->bound
,
229 (long) next_mapping
->nr_bytes
);
231 sim_io_error (sd
, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
234 (long) (addr
+ (nr_bytes
- 1)),
237 (long) next_mapping
->base
,
238 (long) next_mapping
->bound
,
239 (long) next_mapping
->nr_bytes
);
242 /* create/insert the new mapping */
243 *last_mapping
= new_sim_core_mapping (sd
,
245 space
, addr
, nr_bytes
, modulo
,
246 client
, buffer
, free_buffer
);
247 (*last_mapping
)->next
= next_mapping
;
252 /* Attach memory or a memory mapped device to the simulator.
253 See sim-core.h for a full description. */
255 #if EXTERN_SIM_CORE_P
257 sim_core_attach (SIM_DESC sd
,
263 address_word nr_bytes
,
266 void *optional_buffer
)
268 sim_core
*memory
= STATE_CORE (sd
);
273 /* check for for attempt to use unimplemented per-processor core map */
275 sim_io_error (sd
, "sim_core_map_attach - processor specific memory map not yet supported");
277 if (client
!= NULL
&& modulo
!= 0)
280 sim_hw_abort (sd
, client
, "sim_core_attach - internal error - modulo and callback memory conflict");
282 sim_io_error (sd
, "sim_core_attach - internal error - modulo and callback memory conflict");
286 unsigned mask
= modulo
- 1;
288 while (mask
>= sizeof (uint64_t)) /* minimum modulo */
295 if (mask
!= sizeof (uint64_t) - 1)
298 sim_hw_abort (sd
, client
, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo
);
300 sim_io_error (sd
, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo
);
304 /* verify consistency between device and buffer */
305 if (client
!= NULL
&& optional_buffer
!= NULL
)
308 sim_hw_abort (sd
, client
, "sim_core_attach - internal error - conflicting buffer and attach arguments");
310 sim_io_error (sd
, "sim_core_attach - internal error - conflicting buffer and attach arguments");
314 if (optional_buffer
== NULL
)
316 int padding
= (addr
% sizeof (uint64_t));
317 unsigned long bytes
= (modulo
== 0 ? nr_bytes
: modulo
) + padding
;
318 free_buffer
= zalloc (bytes
);
319 buffer
= (char*) free_buffer
+ padding
;
323 buffer
= optional_buffer
;
334 /* attach the region to all applicable access maps */
339 if (mapmask
& (1 << map
))
341 sim_core_map_attach (sd
, &memory
->common
.map
[map
],
342 level
, space
, addr
, nr_bytes
, modulo
,
343 client
, buffer
, free_buffer
);
348 /* Just copy this map to each of the processor specific data structures.
349 FIXME - later this will be replaced by true processor specific
353 for (i
= 0; i
< MAX_NR_PROCESSORS
; i
++)
355 CPU_CORE (STATE_CPU (sd
, i
))->common
= STATE_CORE (sd
)->common
;
362 /* Remove any memory reference related to this address */
363 #if EXTERN_SIM_CORE_P
365 sim_core_map_detach (SIM_DESC sd
,
366 sim_core_map
*access_map
,
371 sim_core_mapping
**entry
;
372 for (entry
= &access_map
->first
;
374 entry
= &(*entry
)->next
)
376 if ((*entry
)->base
== addr
377 && (*entry
)->level
== level
378 && (*entry
)->space
== space
)
380 sim_core_mapping
*dead
= (*entry
);
381 (*entry
) = dead
->next
;
382 if (dead
->free_buffer
!= NULL
)
383 free (dead
->free_buffer
);
391 #if EXTERN_SIM_CORE_P
393 sim_core_detach (SIM_DESC sd
,
399 sim_core
*memory
= STATE_CORE (sd
);
401 for (map
= 0; map
< nr_maps
; map
++)
403 sim_core_map_detach (sd
, &memory
->common
.map
[map
],
404 level
, address_space
, addr
);
406 /* Just copy this update to each of the processor specific data
407 structures. FIXME - later this will be replaced by true
408 processor specific maps. */
411 for (i
= 0; i
< MAX_NR_PROCESSORS
; i
++)
413 CPU_CORE (STATE_CPU (sd
, i
))->common
= STATE_CORE (sd
)->common
;
420 STATIC_INLINE_SIM_CORE\
422 sim_core_find_mapping (sim_core_common
*core
,
426 transfer_type transfer
,
427 int abort
, /*either 0 or 1 - hint to inline/-O */
428 sim_cpu
*cpu
, /* abort => cpu != NULL */
431 sim_core_mapping
*mapping
= core
->map
[map
].first
;
432 ASSERT ((addr
& (nr_bytes
- 1)) == 0); /* must be aligned */
433 ASSERT ((addr
+ (nr_bytes
- 1)) >= addr
); /* must not wrap */
434 ASSERT (!abort
|| cpu
!= NULL
); /* abort needs a non null CPU */
435 while (mapping
!= NULL
)
437 if (addr
>= mapping
->base
438 && (addr
+ (nr_bytes
- 1)) <= mapping
->bound
)
440 mapping
= mapping
->next
;
444 SIM_CORE_SIGNAL (CPU_STATE (cpu
), cpu
, cia
, map
, nr_bytes
, addr
, transfer
,
445 sim_core_unmapped_signal
);
451 STATIC_INLINE_SIM_CORE\
453 sim_core_translate (sim_core_mapping
*mapping
,
456 return (void *)((uint8_t *) mapping
->buffer
457 + ((addr
- mapping
->base
) & mapping
->mask
));
461 #if EXTERN_SIM_CORE_P
462 /* See include/sim/sim.h. */
464 sim_memory_map (SIM_DESC sd
)
466 sim_core
*core
= STATE_CORE (sd
);
468 char *s1
, *s2
, *entry
;
471 "<?xml version='1.0'?>\n"
472 "<!DOCTYPE memory-map PUBLIC '+//IDN gnu.org//DTD GDB Memory Map V1.0//EN'"
473 " 'http://sourceware.org/gdb/gdb-memory-map.dtd'>\n"
476 for (map
= 0; map
< nr_maps
; ++map
)
478 sim_core_mapping
*mapping
;
480 for (mapping
= core
->common
.map
[map
].first
;
482 mapping
= mapping
->next
)
484 /* GDB can only handle a single address space. */
485 if (mapping
->level
!= 0)
488 entry
= xasprintf ("<memory type='ram' start='%#" PRIxTW
"' "
489 "length='%#" PRIxTW
"'/>\n",
490 mapping
->base
, mapping
->nr_bytes
);
491 /* The sim memory map is organized by access, not by addresses.
492 So a RWX memory map will have three independent mappings.
493 GDB's format cannot support overlapping regions, so we have
496 Further, GDB can only handle RX ("rom") or RWX ("ram") mappings.
497 We just emit "ram" everywhere to keep it simple. If GDB ever
498 gains support for more stuff, we can expand this.
500 Using strstr is kind of hacky, but as long as the map is not huge
501 (we're talking <10K), should be fine. */
502 if (strstr (s1
, entry
) == NULL
)
504 s2
= concat (s1
, entry
, NULL
);
512 s2
= concat (s1
, "</memory-map>", NULL
);
519 #if EXTERN_SIM_CORE_P
521 sim_core_read_buffer (SIM_DESC sd
,
528 sim_core_common
*core
= (cpu
== NULL
? &STATE_CORE (sd
)->common
: &CPU_CORE (cpu
)->common
);
532 address_word raddr
= addr
+ count
;
533 sim_core_mapping
*mapping
=
534 sim_core_find_mapping (core
, map
,
535 raddr
, /*nr-bytes*/1,
537 0 /*dont-abort*/, NULL
, NULL_CIA
);
541 if (mapping
->device
!= NULL
)
543 int nr_bytes
= len
- count
;
544 if (raddr
+ nr_bytes
- 1> mapping
->bound
)
545 nr_bytes
= mapping
->bound
- raddr
+ 1;
546 /* If the access was initiated by a cpu, pass it down so errors can
547 be propagated properly. For other sources (e.g. GDB or DMA), we
548 can only signal errors via the return value. */
551 sim_cia cia
= cpu
? CPU_PC_GET (cpu
) : NULL_CIA
;
552 sim_cpu_hw_io_read_buffer (cpu
, cia
, mapping
->device
,
553 (unsigned_1
*)buffer
+ count
,
558 else if (sim_hw_io_read_buffer (sd
, mapping
->device
,
559 (unsigned_1
*)buffer
+ count
,
562 nr_bytes
) != nr_bytes
)
568 ((unsigned_1
*)buffer
)[count
] =
569 *(unsigned_1
*)sim_core_translate (mapping
, raddr
);
577 #if EXTERN_SIM_CORE_P
579 sim_core_write_buffer (SIM_DESC sd
,
586 sim_core_common
*core
= (cpu
== NULL
? &STATE_CORE (sd
)->common
: &CPU_CORE (cpu
)->common
);
590 address_word raddr
= addr
+ count
;
591 sim_core_mapping
*mapping
=
592 sim_core_find_mapping (core
, map
,
593 raddr
, /*nr-bytes*/1,
595 0 /*dont-abort*/, NULL
, NULL_CIA
);
599 if (mapping
->device
!= NULL
)
601 int nr_bytes
= len
- count
;
602 if (raddr
+ nr_bytes
- 1 > mapping
->bound
)
603 nr_bytes
= mapping
->bound
- raddr
+ 1;
604 /* If the access was initiated by a cpu, pass it down so errors can
605 be propagated properly. For other sources (e.g. GDB or DMA), we
606 can only signal errors via the return value. */
609 sim_cia cia
= cpu
? CPU_PC_GET (cpu
) : NULL_CIA
;
610 sim_cpu_hw_io_write_buffer (cpu
, cia
, mapping
->device
,
611 (unsigned_1
*)buffer
+ count
,
616 else if (sim_hw_io_write_buffer (sd
, mapping
->device
,
617 (unsigned_1
*)buffer
+ count
,
620 nr_bytes
) != nr_bytes
)
626 *(unsigned_1
*)sim_core_translate (mapping
, raddr
) =
627 ((unsigned_1
*)buffer
)[count
];
635 #if EXTERN_SIM_CORE_P
637 sim_core_set_xor (SIM_DESC sd
,
641 /* set up the XOR map if required. */
642 if (WITH_XOR_ENDIAN
) {
644 sim_core
*core
= STATE_CORE (sd
);
645 sim_cpu_core
*cpu_core
= (cpu
!= NULL
? CPU_CORE (cpu
) : NULL
);
646 if (cpu_core
!= NULL
)
651 mask
= WITH_XOR_ENDIAN
- 1;
654 while (i
- 1 < WITH_XOR_ENDIAN
)
656 cpu_core
->byte_xor
[i
-1] = mask
;
657 mask
= (mask
<< 1) & (WITH_XOR_ENDIAN
- 1);
664 core
->byte_xor
= WITH_XOR_ENDIAN
- 1;
672 sim_engine_abort (sd
, NULL
, NULL_CIA
,
673 "Attempted to enable xor-endian mode when permanently disabled.");
679 #if EXTERN_SIM_CORE_P
681 reverse_n (unsigned_1
*dest
,
682 const unsigned_1
*src
,
686 for (i
= 0; i
< nr_bytes
; i
++)
688 dest
[nr_bytes
- i
- 1] = src
[i
];
694 #if EXTERN_SIM_CORE_P
696 sim_core_xor_read_buffer (SIM_DESC sd
,
703 address_word byte_xor
704 = (cpu
== NULL
? STATE_CORE (sd
)->byte_xor
: CPU_CORE (cpu
)->byte_xor
[0]);
705 if (!WITH_XOR_ENDIAN
|| !byte_xor
)
706 return sim_core_read_buffer (sd
, cpu
, map
, buffer
, addr
, nr_bytes
);
708 /* only break up transfers when xor-endian is both selected and enabled */
710 unsigned_1 x
[WITH_XOR_ENDIAN
+ 1]; /* +1 to avoid zero-sized array */
711 unsigned nr_transfered
= 0;
712 address_word start
= addr
;
713 unsigned nr_this_transfer
= (WITH_XOR_ENDIAN
- (addr
& ~(WITH_XOR_ENDIAN
- 1)));
715 /* initial and intermediate transfers are broken when they cross
716 an XOR endian boundary */
717 while (nr_transfered
+ nr_this_transfer
< nr_bytes
)
718 /* initial/intermediate transfers */
720 /* since xor-endian is enabled stop^xor defines the start
721 address of the transfer */
722 stop
= start
+ nr_this_transfer
- 1;
723 SIM_ASSERT (start
<= stop
);
724 SIM_ASSERT ((stop
^ byte_xor
) <= (start
^ byte_xor
));
725 if (sim_core_read_buffer (sd
, cpu
, map
, x
, stop
^ byte_xor
, nr_this_transfer
)
727 return nr_transfered
;
728 reverse_n (&((unsigned_1
*)buffer
)[nr_transfered
], x
, nr_this_transfer
);
729 nr_transfered
+= nr_this_transfer
;
730 nr_this_transfer
= WITH_XOR_ENDIAN
;
734 nr_this_transfer
= nr_bytes
- nr_transfered
;
735 stop
= start
+ nr_this_transfer
- 1;
736 SIM_ASSERT (stop
== (addr
+ nr_bytes
- 1));
737 if (sim_core_read_buffer (sd
, cpu
, map
, x
, stop
^ byte_xor
, nr_this_transfer
)
739 return nr_transfered
;
740 reverse_n (&((unsigned_1
*)buffer
)[nr_transfered
], x
, nr_this_transfer
);
747 #if EXTERN_SIM_CORE_P
749 sim_core_xor_write_buffer (SIM_DESC sd
,
756 address_word byte_xor
757 = (cpu
== NULL
? STATE_CORE (sd
)->byte_xor
: CPU_CORE (cpu
)->byte_xor
[0]);
758 if (!WITH_XOR_ENDIAN
|| !byte_xor
)
759 return sim_core_write_buffer (sd
, cpu
, map
, buffer
, addr
, nr_bytes
);
761 /* only break up transfers when xor-endian is both selected and enabled */
763 unsigned_1 x
[WITH_XOR_ENDIAN
+ 1]; /* +1 to avoid zero sized array */
764 unsigned nr_transfered
= 0;
765 address_word start
= addr
;
766 unsigned nr_this_transfer
= (WITH_XOR_ENDIAN
- (addr
& ~(WITH_XOR_ENDIAN
- 1)));
768 /* initial and intermediate transfers are broken when they cross
769 an XOR endian boundary */
770 while (nr_transfered
+ nr_this_transfer
< nr_bytes
)
771 /* initial/intermediate transfers */
773 /* since xor-endian is enabled stop^xor defines the start
774 address of the transfer */
775 stop
= start
+ nr_this_transfer
- 1;
776 SIM_ASSERT (start
<= stop
);
777 SIM_ASSERT ((stop
^ byte_xor
) <= (start
^ byte_xor
));
778 reverse_n (x
, &((unsigned_1
*)buffer
)[nr_transfered
], nr_this_transfer
);
779 if (sim_core_read_buffer (sd
, cpu
, map
, x
, stop
^ byte_xor
, nr_this_transfer
)
781 return nr_transfered
;
782 nr_transfered
+= nr_this_transfer
;
783 nr_this_transfer
= WITH_XOR_ENDIAN
;
787 nr_this_transfer
= nr_bytes
- nr_transfered
;
788 stop
= start
+ nr_this_transfer
- 1;
789 SIM_ASSERT (stop
== (addr
+ nr_bytes
- 1));
790 reverse_n (x
, &((unsigned_1
*)buffer
)[nr_transfered
], nr_this_transfer
);
791 if (sim_core_read_buffer (sd
, cpu
, map
, x
, stop
^ byte_xor
, nr_this_transfer
)
793 return nr_transfered
;
799 #if EXTERN_SIM_CORE_P
801 sim_core_trans_addr (SIM_DESC sd
,
806 sim_core_common
*core
= (cpu
== NULL
? &STATE_CORE (sd
)->common
: &CPU_CORE (cpu
)->common
);
807 sim_core_mapping
*mapping
=
808 sim_core_find_mapping (core
, map
,
811 0 /*dont-abort*/, NULL
, NULL_CIA
);
814 return sim_core_translate (mapping
, addr
);
820 /* define the read/write 1/2/4/8/16/word functions */
823 #include "sim-n-core.h"
826 #include "sim-n-core.h"
830 #include "sim-n-core.h"
834 #include "sim-n-core.h"
838 #include "sim-n-core.h"
841 #include "sim-n-core.h"
845 #include "sim-n-core.h"
848 #include "sim-n-core.h"
851 #include "sim-n-core.h"