OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [testsuite/] [gdb.base/] [m32rovly.c] - Diff between revs 107 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 107 Rev 1765
 
 
/*
/*
 * Ovlymgr.c -- Runtime Overlay Manager for the GDB testsuite.
 * Ovlymgr.c -- Runtime Overlay Manager for the GDB testsuite.
 */
 */
 
 
#include "ovlymgr.h"
#include "ovlymgr.h"
 
 
/* Local functions and data: */
/* Local functions and data: */
 
 
extern unsigned long _ovly_table[][4];
extern unsigned long _ovly_table[][4];
extern unsigned long _novlys __attribute__ ((section (".data")));
extern unsigned long _novlys __attribute__ ((section (".data")));
enum ovly_index { VMA, SIZE, LMA, MAPPED};
enum ovly_index { VMA, SIZE, LMA, MAPPED};
 
 
static void ovly_copy (unsigned long dst, unsigned long src, long size);
static void ovly_copy (unsigned long dst, unsigned long src, long size);
 
 
/* Flush the data and instruction caches at address START for SIZE bytes.
/* Flush the data and instruction caches at address START for SIZE bytes.
   Support for each new port must be added here.  */
   Support for each new port must be added here.  */
/* FIXME: Might be better to have a standard libgloss function that
/* FIXME: Might be better to have a standard libgloss function that
   ports provide that we can then use.  Use libgloss instead of newlib
   ports provide that we can then use.  Use libgloss instead of newlib
   since libgloss is the one intended to handle low level system issues.
   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
   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.  */
   but not be completely obscure as other things may need this facility.  */
 
 
static void
static void
FlushCache (void)
FlushCache (void)
{
{
#ifdef __M32R__
#ifdef __M32R__
  volatile char *mspr = (char *) 0xfffffff7;
  volatile char *mspr = (char *) 0xfffffff7;
  *mspr = 1;
  *mspr = 1;
#endif
#endif
}
}
 
 
/* OverlayLoad:
/* OverlayLoad:
 * Copy the overlay into its runtime region,
 * Copy the overlay into its runtime region,
 * and mark the overlay as "mapped".
 * and mark the overlay as "mapped".
 */
 */
 
 
bool
bool
OverlayLoad (unsigned long ovlyno)
OverlayLoad (unsigned long ovlyno)
{
{
  unsigned long i;
  unsigned long i;
 
 
  if (ovlyno < 0 || ovlyno >= _novlys)
  if (ovlyno < 0 || ovlyno >= _novlys)
    exit (-1);  /* fail, bad ovly number */
    exit (-1);  /* fail, bad ovly number */
 
 
  if (_ovly_table[ovlyno][MAPPED])
  if (_ovly_table[ovlyno][MAPPED])
    return TRUE;        /* this overlay already mapped -- nothing to do! */
    return TRUE;        /* this overlay already mapped -- nothing to do! */
 
 
  for (i = 0; i < _novlys; i++)
  for (i = 0; i < _novlys; i++)
    if (i == ovlyno)
    if (i == ovlyno)
      _ovly_table[i][MAPPED] = 1;       /* this one now mapped */
      _ovly_table[i][MAPPED] = 1;       /* this one now mapped */
    else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
    else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
      _ovly_table[i][MAPPED] = 0;        /* this one now un-mapped */
      _ovly_table[i][MAPPED] = 0;        /* this one now un-mapped */
 
 
  ovly_copy (_ovly_table[ovlyno][VMA],
  ovly_copy (_ovly_table[ovlyno][VMA],
             _ovly_table[ovlyno][LMA],
             _ovly_table[ovlyno][LMA],
             _ovly_table[ovlyno][SIZE]);
             _ovly_table[ovlyno][SIZE]);
 
 
  FlushCache ();
  FlushCache ();
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* OverlayUnload:
/* OverlayUnload:
 * Copy the overlay back into its "load" region.
 * Copy the overlay back into its "load" region.
 * Does NOT mark overlay as "unmapped", therefore may be called
 * Does NOT mark overlay as "unmapped", therefore may be called
 * more than once for the same mapped overlay.
 * more than once for the same mapped overlay.
 */
 */
 
 
bool
bool
OverlayUnload (unsigned long ovlyno)
OverlayUnload (unsigned long ovlyno)
{
{
  if (ovlyno < 0 || ovlyno >= _novlys)
  if (ovlyno < 0 || ovlyno >= _novlys)
    exit (-1);  /* fail, bad ovly number */
    exit (-1);  /* fail, bad ovly number */
 
 
  if (!_ovly_table[ovlyno][MAPPED])
  if (!_ovly_table[ovlyno][MAPPED])
    exit (-1);  /* error, can't copy out a segment that's not "in" */
    exit (-1);  /* error, can't copy out a segment that's not "in" */
 
 
  ovly_copy (_ovly_table[ovlyno][LMA],
  ovly_copy (_ovly_table[ovlyno][LMA],
             _ovly_table[ovlyno][VMA],
             _ovly_table[ovlyno][VMA],
             _ovly_table[ovlyno][SIZE]);
             _ovly_table[ovlyno][SIZE]);
 
 
  return TRUE;
  return TRUE;
}
}
 
 
#ifdef __D10V__
#ifdef __D10V__
#define IMAP0       (*(short *)(0xff00))
#define IMAP0       (*(short *)(0xff00))
#define IMAP1       (*(short *)(0xff02))
#define IMAP1       (*(short *)(0xff02))
#define DMAP        (*(short *)(0xff04))
#define DMAP        (*(short *)(0xff04))
 
 
static void
static void
D10VTranslate (unsigned long logical,
D10VTranslate (unsigned long logical,
               short *dmap,
               short *dmap,
               unsigned long **addr)
               unsigned long **addr)
{
{
  unsigned long physical;
  unsigned long physical;
  unsigned long seg;
  unsigned long seg;
  unsigned long off;
  unsigned long off;
 
 
  /* to access data, we use the following mapping
  /* to access data, we use the following mapping
     0x00xxxxxx: Logical data address segment        (DMAP translated memory)
     0x00xxxxxx: Logical data address segment        (DMAP translated memory)
     0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
     0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
     0x10xxxxxx: Physical data memory segment        (On-chip data memory)
     0x10xxxxxx: Physical data memory segment        (On-chip data memory)
     0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
     0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
     0x12xxxxxx: Phisical unified memory segment     (Unified memory)
     0x12xxxxxx: Phisical unified memory segment     (Unified memory)
     */
     */
 
 
  /* Addresses must be correctly aligned */
  /* Addresses must be correctly aligned */
  if (logical & (sizeof (**addr) - 1))
  if (logical & (sizeof (**addr) - 1))
    exit (-1);
    exit (-1);
 
 
  /* If the address is in one of the two logical address spaces, it is
  /* If the address is in one of the two logical address spaces, it is
     first translated into a physical address */
     first translated into a physical address */
  seg = (logical >> 24);
  seg = (logical >> 24);
  off = (logical & 0xffffffL);
  off = (logical & 0xffffffL);
  switch (seg)
  switch (seg)
      {
      {
      case 0x00: /* in logical data address segment */
      case 0x00: /* in logical data address segment */
        if (off <= 0x7fffL)
        if (off <= 0x7fffL)
          physical = (0x10L << 24) + off;
          physical = (0x10L << 24) + off;
        else
        else
          /* Logical address out side of on-chip segment, not
          /* Logical address out side of on-chip segment, not
             supported */
             supported */
          exit (-1);
          exit (-1);
        break;
        break;
      case 0x01: /* in logical instruction address segment */
      case 0x01: /* in logical instruction address segment */
        {
        {
          short map;
          short map;
          if (off <= 0x1ffffL)
          if (off <= 0x1ffffL)
            map = IMAP0;
            map = IMAP0;
          else if (off <= 0x3ffffL)
          else if (off <= 0x3ffffL)
            map = IMAP1;
            map = IMAP1;
          else
          else
            /* Logical address outside of IMAP[01] segment, not
            /* Logical address outside of IMAP[01] segment, not
               supported */
               supported */
            exit (-1);
            exit (-1);
          if (map & 0x1000L)
          if (map & 0x1000L)
            {
            {
            /* Instruction memory */
            /* Instruction memory */
              physical = (0x11L << 24) | off;
              physical = (0x11L << 24) | off;
            }
            }
          else
          else
            {
            {
            /* Unified memory */
            /* Unified memory */
              physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
              physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
              if (physical > 0xffffffL)
              if (physical > 0xffffffL)
                /* Address outside of unified address segment */
                /* Address outside of unified address segment */
                exit (-1);
                exit (-1);
              physical |= (0x12L << 24);
              physical |= (0x12L << 24);
            }
            }
          break;
          break;
        }
        }
      case 0x10:
      case 0x10:
      case 0x11:
      case 0x11:
      case 0x12:
      case 0x12:
        physical = logical;
        physical = logical;
        break;
        break;
      default:
      default:
        exit (-1);      /* error */
        exit (-1);      /* error */
      }
      }
 
 
  seg = (physical >> 24);
  seg = (physical >> 24);
  off = (physical & 0xffffffL);
  off = (physical & 0xffffffL);
  switch (seg)
  switch (seg)
    {
    {
    case 0x10:  /* dst is a 15 bit offset into the on-chip memory */
    case 0x10:  /* dst is a 15 bit offset into the on-chip memory */
      *dmap = 0;
      *dmap = 0;
      *addr = (long *) (0x0000 + ((short)off & 0x7fff));
      *addr = (long *) (0x0000 + ((short)off & 0x7fff));
      break;
      break;
    case 0x11:  /* dst is an 18-bit offset into the on-chip
    case 0x11:  /* dst is an 18-bit offset into the on-chip
                   instruction memory */
                   instruction memory */
      *dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
      *dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
      *addr = (long *) (0x8000 + ((short)off & 0x3fff));
      *addr = (long *) (0x8000 + ((short)off & 0x3fff));
      break;
      break;
    case 0x12:  /* dst is a 24-bit offset into unified memory */
    case 0x12:  /* dst is a 24-bit offset into unified memory */
      *dmap = off >> 14;
      *dmap = off >> 14;
      *addr = (long *) (0x8000 + ((short)off & 0x3fff));
      *addr = (long *) (0x8000 + ((short)off & 0x3fff));
      break;
      break;
    default:
    default:
      exit (-1);        /* error */
      exit (-1);        /* error */
    }
    }
}
}
#endif /* __D10V__ */
#endif /* __D10V__ */
 
 
static void
static void
ovly_copy (unsigned long dst, unsigned long src, long size)
ovly_copy (unsigned long dst, unsigned long src, long size)
{
{
#ifdef  __M32R__
#ifdef  __M32R__
  memcpy ((void *) dst, (void *) src, size);
  memcpy ((void *) dst, (void *) src, size);
  return;
  return;
#endif /* M32R */
#endif /* M32R */
 
 
#ifdef  __D10V__
#ifdef  __D10V__
  unsigned long *s, *d, tmp;
  unsigned long *s, *d, tmp;
  short dmap_src, dmap_dst;
  short dmap_src, dmap_dst;
  short dmap_save;
  short dmap_save;
 
 
  /* all section sizes should by multiples of 4 bytes */
  /* all section sizes should by multiples of 4 bytes */
  dmap_save = DMAP;
  dmap_save = DMAP;
 
 
  D10VTranslate (src, &dmap_src, &s);
  D10VTranslate (src, &dmap_src, &s);
  D10VTranslate (dst, &dmap_dst, &d);
  D10VTranslate (dst, &dmap_dst, &d);
 
 
  while (size > 0)
  while (size > 0)
    {
    {
      /* NB: Transfer 4 byte (long) quantites, problems occure
      /* NB: Transfer 4 byte (long) quantites, problems occure
         when only two bytes are transfered */
         when only two bytes are transfered */
      DMAP = dmap_src;
      DMAP = dmap_src;
      tmp = *s;
      tmp = *s;
      DMAP = dmap_dst;
      DMAP = dmap_dst;
      *d = tmp;
      *d = tmp;
      d++;
      d++;
      s++;
      s++;
      size -= sizeof (tmp);
      size -= sizeof (tmp);
      src += sizeof (tmp);
      src += sizeof (tmp);
      dst += sizeof (tmp);
      dst += sizeof (tmp);
      if ((src & 0x3fff) == 0)
      if ((src & 0x3fff) == 0)
        D10VTranslate (src, &dmap_src, &s);
        D10VTranslate (src, &dmap_src, &s);
      if ((dst & 0x3fff) == 0)
      if ((dst & 0x3fff) == 0)
        D10VTranslate (dst, &dmap_dst, &d);
        D10VTranslate (dst, &dmap_dst, &d);
    }
    }
  DMAP = dmap_save;
  DMAP = dmap_save;
#endif /* D10V */
#endif /* D10V */
}
}
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.