NewSafeStoragePinnedImpl.Mesa
This code and global frame must be pinned.
last edited December 6, 1983 2:33 pm by Paul Rovner
DIRECTORY
Basics USING[HighHalf],
CedarMicrocode USING[RTMOVESTATUS, DISABLEMICROCODE, ENABLEMICROCODE, microcodeVersion],
DeviceCleanup USING[Item, Reason, Await],
GermSwap USING[switches],
PrincOps USING[PsbIndex],
RCMicrocodeOps USING[], -- export of rcMicrocodeExists
VM USING[AddressForPageNumber, Allocate, Interval, Pin, PagesForWords],
ZCT USING[ZeroCountTable, ZCTObject, FOSTableObject];
NewSafeStoragePinnedImpl: PROGRAM
IMPORTS Basics, CedarMicrocode, DeviceCleanup, GermSwap, 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.
END.