-- Cedar Nucleus: device on/off across germ swaps
-- DeviceCleanup.mesa
-- Andrew Birrell May 25, 1983 6:18 pm
DeviceCleanup: DEFINITIONS =
BEGIN
Reason:
TYPE =
MACHINE
DEPENDENT {
turnOff(0) , -- stop fetches to memory other than to controller status block
turnOn, -- inverse of turnOff
disconnect, -- release resources e.g. special real memory in preparation for booting new system
kill, -- prepare for demise of controller microcode
(255)
};
Await:
PROCEDURE [pItem:
POINTER
TO Item]
RETURNS [Reason] =
INLINE { RETURN[linkage.Await[pItem]] };
Wait until next execution of Perform
InitializeSampleCleanup: PROCEDURE [<parameters>] =
BEGIN
item: DeviceCleanup.Item;
reason: DeviceCleanup.Reason;
<private state>
<initialization code - may call other procedures>
Following code loops forever - must not call other procedures except INLINE, fixed frame
DO
reason ← DeviceCleanup.Await[@item];
SELECT reason FROM
turnOff => <code to turn device off>;
turnOn => <code to turn device on>;
disconnect => <code to release resources such as special real memory>;
kill => <code to prepare for demise of controller microcode>;
ENDCASE => NULL <Any select arms irrelevant for a given device may be omitted>
ENDLOOP
END;
Item: TYPE [2];
Perform:
PROCEDURE [reason: Reason] =
INLINE { linkage.Perform[reason] };
Execute each waiting cleanup procedure, passing given reason
Interrupts should have been previously disabled
Linkage:
PRIVATE
TYPE =
RECORD [
Await: PROCEDURE [POINTER TO Item] RETURNS [Reason],
Perform: PROCEDURE [Reason]
];
linkage: PRIVATE Linkage;
InitializeDeviceCleanup: PRIVATE PROC; -- called early on from DebugNub
END.