SafeStoragePinnedImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
This code and global frame must be pinned.
Paul Rovner, December 6, 1983 2:33 pm
Russ Atkinson (RRA) May 22, 1985 9:48:04 pm PDT
DIRECTORY
Basics USING [HighHalf],
CedarMicrocode USING [RTMOVESTATUS, DISABLEMICROCODE, ENABLEMICROCODE, microcodeVersion],
DeviceCleanup USING [Item, Reason, Await],
GermSwap USING [switches],
PrincOps USING [PsbIndex],
RealExceptions USING [FlagsArray, Init],
RCMicrocodeOps USING [], -- export of rcMicrocodeExists
VM USING [AddressForPageNumber, Allocate, Interval, Pin, PagesForWords, SimpleAllocate, SwapIn],
ZCT USING [ZeroCountTable, ZCTObject, FOSTableObject];
SafeStoragePinnedImpl: PROGRAM
IMPORTS Basics, CedarMicrocode, DeviceCleanup, GermSwap, RealExceptions, VM
EXPORTS ZCT, RCMicrocodeOps
= BEGIN
zct: PUBLIC ZCT.ZeroCountTable ← NIL;
rcMicrocodeWasEnabled: PUBLIC BOOLFALSE;
rcMicrocodeExists: PUBLIC BOOLFALSE;
ucVersion: NAT;
useSoftware: BOOL ← GermSwap.switches[s]; -- for debugging
InitializeCleanup: PUBLIC PROC = {
TurnOn[firstTime: TRUE];
DO
item: DeviceCleanup.Item;
reason: DeviceCleanup.Reason ← DeviceCleanup.Await[@item];
SELECT reason FROM
turnOff, kill => TurnOff[];
turnOn => TurnOn[];
ENDCASE;
ENDLOOP;
};
TurnOff: PROC = INLINE { -- save ucode state
IF rcMicrocodeExists AND rcMicrocodeWasEnabled
THEN CedarMicrocode.DISABLEMICROCODE[zct];
};
TurnOn: PROC [firstTime: BOOLFALSE] = INLINE { -- restore ucode state
START COMPATIBILITY BOILERPLATE
[] ← CedarMicrocode.RTMOVESTATUS[177777B--initialize--, gcStateBank];
END COMPATIBILITY BOILERPLATE
IF firstTime OR rcMicrocodeWasEnabled THEN {
ucVersion ← CedarMicrocode.ENABLEMICROCODE[zct];
rcMicrocodeWasEnabled ← TRUE;
rcMicrocodeExists
← (ucVersion = CedarMicrocode.microcodeVersion) AND NOT useSoftware;
IF NOT rcMicrocodeExists THEN {
CedarMicrocode.DISABLEMICROCODE[zct];
rcMicrocodeWasEnabled ← FALSE;
};
};
};
START HERE
zctInterval: VM.Interval
= VM.Allocate[count: VM.PagesForWords[SIZE[ZCT.ZCTObject]+SIZE[ZCT.FOSTableObject]],
    in64K--permanent--: TRUE];
START COMPATIBILITY BOILERPLATE
Foo: TYPE = MACHINE DEPENDENT RECORD[
a: WORD ← 0,
b: WORD ← 0,
reclaimState: CARDINAL,
collector: CARDINAL --PROCESS
];
gcsInterval: VM.Interval = VM.Allocate[count: 1, alignment: 8, in64K--permanent--: TRUE];
gcState: LONG POINTER TO Foo ← VM.AddressForPageNumber[gcsInterval.page];
gcStateBank: CARDINAL ← Basics.HighHalf[LOOPHOLE[gcState, LONG CARDINAL]];
VM.Pin[gcsInterval];
gcState.reclaimState ← 100000B;
gcState.collector ← LAST[PrincOps.PsbIndex] + 1;
END COMPATIBILITY BOILERPLATE
VM.Pin[[page: zctInterval.page, count: 1]];
zct ← VM.AddressForPageNumber[zctInterval.page]; -- pinned. On a page boundary.
{
This hack is here because much earlier and we could not be sure of cufficient facilities to allocated the storage.
interval: VM.Interval ← VM.SimpleAllocate[VM.PagesForWords[SIZE[RealExceptions.FlagsArray]]];
VM.SwapIn[interval];
RealExceptions.Init[VM.AddressForPageNumber[interval.page]];
};
END.