From: Andrew Cagney Date: Thu, 12 Feb 1998 05:09:25 +0000 (+0000) Subject: * gdb.base/d10vovly.c (D10VTranslate): Map IMAP0 to low 128k of X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b6b48d03136e79eb00afa60689f047c31cbe940e;p=binutils-gdb.git * 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. --- diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 29c65995ba9..1d53d80a259 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,22 @@ +Thu Feb 12 13:49:30 1998 Andrew Cagney + + * 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 + + * 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 * 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 index 00000000000..9bbdbf8f3fd --- /dev/null +++ b/gdb/testsuite/gdb.base/d10vovly.c @@ -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; +} +