%
Page Numbers: Yes First Page: 1
Heading:
MODEL 1:memrwd.mcSeptember 17, 1981 6:51 PM%
title[memRWd];
top level;
%
A FEW RULES


Subroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and in subroutine description. Subroutines return single values in T, and they accept single values in T. Two parameter subroutines accept their values in rscr and rscr2. Subroutines may use the global variables Mrow, Mcol, etc.

Global values for D board

Abbreviations used herein
iInit
MMap
colColumn
CCache
DcacheData
nextFooincrements foo loop variable, returns with fast branch condition to check for done w/ loop
getFooreturns current value of loop variable, foo
getFooRtnsubroutine that returns in T the saved value of foo’s return link
iFooCtrlinitialize foo loop control
%
%
September 17, 1981 6:50 PM
Add check to see if memState.Dtest bits are set. If not, just return.
Note: There is no specific bit that enables the gallpat cache data test. That test runs if any other test is enabled.
May 26, 1981 9:50 AM
Invert the order of GallPat test and HoldTest-- hold test sets mcr.
May 21, 1981 3:47 PM
Add GallPat test for cache data.
September 19, 1979 7:16 PM
Add call to disableConditionalTask to beginDtest.
September 13, 1979 4:46 PM
Change control structure so that a single subroutine invokes each dboard test. Last previous mod on 28Dec78.
%

* September 17, 1981 6:50 PM
beginDtest:
pushReturn[];
checkMtest[memFlags.dBoard, dTestDone];
call[disableConditionalTask];
call[cDataTest1];
call[cdaTest];
call[cdGallPat];
call[cdHoldTest];
dTestDone:
returnP[];

%
To test the D-board cache data by reading and writing it:
TESTSYNDROME ← 0;-- initialize the D-board
--For the first set of tests, disable the cache flags and the base registers
test1MCR ← [ disHold];
SetMCR[test1MCR];
FOR va ← 0, va ← va + 20b UNTIL va >= 1000B DO
col ← colFromVa[va];
SetMcr[test1MCR OR useMcrV OR (mcrV:col)];
store ← va, MD ← 0;
ENDLOOP;
-- end of initialization sequence
FOR patX IN PatX DO-- begin testing current va
FOR va IN [0..4000) DO
pattern ← getPat[patX, va];
md ← pattern, store ← va;
ENDLOOP;
-- end of data writing loop
FOR va IN [0..4000) DO
pattern ← getPat[patX, va];
FETCH ← va;
x1 ← MDI;
x2 ← MD;
IF x1 #x2 THEN ERROR;
IF x1 # pattern THEN ERROR;
ENDLOOP;
-- end of check loop
ENDLOOP;-- end of pattern loop

SetCFlags: PROCEDURE[baseRegs, va, cacheFlags, column] =
BEGIN
realBR ← make24BitBR[baseRegs];
mcrValue ← [useMcrV, mcrv: col, noRef, disHold];
SetBR[realBR-cacheFlags];
dummyRef ← va;
CFLAGS ← cacheFlags;
END;
%

* March 20, 1978 1:59 PM
cDataTest1:
pushReturn[];
call[iDboard];
checkMtest[memFlags.dRW, cdXit];
t←rscr←(rscr)-(rscr);* BRHI = va = 0
call[presetCache],rscr2 ← t;* cache flags=0
call[setMCR], t ← r0;

cd1PatI:
call[iCDpatCtrl];

cd1PatL:
call[nextCDpat];
skpif[alu#0];
branch[cdXit];
noop;

cd1wVaI:
call[iCDvaCtrl], t ← r0;* init cache beginning w/ va=0
cd1wVaL:
call[nextVa];* sets va directly
skpif[alu#0];
branch[cd1rVa];* go read what we’ve written
noop;
call[getCDpat];* knows about va
DBuf ← t, store ← va;
branch[cd1wVaL];

cd1rVa:
call[iCDvaCtrl], t ← r0;* init cache beginning w/ va=0

cd1rVaL:* top of read/check loop
call[nextVa];
skpif[alu#0];
branch[cd1PatL];* no more to check. try next pattern

fetch ← va;
noop;
t ← (r0) + (md);* removed: + (r0); for a while
CData ← md;* try both immediate and regular md

%*------------------------------------------------------------------------------
Perform two tests on cache data. First (cd1rerr1), make sure the values from MD and from MDI are the same. Second (cd1rerr2), make sure the value we got from the cache is the same as the one we wrote. In both cases, CData contains the value from the cache, and va is the current cache address.
%*------------------------------------------------------------------------------
t#(CData);* T contains cache data from MD,
skpif[alu=0];* CData contains cache data from MDI
cd1rerr1:* va is the address we referenced.
error;* two reads of mem data don’t macth

call[getCDpat];* put current pattern in rscr
rscr ← t;
t ← t # (CData);* compare current pattern, cache data
skpif[alu=0];* t = bad bits, CDdata = val from cache
cd1Rerr2:* va is the address we referenced.
error;* and rscr = expected data
branch[cd1rVaL];

cdXit:
returnP[];

* January 12, 1978 10:20 AM
%
Exhaustive test of Cache Addressing
Perform exhaustive test of cache addressing mechanism:
zeroCache[];
FOR va IN [0..cdMaxVa) DO
-- catch bad stores ahead of va
IF cache[va] # 0 THEN FindErrUP[];
cache[va] ← -1;
ENDLOOP;
zeroCache[];
FOR va DECREASING IN [0..cdMaxVa) DO
-- catch bad stores below va
IF cache[i] # 0 THEN FindErrDown[];
cach[i] ← -1;
ENDLOOP;
FindErrUP: PROCEDURE[va] =
BEGIN
zeroCache[];
FOR va2 IN [0..cdMaxVa) DO
IF cache[va] # 0 THEN ERROR;-- store at va2-1 cloobbered va
cache[va2] ← -1;
ENDLOOP;
addrGhosts ← addrGhosts + 1;
END;
FindErrDown: PROCEDURE[va] =
BEGIN
zeroCache[];
FOR va2 DECREASING IN [0..cdMaxVa) DO
IF cache[va] # 0 THEN ERROR;-- store at va2-1 cloobbered va
cache[va2] ← -1;
ENDLOOP;
END;
%
* December 28, 1978 1:47 PM
cdaTest:* cache data addressing test
pushReturn[];
checkMtest[memFlags.dAddr, cdaTestXit];
call[zeroCache0];* zero cache. Begin at va=0
call[iCDvaCtrl], t←r0;

cdaUpL:* FOR va IN [0..cdMaxVa) DO
call[nextVa];
skpif[alu#0],t←cm1;
branch[cdaUpXit];* try decreasing va now

fetch ← va;* rscr = last va
CData ← md;
CData ← CData;
skpif[alu=0];
branch[cdaUpErr];* see which store caused the problem

branch[cdaUpL], store←va, DBuf←t;* cache[va] ← -1

cdaUpXit:* try the same test w/ decreasing va
call[zeroCache0];
call[iCDvaCtrl], t←r0;

cdaDownL:* FOR va DECREASING IN [0..cdMaxVa) DO
call[nextVa];
skpif[alu#0];* nextVa writes directly into va
branch[cdaTestXit];

t ← cdMaxVa;* cdMaxVa = last address + 1
t ← t-1;* max valid address into t
va ← t-(va);* make va Decrease!
fetch ← va;
CData ← md;
CData ← CData;
skpif[alu=0];
branch[cdaDownErr];* see which write caused the failure

t ← cm1;
branch[cdaDownL],DBuf←t, store←va;* cache[va]←-1

cdaUpErr:* va-1 = last address used for a store.
* We know that a store in the interval [0..va) has clobbered location va. Loop again
* and check location va after each store. KEEP (at entry) Va IN R1

r1 ← va;* TEMPRORARY EXPEDIENT
call[zeroCache0];
call[iCdVaCtrl], t←r0;

cdaUpErrL:* FOR va2 IN [0..cdMaxVa) DO
call[nextVa];
skpif[alu#0];
branch[cdaUpNoFind];

fetch ← r1;
CData ← md;
CData ← CData;
skpif[alu=0];* CData = bad value
cdaUpError:* r1 = clobbered address.
error;* va-1 = addr whose store clobbered r1 addr

t←va;* see if we are about to write the location
t-(r1);* that was clobbered earlier. If so, skip it
skpif[alu#0];* --its a transient problem. Continue testing
branch[cdaUpErrL];* since we might find another problem

t ←cm1;
branch[cdaUpErrL], store←va, DBuf←t;* cache[va2] ← -1

cdaUpNoFind:
error;* This suggests a transient error.

cdaDownErr:* va-1=last address used for a store.
* We know that a store in the interval [0..va) has clobbered location va. Loop again
* and check location va after each store.
r1 ← va;* KEEP clobbered Addr in R1!!
call[zeroCache0];

call[iCDvaCtrl], t←r0;
cdaDownErrL:* FOR va2 DECREASING IN [0..cdMaxVa) DO
call[nextVa];
skpif[alu#0];
branch[cdaDownNoFind];

t ← cdMaxVa;
t←t-1;* make va DECREASING from last
va ← t-(va);* valid address

fetch ← r1;
CData ← md;
CData ← CData;
skpif[alu=0];
cdaDownError:* CData = bad value, r1 = clobbered address
error;* va+1 = addr whose store clobbered r1 addr

t ← rscr ← (va);* remember this va for next time

t-(r1);* see if we are about to write the location
skpif[alu#0];* that was clobbered earlier. If so, skip it
branch[cdaDownErrL];* --its a transient problem. Continue testing
* since we might find another problem
t ← cm1;
branch[cdaDownErrL], DBuf←t, store←va;* cache[va2] ← -1;

cdaDownNoFind:* This suggests a transient error.
error;

cdaTestXit:
r1 ← 1c;* just in case we continued from Midas
returnP[];

* December 27, 1978 11:00 AM
%
TEST HOLD, MD, MDI INTERACTIONS

Fetch known values under different timing circumstances to make sure the memory system returns the correct value. These tests try to retrieve a known value w/ zero, one or two noops between fetch← and ←md. Both md and mdi are tested. The test calls cdHoldReset to force a zero into md.
%
cdHoldTest:* init some values
pushReturn[];
checkMtest[memFlags.dHold, afterCDhold];
t ← mcr.noWake;
call[setMCR];
DBuf ← r0, STORE ← r0;* cacheData[0] ← 0
rscr ← t ← cm1;
DBuf ← t, store ← r1;* cacheData[1] ← 177777b

call[cdHoldReset];
t ← fetch ← r1;
t ← md;* zero noops
t ← t # (rscr);
skpif[alu=0];
cdHoldErr0:
error;* t=bad bits, rscr = expected value, r1=addr

call[cdHoldReset];
t ← fetch ← r1;
noop;* one noop
t ← md;
t ← t # (rscr);
skpif[alu=0];
cdHoldErr1:
error;* t=bad bits, rscr = expected value, r1=addr

call[cdHoldReset];
t ← fetch ← r1;
noop;* two noops
noop;
t ← md;
t ← t # (rscr);
skpif[alu=0];
cdHoldErr2:
error;* t=bad bits, rscr = expected value, r1=addr

call[cdHoldReset];
t ← fetch ← r1;
t ← (md) + (r0);* zero noops, use mdi
t ← t # (rscr);
skpif[alu=0];
cdHoldMdiErr0:
error;* t=bad bits, rscr = expected value, r1=addr

call[cdHoldReset];
t ← fetch ← r1;
noop;* one noop
t ← (md) + (r0);* use mdi
t ← t # (rscr);
skpif[alu=0];
cdHoldMdiErr1:
error;* t=bad bits, rscr = expected value, r1=addr

call[cdHoldReset];
t ← fetch ← r1;
noop;* two noops
noop;
t ← (md) + (r0);* use mdi
t ← t # (rscr);
skpif[alu=0];
cdHoldMdiErr2:
error;* t=bad bits, rscr = expected value, r1=addr
branch[afterCDhold];

*
This subroutine forces a zero into md.
cdHoldReset:
subroutine;
fetch ← r0;
t ← md;
return;
top level;
afterCDhold:
returnP[];

* May 26, 1981 10:31 AM

%
cdGallPat:
Traditional gallpat test: zero memory then write each cell of the memory.
After each write, read all of the memory to see if any other cell has been effected by the write
%

cdGallPat:
pushReturn[];
call[cdDoGallPat], t←a0;* background with zeros
call[cdDoGallPat], t←a1;* background with ones
returnP[];

cdDoGallPat:
pushReturnAndT[];
call[setCache0], t← Stack;

call[iCdVaCtrl],t←a0;* Start va at zero
cdGallPatL:* Top of MAIN LOOP
call[nextVa];
skpif[alu#0];
branch[cdGallPatXit];
t← cdMaxVa;
call[cdCheckVaRange],rscr←a0;* cache[0..cdMaxVa) should be =stack

cdGallPat2:
t← not(stack);
Pd← (Store← va)-1, DBuf← t;
branch[cdNoChk, ALU<0];
rscr← a0;* placement requires instr here
call[cdCheckVaRange], t← (va)-1;* check the interval [0..va)
rscr← (va)+1;
call[cdCheckVaRange], t← cdMaxVa;* check the interval (va..cdMaxVa)
noop;* for placement.

cdNoChk:
Fetch←va;
t← not(stack);
t#(Md);
skpif[ALU=0], t← (va)+1;
cdGallPErr2:* can’t find the value (not(stack)) we
error;* just wrote!

cdGall3:
t←va;
Store←t, DBuf← stack;* restore it to original value

t←SUB[cdMaxVa!,1]C;
cdGall4L:
Fetch←t;
(md)#(stack);
skpif[ALU=0], t← t-1;
cdGallErr3:* storing Stack into va clobbered location
error;* at t+1
branch[cdGall4L, ALU>=0];

branch[cdGallPatL];
cdGallPatXit:
pReturnP[];

* May 26, 1981 10:11 AM

cdCheckVaRange: subroutine;* Enter w/ t=lastva+1, rscr=1st va, stack=expected value.

Q← Stack&+1;* Keep expected value in Q
Stack← link;* Save return link
top level;
(rscr)-t;
branch[.+2, alu<0];
branch[cdCheckVaXit], link← stack&-1;
noop;* for placement

cdChkVaRangeL:
rscr← (Fetch←rscr)+1;* fetch current value and increment va
(Md)#(Q);
skpif[alu=0], (rscr)#t;
cdChkErr:* cache[RSCR+1] is not same as Q
error;* see return link on STACK to find
*where this problem has occured. This subroutine is called from cdGallpat.

loopWhile[ALU#0, cdChkVaRangeL];
subroutine;
link← stack&-1;
cdCheckVaXit:
return;