DIRECTORY Basics USING [BITAND, BITSHIFT], CountedVM USING [Handle, Allocate, Free], PrincOps USING [ControlLink, FrameHandle, StateVector], PrincOpsUtils USING [GetReturnFrame], XBus, XOps, TrapSupport USING [opTrapTable]; XBusImpl: CEDAR PROGRAM IMPORTS Basics, CountedVM, XBus, PrincOpsUtils EXPORTS XBus = BEGIN OPEN XOps, XBus; mBusCtl: POINTER = LOOPHOLE[2]; lBusOutData: POINTER = LOOPHOLE[2]; lBusInData: POINTER = LOOPHOLE[2]; mBusAddr: POINTER = LOOPHOLE[3]; lBusAddr: POINTER = LOOPHOLE[3]; timer: LONG POINTER = LOOPHOLE[LONG[64]]; masterClear: LONG POINTER = LOOPHOLE[LONG[13]]; MBusTimeout: PUBLIC SIGNAL = CODE; MBusTimeoutTrap: PROC = TRUSTED { frame: PrincOps.FrameHandle; state: RECORD [a: WORD, v: PrincOps.StateVector]; state.v _ STATE; state.v.dest _ PrincOps.ControlLink[frame[frame _ PrincOpsUtils.GetReturnFrame[]]]; frame.pc _ [frame.pc + 2]; -- Advance PC over the 2 bytes of the trapping opcode state.v.stkptr _ state.v.stkptr - 6; --Clear args from the stack MBusTimeout[]; RETURN WITH state.v; }; PCRefreshOn: PUBLIC PROC = { BusMasterWrite[timer+3, 84]; BusMasterWrite[timer+1, 18]; BusMasterWrite[masterClear, 0]; BusMasterWrite[LOOPHOLE[LONG[12]], 0]; BusMasterWrite[LOOPHOLE[LONG[1]], Basics.BITAND[8191, 255]]; BusMasterWrite[LOOPHOLE[LONG[1]], Basics.BITSHIFT[8191, -8]]; BusMasterWrite[LOOPHOLE[LONG[11]], 88]; BusMasterWrite[LOOPHOLE[LONG[10]], 0]; }; XReadL: PROC [add: POINTER] RETURNS [WORD] = { RETURN[XBus.ReadL[LOOPHOLE[add]]]; }; XReadM: PROC [add: POINTER] RETURNS [WORD] = { RETURN[XBus.ReadM[LOOPHOLE[add]]]; }; XWriteL: PROC [add: POINTER, data: WORD] = { XBus.WriteL[LOOPHOLE[add], data]; }; XWriteM: PROC [add: POINTER, data: WORD] = { XBus.WriteM[LOOPHOLE[add], data]; }; XWriteMBus: PROC [controlData: WORD, from, to: LONG POINTER, byteInterval, wordCnt: CARDINAL] = { XBus.WriteMBus[controlData, from, to, byteInterval, wordCnt]; }; XReadMBus: PROC [controlData: WORD, to, from: LONG POINTER, byteInterval, wordCnt: CARDINAL] = { XBus.ReadMBus[controlData, to, from, byteInterval, wordCnt]; }; XWriteIBMBus: PROC [controlData: WORD, from, to: LONG POINTER, byteInterval, wordCnt: CARDINAL] = { XBus.WriteIBMBus[controlData, from, to, byteInterval, wordCnt]; }; XReadIBMBus: PROC [controlData: WORD, to, from: LONG POINTER, byteInterval, wordCnt: CARDINAL] = { XBus.ReadIBMBus[controlData, to, from, byteInterval, wordCnt]; }; TestWriteSignal: SIGNAL = CODE; TestReadSignal: SIGNAL = CODE; MTest: PROC [nSeconds: LONG CARDINAL _ 10] = TRUSTED { vm1, vm2, vm3: CountedVM.Handle _ NIL; writeDataArray: LONG POINTER TO ARRAY [0..32767) OF WORD; readDataArray: LONG POINTER TO ARRAY [0..32767) OF WORD; readDataArrayX: LONG POINTER TO ARRAY [0..1) OF WORD; --extra array for reread writeControlData: CARDINAL _ 8902H; readControlData: CARDINAL _ 8A01H; loopEnd: LONG CARDINAL _ (nSeconds + 1) * 3097 / 10000; --empirical value vm1 _ CountedVM.Allocate[LONG[32767]]; vm2 _ CountedVM.Allocate[LONG[32767]]; vm3 _ CountedVM.Allocate[LONG[1]]; writeDataArray _ vm1.pointer; readDataArray _ vm2.pointer; readDataArrayX _ vm3.pointer; --Breakpoint place FOR I: CARDINAL IN [0..32767) DO writeDataArray[I] _ I; --Initialize the write array readDataArray[I] _ 125252B; --Put benign value in read array ENDLOOP; FOR J: LONG CARDINAL IN [0..loopEnd) DO WriteMBus[writeControlData, writeDataArray, LOOPHOLE[10000h], 2, 32767]; ReadMBus[readControlData, readDataArray, LOOPHOLE[10000h], 2, 32767]; FOR I: CARDINAL IN [0..32767) DO writeDataArray[I] _ 0 - I; IF readDataArray[I] # I THEN { ReadMBus[readControlData, readDataArrayX, LOOPHOLE[10000h + I + I], 2, 1]; IF readDataArrayX[0] # readDataArray[I] THEN TestReadSignal[] ELSE TestWriteSignal[]; }; ENDLOOP; WriteMBus[writeControlData, writeDataArray, LOOPHOLE[10000h], 2, 32767]; ReadMBus[readControlData, readDataArray, LOOPHOLE[10000h], 2, 32767]; FOR I: CARDINAL IN [0..32767) DO writeDataArray[I] _ I; IF readDataArray[I] # (0 - I) THEN { ReadMBus[readControlData, readDataArrayX, LOOPHOLE[10000h + I + I], 2, 1]; IF readDataArrayX[0] # readDataArray[I] THEN TestReadSignal[] ELSE TestWriteSignal[]; }; ENDLOOP; ENDLOOP; CountedVM.Free[vm1]; CountedVM.Free[vm2]; CountedVM.Free[vm3]; }; PCTest: PROC [nSeconds: LONG CARDINAL _ 10] = TRUSTED { vm1, vm2, vm3: CountedVM.Handle _ NIL; writeDataArray: LONG POINTER TO ARRAY [0..4096) OF WORD; readDataArray: LONG POINTER TO ARRAY [0..4096) OF WORD; readDataArrayX: LONG POINTER TO ARRAY [0..1) OF WORD; --extra array for reread writeControlData: CARDINAL _ 2H; readControlData: CARDINAL _ 1H; loopEnd: LONG CARDINAL _ (nSeconds + 1) * 2; --guess; verify this vm1 _ CountedVM.Allocate[LONG[4096]]; vm2 _ CountedVM.Allocate[LONG[4096]]; vm3 _ CountedVM.Allocate[LONG[1]]; writeDataArray _ vm1.pointer; readDataArray _ vm2.pointer; readDataArrayX _ vm3.pointer; --Breakpoint place FOR I: CARDINAL IN [0..4096) DO readDataArray[I] _ 125252B; writeDataArray[I] _ I; ENDLOOP; FOR J: LONG CARDINAL IN [0..loopEnd) DO WriteIBMBus[writeControlData, writeDataArray, LOOPHOLE[0A0000], 1, 4096]; ReadIBMBus[readControlData, readDataArray, LOOPHOLE[0A0000], 1, 4096]; FOR I: CARDINAL IN [0..4096) DO writeDataArray[I] _ 0 - I; --Setup for the loop below IF readDataArray[I] # I THEN { ReadIBMBus[readControlData, readDataArrayX, LOOPHOLE[0A0000 + I + I], 1, 1]; IF readDataArrayX[0] # readDataArray[I] THEN TestReadSignal[] ELSE TestWriteSignal[]; }; ENDLOOP; WriteIBMBus[writeControlData, writeDataArray, LOOPHOLE[0A0000], 1, 4096]; ReadIBMBus[readControlData, readDataArray, LOOPHOLE[0A0000], 1, 4096]; FOR I: CARDINAL IN [0..4096) DO writeDataArray[I] _ I; --Setup for the loop above IF readDataArray[I] # (0 - I) THEN { ReadIBMBus[readControlData, readDataArrayX, LOOPHOLE[0A0000 + I + I], 1, 1]; IF readDataArrayX[0] # readDataArray[I] THEN TestReadSignal[] ELSE TestWriteSignal[]; }; ENDLOOP; ENDLOOP; CountedVM.Free[vm1]; CountedVM.Free[vm2]; CountedVM.Free[vm3]; }; MWriteTest: PROC ~ { first: LONG POINTER = LOOPHOLE[LONG[0]]; last: LONG POINTER = LOOPHOLE[0FFFFEh]; data: WORD; FOR i: LONG POINTER _ first, i+2 WHILE i#last DO XBus.MemWrite[i, 0]; ENDLOOP; FOR i: LONG POINTER _ first, i+2 WHILE i#last DO IF (data _ XBus.MemRead[i])#0 THEN TestWriteSignal; XBus.MemWrite[i, 0FFFFh]; ENDLOOP; FOR i: LONG POINTER _ first, i+2 WHILE i#last DO IF (data _ XBus.MemRead[i])#0FFFFh THEN TestWriteSignal[]; ENDLOOP; }; Initialize: PROC = TRUSTED { TrapSupport.opTrapTable.misc[aWriteMBus] _ LOOPHOLE[MBusTimeoutTrap]; TrapSupport.opTrapTable.misc[aReadMBus] _ LOOPHOLE[MBusTimeoutTrap]; TrapSupport.opTrapTable.misc[aWriteIBMBus] _ LOOPHOLE[MBusTimeoutTrap]; TrapSupport.opTrapTable.misc[aReadIBMBus] _ LOOPHOLE[MBusTimeoutTrap]; }; Initialize[]; END. šXBusImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Last Edited by: Gasbarro, October 24, 1986 10:03:36 am PDT Tim Diebert: July 15, 1986 12:31:12 pm PDT Ed Fiala: August 21, 1986 3:22:03 pm PDT Ed Fiala: October 13, 1986 3:05:10 pm PDT Ed Fiala: October 24, 1986 10:03:32 am PDT The opcode trap here are modeled after stuff in TrapsImpl.mesa and StorageTrapsImpl.mesa. Changes needed: 1) The definitions in XOps.mesa maybe should be moved to PrincOps.mesa. The Misc alpha definitions in CedarMicrocode.mesa should also be moved to PrincOps.mesa MBusHung trap handler; this trap occurs when the MBus acknowledgment is not received for 10 microseconds in the ReadMBus, WriteMBus, ReadIBMBus, and WriteIBMBus opcodes. The trap occurs with the return PC pointing at the opcode which trapped and with the opcode arguments on the stack; the wordcount argument reflects the progress of the opcode, so it gives the 16-bit words remaining to be transferred. The code here advances the PC across the opcode and flushes the arguments from the stack. A descriptor for this procedure is put in the MISC opcode trap table entries which have indices corresponding to the alpha bytes of the four opcodes by the initialization code. These are here so that you can get at ReadL, ReadM, etc. from the interpreter These procedures test the ReadMBus, WriteMBus, ReadPCBus, and WritePCBus opcodes When nSeconds was 14,400 and the inner loop was J in [0..(nSeconds + 1)/2, the program took 23,247 seconds. At 6 microseconds/word, each WriteMBus or ReadMBus instruction below takes 0.2 seconds, so each iteration of the main loop should take 0.8 seconds plus the time to initialize the writeDataArray and execute the compare loop; altogether, this should take about 2 seconds per iteration of the outer loop. Reread the data to descriminate write errors from read errors; obtaining a different value on the reread indicates a flakey read problem; obtaining the same wrong value as the first read could indicate either a write problem or a solid read problem. At 9 microseconds/word, each WriteIBMBus or ReadIBMBus instruction below takes 0.04 seconds, so each iteration of the main loop should take 0.16 seconds plus the time to initialize the writeDataArray and execute the compare loop; altogether, this should take about 0.4 seconds per iteration of the outer loop. Initialization of the opcode traps for MBus and IBMPCBus timeout. Κ ―˜code™Kšœ Οmœ7™BK™:K™*K™(K™)K™*K™K™Y—K™K™°K™šΟk ˜ Kšœžœžœžœ˜ Kšœ žœ˜)Kšœ žœ)˜7Kšœžœ˜%Kšœ˜Kšœ˜Kšœ žœ˜ K˜—šœ žœž˜Kšžœ'˜.Kšžœžœžœ ˜%K˜Kšœ žœžœ˜Kšœ žœžœ˜#Kšœ žœžœ˜"Kšœ žœžœ˜ Kšœ žœžœ˜ K˜Kš œžœžœžœžœ˜)Kš œ žœžœžœžœ˜/K˜KšΟn œžœžœžœ˜"K˜Kšœ‘™‘šŸœžœžœ˜!K˜Kšœžœžœ˜1Kšœ žœ˜K˜SKšœΟc5˜QKšœ& ˜AKšœ˜Kšžœžœ ˜Kšœ˜—K˜šŸ œžœžœž˜Kšœ˜Kšœ˜Kšœ˜Kšœžœžœ ˜&Kšœžœžœ žœ ˜˜>K˜—K˜K˜KšœP™PKšŸœžœžœ˜KšŸœžœžœ˜K˜Kšœk™kš Ÿœžœ žœžœ žœ˜6Kšœ"žœ˜&Kš œžœžœžœžœ žœžœ˜9Kš œžœžœžœžœ žœžœ˜8Kšœžœžœžœžœžœžœ ˜OKšœžœ ˜#Kšœžœ ˜"Kšœ žœžœ# ˜JK˜Kšœžœ ˜&Kšœžœ ˜&Kšœžœ˜"K˜K˜Kšœ ˜1K˜š žœŸœžœžœ ž˜ Kšœ ˜4Kšœ  ˜=Kšžœ˜—K˜Kšœ­™­š žœŸœžœžœžœž˜'K˜Kšœ,žœ˜HKšœ)žœ˜Eš žœŸœžœžœ ž˜ K˜šžœžœ˜Kšœω™ωKšœ*žœ˜JJšžœ&žœžœ˜UK˜—Kšžœ˜—K˜Kšœ,žœ˜HKšœ)žœ˜Eš žœŸœžœžœ ž˜ K˜šžœžœ˜$Kšœ*žœ˜JJšžœ&žœžœ˜UK˜—Kšžœ˜—K˜Kšžœ˜—K˜K˜K˜Kšœ˜—K˜š Ÿœžœ žœžœ žœ˜7Kšœ"žœ˜&Kš œžœžœžœžœ žœžœ˜8Kš œžœžœžœžœ žœžœ˜7Kšœžœžœžœžœžœžœ ˜OKšœžœ˜ Kšœžœ˜Kšœ žœžœ ˜BK˜Kšœžœ˜%Kšœžœ˜%Kšœžœ˜"K˜K˜Kšœ ˜1K˜š žœŸœžœžœ ž˜K˜K˜Kšžœ˜—K˜Kšœ΅™΅š žœŸœžœžœžœž˜'K˜Kšœ.žœ˜IKšœ+žœ˜Fš žœŸœžœžœ ž˜Kšœ ˜6šžœžœ˜Kšœ,žœ˜LJšžœ&žœžœ˜UK˜—Kšžœ˜—K˜Kšœ.žœ˜IKšœ+žœ˜Fš žœŸœžœžœ ž˜Kšœ ˜2šžœžœ˜$Kšœ,žœ˜LJšžœ&žœžœ˜UK˜—Kšžœ˜—K˜Kšžœ˜—K˜K˜K˜Kšœ˜—K˜šŸ œžœ˜Kš œžœžœžœžœ˜(Kšœžœžœžœ ˜'Kšœžœ˜ K˜š žœžœžœžœž˜0Kšœ˜Kšžœ˜—š žœžœžœžœž˜0Kšžœžœ˜3Kšœ˜Kšžœ˜—š žœžœžœžœž˜0Kšžœ!žœ˜:Kšžœ˜—Kšœ˜—K˜šœA™AK™šŸ œžœžœ˜Kšœ+žœ˜EKšœ*žœ˜DKšœ-žœ˜GKšœ,žœ˜Fšœ˜K˜——K˜ K˜—Kšžœ˜——…—L-•