// IfsInitSwap.bcpl -- IFS swappable initialization // Copyright Xerox Corporation 1979, 1980, 1981 // Last modified June 25, 1981 7:07 PM by Taft get "Ifs.decl" get "IfsRs.decl" get "IfsDirs.decl" get "AltoFileSys.d" get "IfsInit.decl" get "Pup0.decl" get "Pup1.decl" external [ // outgoing procedures InitIFSPart3; FreeStackEvent // incoming procedures MakeFree; OpenIFSPart2; CreateIFSPart2; IFSError; CheckDirectory InitPupLevel1; PupChecksum; IfsPupChecksum; InitRSMgr; InitXMOverlays InitFtpServ; InitTelnet; InitMail; InitMiscellaneous; InitEventMgr InitAllocSpy; InitVMemSpy; InitBackup; InitPrintError; InitLeaf; InitPress InitMemoryError CreateOFT; DestroyOFT; SetAllocation OpenVFile; IFSOpenFile; PositionPage; Closes; MoveBlock; SetBlock; Usc CallersFrame; AddToZone; Allocate; Free; Zero; ReadCalendar InitializeContext; Enqueue; ExtractSubstring CreateEvent; InstallSysParams; FreePointer; VFileReadPage; VFileWritePage // outgoing statics infoVMD // incoming statics sysZone; bigZone; smallZone; ifsCtxQ; primaryIFS; system numVMemBufs; numPBIs; lenJobT; dPSIB CtxRunning; rtpStackSize; isb; monthNames; numOvXMPages leafPresent; leafEnabled; spyBuffer ] static [ infoVMD ] manifest [ stkLim = 335b cursorBitMap = 431b ] //---------------------------------------------------------------------------- let InitIFSPart3() be //---------------------------------------------------------------------------- // This procedure will be called in as an overlay. It cuts up the resident // initialization code into vmem buffers, finishes opening the primary file // system, calls swappable initialization in other modules, and arranges to // turn the remaining stack into vmem buffers. // Much of this initialization is very delicate, and it is crucial that // it be done in the correct order. [ // Set up dummy context in which we pretend to run (for access checks, etc.) let saveCtxRunning = CtxRunning let v = vec lenRSCtx; CtxRunning = v Zero(v, lenRSCtx) CtxRunning>>RSCtx.userInfo = system // Finish opening (or creating) primary file system. // I hope we have enough VMem buffers to do this now! if isb>>ISB.creatingPrimary then CreateIFSPart2(primaryIFS) let ec = nil unless OpenIFSPart2(primaryIFS, lv ec) do IFSError(ec) // Verify that the directory is well-formed if isb>>ISB.verifyTree then CheckDirectory(primaryIFS) // Open the Info file OpenSystemInfo() // Now, at last, we can decide how to carve up the remaining // resident initialization, move code into XM, etc., which is not possible // until we can look at SysParam.enableLeaf in the Info file. leafEnabled = VFileReadPage(infoVMD, spPage)>>SysParams.enableLeaf if leafEnabled then leafPresent = true // can also be forced by /L switch // Prepare to discard leaf resident code if Leaf is not to be present unless leafPresent do [ let lenLeafResident = isb>>ISB.pcI - isb>>ISB.pcL isb>>ISB.pcI = isb>>ISB.pcL isb>>ISB.initStart = isb>>ISB.initStart - lenLeafResident if spyBuffer ne 0 then spyBuffer = spyBuffer - lenLeafResident ] // InitIFSPart3 (cont'd) // Attempt to load overlays into extended memory. // If this is successful it will consume some of the storage // formerly occupied by initialization code, updating isb>>ISB.initStart. InitXMOverlays() // Determine how many VMem buffers are potentially available, and let // InitRSMgr decide how many jobs can be supported and how much // additional space must be given up for zones and PBIs. let potentialVMemBufs = numVMemBufs + (isb>>ISB.bigZoneBot - isb>>ISB.initStart) rshift logStdPageLength if isb>>ISB.residentCodeXM then potentialVMemBufs = potentialVMemBufs - 1 + // -1 for breakage (isb>>ISB.pcI - isb>>ISB.pcX) rshift logStdPageLength InitEventMgr() InitRSMgr(potentialVMemBufs) // must follow InitEventMgr -- calls CreateEvent // Turn additional space over to the zones if isb>>ISB.smallZoneIncr ne 0 then [ AddToZone(smallZone, isb>>ISB.initStart, isb>>ISB.smallZoneIncr) isb>>ISB.initStart = isb>>ISB.initStart + isb>>ISB.smallZoneIncr ] if isb>>ISB.bigZoneIncr ne 0 then [ // round up to next page boundary, since scraps will go to bigZone anyway let newFree = ((isb>>ISB.initStart + isb>>ISB.bigZoneIncr) % (1 lshift logStdPageLength -1)) +1 AddToZone(bigZone, isb>>ISB.initStart, newFree - isb>>ISB.initStart) isb>>ISB.initStart = newFree ] // Turn the remaining initialization code into vMem buffers. MakeFree(bigZone, isb>>ISB.initStart, isb>>ISB.bigZoneBot-isb>>ISB.initStart) // If we moved resident code into XM, turn it into free storage as well. // Must do this after the preceding MakeFree to avoid the AddToZone bug. if isb>>ISB.residentCodeXM then MakeFree(bigZone, isb>>ISB.pcX, isb>>ISB.pcI - isb>>ISB.pcX) // Initialize Pup package, with routing table big enough to cope with // simultaneous connections from many networks. InitPupLevel1(sysZone, ifsCtxQ, numPBIs, 0, (leafPresent? lenJobT+2, lenJobT+15)) PupChecksum = IfsPupChecksum //install microcoded checksum routine // Limit allocation of rendezvous and transient unregistered sockets. // (Registered sockets' allocations are managed by DistributedPBIs.) SetAllocation(dPSIB - offset PupSoc.psib/16, 6, 5, 5) // Extra RTP stack space needed to handle overlay faults. // Even more space needed with Extended Emulator, since RTPFSM references // a large table. rtpStackSize = (numOvXMPages gr 0? 300, 180) // InitIFSPart3 (cont'd) // Execute all other swappable initialization InitTimeIO() InitAllocSpy() InitVMemSpy() InitTelnet() InitMiscellaneous() // must follow OpenSystemInfo -- uses infoVMD InitPress() // must follow OpenSystemInfo -- uses infoVMD InitBackup() // must follow OpenSystemInfo -- uses infoVMD InitFtpServ() InitMail() // must follow OpenSystemInfo and InitFtpServ if leafPresent then [ InitLeaf() // primaryIFS must have a bigger OFT if Leaf is present. // n.b. this depends on there being no open files at this time! unless DestroyOFT(primaryIFS) do IFSError(ecCantDestroyOFT) CreateOFT(primaryIFS, 128) // must be power of 2 ] InstallSysParams(true) // must follow all of the Init routines above InitPrintError() InitMemoryError() // Record starting time and Ifs.run creation time let sp = VFileWritePage(infoVMD, spPage) ReadCalendar(lv sp>>SysParams.ifsStartTime) MoveBlock(lv sp>>SysParams.runFileCreated, lv isb>>ISB.runFileCreated, 2) // Create an event to free up all of the remaining stack. isb>>ISB.stkBase = @stkLim isb>>ISB.stkLength = CallersFrame()-isb>>ISB.stkBase-2 CreateEvent(FreeStackEvent) @stkLim = CallersFrame()-1 CtxRunning = saveCtxRunning // Change cursor to 'IFS' MoveBlock(cursorBitMap, table [ 0; 0; 0; 0; 71706b; 21011b; 21010b; 21606b 21001b; 21011b; 71006b; 0; 77777b; 0; 0; 0 ], 16) ] //---------------------------------------------------------------------------- and FreeStackEvent(ecb) be //---------------------------------------------------------------------------- [ MakeFree(bigZone, isb>>ISB.stkBase, isb>>ISB.stkLength) Free(sysZone, ecb) FreePointer(lv isb>>ISB.xepTable) Free(sysZone, isb) ] //--------------------------------------------------------------------------- and OpenSystemInfo() be //--------------------------------------------------------------------------- [ let name = "Info!1" infoVMD = OpenVFile(name, systemInfoPages) if infoVMD eq 0 then [ let str = IFSOpenFile(name, 0, modeWrite) if str eq 0 then IFSError(ecCreateEssentialFile) PositionPage(str, systemInfoPages) Closes(str) infoVMD = OpenVFile(name, systemInfoPages) if infoVMD eq 0 then IFSError(ecTridentFile, name) ] ] //--------------------------------------------------------------------------- and InitTimeIO() be // make legal constant string for modified IfsTimeIO //--------------------------------------------------------------------------- monthNames = ExtractSubstring("x*007January*000*000*010February*000*005March*000*000*000*000*005April*000*000*000*000*003May*000*000*000*000*000*000*004June*000*000*000*000*000*004July*000*000*000*000*000*006August*000*000*000*011September*007October*000*000*010November*000*010December*000") +1