LizardRosemary5CheckSynchImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by McCreight, April 7, 1986 4:45:29 pm PST
Herrmann, September 5, 1985 10:53:41 am PDT
DIRECTORY
Cluster2, Dragon, DragonRosemary, DragOpsCross, DragOpsCrossUtils, IFU2, LizardHeart;
LizardRosemary5CheckSynchImpl: CEDAR PROGRAM
IMPORTS Cluster2, DragonRosemary, DragOpsCrossUtils, LizardHeart =
BEGIN
CSynch: PROC [ data: REF ANY, basicInst: IFU2.BasicInst ] RETURNS [deltaInstrCount: INT ← 1] -- IFU2.CheckSynchProc -- =
BEGIN
CheckAInB: PROC [ a, b: REF ANY ] =
BEGIN
FOR la: LIST OF REF ANYNARROW[a, LIST OF REF ANY], la.rest WHILE la#NIL DO
WITH la.first SELECT FROM
rsa: Dragon.RegStore => {
IF rsa.instr<basicInst.instr THEN EXIT; -- ancient history
SELECT rsa.reg FROM
euJunk, euToKBus, IN [euBogus..ifuLast] => LOOP;
euMAR => LOOP; -- haven't quite got this synchronized yet
ENDCASE => -- look for it in the other list
FOR lb: LIST OF REF ANYNARROW[b, LIST OF REF ANY], lb.rest DO
IF lb = NIL THEN GOTO NotFound;
WITH lb.first SELECT FROM
rsb: Dragon.RegStore => {
IF rsb.instr<rsa.instr THEN GOTO NotFound;
IF rsb.instr=rsa.instr AND rsb.reg=rsa.reg THEN {
IF rsb.data#rsa.data THEN GOTO NotFound ELSE EXIT;
};
};
ctb: Dragon.CacheTrans =>
IF ctb.instr<basicInst.instr THEN GOTO NotFound;
ENDCASE => NULL;
REPEAT
NotFound=> DragonRosemary.Assert[FALSE,
"Cluster & Rosemary disagree on register store"];
ENDLOOP;
};
cta: Dragon.CacheTrans =>
IF cta.instr<basicInst.instr THEN EXIT;
ENDCASE => NULL;
ENDLOOP;
END; -- of CheckAInB
ks: Cluster2.KitchenSink = NARROW[data];
sim: Cluster2.LizardSimulation = ks.lizardSimulation;
IF (NOT ks.controlPanel.reset) THEN {
Rosemary instruction number basicInst.instr has finished, for better or worse.
IF basicInst.trapped THEN deltaInstrCount ← 0;
SELECT basicInst.trapPC FROM
reschedulePC => { -- Get Lizard to Reschedule on the next instruction
status: DragOpsCross.IFUStatusRec ← LOOPHOLE[sim.processor.regs[ifuStatus]];
status.reschedule ← TRUE;
sim.processor.regs[ifuStatus] ← LOOPHOLE[status];
deltaInstrCount ← 0; -- Lizard doesn't generate a trapped instruction for Reschedule
};
ENDCASE => {
IF basicInst.instr >= 0 THEN {
IF sim # NIL THEN {
Get Lizard to do the same instruction, and then compare them.
lizardNewPC: Dragon.Word ← DragOpsCrossUtils.WordToCard[sim.processor.regs[ifuPC]];
DragonRosemary.Assert[ sim.processor.stats.instructions = basicInst.instr , "Cluster & Lizard instruction counts disagree"];
DragonRosemary.Assert[ lizardNewPC = basicInst.pc , "Cluster & Lizard PC's disagree"];
LizardHeart.InstructionExecute[sim.processor];
IF basicInst.trapped AND basicInst.trapPC = ifuPageFaultPC THEN
{ -- "execute" the Lizard instruction that causes the page fault
oldStatus: Dragon.RegStore;
LizardHeart.InstructionExecute[sim.processor]; -- the faulting instruction
deltaInstrCount ← 1;
oldStatus ← NARROW[sim.lastInstrOps.first];
DragonRosemary.Assert[oldStatus.instr = sim.processor.stats.instructions,
"Couldn't find Lizard's save of processor status for IFU page fault"];
oldStatus.instr ← oldStatus.instr-1; -- conforms with Rosemary's view
};
CheckAInB[a: ks.rosemaryStores, b: sim.lastInstrOps];
CheckAInB[a: sim.lastInstrOps, b: ks.rosemaryStores];
DragonRosemary.Assert[ (sim.control=doAbort) = basicInst.trapped, "Cluster & Lizard disagree about trap"];
}; -- end of Lizard check
IF basicInst.op = x377B AND basicInst.alpha = 0FFH AND basicInst.beta = 0FFH THEN
ERROR Cluster2.SuccessHalt;
IF (basicInst.op = dTrap) OR (basicInst.op = x377B) THEN SIGNAL Cluster2.Breakpoint;
};
};
ks.controlPanel.instrCount ← basicInst.instr+deltaInstrCount;
};
END;
reschedulePC: Dragon.HexWord = DragOpsCrossUtils.TrapIndexToBytePC[RescheduleTrap];
ifuPageFaultPC: Dragon.HexWord = DragOpsCrossUtils.TrapIndexToBytePC[IFUPageFaultTrap];
Cluster2.csProcRec.proc ← CSynch;
END.