<> <> <> <> <> <> <<>> DIRECTORY MicrocodeBooting USING [ BootFileNumber, MicrocodeType, nullBootFileNumber ], File USING [ Handle, PageNumber, Volume, VolumeFile, VolumeID, nullVolumeID ], GermSwap USING [ Switches ], Rope USING [ ROPE ]; Booting: CEDAR DEFINITIONS = BEGIN ROPE: TYPE ~ Rope.ROPE; Switches: TYPE = GermSwap.Switches; switches: Switches; <> MicrocodeType: TYPE = MicrocodeBooting.MicrocodeType; <<= { altoMesa, lisp, smalltalk76, smalltalk80, pilotMesa, cedarMesa }>> BootFileNumber: TYPE = MicrocodeBooting.BootFileNumber; nullMicrocode: BootFileNumber = MicrocodeBooting.nullBootFileNumber; Bootee: TYPE = RECORD[ SELECT type: * FROM noOp => NULL, file => [ file: File.Handle, firstPage: File.PageNumber _ [0] ], logical => [ volume: File.Volume _ NIL, root: File.VolumeFile[checkpoint..debuggee] _ bootFile ], physical => [ volume: File.--Physical--VolumeID _ File.nullVolumeID, root: File.VolumeFile[checkpoint..bootFile] _ bootFile ], microcode => [ bfn: BootFileNumber _ nullMicrocode ], bootButton => NULL, self => NULL, ENDCASE ]; Boot: PROC [boot: Bootee, switches: Switches, outload: Bootee _ [noOp[]] ] RETURNS [rejection: ROPE _ NIL]; <> <<>> <> <<>> <<"switches" is ignored by some variants. (Today, "bootButton" and "microcode".)>> <<>> <<"self" boots from the boot location which was used to boot this run.>> <<"bootButton" emulates pressing the physical boot button>> <<"microcode" boots new microcode. Default will use installed disk microcode.>> <<"physical" boots from the specified root of the physical volume having the specified ID (nullVolumeID means the physical volume containing page 0 of the system volume).>> <<"logical" boots from the specified root of the specified logical volume (NIL means the system volume).>> <<"file" boots from the specified file (first makes the file bootable).>> <<>> <> inloadedOnce: BOOL; <> GetBootFileNumber: PROC [MicrocodeType] RETURNS [BootFileNumber]; <> Checkpoint: PROC RETURNS [rejection: ROPE _ NIL]; <> <> <> <> <> CheckpointProc: TYPE = PROC [clientData: REF ANY] RETURNS [rejection: ROPE _ NIL]; <> RollbackProc: TYPE = PROC [clientData: REF ANY]; <> RegisterProcs: PROC [c: CheckpointProc _ NIL, r: RollbackProc _ NIL, b: CheckpointProc _ NIL, clientData: REF ANY _ NIL]; <<... registers checkpoint, roolback, and booting procedures to be called when the appropriate event occurs. Note that the pairing of the procs is important if someone rejects the checkpoint: for each CheckpointProc that had been called, the associated RollbackProc (if any) is called on a rejection. The booting procedure needs no such pairing (it is not expected to make significant changes).>> Deregister: PROC [c: CheckpointProc _ NIL, r: RollbackProc _ NIL, b: CheckpointProc _ NIL]; <<... removes the given registration.>> DeleteCheckpoint: PROC [volume: File.Volume]; <> <<>> CallBootingProcs: PROC RETURNS [rejection: ROPE]; <> END.