*----------------------------------------------------------- Title[PilotBoot.mc...June 18, 1982 3:31 PM...Taft]; * Pilot Germ boot sequence *----------------------------------------------------------- TopLevel; DontKnowRBase; Set[XTask, IP[EMU]]; *----------------------------------------------------------- * Data structures *----------------------------------------------------------- * Germ conventions: MC[baseGerm, 1000]; * = BootSwap.countSkip * wordsPerPage * pRequest: POINTER TO Request = LOOPHOLE[1360B]; MC[pRequest, 1360]; * Request: TYPE = MACHINE DEPENDENT RECORD [ MC[Req.action, 0]; * action: Action, MC[Req.deviceType, 1]; * deviceType: Device.type, MC[Req.deviceOrdinal, 2]; * deviceOrdinal: CARDINAL, MC[Req.vp, 3]; * vp: SELECT OVERLAID * FROM * disk => [diskFileID: DiskFileID], * ethernet => [bfn, net, host: CARDINAL]; * Device.Type: TYPE = {diablo31, sa800, sa1000, sa4000, cdc9730, ethernet}; MC[DType.sa4000, 3]; * Actually, Dorado Trident disk MC[DType.ethernet, 5]; * Action: TYPE = {inLoad, outLoad, bootPhysicalVolume, teleDebug, noOp}; MC[Act.bootPhysicalVolume, 2]; * pSwitches: POINTER TO ARRAY [0..2] OF CARDINAL = LOOPHOLE[1242B]; MC[pSwitches, 1242]; *----------------------------------------------------------- * Entry conditions: * Real memory has been mapped contiguously at the bottom of virtual * memory, and zeroed. Base registers have been set up. * I/O devices have been initialized and are quiescent. * Exit conditions: * Germ loaded into memory and Mesa emulator started executing it. *----------------------------------------------------------- GermBoot: RBase← RBase[BTemp0]; MemBase← IOBR; BootDataPtr← baseGerm; * Where to load it BTemp2← Desc.bi.germ, SCall[DiskBootSoft]; * What to load GermBootFailed: Breakpoint, Branch[.]; * +1: boot failed * Store into the Germ the magic values that tell it what to do. T← And[pRequest!, 177400]C; * Set up the Request T← T OR (And[pRequest!, 377]C); T← (Store← T)+1, DBuf← Act.bootPhysicalVolume; T← (Store← T)+1, DBuf← DType.sa4000; Store← T, DBuf← 0C; T← And[pSwitches!, 177400]C; * Set up the Switches -- all zeroes T← T OR (And[pSwitches!, 377]C); Cnt← 2S; T← (Store← T)+1, DBuf← 0C, Branch[., Cnt#0&-1]; * We ought to be able to remap the Germ into MDS 76 simply by exchanging map * entries in MDSs 0 and 76 for those pages into which the Germ was read. * However, that would leave a hole (vacant pages) in MDS 0, and apparently * the Germ can't cope with that. So instead we steal some pages from the * end of mapped virtual memory, remap them into MDS 76, and copy the Germ. * Note that BootDataPtr points to start of the page after the Germ. T← BootDataPtr, RBase← RBase[RTemp0]; RTemp2← Q← T; * Save it in 2 places RTemp1← A0, MemBase← LPtr; FindEndMappedVM: T← RSH[RTemp1, 10]; BRHi← T; T← LSH[RTemp1, 10]; BRLo← T; RTemp0← A0, SCall[ReadMapPage]; Branch[GermRemapLpE]; * +1: found first vacant page RTemp1← (RTemp1)+1, Branch[FindEndMappedVM]; * +2: not vacant GermRemapLp: RTemp2← (RTemp2)-(400C), * RTemp2← VA of page to do Branch[GermRemapDone, ALU=0]; T← RTemp1← (RTemp1)-1; * T← last mapped virtual page Call[SetBRAndFlushPage]; RTemp0← A0, Call[ReadMapPage]; RTemp3← T, * Old contents of that map entry DispTable[1, 1, 1]; * Always return here from ReadMapPage T← 60000C, Call[WriteMapPage]; * Make it vacant T← RSH[RTemp2, 10]; * T← Germ page number to do T← T+(LShift[PilotMDSHi!, 10]C); * T← that page # in MDS 76 Call[SetBRAndFlushPage]; * Actually, don't need to flush T← RTemp3, Call[WriteMapPage]; * Put stolen page into the map GermRemapLpE: PD← (RTemp2)-(baseGerm), Branch[GermRemapLp]; * See if done all pages * At this point, LPtr points to the base of where the Germ will go in MDS 76. * Q still has the VA of the first page after where the Germ is now in MDS 0. GermRemapDone: RTemp2← Q; T← (RTemp2)-(baseGerm); * Not the world's fastest BLT loop, but who cares? RTemp2← (RTemp2)-1, MemBase← IOBR; Fetch← RTemp2; T← T-1, MemBase← LPtr; Store← T, DBuf← MD, Branch[.-3, ALU#0]; Branch[MGo]; * Go start it up!