// IfsBootSend.bcpl -- Boot Server -- overflow from IfsBootServ.bcpl // Copyright Xerox Corporation 1981, 1982, 1983 // Last modified January 22, 1983 10:48 AM by Taft get "Pup0.decl" get "Pup1.decl" get "Ifs.decl" get "IfsRs.decl" get "IfsBootServ.decl" get "IfsServEFTP.decl" external [ // outgoing procedures SendBootFile; SendMicrocodeFile; FindBFE; BFTCompareKey // incoming procedures PupServSend OpenLevel1Socket; CloseLevel1Socket; GetPBI; CompletePup; DeclarePupSoc IFSOpenFile; SetFilePos; ReadBlock; Closes Free; Zero; Usc; DoubleIncrement; DestroyJob; ReadRecLE // incoming statics @bs; sysZone ] //---------------------------------------------------------------------------- let FindBFE(bfn) = valof //---------------------------------------------------------------------------- // Looks up boot file number bfn and returns a pointer to the // corresponding boot file entry (bfe) if found and zero if not found. // Caller must keep bfe in a locked cell until finished with it. // Caller is responsible for locking the BFT to maintain consistency. [ let bfe = ReadRecLE(bs>>BS.tree, bfn, 0, true) resultis bfn eq bfe>>BFE.bfn? bfe, 0 ] //---------------------------------------------------------------------------- and BFTCompareKey(bfn, bfe) = Usc(bfn, bfe>>BFE.bfn) //---------------------------------------------------------------------------- // CompareKey routine handed to the B-tree package //---------------------------------------------------------------------------- // and BFTEntryLength(bfe) = bfe>>BFE.length //---------------------------------------------------------------------------- // Length routine handed to the B-tree package; hand-coded in IfsBootA.asm //---------------------------------------------------------------------------- and SendBootFile(ctx) be // a BootCtx //---------------------------------------------------------------------------- [ let ftp = vec lenFTP; Zero(ftp, lenFTP) ftp>>FTP.frnPort = lv ctx>>BootCtx.port ftp>>FTP.realName = ctx>>BootCtx.name let fast = (ctx>>BootCtx.booterFlags & bsFastBooter) ne 0 ftp>>FTP.timeOut1 = fast? 100, 3000 // 1 sec, 30 sec ftp>>FTP.timeOut2 = fast? 400, 6000 // 4 sec, 60 sec if PupServSend(ftp, ctx>>BootCtx.bytesToSkip) then DoubleIncrement(fast? lv bs>>BS.stats.fastSends, lv bs>>BS.stats.slowSends) Free(sysZone, ctx>>BootCtx.name) bs>>BS.flags = bs>>BS.flags & not ctx>>BootCtx.booterFlags DestroyJob() ] //---------------------------------------------------------------------------- and SendMicrocodeFile(ctx) be // a BootCtx //---------------------------------------------------------------------------- // Send microcode boot file by skipping the overhead page at the beginning // and sending the rest of the file as Pups containing multiples of // 3 words (for the benefit of D0s), terminated by an empty Pup. // The protocol employs no acknowledgments -- if a packet is lost, the // requestor must ask the boot server to send the whole file over again. [ let soc = vec lenPupSoc OpenLevel1Socket(soc, 0, lv ctx>>BootCtx.port) // D0s require that the boot file come from a socket whose // low-order socket number is 4! soc>>PupSoc.lclPort.socket↑2 = socketMiscServices DeclarePupSoc(soc) let stream = IFSOpenFile(ctx>>BootCtx.name) if stream ne 0 then [ SetFilePos(stream, 0, 512) // skip overhead page let words = nil let seqNo = 0 [ // repeat let pbi = GetPBI(soc) words = ReadBlock(stream, lv pbi>>PBI.pup.words, uCodeWordsPerPup) pbi>>PBI.pup.id↑1 = 1 // D0s require this pbi>>PBI.pup.id↑2 = seqNo CompletePup(pbi, ptBootMicrocodeReply, pupOvBytes + words lshift 1) seqNo = seqNo+1 ] repeatuntil words eq 0 Closes(stream) ] CloseLevel1Socket(soc) DeclarePupSoc(0) Free(sysZone, ctx>>BootCtx.name) bs>>BS.flags = bs>>BS.flags & not ctx>>BootCtx.booterFlags DestroyJob() ]