-- 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.