<> <> <> <> <> 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 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 <<>> <> [] _ CedarMicrocode.RTMOVESTATUS[177777B--initialize--, gcStateBank]; <> 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; }; }; }; <> zctInterval: VM.Interval = VM.Allocate[count: VM.PagesForWords[SIZE[ZCT.ZCTObject]+SIZE[ZCT.FOSTableObject]], in64K--permanent--: TRUE]; <> 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; <> VM.Pin[[page: zctInterval.page, count: 1]]; zct _ VM.AddressForPageNumber[zctInterval.page]; -- pinned. On a page boundary. { <> interval: VM.Interval _ VM.SimpleAllocate[VM.PagesForWords[SIZE[RealExceptions.FlagsArray]]]; VM.SwapIn[interval]; RealExceptions.Init[VM.AddressForPageNumber[interval.page]]; }; END.