*----------------------------------------------------------- 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;