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
41static MODULE_INIT_FN sim_core_init;
42static MODULE_UNINSTALL_FN sim_core_uninstall;
43#endif
44
45#if EXTERN_SIM_CORE_P
46SIM_RC
47sim_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
64static void
65sim_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
88static SIM_RC
89sim_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) \
100sim_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
101#endif
102
103#if EXTERN_SIM_CORE_P
104void
105sim_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
137static sim_core_mapping *
138new_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
165static void
166sim_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
250void
251sim_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
358static void
359sim_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
386void
387sim_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
414STATIC_INLINE_SIM_CORE\
415(sim_core_mapping *)
416sim_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
445STATIC_INLINE_SIM_CORE\
446(void *)
447sim_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
456unsigned
457sim_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
514unsigned
515sim_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
572void
573sim_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
616static void
617reverse_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
631unsigned
632sim_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
684unsigned
685sim_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
736void *
737sim_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