
/*
 * Ovlymgr.c -- Runtime Overlay Manager for the GDB testsuite.
 */

#include "ovlymgr.h"

/* Local functions and data: */

extern unsigned long _ovly_table[][4];
extern unsigned long _novlys __attribute__ ((section (".data")));
enum ovly_index { VMA, SIZE, LMA, MAPPED};

static void ovly_copy (unsigned long dst, unsigned long src, long size);

/* Flush the data and instruction caches at address START for SIZE bytes.
   Support for each new port must be added here.  */
/* FIXME: Might be better to have a standard libgloss function that
   ports provide that we can then use.  Use libgloss instead of newlib
   since libgloss is the one intended to handle low level system issues.
   I would suggest something like _flush_cache to avoid the user's namespace
   but not be completely obscure as other things may need this facility.  */
 
static void
FlushCache (void)
{
#ifdef __M32R__
  volatile char *mspr = (char *) 0xfffffff7;
  *mspr = 1;
#endif
}

/* _ovly_debug_event:
 * Debuggers may set a breakpoint here, to be notified 
 * when the overlay table has been modified.
 */
static void
_ovly_debug_event (void)
{
}

/* OverlayLoad:
 * Copy the overlay into its runtime region,
 * and mark the overlay as "mapped".
 */

bool
OverlayLoad (unsigned long ovlyno)
{
  unsigned long i;

  if (ovlyno < 0 || ovlyno >= _novlys)
    exit (-1);	/* fail, bad ovly number */

  if (_ovly_table[ovlyno][MAPPED])
    return TRUE;	/* this overlay already mapped -- nothing to do! */

  for (i = 0; i < _novlys; i++)
    if (i == ovlyno)
      _ovly_table[i][MAPPED] = 1;	/* this one now mapped */
    else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
      _ovly_table[i][MAPPED] = 0;	/* this one now un-mapped */

  ovly_copy (_ovly_table[ovlyno][VMA], 
	     _ovly_table[ovlyno][LMA], 
	     _ovly_table[ovlyno][SIZE]);

  FlushCache ();
  _ovly_debug_event ();
  return TRUE;
}

/* OverlayUnload:
 * Copy the overlay back into its "load" region.
 * Does NOT mark overlay as "unmapped", therefore may be called
 * more than once for the same mapped overlay.
 */
 
bool
OverlayUnload (unsigned long ovlyno)
{
  if (ovlyno < 0 || ovlyno >= _novlys)
    exit (-1);  /* fail, bad ovly number */
 
  if (!_ovly_table[ovlyno][MAPPED])
    exit (-1);  /* error, can't copy out a segment that's not "in" */
 
  ovly_copy (_ovly_table[ovlyno][LMA], 
	     _ovly_table[ovlyno][VMA],
	     _ovly_table[ovlyno][SIZE]);

  _ovly_debug_event ();
  return TRUE;
}

#ifdef __D10V__
#define IMAP0       (*(short *)(0xff00))
#define IMAP1       (*(short *)(0xff02))
#define DMAP        (*(short *)(0xff04))

static void
D10VTranslate (unsigned long logical,
	       short *dmap,
	       unsigned long **addr)
{
  unsigned long physical;
  unsigned long seg;
  unsigned long off;

  /* to access data, we use the following mapping 
     0x00xxxxxx: Logical data address segment        (DMAP translated memory)
     0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
     0x10xxxxxx: Physical data memory segment        (On-chip data memory)
     0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
     0x12xxxxxx: Phisical unified memory segment     (Unified memory)
     */

  /* Addresses must be correctly aligned */
  if (logical & (sizeof (**addr) - 1))
    exit (-1);

  /* If the address is in one of the two logical address spaces, it is
     first translated into a physical address */
  seg = (logical >> 24);
  off = (logical & 0xffffffL);
  switch (seg) 
      {
      case 0x00: /* in logical data address segment */
	if (off <= 0x7fffL)
	  physical = (0x10L << 24) + off;
	else
	  /* Logical address out side of on-chip segment, not
             supported */
	  exit (-1);
	break;
      case 0x01: /* in logical instruction address segment */
	{
	  short map;
	  if (off <= 0x1ffffL)
	    map = IMAP0;
	  else if (off <= 0x3ffffL)
	    map = IMAP1;
	  else
	    /* Logical address outside of IMAP[01] segment, not
	       supported */
	    exit (-1);
	  if (map & 0x1000L)
	    {
	    /* Instruction memory */
	      physical = (0x11L << 24) | off;
	    }
	  else
	    {
	    /* Unified memory */
	      physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
	      if (physical > 0xffffffL)
		/* Address outside of unified address segment */
		exit (-1);
	      physical |= (0x12L << 24);
	    }
	  break;
	}
      case 0x10:
      case 0x11:
      case 0x12:
	physical = logical;
	break;
      default:
	exit (-1);	/* error */
      }

  seg = (physical >> 24);
  off = (physical & 0xffffffL);
  switch (seg) 
    {
    case 0x10:	/* dst is a 15 bit offset into the on-chip memory */
      *dmap = 0;
      *addr = (long *) (0x0000 + ((short)off & 0x7fff));
      break;
    case 0x11:	/* dst is an 18-bit offset into the on-chip
		   instruction memory */
      *dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
      *addr = (long *) (0x8000 + ((short)off & 0x3fff));
      break;
    case 0x12:	/* dst is a 24-bit offset into unified memory */
      *dmap = off >> 14;
      *addr = (long *) (0x8000 + ((short)off & 0x3fff));
      break;
    default:
      exit (-1);	/* error */
    }
}
#endif /* __D10V__ */

static void
ovly_copy (unsigned long dst, unsigned long src, long size)
{
#ifdef  __D10V__
  unsigned long *s, *d, tmp;
  short dmap_src, dmap_dst;
  short dmap_save;

  /* all section sizes should by multiples of 4 bytes */
  dmap_save = DMAP;

  D10VTranslate (src, &dmap_src, &s);
  D10VTranslate (dst, &dmap_dst, &d);

  while (size > 0)
    {
      /* NB: Transfer 4 byte (long) quantites, problems occure
	 when only two bytes are transfered */
      DMAP = dmap_src;
      tmp = *s;
      DMAP = dmap_dst;
      *d = tmp; 
      d++;
      s++;
      size -= sizeof (tmp);
      src += sizeof (tmp);
      dst += sizeof (tmp);
      if ((src & 0x3fff) == 0)
	D10VTranslate (src, &dmap_src, &s);
      if ((dst & 0x3fff) == 0)
	D10VTranslate (dst, &dmap_dst, &d);
    }
  DMAP = dmap_save;
#else
  memcpy ((void *) dst, (void *) src, size);
#endif /* D10V */
  return;
}

