<> <> <> <> <> <> <> <> <<>> <> <<>> <= 2^30 aren't tested (Lizard limitation). 17) **IFU page fault priority over EU stack overflow is not tested (see GenTraps2). 18) **IO Access faults on IOD, IODA, and ION aren't tested. 19) **Verify that EU stack overflow occurs with greater priority than an ALU trap caused on the instruction following a SIP which reenables interrupts. 20) **Verify that EU stack overflow occurs with greater priority than Reschedule following a SIP which reenables interrupts (tested in GenTraps2). 21) **EU write protect fault occurs in sequence for a storage write and the CST instruction, that machine state which would have been affected by the faulting instruction is not modified, and that euMAR contains the fault address. (Lizard doesn't simulate write protect faults.) 22) **Reschedule trap isn't tested because it is not simulated.>> <<>> DIRECTORY Basics USING [DoubleShiftLeft], DebuggerDefs, DragOpsCross USING [ProcessorRegister, XopBase, TrapBase, TrapWidthBytes, TrapIndex, Inst], --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, FieldDescriptorToCard, IntToWord, CardToByte], --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 GenTraps: CEDAR PROGRAM IMPORTS Basics, 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]; 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]]; aux13: AuxRegSpec = [aux[13]]; 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[]; Overflow: Label = GenLabel[]; BoundsCheck: Label = GenLabel[]; LispNaN: Label = GenLabel[]; UserModeViolation: Label = GenLabel[]; EUPageFlt: Label = GenLabel[]; EUPageFaultBad: Label = GenLabel[]; EUWPFlt: Label = GenLabel[]; EUWPFaultBad: Label = GenLabel[]; IFUPageFault: Label = GenLabel[]; IFUPageFaultBad: Label = GenLabel[]; IFUPageFaultPC: LONG CARDINAL = 300000000B; EUPageFaultAddress: LONG CARDINAL = IFUPageFaultPC/4; EUStackOverflow: Label = GenLabel[]; Reschedule: Label = GenLabel[]; RescheduleBad: Label = GenLabel[]; KFCTrap: Label = GenLabel[]; KFCBad: Label = GenLabel[]; Xop1Trap: Label = GenLabel[]; Xop1Bad: Label = GenLabel[]; Xop2Trap: Label = GenLabel[]; Xop2Bug: Label = GenLabel[]; Xop3Trap: Label = GenLabel[]; Xop3Bug: Label = GenLabel[]; Xop5Trap: Label = GenLabel[]; Xop5Bug: Label = GenLabel[]; ErrorXop1Trap: Label = GenLabel[]; AlreadyInKernel: Label = GenLabel[]; TurnOnTraps: Label = GenLabel[]; TurnOffTraps: Label = GenLabel[]; TurnOnUserMode: Label = GenLabel[]; enterIFUStatusTest: Label = GenLabel[]; enterIFUStackOverflowTest: Label = GenLabel[]; enterSLimitTest: Label = GenLabel[]; enterIFUPageFaultTest: Label = GenLabel[]; enterEUPageFaultTest: Label = GenLabel[]; enterModeFaultPriorityTest: Label = GenLabel[]; <= DragOpsCross.KernelLimit = 100000000B to be written in user mode; the Softcard only permits addresses in [1,000,000B..2,000,000B) to be referenced.>> userMemAddr: LONG CARDINAL = IF withSoftCard THEN 1770000B ELSE 100000000B; kernelMemAddr: LONG CARDINAL = IF withSoftCard THEN 17760000B ELSE 77777777B; <> <<>> <> <<>> <> <> FillXop: PROC [inst: CARDINAL, dest: Label] = { SetOutputPC[inst * DragOpsCross.TrapWidthBytes + DragOpsCross.XopBase * bytesPerWord]; drJDB[UseLabel16[dest]]; }; <> FillTrap: PROC [tx: DragOpsCross.TrapIndex, dest: Label] = { SetOutputPC[LOOPHOLE[tx, CARDINAL] * DragOpsCross.TrapWidthBytes + DragOpsCross.TrapBase * bytesPerWord]; drJDB[UseLabel16[dest]]; }; <> 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]; }; <<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.>> StandardTrap: PROC [dest: Label, code: CARDINAL] = { TrapUnexpected: Label = GenLabel[]; SetLabel[dest]; drLIB[code]; drRJNEB[popSrc, aux8, UseLabel8B[TrapUnexpected]]; <> GetYoungestPC[]; drRVADD[topDst, const4, topSrc]; SetYoungestPC[]; drRETN[]; SetLabel[TrapUnexpected]; Pause[]; }; <> WriteAtAddress: PROC [addr: LONG CARDINAL] ~ { <> oldPC: LONG CARDINAL = GetOutputPC[area]; bytePC: LONG CARDINAL _ Basics.DoubleShiftLeft[[lc[addr]], 2].lc; SetOutputPC[bytePC]; --pc is a byte address OutputWord[area, IntToWord[-1], FALSE]; SetOutputPC[oldPC]; drLC0[]; drLIQB[CardToWord[addr]]; drWB[0]; }; <> WriteTrapAtAddress: PROC [addr: LONG CARDINAL] ~ { WriteAtAddress[addr]; XPause[]; XPause[]; XPause[]; XPause[]; }; <> <<>> <> <<>> <> <<>> GenIFUStatus: PROC [] ~ { UCall1: Label = GenLabel[]; UCall2: Label = GenLabel[]; UJump1: Label = GenLabel[]; JQBNop0: Label = GenLabel[]; JSDNop0: Label = GenLabel[]; BeginUserTest: Label = GenLabel[]; CheckTrapEnable: Label = GenLabel[]; CheckTrapDisable: Label = GenLabel[]; CheckUserMode: Label = GenLabel[]; BadEnable: Label = GenLabel[]; SetLabel[enterIFUStatusTest]; <> drLIQB[CardToWord[userMemAddr]]; drROR[aux0, topSrc, popSrc]; drJDB[UseLabel16[BeginUserTest]]; --inst 50 SetLabel[CheckTrapEnable]; GetYoungestStatus[]; drLIQB[CardToWord[200000B]]; drOR[]; drDUP[]; SetYoungestStatus[]; --Set trapsEnabled drLIP[ifuYoungestL]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[BadEnable]]; drRETN[]; SetLabel[BadEnable]; XPause[]; SetLabel[CheckTrapDisable]; GetYoungestStatus[]; drLIQB[CardToWord[37777577777B]]; drAND[]; drDUP[]; SetYoungestStatus[]; --Set trapsEnabled drLIP[ifuYoungestL]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[BadEnable]]; drRETN[]; SetLabel[CheckUserMode]; GetYoungestStatus[]; drLIQB[CardToWord[400000B]]; drOR[]; drDUP[]; SetYoungestStatus[]; --Set trapsEnabled drLIP[ifuYoungestL]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[BadEnable]]; drRETN[]; SetLabel[BeginUserTest]; <> drLFC[UseLabel16[CheckTrapEnable]]; drLFC[UseLabel16[CheckTrapDisable]]; drLFC[UseLabel16[CheckUserMode]]; <> drROR[aux9, aux0, aux1]; drROR[aux9, aux2, aux3]; drROR[aux10, aux4, aux5]; drROR[aux11, aux6, aux7]; drROR[aux12, aux8, aux9]; drROR[aux13, aux10, aux11]; drROR[aux14, aux12, aux13]; drROR[aux15, aux14, aux14]; drROR[aux15, aux15, aux15]; drROR[pushDst, const0, const1]; --1st push drROR[topDst, const2, const3]; drROR[pushDst, const4, const5]; --2nd push drROR[belowDst, const6, const7]; drROR[topDst, const8, const9]; drROR[topDst, const10, const11]; drLIP[0]; --3rd push drLIP[127]; --4th push drLIP[159]; --5th push <> drLFC[3]; drLIP[ifuYoungestL]; --6th push drLIP[ifuYoungestPC]; --7th push drLIP[ifuEldestL]; --8th push drLIP[ifuSLimit]; --9th push drASL[377B]; --0 pushes on the EU stack, 1 call on the IFU stack WriteAtAddress[userMemAddr]; <<***FIXES NEEDED HERE. IODA[2B] does [S] _ PRead[0 + [S], BetaZ].>> --drLIQB[CardToWord[userMemAddr]]; drIODA[2B]; drASL[377B]; --0 pushes again <> drLC0[]; drDUP[]; drADD[]; --1st push = reg0 drLC1[]; --2 pushes drLIDB[0]; drLIQB[CardToWord[0]]; --4 pushes drLRn[reg11]; --5 pushes drQADD[topAtop, const0]; drRADD[belowDst, topSrc, belowSrcPop]; --4 pushes drSUB[]; --3 pushes drQSUB[topAtop, const0]; drRSUB[belowDst, popSrc, belowSrc]; --2 pushes drQLADD[topAtop, const0]; drRLADD[belowDst, popSrc, const0]; --1 push drQLSUB[topAtop, const0]; --1 push drRLSUB[pushDst, popSrc, const0]; drRUADD[belowDst, const0, popSrc]; --0 pushes drRUSUB[pushDst, const0, const0]; --1 push drRVADD[pushDst, const0, topSrc]; --2 pushes drRVSUB[topDst, topSrc, const0]; drAND[]; --1 push drQAND[pushAtop, const0]; --2 pushes drRAND[topDst, topSrc, topSrc]; drOR[]; --1 push drQOR[pushAtop, const0]; --2 pushes drADDB[0]; drSUBB[0]; drADDDB[0]; drSUBDB[0]; drADDQB[CardToWord[0]]; drSUBQB[CardToWord[0]]; drRXOR[topDst, topSrc, topSrc]; drRAND[topDst, topSrc, const0]; --Zero [S] drFSDB[FieldDescriptorToCard[[mask: 6, shift: 20]]]; --1 push drRFU[pushDst, topSrc, topSrc]; --2 pushes drSHDL[FieldDescriptorToCard[[mask: 32, shift: 0]]]; --1 push drSHL[FieldDescriptorToCard[[mask: 0, shift: 32]]]; --1 push drSHR[FieldDescriptorToCard[[mask: 16, shift: 16]]]; --1 push drJ1[]; drJ2[]; XPause[]; drJ3[]; XPause[]; XPause[]; drJ5[]; XPause[]; XPause[]; XPause[]; XPause[]; drJDB[3]; drJQB[UseLabel32[JQBNop0]]; SetLabel[JQBNop0]; drLIQB[UseLabel32[JSDNop0]]; drJSD[]; SetLabel[JSDNop0]; drEXDIS[]; --0 pushes drLIDB[0]; --1 push drASL[377B]; --0 pushes, 0 locals (S _ 0B, L = 1B) drAL[0]; drLIQB[CardToWord[userMemAddr]]; --legal address already used, 1 push FOR I: CARDINAL IN [0..17) DO drDUP[]; ENDLOOP; drSRn[reg0]; --Now have L = 1B, S = 21B (= 16 locals, 1 push) drLRIn[reg0, 0]; drSRIn[reg0, 0]; drDUP[]; drJEBB[0, 3]; drDUP[]; drJNEBB[0, 3]; drDUP[]; drJNEBBJ[0, 3]; drRJEB[topSrc, topSrc, 3]; drRJEBJ[topSrc, topSrc, 3]; drRJGB[topSrc, topSrc, 3]; drRJGBJ[topSrc, topSrc, 3]; drRJLB[topSrc, topSrc, 3]; drRJLBJ[topSrc, topSrc, 3]; drRJGEB[topSrc, topSrc, 3]; drRJGEBJ[topSrc, topSrc, 3]; drRJLEB[topSrc, topSrc, 3]; drRJLEBJ[topSrc, topSrc, 3]; drRJNEB[topSrc, topSrc, 3]; drRJNEBJ[topSrc, topSrc, 3]; --Still have 1 push (L = 1B, S = 21B) drLIQB[CardToWord[userMemAddr - 1]]; --2 pushes drRBC[topDst, topSrc, belowSrc]; --won't trap drQBC[topAtop, belowSrc]; --won't trap drDIS[]; drLIQB[CardToWord[userMemAddr + 1]]; drBC[]; --1 push drDUP[]; --2 pushes drLC0[]; drRX[]; drDIS[]; --1 push drQRX[pushAtop, const0]; drDIS[]; drLGF[0]; drDIS[]; --(aux0 was initialized to userMemAddr above) drRAI[reg1, aux0, 0]; drDUP[]; drRB[0]; drDIS[]; drRRI[reg1, reg13, 0]; --(reg0 .. reg15 were set to userMemAddr above) drRRX[reg1, reg13, const0]; drRSB[0]; drDIS[]; drWAI[reg1, aux0, 0]; drWRI[reg1, reg13, 0]; drLC0[]; drWSB[0]; --Still have 1 push IF NOT withSoftCard THEN { drLIB[1]; drLC0[]; drCST[0]; }; drASL[377B]; --0 pushes drLIB[1]; drJSR[]; drDFC[UseLabel32[UCall1]]; drLFC[UseLabel16[UCall2]]; drLIB[13]; drROR[aux8, topSrc, popSrc]; --Indicate XOP1 trap expected OutputByte[area, CardToByte[1B]]; drLIB[14]; drROR[aux8, topSrc, popSrc]; --Indicate XOP2 trap expected OutputAlphaBeta[area, (234B * 400B) + 123B]; drLIB[15]; drROR[aux8, topSrc, popSrc]; --Indicate XOP3 trap expected OutputByte[area, CardToByte[364B]]; OutputAlphaBeta[area, 234B]; drLIB[16]; drROR[aux8, topSrc, popSrc]; --Indicate XOP5 trap expected OutputByte[area, CardToByte[40B]]; OutputWord[area, CardToWord[345B]]; EnterKernel[]; --KFC trap returns in Kernel mode with traps disabled. EnterUser[]; --Enter user mode and enable traps drLIQB[CardToWord[userMemAddr]]; --1 push drLIQB[UseLabel32[UCall1]]; --2 pushes drPSB[0]; --1 push drAS[1]; --2 pushes drSFC[]; --1 push drSFCI[]; drJB[UseLabel8A[UJump1]]; SetLabel[UCall1]; drRETN[]; SetLabel[UCall2]; drALS[377B]; --L _ S-1 drRET[1B]; --S _ L+1 SetLabel[UJump1]; drASL[17B]; --16 local registers, 0 EU pushes, 1 call on the IFU stack <> drLIB[8]; --1 push drROR[aux8, topSrc, topSrc]; --Indicate mode fault trap expected (aux8 = 8) <> drROR[aux0, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[aux1, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[aux2, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[aux3, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[aux4, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[aux5, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[aux6, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[aux7, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const0, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const1, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const2, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const3, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const4, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const5, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const6, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const7, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const8, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const9, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const10, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; drROR[const11, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; <> <> drSIP[0]; XPause[]; XPause[]; XPause[]; XPause[]; drSIP[242]; XPause[]; XPause[]; XPause[]; XPause[]; drSIP[246]; XPause[]; XPause[]; XPause[]; XPause[]; <> drLIP[ifuEldestPC]; XPause[]; XPause[]; XPause[]; XPause[]; drDIS[]; --16 locals, 1 push, 2 calls on the IFU stack <> --drIOD[4B]; XPause[]; XPause[]; XPause[]; --drION[4B]; XPause[]; XPause[]; XPause[]; --drIODA[4B]; XPause[]; XPause[]; XPause[]; <> --WriteTrapAtAddress[kernelMemAddr]; <> drASL[17B]; --16 locals, 0 pushes on the EU stack, 2 calls on the IFU stack, user mode EnterKernel[]; --Use KFC to enter kernel mode and return with traps disabled. FOR I: CARDINAL IN [0..0] DO GetEldestPC[]; ENDLOOP; }; <> GenIFUStackOverflow: PROC [] ~ { UCall3: Label = GenLabel[]; JQBNop1: Label = GenLabel[]; JSDNop1: Label = GenLabel[]; exitIFUStackOverflowTest: Label = GenLabel[]; eleventhCall: Label = GenLabel[]; drJB[UseLabel8A[enterIFUStackOverflowTest]]; SetLabel[UCall3]; XPause[]; --DFC, SFC, or SFCI trap was expected but didn't. SetLabel[enterIFUStackOverflowTest]; drASL[377B]; --0 locals, 0 pushes on the EU stack, 0 calls on the IFU stack EnableTraps[]; <> 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 drLFC[4]; --11 calls XPause[]; <> drJ1[]; drJ2[]; XPause[]; drJ3[]; XPause[]; XPause[]; drJ5[]; XPause[]; XPause[]; XPause[]; XPause[]; drJB[2]; drJDB[3]; drJQB[UseLabel32[JQBNop1]]; XPause[]; SetLabel[JQBNop1]; drLIQB[UseLabel32[JSDNop1]]; drJSD[]; XPause[]; SetLabel[JSDNop1]; drLIB[1]; drJSR[]; <> drLIB[2]; drLIB[1]; drQBC[pushAtop, belowSrc]; drDIS[]; drRBC[pushDst, reg1, reg0]; drDIS[]; drEXDIS[]; drLIB[2]; drBC[]; drLIB[1]; drROR[aux8, popSrc, topSrc]; --Indicate IFU stack overflow expected <> drLFC[3]; XPause[]; XPause[]; XPause[]; drDFC[UseLabel32[UCall3]]; XPause[]; drLIQB[UseLabel32[UCall3]]; drSFC[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; <<1, 2, 3, and 5-byte Xops should cause IFU stack overflow trap>> OutputByte[area, CardToByte[1B]]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; OutputAlphaBeta[area, (234B * 400B) + 123B]; XPause[]; XPause[]; XPause[]; XPause[]; OutputByte[area, CardToByte[364B]]; OutputAlphaBeta[area, 234B]; XPause[]; XPause[]; XPause[]; OutputByte[area, CardToByte[40B]]; OutputWord[area, CardToWord[345B]]; XPause[]; drKFC[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; <> drLIB[1]; drLIB[2]; drQBC[pushAtop, belowSrc]; XPause[]; XPause[]; XPause[]; XPause[]; drRBC[pushDst, topSrc, belowSrc]; XPause[]; XPause[]; XPause[]; drEXDIS[]; drLIB[1]; drBC[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; <> drLIQB[CardToWord[10000000000B]]; drDUP[]; drLADD[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; <> drADD[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; <> drLIQB[CardToWord[EUPageFaultAddress]]; drROR[aux9, topSrc, topSrc]; drRB[0]; XPause[]; XPause[]; XPause[]; XPause[]; <> drASL[17B]; --L = 1, S = 20B drLIB[21B]; drSIP[ifuSLimit]; drDUP[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; drDIS[]; drLIB[160B]; drSIP[ifuSLimit]; drROR[aux8, const0, const0]; --Indicate no traps expected GetEldestPC[]; --Clear 1 call to enter user mode EnterUser[]; drLFC[UseLabel16[eleventhCall]]; --11 calls again <> drJDB[UseLabel16[exitIFUStackOverflowTest]]; --10 calls SetLabel[eleventhCall]; drLIB[1]; drROR[aux8, topSrc, popSrc]; --Indicate IFU stack overflow expected <> drRADD[const1, const0, const0]; XPause[]; XPause[]; XPause[]; <> --****drLC0[]; drWB[0]; XPause[]; XPause[]; XPause[]; XPause[]; drROR[aux8, const0, const0]; --Indicate no traps expected drRET[377B]; --returns from 11th call and trims stack SetLabel[exitIFUStackOverflowTest]; EnterKernel[]; <> FOR I: CARDINAL IN [0..9] DO GetEldestPC[]; ENDLOOP; drASL[17B]; --L = 1, S = 20B, traps enabled, Kernel mode, 0 calls on the stack }; GenSLimit: PROC [] ~ { <> SLimitTest: PROC [SL: CARDINAL] ~ { drLIB[SL]; drSIP[ifuSLimit]; drROR[aux8, aux15, aux15]; drASL[SL]; XPause[]; XPause[]; XPause[]; XPause[]; --SLimit drASL[SL + 15]; XPause[]; XPause[]; XPause[]; XPause[]; --SLimit + 15 drROR[aux8, const0, const0]; drASL[SL + 16]; --SLimit + 16 drASL[SL - 1]; --SLimit - 1 drASL[0]; --SLimit }; <> SetLabel[enterSLimitTest]; drASL[7B]; --L = 1, S = 10B, traps enabled, Kernel mode, 0 calls on the stack EnableTraps[]; drLIB[13B]; drSIP[ifuSLimit]; drLIQB[CardToWord[userMemAddr]]; drSRn[reg0]; --Memory address for LRIn below drLC0[]; --S = 11B drLIB[9]; drROR[aux8, topSrc, topSrc]; --aux8 _ EU stk ovf trap expected drROR[aux15, topSrc, popSrc]; --aux15 _ EU stk ovf trap expected for SLimitTests below drDUP[]; --S = 12B <> drLFC[4]; XPause[]; <> drDUP[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; drLRn[reg2]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; drQADD[pushA0, const0]; XPause[]; XPause[]; XPause[]; XPause[]; drRADD[pushDst, const0, const0]; XPause[]; XPause[]; XPause[]; drLRIn[reg0, 0]; XPause[]; XPause[]; XPause[]; XPause[]; <= 40B in this test, so I changed the code to have fewer locals.>> FOR I: CARDINAL IN [1..16] DO drAS[I]; XPause[]; XPause[]; XPause[]; XPause[]; drASL[11B + I]; XPause[]; XPause[]; XPause[]; XPause[]; drRET[11B + I]; XPause[]; XPause[]; XPause[]; XPause[]; ENDLOOP; <> drASL[377B]; --S = 0, L = 1 (won't trap) drLIB[160B]; drSIP[ifuSLimit]; --S in [160B..177B] will trap drLIP[ifuEldestPC]; drDIS[]; --clear the call stack drSRn[reg15]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; drQAND[topAtop, popSrc]; XPause[]; XPause[]; XPause[]; XPause[]; drRAND[belowDst, topSrc, popSrc]; XPause[]; XPause[]; XPause[]; drSRIn[reg0, 0]; XPause[]; XPause[]; XPause[]; XPause[]; drDIS[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; <> drROR[aux8, const0, const0]; --Indicate no trap expected drAL[377B]; --L _ 0 <> SLimitTest[4B]; SLimitTest[10B]; SLimitTest[20B]; SLimitTest[1B]; drASL[377B]; SLimitTest[40B]; SLimitTest[100B]; SLimitTest[2B]; SLimitTest[157B]; <> drLIB[21B]; drSIP[ifuSLimit]; drAL[1B]; --L = 1 again drASL[15B]; --S = 16B drLIB[6]; drROR[aux8, topSrc, popSrc]; --Bounds check should prevail drLIB[1]; drLIB[2]; --S = 20B (1 less than SLimit) drQBC[pushAtop, belowSrc]; XPause[]; XPause[]; XPause[]; XPause[]; drRBC[pushDst, topSrc, belowSrc]; XPause[]; XPause[]; XPause[]; <> drAS[376B]; drLIB[7]; drROR[aux8, topSrc, popSrc]; --NaN prevails drLIQB[CardToWord[10000000000B]]; drDUP[]; --S = 20B (1 less than SLimit) drRLADD[pushDst, topSrc, belowSrc]; XPause[]; XPause[]; XPause[]; drDIS[]; drLIB[5]; drROR[aux8, topSrc, popSrc]; --Overflow prevails drDUP[]; --S = 20B (1 less than SLimit) drRADD[pushDst, topSrc, belowSrc]; XPause[]; XPause[]; XPause[]; <<****Address check isn't implemented any more.>> --drAS[376B]; EnterUser[]; drDUP[]; --drLIB[4]; drROR[aux8, topSrc, popSrc]; --drLC0[]; drWB[0]; XPause[]; XPause[]; XPause[]; XPause[]; <<>> <<****Used to test that Reschedule won out over EUStackOverflow here.>> <> drASL[377B]; --S = 0, L = 1 (won't trap) drLIB[160B]; drSIP[ifuSLimit]; --S in [160B..177B] will trap drLIB[8]; drROR[aux8, topSrc, topSrc]; --Indicate ModeFault expected EnterUser[]; drRADD[const1, popSrc, topSrc]; XPause[]; XPause[]; XPause[]; EnterKernel[]; --Enter Kernel mode and disable traps drASL[17B]; --L = 1, S = 20B, traps disabled, Kernel mode, 0 calls on the stack }; <> GenIFUPageFault: PROC [] ~ { oldPC: LONG CARDINAL; LFCFaultOK: Label = GenLabel[]; RETNFaultOK: Label = GenLabel[]; CJumpFOK0: Label = GenLabel[]; CJumpFOK1: Label = GenLabel[]; FallThruOK: Label = GenLabel[]; endIFUPFTest: Label = GenLabel[]; nearFaultPagePC0: LONG CARDINAL = 277777600B; nearFaultPagePC1: LONG CARDINAL = 310007600B; IFUPageFaultPC1: LONG CARDINAL = 310010000B; nearFaultPagePC2: LONG CARDINAL = 320007775B; --Must be page boundary - 3 SetLabel[enterIFUPageFaultTest]; drASL[377B]; --L = 1, S = 0 EnableTraps[]; drLIQB[CardToWord[nearFaultPagePC0]]; --location to which page fault trap returns drLIB[10]; drROR[aux8, popSrc, topSrc]; --IFU page fault expected drJQB[CardToWord[IFUPageFaultPC]]; --Will cause IFU page fault oldPC _ GetOutputPC[area]; SetOutputPC[nearFaultPagePC0]; drLIQB[UseLabel32[LFCFaultOK]]; drLFC[IFUPageFaultPC - GetOutputPC[area]]; --IFU page fault next SetLabel[LFCFaultOK]; drLIQB[CardToWord[IFUPageFaultPC]]; SetYoungestPC[]; drLIQB[UseLabel32[RETNFaultOK]]; drRETN[]; --Will cause IFU page fault SetLabel[RETNFaultOK]; drLIQB[UseLabel32[CJumpFOK0]]; drRJEB[const0, const0, IFUPageFaultPC - GetOutputPC[area]]; --IFU page fault next SetLabel[CJumpFOK0]; drLIQB[UseLabel32[CJumpFOK1]]; drRJEBJ[const0, const0, IFUPageFaultPC - GetOutputPC[area]]; --IFU page fault next SetLabel[CJumpFOK1]; drLIQB[UseLabel32[FallThruOK]]; drJB[IFUPageFaultPC - GetOutputPC[area] - 1]; SetOutputPC[IFUPageFaultPC - 1]; drJ1[]; --Next instruction causes IFU page fault SetOutputPC[nearFaultPagePC1]; SetLabel[FallThruOK]; <> drROR[aux8, const0, const0]; --Indicate no traps expected <> drRJNEB[const0, const0, IFUPageFaultPC1 - GetOutputPC[area]]; <> drRJNEBJ[const0, const0, IFUPageFaultPC1 - GetOutputPC[area]]; drJB[IFUPageFaultPC1 - GetOutputPC[area] - 3]; SetOutputPC[IFUPageFaultPC1 - 3]; <> drRJEB[const0, const0, 370B]; SetOutputPC[IFUPageFaultPC1 - 3 - 10B]; drJQB[CardToWord[nearFaultPagePC2]]; SetOutputPC[nearFaultPagePC2]; <> drRJEBJ[const0, const0, 370B]; SetOutputPC[nearFaultPagePC2 - 10B]; drJQB[CardToWord[oldPC]]; SetOutputPC[oldPC]; <<**Should test EU stack overflow coincident with IFU page fault.>> }; <> GenEUPageFault: PROC [] ~ { OKState: Label = GenLabel[]; BadState: Label = GenLabel[]; SetLabel[enterEUPageFaultTest]; drASL[377B]; --L = 1, S = 0 EnableTraps[]; drLIB[2]; drROR[aux8, popSrc, topSrc]; --EU page fault expected <> drLIB[21B]; drSIP[ifuSLimit]; drASL[16B]; --S = 17B drLIQB[CardToWord[EUPageFaultAddress]]; drROR[aux9, topSrc, topSrc]; drRB[0]; XPause[]; XPause[]; XPause[]; XPause[]; drASL[377B]; --L = 1, S = 0 drLIQB[CardToWord[EUPageFaultAddress]]; drRB[0]; XPause[]; XPause[]; XPause[]; XPause[]; drRJEBJ[topSrc, aux9, UseLabel8B[OKState]]; --Make sure RB[0] didn't smash [S] SetLabel[BadState]; XPause[]; SetLabel[OKState]; drLIB[123B]; drROR[aux10, popSrc, topSrc]; <> drRRX[aux10, popSrc, const0]; XPause[]; XPause[]; XPause[]; <> drLIB[123B]; drRJNEB[popSrc, aux10, UseLabel8B[BadState]]; <> drRJNEB[topSrc, aux9, UseLabel8B[BadState]]; drLIDB[123456B]; drWSB[0]; XPause[]; XPause[]; XPause[]; XPause[]; drLIDB[123456B]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[BadState]]; drRJNEB[topSrc, aux9, UseLabel8B[BadState]]; IF NOT withSoftCard THEN { drLIDB[111111B]; --new value drLIDB[122222B]; --old value <> drCST[0]; XPause[]; XPause[]; XPause[]; XPause[]; }; drLIDB[122222B]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[BadState]]; drDIS[]; drSFCI[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; drRJNEB[topSrc, aux9, UseLabel8B[BadState]]; <> <<[S] _ PRead[AlphaZ + [S], BetaZ] with address check.>> --drIODA[2B]; XPause[]; XPause[]; XPause[]; --drRJNEB[popSrc, aux9, UseLabel8B[BadState]]; --drLIB[123B]; drROR[pushDst, aux9, const0]; <> --drIODA[3B]; --drRJNEB[popSrc, aux9, UseLabel8B[BadState]]; --drJNEBB[123B, UseLabel8B[BadState]]; }; <> GenModeFaultPriority: PROC [] ~ { SetLabel[enterModeFaultPriorityTest]; drASL[377B]; --L = 1, S = 0 drLIB[8]; drROR[aux8, topSrc, popSrc]; --code for ModeFault trap EnterUser[]; drLIQB[CardToWord[10000000000B]]; drDUP[]; <> drRLADD[const2, belowSrc, topSrc]; XPause[]; XPause[]; XPause[]; <> drRADD[const2, belowSrc, topSrc]; XPause[]; XPause[]; XPause[]; <> drRBC[const2, belowSrc, popSrc]; XPause[]; XPause[]; XPause[]; drDIS[]; drLC0[]; drLIQB[CardToWord[EUPageFaultAddress]]; <> drRRX[const2, popSrc, belowSrcPop]; XPause[]; XPause[]; XPause[]; EnterKernel[]; --Indicate KFC trap expected <> }; <> XPause: PROC = { HandCodingSupport.OutputByte[HandCodingSupport.GetCurrentArea[], LOOPHOLE[2]]; }; <> 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. <> drLIB[1]; drROR[const5, topSrc, topSrc]; drROR[const6, topSrc, topSrc]; drROR[const7, topSrc, topSrc]; drROR[const8, topSrc, topSrc]; drROR[const9, topSrc, topSrc]; drROR[const10, topSrc, topSrc]; drROR[const11, topSrc, topSrc]; drROR[aux1, topSrc, topSrc]; drROR[aux2, topSrc, topSrc]; drROR[aux3, topSrc, topSrc]; drROR[aux4, topSrc, topSrc]; drROR[aux5, topSrc, topSrc]; drROR[aux6, topSrc, topSrc]; drROR[aux7, topSrc, topSrc]; <> drLC0[]; drSIP[0]; drLC0[]; drSIP[127]; drLC0[]; drSIP[159]; --aux 15, inst. 33 <> FOR I: CARDINAL IN [0..15) DO drLC0[]; ENDLOOP; <> GenIFUStatus[]; GenIFUStackOverflow[]; GenSLimit[]; GenIFUPageFault[]; GenEUPageFault[]; GenModeFaultPriority[]; Halt[177777B]; --Terminate here at the end of the program StandardTrap[IFUStackOverflow, 1]; --priority 2 <> <> StandardTrap[Overflow, 5]; StandardTrap[BoundsCheck, 6]; StandardTrap[LispNaN, 7]; StandardTrap[UserModeViolation, 8]; StandardTrap[EUStackOverflow, 9]; <> <> <> <<1-byte Xop (opcode = 1B) has code 13>> <<2-byte Xop (opcode 234B, alpha = 123B) has code 14>> <<3-byte Xop (opcode 364B, alphabeta = 234B) has code 15>> <<5-byte Xop (opcode 40B, alphabetagammadelta = 345B) has code 16>> SetLabel[EUPageFlt]; drLIB[2]; drRJNEB[popSrc, aux8, UseLabel8B[EUPageFaultBad]]; <> drLIP[euMAR]; drRJNEB[popSrc, aux9, UseLabel8B[EUPageFaultBad]]; GetYoungestPC[]; drRVADD[topDst, topSrc, const4]; SetYoungestPC[]; drRETN[]; SetLabel[EUPageFaultBad]; Pause[]; SetLabel[EUWPFlt]; drLIB[3]; drRJNEB[popSrc, aux8, UseLabel8B[EUWPFaultBad]]; <> drLIQB[CardToWord[EUPageFaultAddress]]; drLIP[euMAR]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[EUWPFaultBad]]; GetYoungestPC[]; drRVADD[topDst, topSrc, const4]; SetYoungestPC[]; drRETN[]; SetLabel[EUWPFaultBad]; Pause[]; SetLabel[IFUPageFault]; <<1 arg = return PC>> drLIB[10]; drRJNEB[popSrc, aux8, UseLabel8B[IFUPageFaultBad]]; GetYoungestPC[]; <> drLIQB[CardToWord[IFUPageFaultPC]]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[IFUPageFaultBad]]; SetYoungestPC[]; drRETN[]; SetLabel[IFUPageFaultBad]; Pause[]; <<****Does Reschedule-waiting have to be cleared here?>> SetLabel[Reschedule]; --Arg is the return PC drLIB[11]; drRJNEB[popSrc, aux8, UseLabel8B[RescheduleBad]]; SetYoungestPC[]; drRETN[]; SetLabel[RescheduleBad]; Pause[]; <> SetLabel[KFCTrap]; drLIB[12]; drRJNEB[popSrc, aux8, UseLabel8B[KFCBad]]; drLIP[ifuYoungestL]; drLIB[377B]; drAND[]; drSIP[ifuYoungestL]; drRETN[]; --Return to caller remaining in Kernel mode with traps disabled. SetLabel[KFCBad]; Pause[]; SetLabel[Xop1Trap]; drLIB[13]; drRJNEB[popSrc, aux8, UseLabel8B[Xop1Bad]]; drRETN[]; --Return to caller remaining in Kernel mode. SetLabel[Xop1Bad]; XPause[]; SetLabel[Xop2Trap]; drLIB[14]; drRJNEB[popSrc, aux8, UseLabel8B[Xop2Bug]]; drJNEBB[123B, UseLabel8B[Xop2Bug]]; --Discard the pushed Alpha drRETN[]; --Return to caller remaining in Kernel mode. SetLabel[Xop2Bug]; XPause[]; SetLabel[Xop3Trap]; drLIB[15]; drRJNEB[popSrc, aux8, UseLabel8B[Xop3Bug]]; drJNEBB[234B, UseLabel8B[Xop3Bug]]; --Discard the pushed AlphaBeta drRETN[]; --Return to caller remaining in Kernel mode. SetLabel[Xop3Bug]; XPause[]; SetLabel[Xop5Trap]; drLIB[16]; drRJNEB[popSrc, aux8, UseLabel8B[Xop5Bug]]; drJNEBB[345B, UseLabel8B[Xop5Bug]]; --Discard the pushed AlphaBetaGammaDelta drRETN[]; --Return to caller remaining in Kernel mode. SetLabel[Xop5Bug]; XPause[]; <> SetLabel[ErrorXop1Trap]; drLIQB[CardToWord[600000B]]; GetYoungestStatus[]; drAND[]; drJEBB[0, UseLabel8B[AlreadyInKernel]]; EnterKernel[]; SetLabel[AlreadyInKernel]; drLIQB[CardToWord[debugBase]]; drLIP[130]; drWSB[euRegBase + 130]; --euMAR drLIB[2]; --Opcode number of XPause[]; drJQB[CardToWord[debuggerBasePC]]; 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[LOOPHOLE[DragOpsCross.Inst.dKFC, CARDINAL], KFCTrap]; FillXop[1B, Xop1Trap]; FillXop[234B, Xop2Trap]; FillXop[364B, Xop3Trap]; FillXop[40B, Xop5Trap]; FillXop[2B, ErrorXop1Trap]; FillTrap[IFUStackOverflowTrap, IFUStackOverflow]; FillTrap[EUPageFault, EUPageFlt]; FillTrap[EUWriteFault, EUWPFlt]; FillTrap[ALUCondOver, Overflow]; FillTrap[ALUCondBC, BoundsCheck]; FillTrap[ALUCondIL, LispNaN]; FillTrap[ModeFault, UserModeViolation]; FillTrap[EUStackOverflowTrap, EUStackOverflow]; FillTrap[IFUPageFaultTrap, IFUPageFault]; FillTrap[RescheduleTrap, Reschedule]; }; END.