Home | History | Annotate | Line # | Download | only in gdb.base
ovlymgr.c revision 1.3
      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.  */
     10 bool
     11 OverlayLoad (unsigned long ovlyno)
     12 {
     13 }
     14 bool
     15 OverlayUnload (unsigned long ovlyno)
     16 {
     17 }
     18 #else /* __SPU__ */
     19 
     20 /* Local functions and data: */
     21 
     22 extern unsigned long _ovly_table[][4];
     23 extern unsigned long _novlys __attribute__ ((section (".data")));
     24 enum ovly_index { VMA, SIZE, LMA, MAPPED};
     25 
     26 static 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 
     36 static void
     37 FlushCache (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  */
     49 static 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 
     59 bool
     60 OverlayLoad (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 
     91 bool
     92 OverlayUnload (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 
    113 static void
    114 D10VTranslate (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 
    207 static void
    208 ovly_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