* gdb.base/d10vovly.c (D10VTranslate): Map IMAP0 to low 128k of
authorAndrew Cagney <cagney@redhat.com>
Thu, 12 Feb 1998 05:09:25 +0000 (05:09 +0000)
committerAndrew Cagney <cagney@redhat.com>
Thu, 12 Feb 1998 05:09:25 +0000 (05:09 +0000)
        on-chip insn memory and IMAP1 to upper 128k.
        (D10VCopy): Handle memory regions crossing 16k boundaries.
        (D10VCopy): Transfer data in 32 bit chunks.

gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/d10vovly.c [new file with mode: 0644]

index 29c65995ba959c29be1e40fa99b193bc7225da55..1d53d80a2599b4f015f46458f6ca5f05a3894d4b 100644 (file)
@@ -1,3 +1,22 @@
+Thu Feb 12 13:49:30 1998  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gdb.base/d10vovly.c (D10VTranslate): Map IMAP0 to low 128k of
+       on-chip insn memory and IMAP1 to upper 128k.
+       (D10VCopy): Handle memory regions crossing 16k boundaries.
+       (D10VCopy): Transfer data in 32 bit chunks.
+
+Tue Feb 10 17:23:22 1998  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gdb.base/overlays.c (main): Exit normally when result is
+       correct.
+
+       * gdb.base/d10v.ld: Update LMAs to reflect current d10v address
+       map.  Include space for printf in .text segment.
+
+       * gdb.base/d10vovly.c (D10VTranslate): New function, handle
+       updated d10v memory VMA/LMA map.
+       (D10VCopy): Call D10VTranslate.
+       
 Fri Feb  6 14:13:12 1998  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * gdb.base/m32rovly.c: Force variable _novlys into .data section.
diff --git a/gdb/testsuite/gdb.base/d10vovly.c b/gdb/testsuite/gdb.base/d10vovly.c
new file mode 100644 (file)
index 0000000..9bbdbf8
--- /dev/null
@@ -0,0 +1,207 @@
+
+/*
+ * Ovlymgr.c -- Runtime Overlay Manager for the Mitsubishi D10V
+ */
+
+#include "ovlymgr.h"
+
+/* Local functions and data: */
+
+extern unsigned long _ovly_table[][4], _novlys;
+enum ovly_index { VMA, SIZE, LMA, MAPPED };
+enum ovly_direction { IN, OUT };
+
+static void D10VCopy (unsigned long dst, unsigned long src, long size);
+
+/* OverlayLoad:
+ * Copy the overlay into its runtime region,
+ * and mark the overlay as "mapped".
+ */
+
+void
+OverlayLoad (int ovlyno)
+{
+  int i;
+
+  if (ovlyno < 0 || ovlyno >= _novlys)
+    exit (-1); /* fail, bad ovly number */
+
+  if (_ovly_table[ovlyno][MAPPED])
+    return;    /* 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 */
+
+  /* copy overlay using D10V DMAP register */
+  D10VCopy (_ovly_table[ovlyno][VMA], _ovly_table[ovlyno][LMA], 
+           _ovly_table[ovlyno][SIZE]);
+}
+
+/* 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.
+ */
+
+void
+OverlayUnload (int 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" */
+
+  D10VCopy (_ovly_table[ovlyno][LMA], _ovly_table[ovlyno][VMA], 
+           _ovly_table[ovlyno][SIZE]);
+}
+
+/* D10VCopy:
+ * Copy a region of memory from src to dest.
+ * Like memcpy, but can copy anywhere in Universal, Data or Instruction memory.
+ */
+
+#define IMAP0       (*(int *)(0xff00))
+#define IMAP1       (*(int *)(0xff02))
+#define DMAP        (*(int *)(0xff04))
+
+static void
+D10VTranslate (unsigned long logical,
+              short *dmap,
+              unsigned long **addr)
+{
+  unsigned long physical;
+  unsigned long seg;
+  unsigned long off;
+  int err = 0;
+  /* 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 + ((int)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 + ((int)off & 0x3fff));
+      break;
+    case 0x12: /* dst is a 24-bit offset into unified memory */
+      *dmap = off >> 14;
+      *addr = (long *) (0x8000 + ((int)off & 0x3fff));
+      break;
+    default:
+      exit (-1);       /* error */
+    }
+
+#if 0
+  printf ("D10VTranslate: logical = %08lx, dmap = %04x, addr = %04x\n",
+         logical, *dmap, *addr);
+#endif
+}
+
+static void 
+D10VCopy (unsigned long dst, unsigned long src, long size)
+{
+  unsigned long *s, *d, tmp;
+  short dmap_src, dmap_dst;
+  short dmap_save;
+
+#if 0
+  printf ("D10VCopy: dst = %08lx, src = %08lx, size = %ld\n",
+         dst, src, size);
+#endif
+
+  /* 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;
+}
+