• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/gdb/gdb/testsuite/gdb.base/
1
2/*
3 * Ovlymgr.c -- Runtime Overlay Manager for the GDB testsuite.
4 */
5
6#include "ovlymgr.h"
7
8#ifdef __SPU__
9/* SPU tool chain provides its own overlay manager.  */
10bool
11OverlayLoad (unsigned long ovlyno)
12{
13}
14bool
15OverlayUnload (unsigned long ovlyno)
16{
17}
18#else /* __SPU__ */
19
20/* Local functions and data: */
21
22extern unsigned long _ovly_table[][4];
23extern unsigned long _novlys __attribute__ ((section (".data")));
24enum ovly_index { VMA, SIZE, LMA, MAPPED};
25
26static void ovly_copy (unsigned long dst, unsigned long src, long size);
27
28/* Flush the data and instruction caches at address START for SIZE bytes.
29   Support for each new port must be added here.  */
30/* FIXME: Might be better to have a standard libgloss function that
31   ports provide that we can then use.  Use libgloss instead of newlib
32   since libgloss is the one intended to handle low level system issues.
33   I would suggest something like _flush_cache to avoid the user's namespace
34   but not be completely obscure as other things may need this facility.  */
35
36static void
37FlushCache (void)
38{
39#ifdef __M32R__
40  volatile char *mspr = (char *) 0xfffffff7;
41  *mspr = 1;
42#endif
43}
44
45/* _ovly_debug_event:
46 * Debuggers may set a breakpoint here, to be notified
47 * when the overlay table has been modified.
48 */
49static void
50_ovly_debug_event (void)
51{
52}
53
54/* OverlayLoad:
55 * Copy the overlay into its runtime region,
56 * and mark the overlay as "mapped".
57 */
58
59bool
60OverlayLoad (unsigned long ovlyno)
61{
62  unsigned long i;
63
64  if (ovlyno < 0 || ovlyno >= _novlys)
65    exit (-1);	/* fail, bad ovly number */
66
67  if (_ovly_table[ovlyno][MAPPED])
68    return TRUE;	/* this overlay already mapped -- nothing to do! */
69
70  for (i = 0; i < _novlys; i++)
71    if (i == ovlyno)
72      _ovly_table[i][MAPPED] = 1;	/* this one now mapped */
73    else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
74      _ovly_table[i][MAPPED] = 0;	/* this one now un-mapped */
75
76  ovly_copy (_ovly_table[ovlyno][VMA],
77	     _ovly_table[ovlyno][LMA],
78	     _ovly_table[ovlyno][SIZE]);
79
80  FlushCache ();
81  _ovly_debug_event ();
82  return TRUE;
83}
84
85/* OverlayUnload:
86 * Copy the overlay back into its "load" region.
87 * Does NOT mark overlay as "unmapped", therefore may be called
88 * more than once for the same mapped overlay.
89 */
90
91bool
92OverlayUnload (unsigned long ovlyno)
93{
94  if (ovlyno < 0 || ovlyno >= _novlys)
95    exit (-1);  /* fail, bad ovly number */
96
97  if (!_ovly_table[ovlyno][MAPPED])
98    exit (-1);  /* error, can't copy out a segment that's not "in" */
99
100  ovly_copy (_ovly_table[ovlyno][LMA],
101	     _ovly_table[ovlyno][VMA],
102	     _ovly_table[ovlyno][SIZE]);
103
104  _ovly_debug_event ();
105  return TRUE;
106}
107
108#ifdef __D10V__
109#define IMAP0       (*(short *)(0xff00))
110#define IMAP1       (*(short *)(0xff02))
111#define DMAP        (*(short *)(0xff04))
112
113static void
114D10VTranslate (unsigned long logical,
115	       short *dmap,
116	       unsigned long **addr)
117{
118  unsigned long physical;
119  unsigned long seg;
120  unsigned long off;
121
122  /* to access data, we use the following mapping
123     0x00xxxxxx: Logical data address segment        (DMAP translated memory)
124     0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
125     0x10xxxxxx: Physical data memory segment        (On-chip data memory)
126     0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
127     0x12xxxxxx: Phisical unified memory segment     (Unified memory)
128     */
129
130  /* Addresses must be correctly aligned */
131  if (logical & (sizeof (**addr) - 1))
132    exit (-1);
133
134  /* If the address is in one of the two logical address spaces, it is
135     first translated into a physical address */
136  seg = (logical >> 24);
137  off = (logical & 0xffffffL);
138  switch (seg)
139      {
140      case 0x00: /* in logical data address segment */
141	if (off <= 0x7fffL)
142	  physical = (0x10L << 24) + off;
143	else
144	  /* Logical address out side of on-chip segment, not
145             supported */
146	  exit (-1);
147	break;
148      case 0x01: /* in logical instruction address segment */
149	{
150	  short map;
151	  if (off <= 0x1ffffL)
152	    map = IMAP0;
153	  else if (off <= 0x3ffffL)
154	    map = IMAP1;
155	  else
156	    /* Logical address outside of IMAP[01] segment, not
157	       supported */
158	    exit (-1);
159	  if (map & 0x1000L)
160	    {
161	    /* Instruction memory */
162	      physical = (0x11L << 24) | off;
163	    }
164	  else
165	    {
166	    /* Unified memory */
167	      physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
168	      if (physical > 0xffffffL)
169		/* Address outside of unified address segment */
170		exit (-1);
171	      physical |= (0x12L << 24);
172	    }
173	  break;
174	}
175      case 0x10:
176      case 0x11:
177      case 0x12:
178	physical = logical;
179	break;
180      default:
181	exit (-1);	/* error */
182      }
183
184  seg = (physical >> 24);
185  off = (physical & 0xffffffL);
186  switch (seg)
187    {
188    case 0x10:	/* dst is a 15 bit offset into the on-chip memory */
189      *dmap = 0;
190      *addr = (long *) (0x0000 + ((short)off & 0x7fff));
191      break;
192    case 0x11:	/* dst is an 18-bit offset into the on-chip
193		   instruction memory */
194      *dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
195      *addr = (long *) (0x8000 + ((short)off & 0x3fff));
196      break;
197    case 0x12:	/* dst is a 24-bit offset into unified memory */
198      *dmap = off >> 14;
199      *addr = (long *) (0x8000 + ((short)off & 0x3fff));
200      break;
201    default:
202      exit (-1);	/* error */
203    }
204}
205#endif /* __D10V__ */
206
207static void
208ovly_copy (unsigned long dst, unsigned long src, long size)
209{
210#ifdef  __D10V__
211  unsigned long *s, *d, tmp;
212  short dmap_src, dmap_dst;
213  short dmap_save;
214
215  /* all section sizes should by multiples of 4 bytes */
216  dmap_save = DMAP;
217
218  D10VTranslate (src, &dmap_src, &s);
219  D10VTranslate (dst, &dmap_dst, &d);
220
221  while (size > 0)
222    {
223      /* NB: Transfer 4 byte (long) quantites, problems occure
224	 when only two bytes are transfered */
225      DMAP = dmap_src;
226      tmp = *s;
227      DMAP = dmap_dst;
228      *d = tmp;
229      d++;
230      s++;
231      size -= sizeof (tmp);
232      src += sizeof (tmp);
233      dst += sizeof (tmp);
234      if ((src & 0x3fff) == 0)
235	D10VTranslate (src, &dmap_src, &s);
236      if ((dst & 0x3fff) == 0)
237	D10VTranslate (dst, &dmap_dst, &d);
238    }
239  DMAP = dmap_save;
240#else
241  memcpy ((void *) dst, (void *) src, size);
242#endif /* D10V */
243  return;
244}
245
246#endif /* __SPU__ */
247