*----------------------------------------------------------- Title[InitialSubrs...August 28, 1985 3:23 PM...Willie-Sue]; * Subroutines to assist in memory system initialization. *----------------------------------------------------------- % *----------------------------------------------------------- Subroutines in this File, by Order of Appearance in Listing SetMCR Set MCR w/ T LongWait Wait T cycles, excluding cost of Call and Return. ClearCacheFlags Clear all the flags of the cache. PresetMap Initialize map to Map[i]← i SetTestSyn Set test syndrome. SetBRForPage Set BR so that VA=0 will point to indicated page. WriteMap Map[BR]← RScr,,RScr2 ResetTags Initialize the tags for the current task. WaitForMapBuf Wait for MapBuf to be not busy % *----------------------------------------------------------- M[PushReturn, TopLevel[] ILC[(Stack&+1← Link)]]; M[ReturnP, (StkP-1, Branch[DoReturn])]; * Cache configuration -- must change when 4K cache data chips are installed. MC[highestCol, 3]; * maximum column index MC[highestRow, 77]; * maximum row index Set[CABitsInPipe1, 6]; * CacheA data bits that appear in Pipe1 Set[cacheShift, 4]; * Position of cache row in VA Set[nBitsInRow, 6]; * Map configuration * Pretend map is 16K, and simply do not touch map entries beyond that. * Emulators do a more thorough initialization and discover the truth about the hardware. * Unfortunately, if there is more real memory than the "map" covers, * the intialization gets very confused and leaves at least some of the map * initialized to vacant. * Hence, the nPagesInMap has been set to 64K (almost) Set[logWordsPerPage, 10]; MC[nPagesInMap, 177400]; TopLevel; *----------------------------------------------------------- DoReturn: * Branched to by ReturnP macro *----------------------------------------------------------- Link← Stack, Branch[Retn]; *----------------------------------------------------------- SetMCR: * Set MCR from T after maximum possible required wait *----------------------------------------------------------- Subroutine; Cnt← 6S, Global; * LoadMCR >8 cycles after last mem op Branch[., Cnt#0&-1]; PD← A0, LoadMCR[T, T], Branch[LWRetn]; * wait for MCR to settle down *----------------------------------------------------------- LongWait: * wait (T + 2) cycles, not counting Call or Return *----------------------------------------------------------- Subroutine; PD← T, Global; LWRetn: T← T-1, Branch[., ALU#0]; Retn: Return; *----------------------------------------------------------- ClearCacheFlags: *----------------------------------------------------------- Subroutine; RowX← highestRow, Global; PushReturn; ClrCacheFRowL: * loop for all the rows of the cache ColX← highestCol; ClrCacheFColL: * loop for the columns in this row * This code performs: CacheA[VA, ColX] ← ColX T← LSH[ColX, nBitsInRow]; * T← VA for ColX and RowX T← T OR (RowX); VA← LSH[T, cacheShift]; T← A0, Call[SetBRForPage]; Set[wantMCR, Or[mcr.useMCRV!, mcr.disCF!, mcr.disHold!, mcr.noWake!, mcr.noRef!, mcr.fdMiss!]]; T← DPF[ColX, 2, mcr.MCRVShift]; * Use ColX as victim; position for MCR T← T OR (HighByte[wantMCR]); T← T OR (LowByte[wantMCR]), Call[SetMCR]; Store← VA, DBuf← 0C; T← 12C, Call[LongWait]; Store← VA, DBuf← 0C; T← 12C, Call[LongWait]; * This code performs: CFlags[VA, ColX] ← Vacant Set[wantMCR, Or[mcr.fdMiss!, mcr.noRefHold!, mcr.noWake!, mcr.useMCRV!]]; T← DPF[ColX, 2, mcr.MCRVShift]; * T← MCR value for ColX as victim T← T OR (HighByte[wantMCR]); T← T OR (LowByte[wantMCR]), Call[SetMCR]; T← Xor[cFlags.Vacant!, cFlags.mask!]C; * CFlags← A wants flags inverted VA← (VA)-T; * Set BR← (VA-flags) RScr← T-T-1, XorSavedCarry; BRLo← VA; BRHi← RScr; * Must put flags on MAR during cycle before CFlags← DummyRef← T; * Really DummyRef← VA CFlags← T; * Put flags in last referenced entry * Repeat for all columns and all rows ColX← (ColX)-1; PD← (RowX)-1, Branch[ClrCacheFColL, ALU>=0]; RowX← (RowX)-1, Branch[ClrCacheFRowL, ALU>=0]; ReturnP; *----------------------------------------------------------- PresetMap: * Reset and initialize the map hardware from an arbitrary state. * Initialize entire map to establish a one-to-one correspondence between * virtual and real memory. *----------------------------------------------------------- Subroutine; PushReturn; Set[wantMCR, Or[mcr.fdMiss!,mcr.disHold!,mcr.disCF!,mcr.disBR!,mcr.noWake!]]; T← HighByte[wantMCR]; T← T OR (LowByte[wantMCR]), Call[SetMCR]; * When the machine powers up, the map may be in an arbitrary state. * Kick-start the automata by performing two fetches. Cope with "tag" bit by * performing a reference that hits and then punch on the map 8 times * to wake it up. Fetch← RM0, T← 40C, Call[LongWait]; * do two fetches, separated by waits Fetch← RM0, T← 40C, Call[LongWait]; RScr← A0, Cnt← 10S, Call[ResetTags]; * reset our tag bit. use VA=0 ResetMapL: RScr← A0; RScr2← A0, Call[WriteMap]; T← mcr.disHold, Branch[ResetMapL, Cnt#0&-1]; * reset MCR for further map testing: T← T OR (mcr.noWake), Call[SetMCR]; * use disHold, noWake B← FaultInfo', * clear any pending wakeups Call[ClearCacheFlags]; * assure beingLoaded not set in cache T← mcr.noWake, Call[SetMCR]; * clear MCR * Read the storage configuration, and set these registers: * PgsPerMod = number of pages per module * ModMask = bit mask of modules present (B0=1 => module 0 present, etc.) ModMask← NOT (Config'); T← LDF[ModMask, 2, 2]; * Storage chip size = 2↑(12 + 2*T) T← DPF[T, 2, 11]; * ShC count ← 2*T MPageX← T-(ShC← T)-1; PgsPerMod← 400C; * 4K chips give 400B pages/module PgsPerMod← ShiftNoMask[PgsPerMod]; * LCY[R, R, 2*n] ModMask← LSH[ModMask, 10]; * Left-justify the module-present bits ModMask← (ModMask) AND (170000C); RScr2← T-T-1, Branch[NoStorage, ALU=0]; Nop; * Placement * MPageX maintains the virtual page minus 1, RScr2 the real page minus 1. FindModule: ModMask← (ModMask) LSH 1, Branch[MapModule, R<0]; T← PgsPerMod, Branch[EndOfStorage, ALU=0]; RScr2← (RScr2)+T, Branch[FindModule]; * Skip nonexistent real pages * PresetMap (cont'd) MapModule: Cnt← PgsPerMod, Branch[PresetMapE]; PresetMapL: RScr2← (RScr2)+1; MPageX← T← (MPageX)+1, Call[SetBRForPage]; * expects T = virtual page RScr← A0, Call[WriteMap]; * Write map entry; WP and Dirty = 0 PresetMapE: DblBranch[PresetMapL, FindModule, Cnt#0&-1]; * Exhausted all real storage. Fill remainder of map with Vacant entries. EndOfStorage: T← nPagesInMap; T← T-(MPageX)-1; RScr2← T-T-1, Cnt← T, Branch[PresetVacantE]; PresetVacantL: Nop; * Placement MPageX← T← (MPageX)+1, Call[SetBRForPage]; RScr← 140000C, Call[WriteMap]; * WP=1, Dirty=1, real page = -1 PresetVacantE: Branch[PresetVacantL, Cnt#0&-1]; ReturnP; * No storage modules are present. NoStorage: Branch[.], Breakpoint; *----------------------------------------------------------- SetTestSyn: * Load the TestSyndrome register from RScr2 *----------------------------------------------------------- Subroutine; PushReturn; T← 62C, Call[LongWait]; T← mcr.noWake, Call[SetMCR]; T← A0, Call[SetBRForPage]; * Zero the current BR Store← T, DBuf← RScr2; * DBuf← data LoadTestSyndrome; * TestSyndrome← DBuf T← 62C, Call[LongWait]; ResetFaultInfo: B← FaultInfo', ReturnP; *----------------------------------------------------------- SetBRForPage: * Set BR such that a reference to address 0 will generate * a VA referencing the specified page. * Enter: T = virtual page number * Clobbers RScr. *----------------------------------------------------------- Subroutine; RScr← LSH[T, logWordsPerPage]; BRLo← RScr; RScr← RSH[T, Sub[20, logWordsPerPage]]; BRHi← RScr, Return; *----------------------------------------------------------- WriteMap: * Write map entry * Enter: RScr = WP and Dirty bits, left-justified * RScr2 = real page number * Current BR contains VA for map entry to be written *----------------------------------------------------------- Subroutine; PushReturn; TIOA← RScr, Call[WaitForMapBuf]; Map← 0S, MapBuf← RScr2, Call[WaitForMapBuf]; ReturnP; *----------------------------------------------------------- WaitForMapBuf: *----------------------------------------------------------- Subroutine; PD← T-T-1; PD← PRef, Branch[., ALU<0]; * MapBufBusy is sign bit Return; *----------------------------------------------------------- ResetTags: * kick start the tag bit for our task. * RScr = address to reference. * Note: Initial calls ResetTags in all tasks simultaneously, with the same * RBase value. However, that's ok because the return PC and argument * (RScr2 and RScr) are the same for all calls. *----------------------------------------------------------- Set[XTask, 1]; Subroutine; RScr2← Link; * Can't use PushReturn in I/O task!! TopLevel; Set[wantMCR, Or[mcr.noRef!,mcr.disHold!,mcr.disCF!,mcr.disBR!,mcr.noWake!]]; T← HighByte[wantMCR]; T← T OR (LowByte[wantMCR]), Call[SetMCR]; Store← RScr, DBuf← RScr; * write and read to cause a hit T← 10C, Call[LongWait]; Link← RScr2; Subroutine; Fetch← RScr, Return; TopLevel;