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