SparcSoftcardMapImpl.Mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Christophe Cuenod, October 18, 1988 9:26:44 am PDT
Bill Jackson (bj) April 19, 1988 3:34:37 am PDT
Christian Le Cocq November 1, 1988 3:57:55 pm PST
DIRECTORY
Basics USING [ FWORD, Card16FromH, HFromCard16, DoubleShiftRight, LongDiv, LongMult ],
DoveInputOutput USING [ Peek, Poke ],
SparcSoftcard,
SparcSoftcardMap;
Daybreak range [1.5 thru 3.5 Mbytes] is mapped onto [0 thru 2.0 Mbytes] of the Sparc softcard.
SparcSoftcardMapImpl: PROGRAM
IMPORTS Basics, DoveInputOutput
EXPORTS SparcSoftcardMap ~ {
Types
MapEntry: TYPE ~ SparcSoftcardMap.MapEntry;
Exact layout of the bits inside a map entry:
MapEntryConcrete: TYPE = MACHINE DEPENDENT RECORD [
dirty: BOOLEAN,
referenced: BOOLEAN,
readOnly: BOOLEAN,
nonCachable: BOOLEAN,
interrupt: BOOLEAN,
task: BYTE,
virtualPageHiHi: [0..7H], -- 3 bits,
virtualPageHiLow: [0..3H], -- 2 bits,
trash: BOOL,
realPage: [0..1FFFH] -- 13 bits
];
Utilities
PeekAtByteAd: PROC [byteAd: CARD32] RETURNS [content: CARD16] ~ {
wordAd: CARD32 ← Basics.DoubleShiftRight[[lc [byteAd]], 1].lc; -- /2
content ← DoveInputOutput.Peek[wordAd];
};
PokeAtByteAd: PROC [byteAd: CARD32, content: CARD16] ~ {
wordAd: CARD32 ← Basics.DoubleShiftRight[[lc [byteAd]], 1].lc; -- /2
DoveInputOutput.Poke[wordAd, content];
};
Map Access
ReadMapEntry: PUBLIC PROC [ mapEntry: MapEntry ] RETURNS [ oldMapEntry: MapEntry ] ~ {
windowNumber: CARD16;
entryAddressHighByte, entryAddressLowByte: CARD32;
oldMapEntryConcrete: Basics.FWORD;
[windowNumber, entryAddressHighByte, entryAddressLowByte] ← ComputeEntryAddress[mapEntry];
PokeAtByteAd[SparcSoftcard.mapWindowIndexRegisterByte, windowNumber];
Store window number
oldMapEntryConcrete.hi ← Basics.HFromCard16[PeekAtByteAd[entryAddressHighByte]];
oldMapEntryConcrete.lo ← Basics.HFromCard16[PeekAtByteAd[entryAddressLowByte]];
oldMapEntry ← EntryFromConcrete[oldMapEntryConcrete];
oldMapEntry.vMSpace.name ← mapEntry.vMSpace.name;
oldMapEntry.virtualAddressByte ← mapEntry.virtualAddressByte; -- for now, see EntryFromConcrete
};
WriteMapEntry: PUBLIC PROC [ mapEntry: SparcSoftcardMap.MapEntry ] ~ {
windowNumber: CARD16;
entryAddressHighByte, entryAddressLowByte: CARD32;
mapEntryConcrete: Basics.FWORD;
[windowNumber, entryAddressHighByte, entryAddressLowByte] ← ComputeEntryAddress[mapEntry];
mapEntryConcrete ← ConcreteFromEntry[mapEntry];
PokeAtByteAd[SparcSoftcard.mapWindowIndexRegisterByte, windowNumber];
Store window number
PokeAtByteAd[entryAddressHighByte, Basics.Card16FromH[mapEntryConcrete.hi]];
Store high part of the entry
PokeAtByteAd[entryAddressLowByte, Basics.Card16FromH[mapEntryConcrete.lo]];
Store low part of the entry
};
ComputeEntryAddress: PROC [ mapEntry: SparcSoftcardMap.MapEntry ] RETURNS [windowNumber: CARD16, entryAddressHighByte, entryAddressLowByte: CARD32]~ {
mapEntryNumber: CARD16;
windowOffset: CARD16;
Computes the entry number into the map
SELECT mapEntry.vMSpace.name FROM
Sets the base of mapEntryNumber
= dMA => {
mapEntryNumber ← 0E000H;
IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR;
Address range limited to 64 Meg.
};
= iOP => {
mapEntryNumber ← 0A000H;
IF mapEntry.virtualAddressByte >= 1000000H THEN ERROR;
Address range limited to 16 Meg.
};
= cP => {
mapEntryNumber ← 0A000H + 1000000H/SparcSoftcard.softcardPageSizeByte;
CP is in the same VM than IOP but 16 Meg farther.
IF mapEntry.virtualAddressByte >= 400000H THEN ERROR;
Address range limited to 4 Meg.
};
= sparcUserData => {
mapEntryNumber ← 0;
IF mapEntry.virtualAddressByte >= 8000000H THEN ERROR;
***
*** In this first implementation the address range is limited to 128 Meg.
*** Only task 0 is implemented.
***
};
= sparcUserProgram => {
mapEntryNumber ← 4000H;
IF mapEntry.virtualAddressByte >= 8000000H THEN ERROR;
***
*** In this first implementation the address range is limited to 128 Meg.
*** Only task 0 is implemented.
***
};
= sparcSuperData => {
mapEntryNumber ← 8000H;
IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR;
The supervisor address range is limited to 64 Meg.
};
= sparcSuperProgram => {
mapEntryNumber ← 0C000H;
IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR;
The supervisor address range is limited to 64 Meg.
};
ENDCASE => ERROR;
mapEntryNumber ← mapEntryNumber + Basics.LongDiv[mapEntry.virtualAddressByte, SparcSoftcard.softcardPageSizeByte];
Adds the offset.
windowNumber ← mapEntryNumber / SparcSoftcard.mapEntriesPerWindow;
windowOffset ← mapEntryNumber MOD SparcSoftcard.mapEntriesPerWindow;
Computes addresses
entryAddressHighByte ← SparcSoftcard.mapWindowBaseByte + SparcSoftcard.mapEntryHighByteOffset + windowOffset * SparcSoftcard.mapEntrySizeByte;
entryAddressLowByte ← SparcSoftcard.mapWindowBaseByte + SparcSoftcard.mapEntryLowByteOffset + windowOffset * SparcSoftcard.mapEntrySizeByte;
};
ConcreteFromEntry: PROC [ mapEntry: SparcSoftcardMap.MapEntry ] RETURNS [mapEntryConcreteFW: Basics.FWORD] ~ {
mapEntryConcrete: MapEntryConcrete;
mapEntryConcrete.readOnly ← mapEntry.flags.readOnly;
mapEntryConcrete.referenced ← mapEntry.flags.referenced;
mapEntryConcrete.dirty ← mapEntry.flags.dirty;
mapEntryConcrete.nonCachable ← mapEntry.flags.nonCachable;
mapEntryConcrete.interrupt ← mapEntry.flags.interrupt;
mapEntryConcrete.task ← 0;
***
*** Now only task 0 is implemented
***
mapEntryConcrete.virtualPageHiHi ← 0;
mapEntryConcrete.virtualPageHiLow ← 0;
***
*** Now only 128 Meg of VM
***
mapEntryConcrete.realPage ← Basics.LongDiv[mapEntry.realAddressByte, SparcSoftcard.softcardPageSizeByte];
mapEntryConcreteFW ← LOOPHOLE[mapEntryConcrete];
};
EntryFromConcrete: PROC [ mapEntryConcreteFW: Basics.FWORD ] RETURNS [mapEntry: SparcSoftcardMap.MapEntry] ~ {
mapEntryConcrete: MapEntryConcrete ← LOOPHOLE[mapEntryConcreteFW];
mapEntry.flags.readOnly ← mapEntryConcrete.readOnly;
mapEntry.flags.referenced ← mapEntryConcrete.referenced;
mapEntry.flags.dirty ← mapEntryConcrete.dirty;
mapEntry.flags.nonCachable ← mapEntryConcrete.nonCachable;
mapEntry.flags.interrupt ← mapEntryConcrete.interrupt;
IF mapEntryConcrete.task#0 THEN ERROR; -- Now only task 0 is implemented
mapEntry.vMSpace.task ← mapEntryConcrete.task;
IF mapEntryConcrete.virtualPageHiHi*4+mapEntryConcrete.virtualPageHiLow#0 THEN ERROR; --Now only 128 Meg of VM
mapEntry.virtualAddressByte ← 0;
mapEntry.realAddressByte ← Basics.LongMult[mapEntryConcrete.realPage, SparcSoftcard.softcardPageSizeByte]
};
}.