%
Page Numbers: Yes First Page: 1
Heading:
Ifu3a.mcMay 6, 1982 11:06 PM%
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Table of Contents
Organized by Occurence of subroutine in this Listing
SubroutineFunction
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
beginIfu3a:"main control", it calls the test subroutines
ifuPcAlphaPipe:Check the data bits of the Pc pipe and the Alpha pipe
ifuXqtTest:execution test for Ifu
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%
May 6, 1982 11:06 PM
Add comments.
May 20, 1981 3:10 PM
Construct this file out of ifu3.mc
May 19, 1981 4:50 PM
Begin adding iMiscEffects test (for RestoreStkP, IDFetch←, Fetch←ID, etc.)
February 1, 1980 8:05 PM
Fix miscellaneous comments, fix performance bug in iFastTest.
September 19, 1979 1:14 PM
Set expectedDispatch<0 in beginIfu3 -- for robustness.
September 18, 1979 11:07 AM
Cause tests that enableConditionalHold to disableConditionalTask as well -- seem to have mysterious bug that is associated with tasking. Fix some comments in IfuXqtTest.
September 17, 1979 6:32 PM
Fix beginIfu3 so that it is a subroutine that calls the test implemented here.
August 1, 1979 6:16 PM
Fix bug in ifuBrkInsTest -- failing to load BrkIns from left half of Bmux.
August 1, 1979 3:24 PM
Invert order of BrkIns←, Pcf←.
August 1, 1979 11:11 AM
Rearrange parts of IfuBrkInsTest for easier scope looping.
August 1, 1979 10:45 AM
Add noop to ifuBrkInsTest to accommodate placement problems.
August 1, 1979 10:36 AM
Fix omitted initialization of ifu memory in ifuBrkInsTest, missking skip instr, set instrset in ifu.
August 1, 1979 9:28 AM
Add the ifuBrkInsTest, add misc. comments.
July 3, 1979 2:27 AM
fix stack underflow error in resched test.
July 3, 1979 2:21 AM
Fix bug in iReschedTest -- clobbered the value that we load PcF with.
July 3, 1979 2:08 AM
Add noops for placement purposes. -- apparently setIUsingInstrSet causes some problems.
July 3, 1979 1:55 AM
Fix resched test, further, to handle the fact that reschedules don’t occur after one IfuJump but after several.
July 3, 1979 12:37 AM
Cause iRamPEtest to enable the ramPE exception condition.
June 29, 1979 5:02 PM
Fix ifuChaos’ ID checking to preserve ID in a register rather than xoring it with the expected value.
June 29, 1979 11:54 AM
Cause ifuChaos to reset memBase and memBX inside the ifuChaosL; check ;Rbase immediately after the IfuJump (in ifuChaos), since afterDispatch leaves POINTERS in a very fragile place (stk+1).
June 29, 1979 10:53 AM
Add missing "coreturn" at sicR2 (inside setIfuChaosRet).
June 24, 1979 6:40 PM
Change ifuChaos to use getIfuMBase, getIfuRBase for checking.
June 19, 1979 9:53 AM
Fix stack bug in iRamtest.
June 18, 1979 9:24 AM
Fix functional bugs in iRamPEtest (check for resched loc, reset rbase, membase, call setUsingInsrSet.
June 18, 1979 9:01 AM
Fix stack bugs in iRamPEtest.
June 17, 1979 4:30 PM
Add iRamPEtest.
June 6, 1979 10:30 AM
Chaos placement errors.
June 5, 1979 11:40 AM
Add calls to enableConditionalTask
June 1, 1979 6:16 PM
Fix ifuChaos errors.
May 30, 1979 10:16 AM
Extend ifuPcAdderTest to cover regular opcodes and two byte jumps.
May 13, 1979 5:12 PM
Add ifuChaose.
May 3, 1979 3:18 PM
Move stack manipulation & vm fix-up code to different part of loop in ifuPcAlphaPipeTest.
May 3, 1979 2:56 PM
Add call to resetIfu after initIfuM1Thru3 in ifuPcAlphaPipe test.
May 1, 1979 5:08 PM
Add sundry comments.
April 27, 1979 5:19 PM
Add call to resetIfu from within ifuPcAlphaPIpe test.
April 26, 1979 5:10 PM
Remove initIfuCache thru ifuTestLoop--moved into ifuTestSubrs.mc.
April 26, 1979 10:18 AM
Add code to use iUsingInstrSet during getCDbyte, putCDbyte; modify the code that puts opcodes in memory to place them in virtual order, Jtest.
April 25, 1979 12:52 PM
Make iFastTest accessible to normal testing. (no longer infinite loop).
April 24, 1979 3:49 PM
Add Pc adder test.
April 24, 1979 9:19 AM
Add ifuTestLoop.
April 24, 1979 8:46 AM
Add PcPipe test, and checkPcX routine & concomitant support code; add top level calls on various tests so that control no longer "falls through".
April 22, 1979 5:25 PM
Move ifuBackground thru ifuCountOnes into ifuRamSubrs.
April 20, 1979 6:09 PM
Fix missing "composeIfuWd[] in getIfuHalt.
April 20, 1979 3:59 PM
Fix register clobbering bug in putIfuWd (another, different one).
April 19, 1979 4:59 PM
Fix stack manipulation bug in ifuBackGround.
April 19, 1979 11:38 AM
Add comments to ifuOpcode Test, diddle various things.
April 11, 1979 9:53 AM
Fix register clobbering bug in putIfuWd.
April 10, 1979 2:37 PM
Rearrange code to fit into functional categories -- prelude for division into different files.
April 4, 1979 11:28 PM
Add test controls to iterate thru the various tests in memory.
April 4, 1979 6:05 PM
Set memBX to zero, disallow wakeups on single memory errors, cause FastTest to invoke resetIfu subroutine.
March 1, 1979 7:17 PM
Add reschedule test.
March 1, 1979 6:26 PM
Change appendPause to appendHalts (3 words, 6 bytes), replace all pause opcodes with halts.
February 17, 1979 6:12 PM
Add noops for placement.
February 7, 1979 9:03 AM
Flush the first munch of ifu program from cache.
February 6, 1979 3:00 PM
Modify initialization to set All the words in Ifu memory to valid parity (pointing to an instruction that causes the processor to get an error).
February 6, 1979 2:15 PM
Fix bug in construction of program at 400 in memory; add noop after pcF← before next ifuJump.
February 5, 1979 10:36 AM
Add fast opcodes, program to memory, etc.
January 29, 1979 10:52 AM
Add code to iMem that inits Ifu’s code base.
January 26, 1979 4:18 PM
Change iMem to background memory so that the first memory referenes of the ifu code won’t cause task 17 wakeups if there’s garbage in storage. Remove mesa opcode stuf described below.
January 22, 1979 6:04 PM
Fix bugs in memory checking code...add code that loads ifu memory w/ mesa opcode values. This is strictly a hack to find out how to hand load ifumemory while the micro/microd/midas interface doesn’t work.
January 22, 1979 11:02 AM
Fix mos← bug, change default pcF, background storage with identity and cause the processor to make memory references, and check for correctness.
January 22, 1979 9:44 AM
Add noops to remove very long ring: placement problem.
January 22, 1979 9:18 AM
Add incClock calls into ifuJump looop; fix problems w/ program at wd 100; add more comments.
January 20, 1979 8:28 AM
Fix putIfuWdPe0 bug, add more "programs" to cache.
January 17, 1979 2:59 PM
Execute from instruction set 3 (because exception addresses get instrSet’ or’d into them).
January 10, 1979 4:50 PM
more opcodes into ifuMemory, more programs into cache, stack+1←ID
January 9, 1979 4:51 PM
icStartIfu loop to reset ifu, pcF before beginning icTopL loop
January 2, 1979 11:12 AM
longWait in initIfuCache to avoid memory system misses
%
* May 20, 1981 3:19 PM
beginIfu3a:
pushReturn[];
expectedDispatch←a1;
call[ifuPcAlphaPipe];* check the data bits of the pc pipe
call[ifuXqtTest];* try various programs
endIfu3a:
returnP[];
* June 5, 1979 11:33 AM
%*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ifuPcAlphaPipe
This test checks the data bits of the Pc pipe, and the data bits of the alpha/H pipe. Proceed by generating different patterns to set into PcFG. After waiting enough time for the Ifu Pipe to fill, perform an Ifu jump and then look at PcX. It should have the same value we originally set into PcFG. Use a two byte opcode and cycle through all possible bit patterns in a byte for the second (alpha) byte.
Don’t forget to initialize the byte in memory pointed to by the pattern (and to undo setting that byte afterwards). We’ll use instruction set 1, and make use of opcode = 1. This opcode gets used by the "test register" mode diagnostics that appear in Ifu1.mc.
call[initIfuCache];--init the memory system for use by this test
call[initIfuMem1Thru3];
FOR pat IN PatX DO
oldByte ← getByte[pat];-- remember the original value where we put opcode
oldByte2 ← getByte[pat+1];-- original value where we put operand (alpha)
putByte[pat,1];-- write opcode = 1 at byte location = pat
FOR bytePat IN [0..400B) DO
putByte[pat+1, bytePat];
PcFG ← pat;
cnt ← 20;
returnLink ← @ L1;
Jump:
IFUJUMP[0];
L1:
IF cameFromLocation # ExpectedLocation THEN
IF cameFromLocation = notReadyLocation
THEN GOTO Jump
ELSE SIGNAL IfuPcAlphaJumpErr[];
putByte[pat, oldByte];-- restore memory to original value
IF PcX # pat THEN SIGNAL PcPipeErr[];
IF IfuData # bytePat THEN SIGNAL AlphaPipeErr[];
ENDLOOP;
putByte[pat, oddByte];-- restore the opcode byte
putByte[pat+1, oddByte2];-- restore the operand byte (alpha)
ENDLOOP;
%*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* May 6, 1982 10:56 PM
ifuPcAlphaPipe:
pushReturn[];
call[initIfuCache];* initialize the memory system
call[resetIfu];
call[setIUsingInstrSet], t ← 1C;
noop;* for placement
call[resetIfu];
call[initIfuM1Thru3];* init instrset1, IFUM 1-3
call[resetIfu];* clear breakpending (from writing IfuM)
call[enableConditionalTask];
call[iPat16];
* This is the top, outer loop. It decides the location of the 2 byte instruction
ifuPcPipeL:* We check the PcPipe by changing that location
call[nextPat16];
skpif[ALU#0];
branch[ifuAfterPcPipe];
noop;* for placement.
call[getCDbyte];* enter w/ t = byte addr, rtns t =
stack+1←t;* contents of that byte location.
call[getPat16];
stack+1←t;* remember current pattern in stack
call[putCDbyte], rscr←2C;* use opcode = "2"
call[iPat8];
* This is the intter loop. It decides the value for the alpha byte.
ifuPcAlphaL:* see if there are more byte patterns
call[nextPat8];* for the current PcF value
skpif[ALU#0], rscr ← t;* save byte pattern in rscr
branch[afterIfuPcAlphaL];
noop;
call[putCDbyte], t ← (stack)+1;* set "alpha" for this opcode. t = addr, rscr = byte value.
PcF ← stack;* now test the Pc pipe
t ← 20C;
cnt←t;* try no more than 20B times
call[ifuPcPipeSetKLink];* set up return link so we can get
ifuPcAlphaJump:
IfuJump[0];* from our ifu jump.
ifuPcPipeCont:* afterDispatch leaves rscr=location
(rscr) # (opAt15);* where IfuJump took us.
skpif[ALU#0];
branch[ifuPcAlphaCheck];
loopUntil[CNT=0&-1, ifuPcAlphaJump];
ifuPcAlphaJumpErr:* after 20B times we should succeed in
error;% executing the opcode (the afterDispatch code takes around 8 cycles). Since that hasn’t happened, something is sadly amiss. RSCR=address where Ifu dispatched the processor. Dispatches to notReady suggest the IFU can’t talk to the memory system; other exception conditions speak for themselves.
%
ifuPcAlphaCheck:
t ← not(PcX’);
t # (stack);* see if PcX matches our pattern
skpif[ALU=0];
ifuPcPipeErr:* PcX should be (stack) and is (t).
error;* data path error or control error.
call[getPat8];
rscr ← ID;
(rscr) # t;
skpif[ALU=0];
ifuAlphaPipeErr:* rscr = ifuData, t = expected data
error;
t ← t-t;
rscr ← (ID)+t;* force ID arithmetic path
t ← (2c);
t # (rscr);
skpif[ALU=0];* should get instruction length (2)
ifuAlphaPipeErr2:* rscr = IfuData, t = bad bits. Expected 2
error;
branch[ifuPcAlphaL];
afterIfuPcAlphaL:
stkp-1;* position stack to old byte
t←stack&+1;* put the old value back into memory
rscr ← t;
call[putCDbyte], t←stack;
branch[ifuPcPipeL], stkp-2;* don’t forget pattern & old byte are on stack.
%*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ifuPcPipeSetKLink
This subroutine sets KLINK to point to an instruction that will GOTO ifuPcPipeCont. This is how we give control back to the PcData routine after an IfuJump.
%*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ifuPcPipeSetKLink:
pushReturn[];
call[ifuPcPipeSetKLink2];
t ← link;
klink ← t;
returnP[];
ifuPcPipeSetKLink2:
coreturn;
branch[ifuPcPipeCont];
ifuAfterPcPipe:
top level;
call[disableConditionalTask];
returnP[];
* January 22, 1979 6:21 PM
%
ifuXqtTestTest the ifu using the memory system cache.
The IfuOpCode Test sequences through a group of small ’programs’ written into memory. The outer loop, whose top is at icNextTest controls which program the test executes. The inner loop whose top is at icNextTestIteration, controls how many ifuJumps the test executes before starting the next test.
The inner loop has two phases. The first performs a simple IfuJump and then pushes ID onto the stack (the operator must look at the stack contents to decide it they (the contents) are correct. The second phase exercises the memory system as well as the ifu. It performs a fetch at the same time it executes an IfuJump. If the data returned from that fetch is not the same as the data returned from a subsequent fetch from the same address, an error has occured. Then the test increments a roving pointer that is forced to stay in the interval [100000B..177777B]. The memory initialization code has written that section of memory with its address (ie., location 135555 contains 135555, etc). The test fetches the contents of memory pointed at by the roving pointer (and complains if the contents is not equal to the address), and stores the address in that location (ie., rewrites the data).
initIfuCache[];
resetIfu[];
rovingPtr ← 100000B
FOR test in TestX DO
PcF←getCurrentProgramLocation[test];
FOR ifuJumpX IN IterationCount DO
ReturnLink ← @L1;-- return to L1 after ifufJump
IfuJump[0];
L1:
pushIDontoStack[];-- eyeball it to see if it is ok
popIDfromStack[];
IF PcX < getBeginLoc[test] or PcX > getEndLoc[test] THEN ERROR;
IF (ifuJumpX ← IfuJumpX+1) ~IN IterationCount THEN GOTO EXIT;
ReturnLink ← @L2;-- return to L2 after ifufJump
IfuJump[0], tempAddr ← FETCH←ID;
L2:
tempV ← MD;
pushIDontoStack[];-- eyeball it to see if it is ok
popIDfromStack[];
IF PcX < getBeginLoc[test] or PcX > getEndLoc[test] THEN ERROR;
FETCH←tempAddr;
IF MD # tempV THEN ERROR;
rovingPtr ← rovingPtr+17B;-- cross munch boundaries & everything
IF rovingPtr>0 THEN rovingPtr ← 100000B;-- only look at top half of memory
FETCH←rovingPtr;
IF (MD#rovingPtr) THEN ERROR;
STORE←rovingPtr, DBuf←rovingPtr;
ENDLOOP;
EXIT:
%
* May 6, 1982 10:57 PM
%
This test exercises the ifu. The loop consists of
IfuJump
check that everything was ok
IfuJump + make a memory reference
check that everything was ok
%
ifuXqtTest:
pushReturn[];
call[initIfuCache];* init the environment:
*the memory system, the ifu memory, the cache
call[setIUsingInstrSet], t ← 3C;
noop;* space for breakpoint so we can easily patch code.
call[enableConditionalTask];
icStartIfu:* reset the ifu, set pcF
call[resetIfu];
t ← (r0)-1;
clockCount ← t;
icSetInstrSet:
t ← 101400C;* instruction set 3
MOS ← t;
noop;* patch to B←t???
call[initItest];
icNextTest:
call[nextITest];
skpif[ALU#0];
branch[icTestDone];
noop;
PcF ← t;* start IFU at current location.
call[initITestCount];
icNextTestIteration:* the beginning Pc is in iCurrentTestLoc
call[nextITestCount];
skpif[ALU#0];
branch[afterTestCount];
icTopL:* top of ifuJump loop
noop;* for placement
call[incClock];
call[icGetResumeLoc];
t ← link;
klink ← t;* afterdispatch uses klink as a return link
ifuJump[0];* control will eventually reach afterDispatch
icResume:
noop;* place for Severo to patch
stack+1 ← ID;* in the worst case (len=3, packed alpha,
stack+1 ← ID;* n#17) we must perform 5 ←IDs to suck
stack+1 ← ID;* the pipe dry and get one IL.
stack+1 ← ID;
stack+1 ← ID;
icDownStack:
noop;* can check the stack here
stkp-4;
stkp-1;
call[checkPcX];* see if PcX is incorrect (approximate
skpif[ALU=0];* check, only)
icPcXErr1:* PcX is not within the range of the
error;% program we are currently executing. Ie., we’re executing an opcode from a memory location NOT in the program we should be executing.
T = current PcX, RSCR = program begin location, RSCR2 = program end location.
%
call[nextITestCount];* see if we’re done executing this test
skpif[ALU#0];
branch[afterTestCount];
icSkipMemOps:* noop to patch if required
noop;
call[icGetResume2];
t ← link;
klink ← t;
ifuJump[0], stack+1 ← (FETCH ← ID);* make mem reference, remember the Id value, & IfuJump
icAfterJump2:
noop;
stack+1 ← MD;* save Md for reference we just made
stack+1 ← ID;* in the worst case (len=3, packed alpha,
stack+1 ← ID;* n#17) we must perform 5 ←IDs to suck
stack+1 ← ID;* the pipe dry and get one IL.
stack+1 ← ID;
stack+1 ← ID;
stkp-4;
stkp-1;
call[checkPcX];* see if PcX is incorrect (approximate
skpif[ALU=0];* check, only)
icPcXErr2:* PcX is not within the range of the
error;% we are currently executing. Ie., we’re executing an opcode from a memory location NOT in the program we should be executing.
T = current PcX, RSCR = program begin location, RSCR2 = program end location.
%
%
Now we check the validity of the memory reference. Since memory is backgrounded with its own address (mem location 5=5, etc) we know the expected value is the same as the address we used in the reference! We saved the Id on the stack, so that stack location contains the MAR value.
%
t ← stack&-1;* retrieve old MD value from stack
fetch ← stack;
rscr ← MD;
(rscr) # t;
skpif[ALU=0];
icMdErr:* t = data after fetch←id, rscr = data
error;* after fetch←stack (where stack contained earlier id)
* a problem here suggests there’s a problem with MemC
stkp-1;
rscr3 ← (rscr3) + (17C);* use large increment so we can move thru
skpif[ALU<0];* entire cache reasonably quickly.
rscr3 ← 100000c;* allow diagnostic to use va[0..77777B]
fetch ← rscr3;
t ← md;
t # (rscr3);
skpif[ALU=0];
icMd2Err:* expect mem[va] = va for va>77777
error;* used rscr3 for va, got md into t.
store ← rscr3, Dbuf ← rscr3;
branch[icNextTestIteration];
afterTestCount:
branch[icNextTest];
icTestDone:
call[disableConditionalTask];
returnP[];
icGetResumeLoc: subroutine;* return w/ link pointing to icResumeLoc
coreturn;
icResumeLoc:* we come here from afterDispatch
branch[icResume];
icGetResume2:
coreturn;
icResume2:
branch[icAfterjump2];
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
checkPcX
This subroutine returns ALU=0 IF PcX is within the range of the "current" program in memroy. Otherwise it returns ALU#0. In either case, it returns with T=PcX, rscr = program begin location and rscr2 = program end location.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
checkPcX:
pushReturn[];
call[getTestBounds];* returns w/ rscr = begin location, RSCR2=
t←not(PcX’);* end location.
t-(rscr);
skpif[alu>=0];
branch[checkPcXFail];
(rscr2)-(t);
skpif[alu>=0];
branch[checkPcXFail];
returnPAndBranch[0C];* no error
checkPcXFail:
returnPAndBranch[1C];