diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:35:26 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:35:26 +0000 |
commit | c906108c21474dfb4ed285bcc0ac6fe02cd400cc (patch) | |
tree | a0015aa5cedc19ccbab307251353a41722a3ae13 /gdb/testsuite/gdb.base/d10vovly.c | |
parent | cd946cff9ede3f30935803403f06f6ed30cad136 (diff) | |
download | binutils-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.zip binutils-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.gz binutils-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.bz2 |
Initial creation of sourceware repositorygdb-4_18-branchpoint
Diffstat (limited to 'gdb/testsuite/gdb.base/d10vovly.c')
-rw-r--r-- | gdb/testsuite/gdb.base/d10vovly.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.base/d10vovly.c b/gdb/testsuite/gdb.base/d10vovly.c new file mode 100644 index 0000000..bdb90fe --- /dev/null +++ b/gdb/testsuite/gdb.base/d10vovly.c @@ -0,0 +1,225 @@ + +/* + * 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 +} + +/* 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 (); + + 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]); + + 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 __M32R__ + memcpy ((void *) dst, (void *) src, size); + return; +#endif /* M32R */ + +#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; +#endif /* D10V */ +} + |