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