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