SoftcardBDVMPrivateImpl.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Ch. Le Cocq, October 26, 1988
Christian Le Cocq December 7, 1988 2:04:14 pm PST
Allocation of the Softcard backdoor memory.
DIRECTORY
GermSwap USING [LP, mdsiGerm],
PrincOps,
PrincOpsUtils,
SparcSoftcard,
SoftcardBDVMPrivate,
VM USING [Interval, PageNumber, PageCount],
VMInternal;
SoftcardBDVMPrivateImpl: MONITOR LOCKS VMInternal.vmStateLock
IMPORTS GermSwap, PrincOpsUtils, VMInternal
EXPORTS SoftcardBDVMPrivate
SHARES VMInternal
~ BEGIN
hook: CARD16 ~ 210B;
MagicStructure: TYPE ~ RECORD [ -- three words (48 bits)!
region: PrincOps.PageNumber,
swPages: CARD16
];
softcardPage: CARD32 = SparcSoftcard.softcardPageSizeByte;
GetBDVMInterval: PUBLIC PROC RETURNS [interval: VM.Interval] ~ {
Description of the procedure.
pMagicStructure: PUBLIC LONG POINTER TO READONLY MagicStructure ←
LOOPHOLE[GermSwap.LP[LOOPHOLE[PrincOps.SD + hook], GermSwap.mdsiGerm]];
interval ← [pMagicStructure.region, pMagicStructure.swPages];
};
AllocateRealMemory: ENTRY PROC [vmPage: PrincOps.PageNumber, realPage: PrincOps.RealPageNumber] RETURNS [errCode: INT ← 0] ~ {
Beware ! you cannot raise an error under VM lock (as I learned painfully)
ENABLE UNWIND => NULL;
vmEntry: VMInternal.VMMapEntry ← VMInternal.GetVMMap[vmPage];
specialFlags: PrincOps.PageFlags ← PrincOps.flagsNone;
specialEntry: in VMInternal.VMMapEntry;
newRME: VMInternal.RMMapEntry ← [
dataState: none,
needsBackingStoreWrite: FALSE,
body: pinned[pinReason: specialRealPageInUse, pinCount: 0]
];
WITH vmE: vmEntry SELECT VMInternal.InOut[vmEntry] FROM
out => IF vmE.dataState#none THEN RETURN[1] --Error nobody should have seen it yet
ENDCASE => RETURN[2];
specialEntry ← [
state: PrincOpsUtils.PageStateFromFlags[specialFlags],
body: in[real: realPage]
];
WITH rmE: VMInternal.rmMap[realPage] SELECT FROM
free => NULL;
ENDCASE => RETURN[3];
VMInternal.rmMap[realPage] ← newRME;
VMInternal.SetVMMap[vmPage, specialEntry];
};
SetBDVM: PROC RETURNS [int: VM.Interval] ~ {
realP: PrincOps.RealPageNumber ← firstBDRealAd/PrincOps.bytesPerPage;
vmPage: PrincOps.PageNumber;
int ← GetBDVMInterval[];
vmPage ← int.page;
THROUGH [0..int.count) DO
[] ← AllocateRealMemory[vmPage, realP];
vmPage ← vmPage+1;
realP ← realP+1;
ENDLOOP;
};
firstBDRealAd: PUBLIC CARD32 ← SparcSoftcard.cedarBackDoorBaseByte+20000h;
interval: VM.Interval ← SetBDVM[];
firstBDVMAd: PUBLIC LONG POINTER ← PrincOpsUtils.AddressForPageNumber[interval.page];
maxBDVMBytes: PUBLIC CARD32 ← interval.count*PrincOps.bytesPerPage;
END.