<> <> <> <> <<>> <> <<>> DIRECTORY DragOpsCross USING [Word, ProcessorRegister, XopBase, TrapBase, TrapWidthBytes, bytesPerWord, TrapIndex, KernalLimit], --XopBase, TrapBase, TrapWidthBytes, Inst, wordsPerPage, bytesPerWord, charsPerWord, bitsPerByte, bitsPerCharacter, bitsPerWord, logWordsPerPage, logBitsPerByte, logBitsPerChar, logBytesPerWord, logCharsPerWord, logBitsPerWord, logBytesPerPage, PageCount, PageNumber, maxPagesInVM, SixBitIndex, FiveBitIndex, Word, TwoWords, FourBitIndex, Half, ThreeBitIndex, FourHalves, TwoHalves, Byte, ZerosByte, OnesByte, EightBytes, FourBytes, ByteIndex, BytesPerWord, TwoBytes, Comparison, ByteAddress, WordAddress, FieldDescriptor, TrapWidthWords, KernalLimit, TrapIndex, StackUnderflowTrap, IFUPageFaultTrap, ResetTrap, IFUStackOverflowTrap, EUStackOverflowTrap, RescheduleTrap, ALUCondOver, ALUCondBC, ALUCondIL, ALUCondDO, EUPageFault, EUWriteFault, AUFault, euStack, euJunk, euMAR, euField, euConstant, euAux, euBogus, euLast, ifuXBus, ifuStatus, ifuSLimit, ifuYoungestL, ifuYoungestPC, ifuEldestL, ifuEldestPC, ifuBogus, ifuL, ifuS, ifuPC, ifuLast, IFUStatusRec, IFUStackIndex, IFUStackSize, IFUOverflow, EUStackIndex, EUStackSize, EULocalIndex, EULocals, EUAuxIndex, EUAuxRegs, EUConstIndex, EUConstants, IOLocation, ioRescheduleRequest, ioResetRequest DragOpsCrossUtils USING [CardToWord], --BytePCToWordAddress, WordAddressToBytePC, IOOperandToCard, CardToIOOperand, FieldDescriptorToCard, CardToFieldDescriptor, StatusToWord, WordToStatus, 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, TrapIndexToBytePC, XopToBytePC HandCoding, --Has opcode and register defs. HandCodingPseudos, --GenLabel, GenLabelHere, SetLabel, Halt, Pause, MakeLabelGlobal, UseLabel8B, UseLabel16, UseLabel32, ProcedureEntry, ProcedureExit, EnableTraps, IndexedJump, SetupField, ExtractField, ShiftLeft, LoadProcessorReg, StoreProcessorReg, DisableTraps, CauseReschedule, CauseReset, GetSPLimit, SetSPLimit, GetL, SetL, GetYoungestPC, GetYoungestL, GetEldestPC, GetEldestL, SetYoungestPC, SetYoungestL, SetEldestPC, SetEldestL HandCodingSupport; --Area, GetCurrentArea, ReserveData, SetOutputPC, GetProc, PutProc, ProcList, NewArea, GenWithArea, Gen1WithArea, ForceOut, GetOutputPC, WordAlign, OutputByte, OutputOneByte, OutputAlphaBeta, OutputAlphaBetaGammaDelta, OutputWord GenTraps2: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; Word: TYPE = DragOpsCross.Word; 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]; KernelLimit: LONG CARDINAL = DragOpsCross.KernalLimit; <> 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[]; oldPC: LONG CARDINAL; start: Label = GenLabel[]; dummy: Label = GenLabel[]; initL: Label = GenLabel[]; <> IFUStackOverflow: Label = GenLabel[]; IFUStkOvfBad: Label = GenLabel[]; EUStackOverflow: Label = GenLabel[]; EUStkOvfBad: Label = GenLabel[]; enterIFUStackOverflowTest: Label = GenLabel[]; enterSLimitTest: 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]]; }; <> 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 Pause[]; Pause[]; Pause[]; Pause[]; Pause[]; Pause[]; <> 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 }; SetLabel[dummy]; Pause[]; Pause[]; Pause[]; Pause[]; Pause[]; Halt[123B]; <<>> <> <> <> SetLabel[IFUStackOverflow]; drALS[377B]; --1 - nargs; nargs = 2 for ifuStatus (return PC and status) drLIB[1]; drRJNEB[popSrc, aux8, UseLabel8B[IFUStkOvfBad]]; GetYoungestPC[]; drLIQB[CardToWord[IFUPageFaultAddress]]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[IFUStkOvfBad]]; drLRn[reg0]; SetYoungestPC[]; --Change return address drEXDIS[]; drRETK[377B]; --nResults - 1 where nResults = 0 SetLabel[IFUStkOvfBad]; Pause[]; <> SetLabel[EUStackOverflow]; drALS[0]; --1 - nargs; nargs = 1 for ifuStatus drLIB[2]; drRJNEB[popSrc, aux8, UseLabel8B[EUStkOvfBad]]; GetYoungestPC[]; drRVADD[topDst, topSrc, const4]; SetYoungestPC[]; drLIB[0]; drSIP[ifuStatus]; --Turn off reschedule-waiting and disable traps drRETK[377B]; --nResults -1; nResults = 0 SetLabel[EUStkOvfBad]; Pause[]; <> oldPC _ GetOutputPC[area]; FillXop[0, dummy]; --opcode 0 = Pause[] FillXop[377B, dummy]; --opcode 377B = Halt[xxx] FillTrap[ResetTrap, start]; FillTrap[IFUStackOverflowTrap, IFUStackOverflow]; FillTrap[EUStackOverflowTrap, EUStackOverflow]; FillTrap[EUPageFault, EUPageFlt]; FillTrap[IFUPageFaultTrap, IFUPageFault]; FillTrap[RescheduleTrap, Reschedule]; SetOutputPC[oldPC]; ProcedureEntry[initL, 0]; drLIB[1]; SetYoungestL[]; -- L _ 1 on return <> drLIB[128-16-1]; SetSPLimit[]; ProcedureExit[0]; WordAlign[area]; <> SetLabel[start]; drLFC[UseLabel16[initL]]; --Initialize L to 1 drASL[255]; --and S = 0. 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[]; Halt[177777B]; --Terminate here at the end of the program }; END.