#include "ovlymgr.h"
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);
static void
FlushCache (void)
{
#ifdef __M32R__
volatile char *mspr = (char *) 0xfffffff7;
*mspr = 1;
#endif
}
static void
_ovly_debug_event (void)
{
}
bool
OverlayLoad (unsigned long ovlyno)
{
unsigned long i;
if (ovlyno < 0 || ovlyno >= _novlys)
exit (-1);
if (_ovly_table[ovlyno][MAPPED])
return TRUE;
for (i = 0; i < _novlys; i++)
if (i == ovlyno)
_ovly_table[i][MAPPED] = 1;
else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
_ovly_table[i][MAPPED] = 0;
ovly_copy (_ovly_table[ovlyno][VMA],
_ovly_table[ovlyno][LMA],
_ovly_table[ovlyno][SIZE]);
FlushCache ();
_ovly_debug_event ();
return TRUE;
}
bool
OverlayUnload (unsigned long ovlyno)
{
if (ovlyno < 0 || ovlyno >= _novlys)
exit (-1);
if (!_ovly_table[ovlyno][MAPPED])
exit (-1);
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;
if (logical & (sizeof (**addr) - 1))
exit (-1);
seg = (logical >> 24);
off = (logical & 0xffffffL);
switch (seg)
{
case 0x00:
if (off <= 0x7fffL)
physical = (0x10L << 24) + off;
else
exit (-1);
break;
case 0x01:
{
short map;
if (off <= 0x1ffffL)
map = IMAP0;
else if (off <= 0x3ffffL)
map = IMAP1;
else
exit (-1);
if (map & 0x1000L)
{
physical = (0x11L << 24) | off;
}
else
{
physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
if (physical > 0xffffffL)
exit (-1);
physical |= (0x12L << 24);
}
break;
}
case 0x10:
case 0x11:
case 0x12:
physical = logical;
break;
default:
exit (-1);
}
seg = (physical >> 24);
off = (physical & 0xffffffL);
switch (seg)
{
case 0x10:
*dmap = 0;
*addr = (long *) (0x0000 + ((short)off & 0x7fff));
break;
case 0x11:
*dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
*addr = (long *) (0x8000 + ((short)off & 0x3fff));
break;
case 0x12:
*dmap = off >> 14;
*addr = (long *) (0x8000 + ((short)off & 0x3fff));
break;
default:
exit (-1);
}
}
#endif
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;
dmap_save = DMAP;
D10VTranslate (src, &dmap_src, &s);
D10VTranslate (dst, &dmap_dst, &d);
while (size > 0)
{
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
return;
}