home *** CD-ROM | disk | FTP | other *** search
- /*
- SetCPU V1.60
- by Dave Haynie, April 13, 1990
- Released to the Public Domain
-
- MMU.C MODULE
-
- This module is responsible for some of the MMU table creation
- functions.
- */
-
- #include "setcpu.h"
-
-
- /* ====================================================================== */
-
- /* This function maps the phantom area for a given memory location. */
-
- void Phantom(tag,loc)
- struct systag *tag;
- ULONG loc;
- {
- ULONG xindex = loc/ROMROUND;
-
- if (xindex < 60)
- tag->maintable[xindex] = PD_ADDR(0x00800000)|PD_DT_PAGE;
- else
- tag->maintable[xindex] = PD_ADDR(0x00ce0000)|PD_DT_PAGE;
- }
-
-
- /* This table contains a list of the blocks of memory that should be
- cache-inhibited. */
-
- static ULONG InTable[] = { 0x00000000,0x00200000,0x00b00000,0x00f00000,0L,0L };
-
-
- /* This function fills the basic MMU table and other standard tag itemd from
- an allocated image. Some tables may need additional information in the
- table. The basic table consists of one table level and uses direct page
- translation on a grain of 128K per entry. Everything's directly mapped
- except for the last two entries, which are for the $FC0000-$FFFFFF area. */
-
- void FillBasicTable(tag,phantoms)
- struct systag *tag;
- LONG phantoms;
- {
- register ULONG i, image, j;
- ULONG page,size,loc;
-
- tag->tagsize = SizeOf(struct systag);
- tag->progver = PROGRAM_VERSION;
- tag->patches = 0;
- tag->patchlist = tag->devs = NULL;
- tag->config = 1;
- tag->BerrSize = 0L;
- tag->OldBerr = tag->BerrHandler = NULL;
- tag->sysstack = NULL;
- tag->sysstksize = 0;
- tag->OldReset = tag->ResetCode = NULL;
- tag->ResetSize = 0;
-
- /* Here I make a table that maps everything straight through. */
- for (i = 0; i < tag->tablesize/sizeof(ULONG); i++)
- tag->maintable[i] = PD_ADDR(i<<17)|PD_DT_PAGE;
- tag->maintable[i] = IV_ADDR(tag)|PD_DT_INVALID;
-
- /* Mark the inhibited pages. */
- for (i = 0; InTable[i+1]; i += 2)
- for (j = InTable[i]/PAGESIZE; j < InTable[i+1]/PAGESIZE; ++j)
- tag->maintable[j] |= PD_CI;
-
- /* Here I map the ROM image to the ROM location. */
- image = (ULONG)tag->romlo;
- loc = tag->romloc/PAGESIZE;
- if (image) {
- if (phantoms) Phantom(tag,image);
- tag->maintable[loc++] = PD_ADDR(image)|PD_WP|PD_DT_PAGE;
- if (phantoms) Phantom(tag,image+PAGESIZE);
- tag->maintable[loc++] = PD_ADDR(image+PAGESIZE)|PD_WP|PD_DT_PAGE;
- }
- image = (ULONG)tag->romhi;
- if (phantoms) Phantom(tag,image);
- tag->maintable[loc++] = PD_ADDR(image)|PD_WP|PD_DT_PAGE;
- if (phantoms) Phantom(tag,image+PAGESIZE);
- tag->maintable[loc] = PD_ADDR(image+PAGESIZE)|PD_WP|PD_DT_PAGE;
-
- /* Here I look for Bridge Cards, which are known to have problems with
- the data cache enabled, so I always disable it, reguardless of
- whether caching is actually enabled in the CACR. */
-
- if (Bridge.Addr && Bridge.Size) {
- page = Bridge.Addr/PAGESIZE;
- size = max((ULONG)Bridge.Size/PAGESIZE,1);
- while (size-- && page < tag->tablesize)
- if ((tag->maintable[page] & PD_DT_TYPE) == PD_DT_PAGE)
- tag->maintable[page++] |= PD_CI;
- }
- }
-
- /* This routine sets up the MMU registers (shadowed in tag fields) in the
- standard SetCPU fashion. The CPU Root Pointer tells the MMU about the
- table I've set up, and all that's left to do is bang the Translation
- Control Register to turn the thing on. Note that the first half of the
- CRP is control data, the second the address of my table. */
-
- void SetMMURegs(tag)
- struct systag *tag;
- {
- tag->CRP[0] = CRP_LIMIT(tag->tablesize/sizeof(ULONG)-1)|CRP_SG|CRP_DT_V4BYTE;
- tag->CRP[1] = (ULONG)(tag->maintable);
-
- tag->TC = TC_PS(0x0a)|TC_IS(tag->wrapup)|
- TC_TIA(0x0f-tag->wrapup)|TC_TIB(0x03)|TC_TIC(0x04)|TC_TID(0);
- }
-
- /* ====================================================================== */
-
- /* This function frees all MMU tables. */
-
- void FreeMMUTable(tag)
- struct systag *tag;
- {
- ULONG i,j, *subtab;
-
- for (i = 0; i < 128; ++i)
- if ((tag->maintable[i] & PD_DT_TYPE) == PD_DT_V4BYTE) {
- for (subtab = (ULONG *)PD_ADDR(tag->maintable[i]), j = 0; j < 8; ++j)
- if ((subtab[j] & PD_DT_TYPE) == PD_DT_V4BYTE)
- FreeMem((char *)PD_ADDR(subtab[j]),STKTABSIZE);
- FreeMem((char *)subtab,SUBTABSIZE);
- }
- FreeMem((char *)tag->maintable,tag->tablesize);
- }
-
- /* ====================================================================== */
-
- /* This function makes subtables for CardROMFile I/O devices. */
-
- void MakeExpTable(tag)
- struct systag *tag;
- {
- ULONG i, *SUBTable, iospace;
- struct ExpROMData *er;
-
- while (er = GetExpROM()) {
- er->next = tag->devs;
- tag->devs = er;
-
- iospace = ((ULONG)er->ROMbase)/ROMROUND;
-
- /* If necessary, modify the table */
- if (tag->maintable[iospace] == PD_ADDR(iospace<<17)|PD_DT_PAGE) {
- if (SUBTable = AllocAligned(SUBTABSIZE,TABROUND)) {
- for (i = 0; i < 8; ++i)
- SUBTable[i] = PD_ADDR((iospace<<17)+(i<<14))|PD_CI|PD_DT_PAGE;
- tag->maintable[iospace] = PD_ADDR(SUBTable)|PD_DT_V4BYTE;
- }
- } else
- SUBTable = (ULONG *)PD_ADDR(tag->maintable[iospace]);
-
- if (SUBTable) {
- er->imagebase = (ULONG)AllocAligned(er->ROMsize,DEVROUND);
- er->tablebase = (ULONG)&SUBTable[0];
-
- MemCopy(er->ROMbase,er->imagebase,er->ROMsize);
- iospace = (er->ROMbase - (iospace * ROMROUND))/DEVROUND;
- for (i = 0; i < er->ROMsize/DEVROUND; ++i)
- SUBTable[iospace+i] = PD_ADDR(er->imagebase+(DEVROUND*i))|PD_CI|PD_DT_PAGE;
- }
- }
- }
-
- /* ====================================================================== */
-
- /* This function hunts down the system stack and translates it into a
- block of 32 bit memory if it's found to be located in Chip RAM. Note
- that this routine must only be called when the MMU is turned on. The
- current functions used to turn the MMU on make use of the supervisor
- stack. This code must be run in user mode to insure that the supervisor
- stack image and the actual stack are the same during the transfer of
- control. */
-
- void MakeFastStack(tag)
- struct systag *tag;
- {
- struct ExecBase *eb = *((struct ExecBase **)4L);
- ULONG i, *SUBTable, *STKTable, tabndx, subndx, stkndx, tmem, base;
-
- base = (((ULONG)eb->SysStkLower)/STKROUND)*STKROUND;
-
- if (base >= 0x00200000L) return;
-
- tag->sysstksize = (((ULONG)eb->SysStkUpper - (ULONG)eb->SysStkLower + 1)/STKROUND)*STKROUND;
- tabndx = base/ROMROUND;
- tmem = tabndx * ROMROUND;
-
- /* Make the I/O level subtable (level 2). Most entries are going to be
- a straight translation. */
-
- if (!(SUBTable = AllocAligned(SUBTABSIZE,TABROUND)) ||
- !(STKTable = AllocAligned(STKTABSIZE,TABROUND))) return;
-
- for (i = 0; i < 8; ++i)
- SUBTable[i] = PD_ADDR(tmem+(i*DEVROUND))|PD_DT_PAGE;
- tag->maintable[tabndx] = PD_ADDR(SUBTable)|PD_DT_V4BYTE;
-
- /* Make the Stack level subtable (level 3). Fill all 16 entries with a
- straight translation. */
-
- subndx = (base - tmem)/DEVROUND;
- tmem += subndx * DEVROUND;
-
- for (i = 0; i < 16; ++i)
- STKTable[i] = PD_ADDR((tmem)+(i*STKROUND))|PD_DT_PAGE;
- SUBTable[subndx] = PD_ADDR(STKTable)|PD_DT_V4BYTE;
-
- /* Now take care of the actual stack translation. */
-
- tag->sysstack = (char *)AllocAligned(tag->sysstksize,STKROUND);
- MemCopy(base,tag->sysstack,tag->sysstksize);
-
- stkndx = (base - tmem)/STKROUND;
-
- for (i = 0; i < tag->sysstksize/STKROUND && i < 16; ++i)
- STKTable[i+stkndx] = PD_ADDR(tag->sysstack+(STKROUND*i))|PD_DT_PAGE;
- FlushATC();
- }
-
- /* This function removes the fast stack translation. Like the fast stack
- creation routine, this must be called with the MMU turned on, in user
- mode, so that both stack images can be identical when the switch is
- made. This routine doesn't clean up the MMU tables, it just deals
- with the stack image. */
-
- void FreeFastStack(tag)
- struct systag *tag;
- {
- struct ExecBase *eb = *((struct ExecBase **)4L);
- ULONG *SUBTable, *STKTable, tabndx, subndx, tmem, base;
-
- base = (((ULONG)eb->SysStkLower)/STKROUND)*STKROUND;
-
- /* Find the stack's translation table. */
-
- tabndx = base/ROMROUND;
- tmem = tabndx * ROMROUND;
- SUBTable = (ULONG *)PD_ADDR(tag->maintable[tabndx]);
-
- subndx = (base - tmem)/DEVROUND;
-
- /* Set things back the way they were. */
-
- Disable();
- STKTable = (ULONG *)PD_ADDR(SUBTable[subndx]);
- MemCopy(tag->sysstack,base,tag->sysstksize);
- SUBTable[subndx] = PD_ADDR(tmem+(subndx*DEVROUND))|PD_DT_PAGE;
- FlushATC();
- Enable();
-
- /* Get rid of the fast image stuff. */
-
- FreeMem((char *)STKTable,STKTABSIZE);
- FreeMem((char *)tag->sysstack,tag->sysstksize);
- }
-
- /* ====================================================================== */
-
- /* This routine knows the best way to reset the system, in an attempt to
- avoid MMU-based troubles. */
-
- void CleverReset()
- {
- geta4();
- CleanBoot();
- }
-