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 BOOL ← FALSE;
rcMicrocodeExists: PUBLIC BOOL ← FALSE;
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:
BOOL ←
FALSE] =
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.