<> <> <> <> <> <> 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 ANY _ NARROW[a, LIST OF REF ANY], la.rest WHILE la#NIL DO WITH la.first SELECT FROM rsa: Dragon.RegStore => { IF rsa.instr LOOP; euMAR => LOOP; -- haven't quite got this synchronized yet ENDCASE => -- look for it in the other list FOR lb: LIST OF REF ANY _ NARROW[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 IF ctb.instr NULL; REPEAT NotFound=> DragonRosemary.Assert[FALSE, "Cluster & Rosemary disagree on register store"]; ENDLOOP; }; cta: Dragon.CacheTrans => IF cta.instr NULL; ENDLOOP; END; -- of CheckAInB ks: Cluster2.KitchenSink = NARROW[data]; sim: Cluster2.LizardSimulation = ks.lizardSimulation; IF (NOT ks.controlPanel.reset) THEN { <> IF basicInst.trapped THEN deltaInstrCount _ 0; SELECT basicInst.trapPC FROM reschedulePC => { -- Get Lizard to Reschedule on the next instruction ERROR; <> <> <> <> }; ENDCASE => { IF basicInst.instr >= 0 THEN { IF sim # NIL THEN { <> 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]; }; <> <<"Couldn't find Lizard's save of processor status for IFU page fault"]};>> CheckAInB[a: ks.rosemaryStores, b: sim.lastInstrOps]; CheckAInB[a: sim.lastInstrOps, b: ks.rosemaryStores]; IF basicInst.op=dKFC THEN deltaInstrCount_0 -- ELSE 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 = x000b) 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.