%
Page Numbers: Yes First Page: 1
Heading:
DORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%

title[memSubrsChaos];
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
table of contents by order of occurence
NameDescription
iChaosCacheInitialize the 4 columns of the 2 rows chaos uses.
sChaosChkAddrssubrutine to verify validity of all of vm after chaos test is done
isChaosMeminitialize mem[va] ← va
iSavedHoldValuesave current holdValue (postamble uses it to drive task/hold simulator)
getSchaosRow0Addrreturn current value of sChaosRow0 shifted into an address
getSchaosRow1Addrreturn current value of sChaosRow1 shifted into an address
sShadowBitToVaset addr.shadowBit in sVa if the current two bit nibble in our random number indicates that this munch should have the shadow bit set.
CFlagsFromTemplateset cflags.dirty for the value for the current munch’s CFLAGS if the current two bit nibble in our random number indicates this munch should be dirty.
iSchaosCodeInitialize the random rm values, patch IM as required by pseudo random number generator.
sChaosAddrFromRandVGenerate an address for "row0" or for "row1" based upon current sChaosRandV
getChaosTaskFreqReturn 7 bit random number to put into task portion of hold&tasksim.
get1Randsubroutine to get a random number
chaosTsk<i>Tst<j>i=0 means task 0, i=1 means simulator task, j IN [0..3]. This is the code that gets patched based on pseudorandom numbers. It’s execution is the chaos test.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%
September 14, 1979 3:37 PM
Make some of the code shorter to help with micro’s storage full problems. Add sChaosCkhkAddrs. Add isChaosMem and iSavedHoldValue, too.
June 25, 1979 11:09 PM
Add get1Rand because mema won’t place due to the way "getRandom[]" works.
June 25, 1979 10:32 PM
add getChaosTaskFrq.
June 25, 1979 8:33 AM
Change placement declarations to accommodate ifu entry points.
April 18, 1979 11:44 AM
Moved iChaosCache, iChaosCode into here from memChaosS.mc
%

* This code duplicated in memChaosS.mc!

mc[
codeRand.store, 40];
mc[
codeRand.wordX, 17];
mc[
codeRand.rowX, 20];
set[
codeRand.colSize, 2];* mc[codeRand.colX, 300];
set[
codeRand.colShift, 6];
set[
codeRand.delaySize, 5];* mc[codeRand.delay, 17400]
set[
codeRand.delayShift, 10];

mc[
addr.shadowBit, lshift[4,skipCacheShift]];* va bit for shadow address

* addrRand is a two bit nibble selected from the current two lsb of a random number.
* the test uses addrRand to determine how to initialize each column of the two rows
* in the cache.
mc[
addrRand.dirty, 1];* mask bit for address template.
mc[
addrRand.shadow, 2];* mask bit for address template

* January 16, 1979 7:26 PM
%
iChaosCache
This code initializes all four columns of two rows of the cache. Eight two-bit nibbles in a random number determine for each column-row munch whether that munch is dirty and whether that munch belongs to the "shadow" address. Remember that eight addresses (munch addresses) are not enough to cause cache misses for two rows worth of data. Consequently there is an extra "shadow" bit that may set in the cache address, and that bit provides enough address space to cause misses in the cache.
Obtain the two row addresses from sChaosRow0 and sChaosRow1. These are row numbers, not addresses!
%

iChaosCache: subroutine;
pushReturn[];
call[getSchaosRow0Addr];
call[xVacateCacheRow];* clear cache "row 0"
call[getSchaosRow1Addr];
call[xVacateCacheRow];* clear cache "row 1"

call[get1Rand];
sChaosRandV ← t;

t ← cm1;* quit row loop when we see -1
stack+1 ← t;* push the two row values onto the stack
call[getSchaosRow0Addr];
stack+1 ← t;
call[getSchaosRow1Addr];
stack+1 ← t;

isChaosCRowL:* top of loop that inits row zero, then row
col ← cm1;* addr.row1
cnt ← 3s;

isChaosColL:
col ← (col) + 1;* move to next column, select it as the current victim
rscr ← t-t;
call[setBR],rscr2←a0;* init BR to zero each time putCFmem clobbers it
call[makeUseMcrv],t ← col;* and perform a reference that will force the
call[setMCR];* desired address into the cache.

call[sShadowBitToVa];* returns after va ← shadowBit
t ← lsh[col, skipCacheShift];
sVa ← (sVa) OR t;* into the munch selection position in the va
t ← stack;* get row address.
sVa ← t or (sVa);* OR the current row into the va
FETCH ← sVa;

call[cFlagsFromTemplate];* get cflags value into RSCR based upon
rscr2 ← col;* sChaosRandV, then write Cflags into cache.
t ← MD;* don’t forget to synchronize w/ memory
call[putCFmem], t ← sVa;* t = va, rscr2 = column, rscr = "cflags"
t ← 100c;* wait for cache to settle down
call[longWait];

sChaosRandV ← rsh[sChaosRandV, 2];* move on to next column...
loopUntil[cnt=0&-1, isChaosColL];

stkp-1;
t ← stack;
t # (cm1);
branch[isChaosCacheXit, ALU=0];* quit when we see -1
branch[isChaosCRowL];
isChaosCacheXit:
noop;* for placement
call[sRestoreMcrVictim];
pReturnP[];* pop the -1 off the stack before returning

* June 25, 1979 2:38 PM

%
sChaosChkAddrs
This code runs at the end of the chaos test. It reads vm to see that mem[va] = va for all the location in the memory. If this isn’t true, some earlier action of the chaos test clobbered the location that now has the incorrect value. Due to the time consumption of this check it does not run at the end of each chaos "run".
%

sChaosChkAddrs:* scan all of vm to see that its still correct
pushReturn[];
call[iSvaCtrl];
sChaosChkAddrsL:
call[nextSva];
skpif[alu#0], rscr2 ← t;* remember sva in rscr2
branch[sChaosChkAddrsXit];* everything was ok
FETCH ← t;
rscr ← MD;
t ← t # (rscr);* compare sva w/ mem[sva]
skpif[alu=0];
sChaosAddrsErr:* t = bad bits, rscr = md, rscr2 = expected
error;* value from memory
branch[sChaosChkAddrsL];* try next value

sChaosChkAddrsXit:
returnP[];

* June 25, 1979 2:40 PM
* init memorsy so that mem[va] = va
isChaosMem:
pushReturn[];
call[iSvaCtrl];
iSchaosL:* background memory w/ "self"
call[nextSva];
skpif[alu#0];
branch[sChaosFlush];
branch[isChaosL], store ← t, DBuf ← t;* mem[va] ← va;
sChaosFlush:* there are dirty munches left in the cache
rscr ← 20000c;* cycle thru the cache to make sure we force
sChaosFlushL:
STORE ← rscr, DBuf ← rscr;* dirty munches to storage
rscr ← (rscr) -1;
loopuntil[alu<0, sChaosFlushL];
noop;
returnP[];

* January 13, 1979 12:29 AM
* Init sSavedHoldValue which we use for starting the Hold simulator.
* Prevent the maximum delay from being longer than 200B - 150B

iSavedHoldValue: subroutine;* fire-up task simulator long enough to
pushReturn[];* save the hold value in sSavedHoldValue
mc[
taskFreqLocC, 302];* UGH! Yes, this is a DUPLICATE definition.
t ← taskFreqLocC;* It copies the one in postamble.mc
call[getIMRH];
t - (150c);
branch[ishOK, ALU>=0];

* the current value of holdFreq is too small. set it to our minimum = 150
rscr ← 150c;
t ← taskFreqLocC;
call[putIMRH];
noop;

ishOK:
B←FaultInfo’[];* remove any lurking memroy errors
call[enableConditionalTask];* HACK. FORCE postamble to make
t ← holdValueLocC;* a new value for hold simulator.
call[getIMRH];* Then we remember its value for
sSavedHoldValue ← t;* future use -- and we diable the
call[disableConditionalTask];* to prevent task sim’s memory refs
* from screwing up the cache.
returnP[];
* January 13, 1979 2:32 AM
%
getSchaosRow0Addr return current value of sChaosRow0 shifted into an address
getSchaosRow1Addr return current value of sChaosRow1 shifted into an address
sShadowBitToVaset addr.shadowBit in sVa if the current two bit nibble in our random number indicates that this munch should have the shadow bit set.
CFlagsFromTemplateset cflags.dirty for the value for the current munch’s CFLAGS if the current two bit nibble in our random number indicates this munch should be dirty.
%
subroutine;
getSchaosRow0Addr:
RBASE ← rbase[sChaosRow0];
t ← sChaosRow0, RBASE ← rbase[defaultRegion];
return, t← lsh[t, cacheShift];
getSchaosRow1Addr:
RBASE ← rbase[sChaosRow1];
t ← sChaosRow1, RBASE ← rbase[defaultRegion];
return, t← lsh[t, cacheShift];
sShadowBitToVa:
(sChaosRandV) AND (addrRand.shadow);* see if shadow bit is set in template
skpif[alu=0], sva ← t-t;
sva ← (sva) OR (addr.shadowBit);* add shadow bit to va
return;

CFlagsFromTemplate:* set rscr ← cflags based upon template dirty bit
noop;
(sChaosRandV) AND (addrRand.dirty);
skpif[alu=0], rscr ← t-t;
rscr ← cflags.dirty;
return;

* January 16, 1979 4:47 PM
%
isChaosCode
Initialize the chaos code. The code immediately below initializes the eight registers rm00-rm03 and rm10-rm13. The emulator level code uses the first group of four and the simulator task uses the last group of four.
Call the subroutine setChaosCode twice, once for the emulator code and once for the simulator task code. That subroutine initializes the FF constants and long jumps used by the chaos code. Notice this requires writing valid instructions into IM.
%
iSchaosCode: subroutine;
pushReturn[];

* TASK 0 RM and Code Init
call[get1Rand];
sChaosRandV ← t;
sSubrScr ← t;* save currend random value
call[sChaosAddrFromRandV];* init rm for first memop of task 0
rm00 ← t;
rm01 ← t;

call[get1Rand];
sChaosRandV ← t;
call[sChaosAddrFromRandV];* init rm for second memop of task 0
rm02 ← t;
rm03 ← t;
call[getsSubrScr];
rscr2 ← t;
call[setChaosCode], t ← r0;* set-up pointer to proper code, init delay


* Sim Task RM and Code Init
call[get1Rand];
sChaosRandV ← t;
sSubrScr ← t;* save currend random value
call[sChaosAddrFromRandV];* init rm for first memop of task 17
rm10 ← t;
rm11 ← t;
rscr2 ← sChaosRandV;

call[get1Rand];
sChaosRandV ← t;
call[sChaosAddrFromRandV];* init rm for second memop of task 17
RM12 ← t;
rm13 ← t;
call[getsSubrScr];
rscr2 ← t;
call[setChaosCode], t ← 4c;* set-up pointer to proper code, init delay
returnP[];
sChaosAddrFromRandV:
pushReturn[];
(sChaosRandV) and (codeRand.rowX);
branch[scaRow0, ALU=0];* this addr should use "row0"
scaRow1:* this addr should use "row1"
noop;
call[getSchaosRow1Addr];
scaMakeAddr:
stack+1 ← t;* remember row address in stack
t ← (sChaosRandV) and (codeRand.wordX);
stack ← t or (stack);* OR row, word bits
t ← ldf[sChaosRandV, codeRand.colSize, codeRand.colShift];
t ← lsh[t, skipCacheShift];
t ← t or (stack&-1);* or column into the addr, pop stack

returnP[];
scaRow0: top level;* current address should come from "row0"
call[getSchaosRow0Addr];
branch[scaMakeAddr];
* June 25, 1979 10:42 PM
getChaosTaskFreq:
pushReturn[];
gctfL:
noop;* for placement
call[get1Rand];
t ← t and (177C);
t ← t - (77C);* don’t want to wait more than 77 cycles
loopUntil[ALU>=0, gctfL];
t ← lsh[t, sim.taskShift];
returnP[];

* June 25, 1979 11:08 PM
get1Rand:
pushReturn[];
noop;* maximize placement advantage
getRandom[];
returnP[];

* April 24, 1978 1:50 AM
%
Chaos Test Code
One of these code segments executes for the task 0 test and one of them executes for the task 17 test. iSchaosCode inits the RM values and writes the appropriate delay constant into IM (as an FF constant). There are four basic tests:
Test 0:fetch, delay, fetch:00
Test 1:
fetch, delay, store:01
Test 2:
store, delay, fetch:10
Test 3:
store, delay, store:11
The Simulator task’s test code is similar except for RM selection and conventions associated with notifying task0 that the simulator code is done.
%

set[
chaosTestBase, 7000]; mc[chaosTestBaseC, chaosTestBase];*++duplicated in memChaosS.mc+++++
set[
chaosDelayBase, 7400]; mc[chaosDelayBaseC, chaosDelayBase];*++duplicated in memChaosS.mc+++++

knowRbase[rm00];
top level;
* FETCH, Delay, FETCH
chaosTsk0Tst0:
FETCH ← rm00,at[chaosTestBase, 0];
noop;
t ← 0c,at[chaosDelayBase,0];* this gets patched each time
call[longWait];
rm01 ← MD;* rm01 ← mem[rm00]
FETCH ← rm02;
rm03 ← MD;* rm03 ← mem[rm02]
branch[chaosAfterChk0];* proceed to check task 17 results

* FETCH, Delay, STORE
chaosTsk0Tst1:
FETCH ← rm00,at[chaosTestBase, 1];
t ← 0c,at[chaosDelayBase,1];* gets patched each time
call[longWait];
rm01 ← MD;* rm01 ← mem[rm00]
STORE ← rm02, DBuf ← rm02;* mem[rm02] ← rm02

branch[chaosAfterChk0];* proceed to check task 17 results

* STORE, Delay, STORE
chaosTsk0Tst2:

STORE ← rm00, DBuf ← rm00,at[chaosTestBase, 3];* mem[rm00] ← rm00
t ← 0c,at[chaosDelayBase,3];* gets patched each time
call[longWait];
FETCH ← rm02;
rm03 ← MD;

branch[chaosAfterChk0];* proceed to check task 17 results

* Store, Delay, FETCh
chaosTsk0Tst3:
STORE ← rm00, DBuf ← rm00,at[chaosTestBase, 2];* mem[rm00] ← rm00
t ← 0c,at[chaosDelayBase,2];* gets patched each time
call[longWait];
STORE ← rm02, DBuf ← rm02;* mem[rm02] ← rm02

branch[chaosAfterChk0];* proceed to check task 17 results
%
CHAOS Task Code
%
set[xtask, 1];
chaosTsk1Tst0:
hold&tasksim ← t,at[chaosTestBase, 4];* awakened by the simulator
noop;* 1st instr after hold&tasksim← doesnt count
block;

FETCH ← rm10;
t ← 0c,at[chaosDelayBase,4];* this gets patched each time
call[longWait];
rm11 ← MD;* rm11 ← mem[rm10]
FETCH ← rm12;
rm13 ← MD;* rm13 ← mem[rm12]

branch[chaosSimXit];* proceed to check task 17 results


chaosTsk1Tst1:

hold&tasksim ← t,at[chaosTestBase, 5];* awakened by the simulator
noop;* 1st instr after hold&tasksim← doesnt count
block;

FETCH ← rm10;
t ← 0c,at[chaosDelayBase,5];* gets patched each time
call[longWait];
rm11 ← MD;* rm11 ← mem[rm10]
STORE ← rm12, DBuf ← rm12;* mem[rm12] ← rm12

branch[chaosSimXit];* proceed to check task 17 results

chaosTsk1Tst2:
hold&tasksim ← t,at[chaosTestBase,6];* awakened by the simulator
noop;* 1st instr after hold← doesnt count
block;

STORE ← rm10, DBuf ← rm10;* mem[rm10] ← rm10
t ← 0c,at[chaosDelayBase,6];* gets patched each time
call[longWait];
FETCH ← rm12;
rm13 ← MD;

branch[chaosSimXit];* proceed to check task 17 results

chaosTsk1Tst3:* STORE, Delay, FETCH

hold&tasksim ← t,at[chaosTestBase,7];* awakened by the simulator
noop;* 1st instr after hold← doesnt count
block;

STORE ← rm10, DBuf ← rm10;* mem[rm10] ← rm10
t ← 0c,at[chaosDelayBase,7];* gets patched each time
call[longWait];
STORE ← rm12, DBuf ← rm12;* mem[rm12] ← rm12

branch[chaosSimXit];* proceed to check task 17 results