DIRECTORY DebuggerDefs, DragOpsCross USING [ProcessorRegister, XopBase, TrapBase, TrapWidthBytes, TrapIndex], --Word, wordsPerPage, bytesPerWord, charsPerWord, bitsPerByte, bitsPerCharacter, bitsPerWord, bytesPerPage, logWordsPerPage, logBitsPerByte, logBitsPerChar, logBytesPerWord, logCharsPerWord, logBitsPerWord, logBytesPerPage, PageCount, PageNumber, maxPagesInVM, SixBitIndex, FiveBitIndex, TwoWords, FourBitIndex, Half, ThreeBitIndex, FourHalves, TwoHalves, Byte, ZerosByte, OnesByte, EightBytes, FourBytes, ByteIndex, BytesPerWord, TwoBytes, Comparison, ByteAddress, WordAddress, FieldDescriptor, RegIndex, PadByte, Lit8, Op4, Op8, JDist8, Inst, OIFormat, OQBformat, LRformat, QRformat, ShortRegQR, OBformat, LRBformat, RRformat, ODBformat, LRRBformat, RJBformat, ShortRegRJB, JBBformat, TrapWidthWords, TrapWidthBytes, XopBase, TrapBase, KernalLimit, TrapIndex, StackUnderflowTrap, IFUPageFaultTrap, ResetTrap, IFUStackOverflowTrap, EUStackOverflowTrap, RescheduleTrap, ALUCondFalse, ALUCondEZ, ALUCondLZ, ALUCondLE, ALUCondSpare, ALUCondNE, ALUCondGE, ALUCondGZ, ALUCondOver, ALUCondBC, ALUCondIL, ALUCondDO, ALUCondNotOver, ALUCondNB, ALUCondNI, ModeFault, MemAccessFault, IOAccessFault, EUPageFault, EUWriteFault, AUFault, euStack, euJunk, euToKBus, euMAR, euField, euConstant, euAux, euBogus, euLast, ifuYoungestL, ifuYoungestPC, ifuEldestL, ifuEldestPC, ifuSLimit, ifuBogus, ifuL, ifuS, ifuPC, ifuLast, EURegs, EULegalRegs, IFURegs, IFULegalRegs, StackedStatusWord, IFUStackIndex, IFUStackSize, IFUOverflow, EUStackIndex, EUStackSize, EULocalIndex, EULocals, EUAuxIndex, EUAuxRegs, EUConstIndex, EUConstants, IOLocation, ioRescheduleRequest, ioResetRequest, IOOperand, PCmdFormat, PCmdByteSelect, PCmdClass, PCmdSpace, PCmdDirection DragOpsCrossUtils USING [CardToWord], --InstToBytes, InstToFormat, BytePCToWordAddress, WordAddressToBytePC, IOOperandToCard, CardToIOOperand, FieldDescriptorToCard, CardToFieldDescriptor, BytesToWord, BytesToHalf, WordToBytes, HalfToBytes, HalvesToWord, WordToHalves, HighHalf, LowHalf, LeftHalf, RightHalf, SwapHalves, WordToInt, IntToWord, WordToCard, HalfToCard, ByteToCard, CardToWord, CardToHalf, CardToByte, DragAnd, DragOr, DragXor, DragNot, VanillaAdd, VanillaSub, AddDelta, HalfNot, HalfAnd, HalfOr, HalfXor, HalfShift, DoubleWordShiftLeft, SingleWordShiftLeft, SingleWordShiftRight, XopToBytePC, TrapIndexToBytePC, FieldUnit HandCoding, --Has opcode and register defs. HandCodingPseudos, --Label, SetLabel, GenLabel, GenLabelHere, UseLabel8A, UseLabel8B, UseLabel16, UseLabel32, LReg, PReg, SReg, AddReg, SubReg, SetRegConst, MoveReg, MoveRegI, LRegI, IndexedJump, ProcedureEntry, ProcedureExit, SetupField, ExtractField, ShiftLeft, LoadProcessorReg, StoreProcessorReg, CauseReschedule, CauseReset, GetSPLimit, SetSPLimit, GetYoungestPC, GetYoungestStatus, GetEldestPC, GetEldestStatus, SetYoungestPC, SetYoungestStatus, SetEldestPC, SetEldestStatus, Pause, Halt HandCodingSupport; --Area, GetProc, PutProc, ProcList, NewArea, GenWithArea, Gen1WithArea, ForceOut, GetCurrentArea, LoadArea, GetOutputPC, SetOutputPC, WordAlign, ReserveData, OutputByte, OutputOneByte, OutputAlphaBeta, OutputAlphaBetaGammaDelta, OutputWord GenTraps2: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DebuggerDefs, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; ProcessorRegister: TYPE = DragOpsCross.ProcessorRegister; ifuSLimit: CARDINAL = LOOPHOLE[ProcessorRegister.ifuSLimit, CARDINAL]; ifuEldestPC: CARDINAL = LOOPHOLE[ProcessorRegister.ifuEldestPC, CARDINAL]; ifuEldestL: CARDINAL = LOOPHOLE[ProcessorRegister.ifuEldestL, CARDINAL]; ifuYoungestPC: CARDINAL = LOOPHOLE[ProcessorRegister.ifuYoungestPC, CARDINAL]; ifuYoungestL: CARDINAL = LOOPHOLE[ProcessorRegister.ifuYoungestL, CARDINAL]; ifuStatus: CARDINAL = LOOPHOLE[ProcessorRegister.ifuStatus, CARDINAL]; euMAR: CARDINAL = LOOPHOLE[ProcessorRegister.euMAR, CARDINAL]; aux0: AuxRegSpec = [aux[0]]; aux1: AuxRegSpec = [aux[1]]; aux2: AuxRegSpec = [aux[2]]; aux3: AuxRegSpec = [aux[3]]; aux4: AuxRegSpec = [aux[4]]; aux5: AuxRegSpec = [aux[5]]; aux6: AuxRegSpec = [aux[6]]; aux14: AuxRegSpec = [aux[14]]; aux15: AuxRegSpec = [aux[15]]; const5: ConstSpec = [const[5]]; const6: ConstSpec = [const[6]]; const7: ConstSpec = [const[7]]; const8: ConstSpec = [const[8]]; const9: ConstSpec = [const[9]]; const10: ConstSpec = [const[10]]; const11: ConstSpec = [const[11]]; All: PROC = { --area: Area = GetCurrentArea[]; IFUStackOverflow: Label = GenLabel[]; IFUStkOvfBad: Label = GenLabel[]; EUStackOverflow: Label = GenLabel[]; EUStkOvfBad: Label = GenLabel[]; Reschedule: Label = GenLabel[]; RescheduleBad: Label = GenLabel[]; ErrorXop1Trap: Label = GenLabel[]; AlreadyInKernel: Label = GenLabel[]; TurnOnTraps: Label = GenLabel[]; TurnOffTraps: Label = GenLabel[]; TurnOnUserMode: Label = GenLabel[]; enterIFUStackOverflowTest: Label = GenLabel[]; enterSLimitTest: Label = GenLabel[]; enterRescheduleTest: Label = GenLabel[]; IFUPageFaultAddress: LONG CARDINAL = 27000000000B; FillXop: PROC [inst: CARDINAL, dest: Label] = { SetOutputPC[inst * DragOpsCross.TrapWidthBytes + DragOpsCross.XopBase * DragOpsCross.bytesPerWord]; drJDB[UseLabel16[dest]]; }; FillTrap: PROC [tx: DragOpsCross.TrapIndex, dest: Label] = { SetOutputPC[LOOPHOLE[tx, CARDINAL] * DragOpsCross.TrapWidthBytes + DragOpsCross.TrapBase * DragOpsCross.bytesPerWord]; drJDB[UseLabel16[dest]]; }; StandardTrap: PROC [dest: Label, code: CARDINAL] = { TrapUnexpected: Label = GenLabel[]; SetLabel[dest]; drALS[1]; --ALS[1 - nargs] drLIB[code]; drRJNEB[popSrc, aux8, UseLabel8B[TrapUnexpected]]; GetYoungestPC[]; drRVADD[topDst, const4, topSrc]; SetYoungestPC[]; drRET[377B]; --RET[nResults - 1] SetLabel[TrapUnexpected]; Pause[]; }; EnableTraps: PROC [] = { drDFC[UseLabel32[TurnOnTraps]]; }; DisableTraps: PROC [] = { drDFC[UseLabel32[TurnOffTraps]]; }; EnterUser: PROC [] = { drDFC[UseLabel32[TurnOnUserMode]]; }; EnterKernel: PROC [] = { drLIB[12]; drROR[aux8, popSrc, topSrc]; drKFC[]; drROR[aux8, const0, const0]; }; XPause: PROC = { HandCodingSupport.OutputByte[HandCodingSupport.GetCurrentArea[], LOOPHOLE[2]]; }; GenIFUStackOverflow: PROC [] ~ { exitIFUStkOvfTest: Label = GenLabel[]; SetLabel[enterIFUStackOverflowTest]; drASL[377B]; --0 locals, 0 pushes on the EU stack, 0 calls on the IFU stack drLIB[40B + 4B + 2B]; drSIP[ifuStatus]; --UserModeKeep + TrapsEnabled + RescheduleKeep drLFC[3]; --1 calls drLFC[3]; --2 calls drLFC[3]; --3 calls drLFC[3]; --4 calls drLFC[3]; --5 calls drLFC[3]; --6 calls drLFC[3]; --7 calls drLFC[3]; --8 calls drLFC[3]; --9 calls drLFC[3]; --10 calls drLIQB[UseLabel32[exitIFUStkOvfTest]]; --Return PC for stack overflow trap drLIB[1]; drROR[aux8, popSrc, topSrc]; --Indicate IFU stack overflow expected drDFC[CardToWord[IFUPageFaultAddress]]; --11 calls SetLabel[exitIFUStkOvfTest]; drROR[aux8, const0, const0]; --Indicate no traps expected FOR I: CARDINAL IN [0..10] DO GetEldestPC[]; ENDLOOP; drASL[17B]; --L = 1, S = 20B, traps enabled, Kernel mode, 0 calls on the stack }; GenSLimit: PROC [] ~ { SetLabel[enterSLimitTest]; drASL[377B]; --S = 0, L = 1 drLIB[1]; drSIP[ifuStatus]; --Turn off trap enable, turn on Reschedule drLC0[]; drLIB[1]; drSIP[ifuSLimit]; drLIB[2]; drROR[aux8, topSrc, popSrc]; --S = SLimit = 1 now drLIB[4B + 1B]; drSIP[ifuStatus]; --Trap enable + Reschedule XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; drROR[aux8, const0, const0]; --No trap expected drLIB[160B]; drSIP[ifuSLimit]; drASL[377B]; --L = 1, S = 0, traps disabled, Kernel mode, 0 calls on the stack }; GenReschedule: PROC [] ~ { RescheduleOK: Label = GenLabel[]; SetLabel[enterRescheduleTest]; drASL[17B]; --L = 1, S = 20B, 0 calls on the stack drLIQB[UseLabel32[RescheduleOK]]; --Reschedule trap will send control here drLIB[11]; drROR[aux8, popSrc, topSrc]; --Reschedule trap expected drLIB[40B + 4B + 1B]; --User mode keep + TrapEnable + Reschedule drSIP[ifuYoungestL]; --**was ifuStatus XPause[]; SetLabel[RescheduleOK]; drROR[aux8, const0, const0]; --No traps expected drLIB[40B + 1B]; --User mode keep + Reschedule (= traps disabled) drSIP[ifuYoungestL]; --Shouldn't trap; **was ifuStatus drLIB[40B + 4B]; drSIP[ifuYoungestL]; --**was ifuStatus --CauseReschedule[]; --drJ1[]; drJ1[]; drJ1[]; drJ1[]; drJ1[]; --XPause[]; }; drLIB[128-16-1]; SetSPLimit[]; drROR[aux8, const0, const0]; --Initialize aux8 to 0, meaning no traps expected. drLIB[6]; drROR[const4, popSrc, topSrc]; --Initialize const4 to 6 for the trap routines. GenIFUStackOverflow[]; GenSLimit[]; GenReschedule[]; Halt[177777B]; --Terminate here at the end of the program SetLabel[IFUStackOverflow]; drLIB[1]; drRJNEB[popSrc, aux8, UseLabel8B[IFUStkOvfBad]]; GetYoungestPC[]; drLIQB[CardToWord[IFUPageFaultAddress]]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[IFUStkOvfBad]]; SetYoungestPC[]; --Change return address drRETN[]; SetLabel[IFUStkOvfBad]; Pause[]; SetLabel[EUStackOverflow]; drLIB[2]; drRJNEB[popSrc, aux8, UseLabel8B[EUStkOvfBad]]; GetYoungestPC[]; drRVADD[topDst, topSrc, const4]; SetYoungestPC[]; --****Turn off reschedule-waiting and disable traps drRETN[]; SetLabel[EUStkOvfBad]; Pause[]; SetLabel[Reschedule]; --Arg is the return PC drLIB[11]; drRJNEB[popSrc, aux8, UseLabel8B[RescheduleBad]]; SetYoungestPC[]; drRETN[]; SetLabel[RescheduleBad]; Pause[]; SetLabel[ErrorXop1Trap]; drLIQB[CardToWord[600000B]]; GetYoungestStatus[]; drAND[]; drJEBB[0, UseLabel8B[AlreadyInKernel]]; EnterKernel[]; SetLabel[AlreadyInKernel]; Pause[]; SetLabel[TurnOnTraps]; --Call here with EnableTraps[] drLIB[377B]; GetYoungestStatus[]; drAND[]; --Preserve L drLIQB[CardToWord[200000B]]; drOR[]; SetYoungestStatus[]; --Set trapsEnabled drRETN[]; SetLabel[TurnOffTraps]; --Call here with DisableTraps[] drLIB[377B]; GetYoungestStatus[]; drAND[]; --Preserve L, clear trapsEnabled and User SetYoungestStatus[]; --Set trapsEnabled drRETN[]; SetLabel[TurnOnUserMode]; --Call here with EnterUser[] drLIB[377B]; GetYoungestStatus[]; drAND[]; --Preserve L drLIQB[CardToWord[600000B]]; drOR[]; SetYoungestStatus[]; drRETN[]; FillXop[2B, ErrorXop1Trap]; FillTrap[IFUStackOverflowTrap, IFUStackOverflow]; FillTrap[EUStackOverflowTrap, EUStackOverflow]; FillTrap[EUPageFault, EUPageFlt]; FillTrap[IFUPageFaultTrap, IFUPageFault]; FillTrap[RescheduleTrap, Reschedule]; }; END. ΘGenTraps2.mesa Copyright c 1986, 1987 by Xerox Corporation. All rights reserved. Edward Fiala March 5, 1986 11:01:20 am PST Fiala November 7, 1986 6:47:27 pm PST Absorb more loose ends from GenTraps that cannot be tested because of Lizard limitations. Fiala March 27, 1987 5:28:57 pm PST Eliminate Reset, Halt, and Pause stuff to run with GenDebugger. Add XPause[] error halt to enter user mode and disable traps before doing Pause[]. This diagnostic tests a few trap conditions which could not conveniently be tested in GenTraps because different handling of the traps would have been required: 1) Verify that IFU stack overflow prevails over ifu page fault. 2) Verify that EU stack overflow trap prevails over reschedule when a SIP enables traps and the EU stack overflow and reschedule-waiting conditions are both true. 3) **Verify that an IFU page fault trap prevails over an EU stack overflow trap. ***THIS IS NOT DEBUGGED YET; DON'T TRY TO RUN IT***. ifuSLimit = 7-bit stack limit register. Any opcode which causes the stack pointer to enter the region [SLimit..SLimit+16) will be trapped to the EU stack overflow location. IFUStackSize = 15. LIP[ifuEldestPC] removes and SIP[ifuEldestPC] adds to the call stack. In this diagnostic, the auxiliary registers are called aux0 .. aux15; the locals reg0 .. reg15; and the constants const0 .. const11. Global register usage is as follows: aux8 contains a code indicating the trap expected (0 if none). const4 contains the constant 6 for trap routines. These labels are for trap procedures. Must be first instruction on a page that is otherwise unused. All traps enter kernel mode and disable traps. Disabling affects only Reschedule, EU stack overflow, and IFU stack overflow. When traps are enabled, the IFU stack allows 11 normal calls but converts the 12th call into an IFU stack overflow trap; when traps are disabled, all 15 levels of the IFU stack are usable. Note, however, that when a trap or KFC is the 12th call, it will complete and disable traps without causing an IFU stack overflow trap. There is no IFU stack underflow trap; the first location in the IFU stack must be made to contain a return link to an appropriate trap procedure (or use the trick of causing a page fault). When traps are enabled, any opcode causing S to wind up in the range [SLimit..SLimit+16) causes an EU stack overflow trap; this detects both underflows and overflows, though underflow can only happen due to a programming error. Xops and KFC trap at opcode*TrapWidthBytes + xopBase*bytesPerWord = 4,000,000B + 20B * opcode. A trap's location is TrapIndex*TrapWidthBytes + TrapBase*bytesPerWord = 4,002,000B + 20B * TrapIndex. TrapIndex definitions are in DragOpsCross. 16 bytes between consecutive trap instructions is insufficient for StandardTrap, so the trap instruction must be filled separately with FillTrap[TrapName, dest]. aux8 has previously been loaded with a code for the trap presently expected (or 0 if none), and an opcode which is supposed to trap is followed by enough XPause[] opcodes to fill out 6 bytes (i.e., enough for a 5-byte trapping opcode and a 1-byte XPause[] after it); then if no trap occurs, the first XPause[] after the opcode will stop simulation; or if the wrong trap occurs, the mismatch on aux8 will cause XPause[] to occur. Otherwise, the trap procedure will return to the 6th byte after the location that trapped. Advance return PC by 6 Procedures to enable and disable traps in the caller's context; must be in Kernel mode. Indicate KFC trap expected by loading 12 into aux8 XPause[] = Pause[] but uses opcode 2 instead of 0. Test conditions which should and should not cause IFU stack overflow trap. Begin here in Kernel mode with traps disabled, and 0 IFU call stack entries. Now in Kernel mode with traps enabled. The DFC completes, but the following instruction is on a non-existent page and gets an IFU page fault which does a 12th call and gets converted into an IFU stack overflow trap. The IFU stack overflow trap handler will return here, if this happened correctly. Remove the 11 calls from the stack and cleanup Verify that EU stack overflow prevails over Reschedule when it is true at the time traps are enabled and Reschedule turned on by a SIP. Indicate EU stack overflow expected. EU stack overflow should prevail over Reschedule here because it is true at the onset of the trap; trap returns here with reschedule-waiting turned off and traps disabled. Verify the occurrence of Reschedule trap when Reschedule is requested by this processor. When the condition (TrapsEnabled & Reschedule) = TRUE as a result of SIP or RET, Reschedule should take immediately. Return here after Reschedule has occurred. User mode keep + Traps enabled (shouldn't trap); turns off Reschedule. CauseReschedule issues the IO command which sends Reschedule to all processors, but this action isn't simulated by Lizard. No-ops while waiting for Reschedule spLimit is set with room for 17 overflow words (just in case). IFU stack overflow trap has code 1 EU stack overflow has code 2 EU write protect fault trap has code 3 Arrive here when an IFU page fault has given rise to an IFU stack overflow trap; the youngest PC should point at the instruction which page faulted. Arrive here when an EU stack overflow trap has occurred with reschedule-waiting also true. Trap must turn off the reschedule-waiting and pop the stack twice to eliminate the EU stack overflow condition. ****Does Reschedule-waiting have to be cleared here? XPause[] (opcode 2) is used instead of Pause[] (opcode 0) to enter the debugger from user mode. This is done by first executing KFC to enter monitor mode and then doing Pause[]. Set trapsEnabled and user mode These calls to FillXop and FillTrap initialize the trap locations with JDB[trap procedure]. Κ ˜codešœ™Kšœ Οmœ7™BK™*K™K™·K™K™ΧK™K™4K™—šΟk ˜ Kšœ ˜ Kšœ žœDΟcε ˜» KšœžœŸΥ˜ϋKšœ Ÿ˜,KšœŸΪ˜ξKšœŸο˜ƒK˜—šœ žœž˜KšžœD˜KKšœžœžœS˜_K˜K–20 sp tabStopsšœžœ"˜9Kšœ­™­K–20 sp tabStopsšœ žœžœžœ˜FKšœY™YK–20 sp tabStopsšœ žœžœ žœ˜JK–20 sp tabStopsšœ žœžœžœ˜HK–20 sp tabStopsšœžœžœ"žœ˜NK–20 sp tabStopsšœžœžœ!žœ˜LK–20 sp tabStopsšœ žœžœžœ˜FK–20 sp tabStopsšœžœžœžœ˜>K–20 sp tabStops˜K–40 sp tabStopsšœŸ™ŸK–40 sp tabStopsšœ˜K–40 sp tabStopsšœ˜K–40 sp tabStopsšœ˜K–40 sp tabStopsšœ˜K–40 sp tabStopsšœ˜K–40 sp tabStopsšœ˜K–40 sp tabStopsšœ˜K–40 sp tabStopsšœ˜K–40 sp tabStopsšœ˜K–40 sp tabStops˜K–40 sp tabStops˜K–40 sp tabStops˜K–40 sp tabStops˜K–40 sp tabStops˜K–40 sp tabStops˜!K–40 sp tabStops˜!K™šΟnœžœ˜ Kšœ ˜ K˜Kšœ%™%K˜%K˜!K˜$K˜ K˜K˜"K˜"K˜$K˜K˜ K˜!K˜#J˜J˜.J˜$J˜(J˜Jšœ=™=Jšœžœžœ˜2K˜K™}K™K™ƒK™K™γK˜Kšœ^™^š œžœžœ˜/Kšœc˜cKšœ˜K˜K˜—Kšœ‘™‘š œžœ.˜˜LJšœ˜JšœŸ.˜AJšœ&™&Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ(Ÿ#˜KJšœ(Ÿ&˜NJšœ)Ÿ ˜3J˜Jšœƒ™ƒJ˜Jšœ˜JšœŸ˜:Jšœ.™.Jš žœžœžœ žœžœ˜5Jšœ ŸB˜OK˜—K˜š  œžœ˜K˜Jšœ˜J˜Kšœ‡™‡JšœŸ˜JšœŸ,˜GJ˜J˜Jšœ$™$Jšœ(Ÿ˜™>Kšœ˜Kšœ ˜ KšœŸ2˜PK˜ Kšœ Ÿ/˜OK˜J˜J˜ J˜J˜JšœŸ*˜9J˜J˜Kšœ"™"Kšœ™Kšœ&™&J˜Jšœ”™”J˜J˜:J˜J˜(J˜7JšœŸ˜)Jšœ ˜ J˜ J˜JšœΛ™ΛJ˜J˜9J˜BJšŸ3˜3Jšœ ˜ J˜J˜Jšœ4™4JšœŸ˜-J˜