-- File: PupMicrocodeBooter.mesa - last edit: -- AOF 3-Feb-88 14:13:24 -- HGM 18-Jun-85 6:45:25 -- Copyright (C) 1983, 1985, 1988 by Xerox Corporation. All rights reserved. DIRECTORY Inline USING [LongCOPY, LowHalf], Process USING [Pause, Yield], Space USING [nullInterval], System USING [Pulses, GetClockPulses, PulsesToMicroseconds], BootServerDefs USING [microcodeReply, WhatHappened], BootServerFriends USING [BootFile, LockFileRead, SetupSpace, UnlockFile], PupDefs USING [ PupBuffer, FastPath, GetLocalPupAddress, SendPup, AccessHandle, DestroyPool, GetBuffer, MakePool], PupTypes USING [PupAddress, miscSrvSoc]; PupMicrocodeBooter: PROGRAM IMPORTS Inline, Process, System, PupDefs, BootServerFriends EXPORTS BootServerDefs = BEGIN microcodeVersionNumber: CARDINAL ← 1; MicrocodeBooter: PUBLIC PROCEDURE [ bf: BootServerFriends.BootFile, him: PupTypes.PupAddress] RETURNS [what: BootServerDefs.WhatHappened] = { RETURN[RealMicrocodeBooter[bf, him, FALSE]]; }; SlowMicrocodeBooter: PUBLIC PROCEDURE [ bf: BootServerFriends.BootFile, him: PupTypes.PupAddress] RETURNS [what: BootServerDefs.WhatHappened] = { RETURN[RealMicrocodeBooter[bf, him, TRUE]]; }; RealMicrocodeBooter: PROCEDURE [ bf: BootServerFriends.BootFile, him: PupTypes.PupAddress, slow: BOOL] RETURNS [what: BootServerDefs.WhatHappened] = BEGIN pulses: System.Pulses ← System.GetClockPulses[]; me: PupTypes.PupAddress ← PupDefs.GetLocalPupAddress[ PupTypes.miscSrvSoc, @him]; packetNumber: CARDINAL ← 0; pool: PupDefs.AccessHandle; from: LONG POINTER; wordsLeft: CARDINAL ← Inline.LowHalf[bf.bytes/2]; -- won't work if more than 256 pages page: CARDINAL; IF ~PupDefs.FastPath[him] THEN slow ← TRUE; IF ~BootServerFriends.LockFileRead[bf] THEN RETURN[diskBusy]; pool ← PupDefs.MakePool[send: 10, receive: 0]; IF bf.space = Space.nullInterval THEN BootServerFriends.SetupSpace[bf]; from ← bf.space.pointer; BEGIN b: PupDefs.PupBuffer; IF from↑ # microcodeVersionNumber THEN GOTO MisMatch; from ← from + 256; -- skip over header page in boot file wordsLeft ← wordsLeft - 256; FOR page ← 0, page + 3 DO length: CARDINAL; length ← IF wordsLeft > 255 THEN 255 ELSE wordsLeft; b ← PupDefs.GetBuffer[pool, send]; b.pup.dest ← him; b.pup.source ← me; b.pup.pupID ← [microcodeVersionNumber, packetNumber]; Inline.LongCOPY[from: from, nwords: length, to: @b.pup.pupWords[0]]; PupDefs.SendPup[b, BootServerDefs.microcodeReply, length*2]; IF slow THEN Pause[]; packetNumber ← packetNumber + 1; from ← from + length; wordsLeft ← wordsLeft - length; IF wordsLeft = 0 THEN EXIT; -- second of three length ← IF wordsLeft > 255 THEN 255 ELSE wordsLeft; b ← PupDefs.GetBuffer[pool, send]; b.pup.dest ← him; b.pup.source ← me; b.pup.pupID ← [microcodeVersionNumber, packetNumber]; Inline.LongCOPY[from: from, nwords: length, to: @b.pup.pupWords[0]]; PupDefs.SendPup[b, BootServerDefs.microcodeReply, length*2]; IF slow THEN Pause[]; packetNumber ← packetNumber + 1; from ← from + length; wordsLeft ← wordsLeft - length; IF wordsLeft = 0 THEN EXIT; -- third of three length ← IF wordsLeft > 258 THEN 258 ELSE wordsLeft; b ← PupDefs.GetBuffer[pool, send]; b.pup.dest ← him; b.pup.source ← me; b.pup.pupID ← [microcodeVersionNumber, packetNumber]; Inline.LongCOPY[from: from, nwords: length, to: @b.pup.pupWords[0]]; PupDefs.SendPup[b, BootServerDefs.microcodeReply, length*2]; IF slow THEN Pause[]; packetNumber ← packetNumber + 1; from ← from + length; wordsLeft ← wordsLeft - length; IF wordsLeft = 0 THEN EXIT; ENDLOOP; b ← PupDefs.GetBuffer[pool, send]; b.pup.dest ← him; b.pup.source ← me; b.pup.pupID ← [microcodeVersionNumber, packetNumber]; PupDefs.SendPup[b, BootServerDefs.microcodeReply, 0]; -- End Marker for Initial pulses ← System.Pulses[System.GetClockPulses[] - pulses]; bf.count ← bf.count + 1; bf.ms ← bf.ms + System.PulsesToMicroseconds[pulses]/1000; what ← micro; EXITS MisMatch => what ← troubles; END; BootServerFriends.UnlockFile[bf]; PupDefs.DestroyPool[pool]; END; microsecondsToPause: LONG CARDINAL ← 10000; saveTheCpu: BOOL ← FALSE; Pause: PROCEDURE = BEGIN start: System.Pulses ← System.GetClockPulses[]; DO pulses: System.Pulses ← System.Pulses[System.GetClockPulses[] - start]; IF saveTheCpu THEN Process.Pause[1] ELSE Process.Yield[]; IF System.PulsesToMicroseconds[pulses] > microsecondsToPause THEN EXIT; ENDLOOP; END; END.