DIRECTORY Core, CoreClasses, CoreCreate, CoreFlat, DynaBusInterface, IO, Ports, Rope, Rosemary, RosemaryUser, SCLogic, SCUtils, TerminalIO; SCPmCodeImpl: CEDAR PROGRAM IMPORTS Ports, Rosemary, SCLogic, SCUtils EXPORTS SCLogic ~ BEGIN OPEN SCLogic; IndexType: TYPE = {Label, ReturnAddress, IOAddr}; NumPCmdBits: NAT = 4; -- Begin Labels ChkPermPC: NAT = Next[Label]; CP1PC: NAT = Next[Label]; CP2PC: NAT = Next[Label]; CP3PC: NAT = Next[Label]; HandleMissPC: NAT = Next[Label]; HM1PC: NAT = Next[Label]; HM2PC: NAT = Next[Label]; HM3PPC: NAT = Next[Label]; HM3nPPC: NAT = Next[Label]; HM3nRPC: NAT = Next[Label]; HMnMPC: NAT = Next[Label]; HMnM11PC: NAT = Next[Label]; HMnM12PC: NAT = Next[Label]; HMnM2PC: NAT = Next[Label]; HMnM3PC: NAT = Next[Label]; HMnM4PC: NAT = Next[Label]; HMRCamReadyPC: NAT = Next[Label]; HMReadRamPC: NAT = Next[Label]; HMReturn1PC: NAT = Next[Label]; HMReturn2PC: NAT = Next[Label]; HMRR2PC: NAT = Next[Label]; HMRR3PC: NAT = Next[Label]; HMRR4PC: NAT = Next[Label]; HMRR5PC: NAT = Next[Label]; HMRR6PC: NAT = Next[Label]; HMRRCVct2PC: NAT = Next[Label]; HMRRCVct3PC: NAT = Next[Label]; HMRRCVct4PC: NAT = Next[Label]; HMRRCVM3PC: NAT = Next[Label]; HMRRCVM4PC: NAT = Next[Label]; IdlePC: NAT = Next[Label]; IOR2PC: NAT = Next[Label]; IOWritePC: NAT = Next[Label]; PCWS3PC: NAT = Next[Label]; PCWS4PC: NAT = Next[Label]; PCWS5PC: NAT = Next[Label]; PCWS6PC: NAT = Next[Label]; PCWS7PC: NAT = Next[Label]; PCWS8PC: NAT = Next[Label]; PCWS9PC: NAT = Next[Label]; PCWS10PC: NAT = Next[Label]; PCWS11PC: NAT = Next[Label]; PCWS12PC: NAT = Next[Label]; PCWS13PC: NAT = Next[Label]; PCWS14PC: NAT = Next[Label]; PCWS14PrimePC: NAT = Next[Label]; PCWS15PC: NAT = Next[Label]; PCWS16PC: NAT = Next[Label]; PCWS17PC: NAT = Next[Label]; PCWSR2PC: NAT = Next[Label]; PCWSRetryPC: NAT = Next[Label]; PSR2PC: NAT = Next[Label]; PSR2PrimePC: NAT = Next[Label]; PSR3PC: NAT = Next[Label]; PSR4PC: NAT = Next[Label]; PSRetryPC: NAT = Next[Label]; PSRetryPrimePC: NAT = Next[Label]; PSReturn1PC: NAT = Next[Label]; PSReturn2PC: NAT = Next[Label]; PSRCamReadyPC: NAT = Next[Label]; PSRRCVM2PC: NAT = Next[Label]; PSRRCVM3PC: NAT = Next[Label]; PSRRCVM4PC: NAT = Next[Label]; PStorePC: NAT = Next[Label]; ResetPC: NAT = Next[Label]; SBTOF2PC: NAT = Next[Label]; SBTOF3PC: NAT = Next[Label]; SIOAF2PC: NAT = Next[Label]; SIOAF3PC: NAT = Next[Label]; SMAF2PC: NAT = Next[Label]; SMAF3PC: NAT = Next[Label]; StoreBTimeOutFaultPC: NAT = Next[Label]; StoreMemAccessFaultPC: NAT = Next[Label]; StoreIOAccessFaultPC: NAT = Next[Label]; TestReadRamPC: NAT = Next[Label]; TestReadRCamPC: NAT = Next[Label]; TestReadVCamPC: NAT = Next[Label]; TestResetVictimPC: NAT = Next[Label]; TestShiftVictimPC: NAT = Next[Label]; TRR2PC: NAT = Next[Label]; TRR3PC: NAT = Next[Label]; TRV2PC: NAT = Next[Label]; TRRC2PC: NAT = Next[Label]; TRRC3PC: NAT = Next[Label]; TRRC4PC: NAT = Next[Label]; TRRC5PC: NAT = Next[Label]; TRRC6PC: NAT = Next[Label]; TRVC2PC: NAT = Next[Label]; TRVC3PC: NAT = Next[Label]; TRVC4PC: NAT = Next[Label]; TRVC5PC: NAT = Next[Label]; TRVC6PC: NAT = Next[Label]; TSV2PC: NAT = Next[Label]; TSV3PC: NAT = Next[Label]; -- End Labels MaxPC: NAT = Next[Label]; NumPCBits: PUBLIC NAT _ 1+SCUtils.Log2[MaxPC-1]; FromRead: NAT = Next[ReturnAddress]; FromIORead: NAT = FromRead; FromWrite: NAT = Next[ReturnAddress]; FromIOWrite: NAT = FromWrite; FromCWS: NAT = Next[ReturnAddress]; MaxStack: NAT = Next[ReturnAddress]; NumStackBits: PUBLIC NAT _ 1+SCUtils.Log2[MaxStack-1]; ABusPAdd: NAT = 0; ABusRqstBuf: NAT = 1; ABusVCam: NAT = 4; ABusCam: NAT = 6; ABusRCam: NAT = 7; ABusIOOld: NAT = 8; ABusIONew: NAT = 9; ABusIOAId: NAT = 12; ABusIOFault: NAT = 13; ABusFault: NAT = 8; DBusNoOp: NAT = 0; DBusPWtLatch: NAT = 1; DBusRRLatch: NAT = 2; DBusABus: NAT = 3; SCmdNoOp: NAT = 0; SCmdLRM: NAT = 1; SCmdLVM: NAT = 2; SCmdVictim: NAT = 3; PCmdNoOp: NAT = 7; PCmdRead: NAT = 8; PCmdWrite: NAT = 9; PCmdCWS: NAT = 10; PCmdDeMap: NAT = 11; PCmdIORead: NAT = 12; PCmdIOWrite: NAT = 13; PCmdBIOWrite: NAT = 15; BCmdBIOW: NAT = ORD[DynaBusInterface.Cmd.BIOWRqst]/2; BCmdCWS: NAT = ORD[DynaBusInterface.Cmd.CWSRqst]/2; BCmdDeMap: NAT = ORD[DynaBusInterface.Cmd.DeMapRqst]/2; BCmdFB: NAT = ORD[DynaBusInterface.Cmd.FBRqst]/2; BCmdIOR: NAT = ORD[DynaBusInterface.Cmd.IORRqst]/2; BCmdIOW: NAT = ORD[DynaBusInterface.Cmd.IOWRqst]/2; BCmdMap: NAT = ORD[DynaBusInterface.Cmd.MapRqst]/2; BCmdRB: NAT = ORD[DynaBusInterface.Cmd.RBRqst]/2; BCmdWB: NAT = ORD[DynaBusInterface.Cmd.WBRqst]/2; BCmdWS: NAT = ORD[DynaBusInterface.Cmd.WSRqst]/2; FaultMemAccess: NAT = 0; FaultIOAccess: NAT = 1; FaultBTimeOut: NAT = 2; signals: Signals _ NEW [SignalsRec[100]]; AOw: NAT = Declare[signals, "AOw", X, Input]; ASh: NAT = Declare[signals, "ASh", X, Input]; AVM: NAT = Declare[signals, "AVM", X, Input]; FBTIP: NAT = Declare[signals, "FBTIP", X, Input]; MyBFault: NAT = Declare[signals, "MyBFault", X, Input]; NonFBTIP: NAT = Declare[signals, "NonFBTIP", X, Input]; PAccessPermission: NAT = Declare[signals, "PAccessPermission", X, Input]; PCmd: NAT = DeclareS[signals, "PCmd", NumPCmdBits, Xs, Input]; PCWSEq: NAT = Declare[signals, "PCWSEq", X, Input]; RamForP: NAT = Declare[signals, "RamForP", X, Input]; RCamForP: NAT = Declare[signals, "RCamForP", X, Input]; RPValid: NAT = Declare[signals, "RPValid", X, Input]; TimeOut: NAT = Declare[signals, "TimeOut", X, Input]; PC: NAT = DeclareS[signals, "PC", NumPCBits, Xs, Input]; Stack: NAT = DeclareS[signals, "Stack", NumStackBits, Xs, Input]; Reset: NAT = Declare[signals, "Reset", X, Input]; PCtlABusCmd: NAT = DeclareS[signals, "PCtlABusCmd", 4, ABusPAdd, Output]; PCtlBCmd: NAT = DeclareS[signals, "PCtlBCmd", 4, Xs, Output]; PCtlBusy: NAT = Declare[signals, "PCtlBusy", H, Output]; PCtlCSCmd: NAT = DeclareS[signals, "PCtlCSCmd", 2, SCmdNoOp, Output]; PCtlDBusCmd: NAT = DeclareS[signals, "PCtlDBusCmd", 2, DBusNoOp, Output]; PCtlEnCamSel: NAT = Declare[signals, "PCtlEnCamSel", L, Output]; PCtlEnCamSelExt: NAT = Declare[signals, "PCtlEnCamSelExt", L, Output]; PCtlFault: NAT = Declare[signals, "PCtlFault", L, Output]; PCtlFaultCode: NAT = DeclareS[signals, "PCtlFaultCode", 3, 0, Output]; PCtlFlagsForB: NAT = Declare[signals, "PCtlFlagsForB", L, Output]; PCtlForceWordAddress: NAT = Declare[signals, "PCtlForceWordAddress", L, Output]; PCtlPartFMch: NAT = Declare[signals, "PCtlPartFMch", L, Output]; PCtlFrzVictim: NAT = Declare[signals, "PCtlFrzVictim", L, Output]; PCtlLdFIFO: NAT = Declare[signals, "PCtlLdFIFO", L, Output]; PCtlLdRBufDataLo: NAT = Declare[signals, "PCtlLdRBufDataLo", L, Output]; PCtlLdRBufDataHi: NAT = Declare[signals, "PCtlLdRBufDataHi", L, Output]; PCtlLdRBufHeader: NAT = Declare[signals, "PCtlLdRBufHeader", L, Output]; PCtlLdSnooper: NAT = Declare[signals, "PCtlLdSnooper", L, Output]; PCtlPartVMch: NAT = Declare[signals, "PCtlPartVMch", L, Output]; PCtlRdRam: NAT = Declare[signals, "PCtlRdRam", L, Output]; PCtlRdRCam: NAT = Declare[signals, "PCtlRdRCam", L, Output]; PCtlRdVCam: NAT = Declare[signals, "PCtlRdVCam", L, Output]; PCtlReleaseP: NAT = Declare[signals, "PCtlReleaseP", L, Output]; PCtlResetVictim: NAT = Declare[signals, "PCtlResetVictim", L, Output]; PCtlRSCmd: NAT = DeclareS[signals, "PCtlRSCmd", 2, SCmdNoOp, Output]; PCtlSelBFC: NAT = Declare[signals, "PCtlSelBFC", L, Output]; PCtlSelRplyData: NAT = Declare[signals, "PCtlSelRplyData", L, Output]; PCtlSetFBTIP: NAT = Declare[signals, "PCtlSetFBTIP", L, Output]; PCtlSetNonFBTIP: NAT = Declare[signals, "PCtlSetNonFBTIP", L, Output]; PCtlSetSnooperValid: NAT = Declare[signals, "PCtlSetSnooperValid", L, Output]; PCtlShftVictim: NAT = Declare[signals, "PCtlShftVictim", L, Output]; PCtlWtMchVCam: NAT = Declare[signals, "PCtlWtMchVCam", L, Output]; PCtlWtRam: NAT = Declare[signals, "PCtlWtRam", L, Output]; NxtPC: NAT = DeclareS[signals, "NxtPC", NumPCBits, Xs, Output ]; NxtStack: NAT = DeclareS[signals, "NxtStack", NumStackBits, Xs, Output]; Push: NAT = Declare[signals, "Push", L, Output]; Vdd: NAT = Declare[signals, "Vdd", X, Power]; Gnd: NAT = Declare[signals, "Gnd", X, Power]; SCPmCode: PUBLIC PROC [] RETURNS [ct: CellType] = { ct _ Create[pmCodeName, signals] }; Init: Rosemary.InitProc = { }; Simple: Rosemary.EvalProc = { v: PROC [ix: NAT] RETURNS [BOOL] = { level: Level _ p[signals[ix].index].l; IF level=X THEN ERROR ELSE RETURN[level=H] }; vs: PROC [ix: NAT] RETURNS [NAT] = { RETURN[Ports.LSToLC[p[signals[ix].index].ls]] }; s: PROC [ix: NAT, l: Level] = { p[signals[ix].index].l _ l }; ss: PROC [ix: NAT, c: CARD] = { IF c=Xs THEN Ports.SetLS[p[signals[ix].index].ls, X] ELSE Ports.LCToLS[c, p[signals[ix].index].ls]; }; ReadRCam1: PROC [sCmd: NAT] = { s[PCtlRdRCam, H]; s[PCtlEnCamSel, H]; s[PCtlEnCamSelExt, L]; }; ReadRCam2: PROC [sCmd: NAT] = { s[PCtlRdRCam, H]; s[PCtlEnCamSel, H]; s[PCtlEnCamSelExt, L]; ss[PCtlCSCmd, sCmd]; }; ReadRCam34: PROC [sCmd: NAT] = { ss[PCtlCSCmd, sCmd]; }; ReadVCam1: PROC [sCmd: NAT] = { s[PCtlRdVCam, H]; s[PCtlEnCamSel, H]; s[PCtlEnCamSelExt, L]; }; ReadVCam2: PROC [sCmd: NAT] = { s[PCtlRdVCam, H]; s[PCtlEnCamSel, H]; s[PCtlEnCamSelExt, L]; ss[PCtlCSCmd, sCmd]; }; ReadVCam34: PROC [sCmd: NAT] = { ss[PCtlCSCmd, sCmd]; }; ReadRam1: PROC [sCmd: NAT, drDBus: {DBus, NoDBus} _ DBus] = { ss[PCtlRSCmd, sCmd]; s[PCtlRdRam, H]; }; ReadRam2: PROC [sCmd: NAT, drDBus: {DBus, NoDBus} _ DBus] = { IF drDBus = DBus THEN ss[PCtlDBusCmd, DBusRRLatch]; }; ReadRam3: PROC [sCmd: NAT, drDBus: {DBus, NoDBus} _ DBus] = { IF drDBus = DBus THEN ss[PCtlDBusCmd, DBusRRLatch]; }; WriteRam1: PROC [sCmd: NAT, data: NAT] = { ss[PCtlRSCmd, sCmd]; s[PCtlWtRam, H]; }; WriteRam2: PROC [sCmd: NAT, data: NAT] = { ss[PCtlRSCmd, sCmd]; ss[PCtlDBusCmd, data]; }; WriteRam3: PROC [sCmd: NAT, data: NAT] = { ss[PCtlDBusCmd, data]; }; Jmp: PROC [dest: NAT] = { IF dest=StoreBTimeOutFaultPC OR dest=StoreMemAccessFaultPC OR dest=StoreIOAccessFaultPC THEN { ss[PCtlABusCmd, ABusIOFault]; s[PCtlWtMchVCam, H]; }; IF dest=IdlePC THEN { s[PCtlBusy, L]; s[PCtlLdRBufDataLo, H]; -- to make WriteSingle (shared) go faster ss[PCtlDBusCmd, DBusPWtLatch]; }; ss[NxtPC, dest]; }; OutputsToDefault[p, signals]; SELECT p[signals[Reset].index].l FROM = X => {OutputsToX[p, signals]; RETURN}; = H => { s[Push, H]; ss[NxtStack, FromRead]; Jmp[ResetPC] }; = L => { SELECT vs[PC] FROM -- Begin Transitions = ResetPC => { IF TRUE THEN { Jmp[IdlePC]; }; }; = IdlePC => { SELECT vs[PCmd] FROM <= PCmdNoOp => { Jmp[IdlePC]; }; = PCmdRead => { IF v[AVM] THEN { Jmp[IdlePC]; }; IF NOT v[AVM] THEN { s[PCtlPartVMch , H]; s[PCtlWtMchVCam, H]; s[Push, H]; ss[NxtStack, FromRead]; Jmp[HandleMissPC]; }; }; = PCmdWrite => { IF v[AVM] THEN { Jmp[PStorePC]; }; IF NOT v[AVM] THEN { s[PCtlPartVMch, H]; s[PCtlWtMchVCam, H]; s[Push, H]; ss[NxtStack, FromWrite]; Jmp[HandleMissPC]; }; }; = PCmdCWS => { IF v[AVM] THEN { ss[PCtlABusCmd, ABusIOOld]; s[PCtlWtMchVCam, H]; Jmp[PCWS3PC]; }; IF NOT v[AVM] THEN { s[PCtlPartVMch , H]; s[PCtlWtMchVCam, H]; s[Push, H]; ss[NxtStack, FromCWS]; Jmp[HandleMissPC]; }; }; = PCmdIORead => { IF v[AVM] THEN { Jmp[IdlePC]; }; IF NOT v[AVM] THEN { s[PCtlPartFMch , H]; s[PCtlWtMchVCam, H]; s[Push, H]; ss[NxtStack, FromIORead]; Jmp[ChkPermPC]; }; }; = PCmdIOWrite => { IF v[AVM] THEN { Jmp[IdlePC]; }; IF NOT v[AVM] THEN { s[PCtlPartFMch , H]; s[PCtlWtMchVCam, H]; s[Push, H]; ss[NxtStack, FromIOWrite]; Jmp[ChkPermPC]; }; }; = PCmdBIOWrite => { IF TRUE THEN { s[PCtlLdRBufHeader, H]; s[PCtlSetNonFBTIP, H]; ss[PCtlBCmd, BCmdBIOW]; ss[PCtlABusCmd, ABusPAdd]; Jmp[PSReturn1PC]; }; }; = PCmdDeMap => { IF TRUE THEN { s[PCtlLdRBufHeader, H]; s[PCtlSetNonFBTIP, H]; ss[PCtlBCmd, BCmdDeMap]; ss[PCtlABusCmd, ABusPAdd]; Jmp[PSReturn1PC]; }; }; ENDCASE => ERROR; }; = ChkPermPC => { IF TRUE THEN { Jmp[CP1PC]; }; }; = CP1PC => { IF TRUE THEN { Jmp[CP2PC]; }; }; = CP2PC => { IF TRUE THEN { Jmp[CP3PC]; }; }; = CP3PC => { IF v[AVM] THEN { Jmp[StoreIOAccessFaultPC]; }; IF NOT v[AVM] THEN { ss[PCtlABusCmd, ABusPAdd]; s[PCtlLdRBufHeader, H]; ss[PCtlDBusCmd, DBusPWtLatch]; s[PCtlLdRBufDataLo, H]; s[PCtlLdRBufDataHi, H]; s[PCtlSetNonFBTIP, H]; Jmp[PSReturn1PC]; SELECT vs[Stack] FROM =FromIORead => { ss[PCtlBCmd, BCmdIOR]; }; = FromIOWrite => { ss[PCtlBCmd, BCmdIOW]; }; ENDCASE => ERROR; }; }; = IOR2PC => { IF v[NonFBTIP] AND NOT v[TimeOut] THEN { Jmp[IOR2PC]; }; IF v[NonFBTIP] AND v[TimeOut] THEN { Jmp[StoreBTimeOutFaultPC]; }; IF NOT v[NonFBTIP] AND v[MyBFault] THEN { s[PCtlFault, H]; s[PCtlSelBFC, H]; s[PCtlReleaseP, H]; Jmp[IdlePC]; }; IF NOT v[NonFBTIP] AND NOT v[MyBFault] THEN { s[PCtlReleaseP, H]; Jmp[IdlePC]; }; }; = PCWSRetryPC => { IF TRUE THEN { Jmp[PCWSR2PC]; }; }; = PCWSR2PC => { IF TRUE THEN { ss[PCtlABusCmd, ABusIOOld]; s[PCtlWtMchVCam, H]; Jmp[PCWS3PC]; }; }; = PCWS3PC => { IF TRUE THEN { ReadRam1[SCmdLVM]; Jmp[PCWS4PC]; }; }; = PCWS4PC => { IF v[AVM] THEN { ReadRam2[SCmdLVM]; Jmp[PCWS5PC]; }; IF NOT v[AVM] THEN { ReadRam2[SCmdLVM]; s[PCtlPartVMch, H]; s[PCtlWtMchVCam, H]; s[Push, H]; ss[NxtStack, FromCWS]; Jmp[HandleMissPC]; }; }; = PCWS5PC => { IF v[RamForP] THEN { s[PCtlLdRBufDataHi, H]; ReadRam3[SCmdLVM]; Jmp[PCWS6PC]; }; IF NOT v[RamForP] THEN { ReadRam1[SCmdLVM]; Jmp[PCWS4PC]; }; }; = PCWS6PC => { IF TRUE THEN { Jmp[PCWS7PC]; }; }; = PCWS7PC => { IF v[PCWSEq] THEN { ss[PCtlABusCmd, ABusIONew]; s[PCtlWtMchVCam, H]; Jmp[PCWS8PC]; }; IF NOT v[PCWSEq] THEN { Jmp[IdlePC]; }; }; = PCWS8PC => { IF TRUE THEN { ReadRam1[SCmdLVM]; Jmp[PCWS9PC]; }; }; = PCWS9PC => { IF TRUE THEN { ReadRam2[SCmdLVM]; ss[PCtlABusCmd, ABusPAdd]; s[PCtlWtMchVCam, H]; Jmp[PCWS10PC]; }; }; = PCWS10PC => { IF v[RamForP] THEN { ReadRam3[SCmdLVM]; WriteRam1[SCmdLVM, DBusRRLatch]; Jmp[PCWS11PC]; }; IF NOT v[RamForP] THEN { ss[PCtlABusCmd, ABusIONew]; s[PCtlWtMchVCam, H]; Jmp[PCWS8PC]; }; }; = PCWS11PC => { IF TRUE THEN { WriteRam2[SCmdLVM, DBusRRLatch]; Jmp[PCWS12PC]; }; }; = PCWS12PC => { IF v[RamForP] THEN { WriteRam3[SCmdLVM, DBusRRLatch]; s[PCtlWtMchVCam, H]; ss[PCtlABusCmd, ABusPAdd]; Jmp[PCWS13PC]; }; IF NOT v[RamForP] THEN { ss[PCtlABusCmd, ABusIONew]; s[PCtlWtMchVCam, H]; Jmp[PCWS8PC]; }; }; = PCWS13PC => { IF TRUE THEN { ReadRCam1[SCmdLVM]; Jmp[PCWS14PC]; }; }; = PCWS14PC => { IF v[ASh] AND v[RCamForP] THEN { ReadRCam2[SCmdLVM]; Jmp[PCWS15PC]; }; IF v[ASh] AND NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[PCWS14PrimePC]; }; IF NOT v[ASh] THEN { s[PCtlReleaseP, H]; Jmp[IdlePC]; }; }; = PCWS14PrimePC => { IF v[RCamForP] THEN { ReadRCam2[SCmdLVM]; Jmp[PCWS15PC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[PCWS14PrimePC]; }; }; = PCWS15PC => { IF v[RCamForP] THEN { ReadRCam34[SCmdLVM]; Jmp[PCWS16PC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[PCWS14PrimePC]; }; }; = PCWS16PC => { IF v[RCamForP] THEN { s[PCtlSetNonFBTIP, H]; ReadRCam34[SCmdLVM]; Jmp[PCWS17PC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[PCWS14PrimePC]; }; }; = PCWS17PC => { IF TRUE THEN { s[PCtlLdRBufHeader, H]; ss[PCtlBCmd, BCmdCWS]; ss[PCtlABusCmd, ABusCam]; Jmp[PSReturn2PC]; }; }; = PSRetryPC => { IF TRUE THEN { WriteRam1[SCmdLVM, DBusPWtLatch]; Jmp[PSR2PC]; }; }; = PSR2PrimePC => { IF v[AVM] THEN { WriteRam2[SCmdLVM, DBusPWtLatch]; Jmp[PSR3PC]; }; IF NOT v[AVM] THEN { s[PCtlPartVMch, H]; s[PCtlWtMchVCam, H]; s[Push, H]; ss[NxtStack, FromWrite]; Jmp[HandleMissPC]; }; }; = PSR2PC => { IF TRUE THEN { WriteRam2[SCmdLVM, DBusPWtLatch]; Jmp[PSR3PC]; }; }; = PSR3PC => { IF v[RamForP] THEN { WriteRam3[SCmdLVM, DBusPWtLatch]; Jmp[PSR4PC]; }; IF NOT v[RamForP] THEN { WriteRam1[SCmdLVM, DBusPWtLatch]; Jmp[PSR2PrimePC]; }; }; = PSR4PC => { IF v[AVM] THEN { Jmp[PStorePC]; }; IF NOT v[AVM] THEN { s[PCtlPartVMch, H]; s[PCtlWtMchVCam, H]; s[Push, H]; ss[NxtStack, FromWrite]; Jmp[HandleMissPC]; }; }; = PStorePC => { IF v[ASh] THEN { ReadRCam1[SCmdLVM]; Jmp[PSRRCVM2PC]; }; IF NOT v[ASh] THEN { s[PCtlReleaseP, H]; Jmp[IdlePC]; }; }; = PSRRCVM2PC => { IF v[RCamForP] THEN { ReadRCam2[SCmdLVM]; Jmp[PSRRCVM3PC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[PSRRCVM2PC]; }; }; = PSRRCVM3PC => { IF v[RCamForP] THEN { ReadRCam34[SCmdLVM]; Jmp[PSRRCVM4PC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[PSRRCVM2PC]; }; }; = PSRRCVM4PC => { IF v[RCamForP] THEN { s[PCtlSetNonFBTIP, H]; ReadRCam34[SCmdLVM]; Jmp[PSRCamReadyPC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[PSRRCVM2PC]; }; }; = PSRCamReadyPC => { IF TRUE THEN { s[PCtlLdRBufHeader, H]; ss[PCtlBCmd, BCmdWS]; ss[PCtlABusCmd, ABusCam]; Jmp[PSReturn2PC]; }; }; = PSReturn1PC => { IF TRUE THEN { Jmp[PSReturn2PC]; }; }; = PSReturn2PC => { IF v[NonFBTIP] AND NOT v[TimeOut] THEN { s[PCtlSelRplyData, H]; Jmp[PSReturn2PC]; }; IF v[NonFBTIP] AND v[TimeOut] THEN { s[PCtlSelRplyData, H]; Jmp[StoreBTimeOutFaultPC]; }; IF NOT v[NonFBTIP] AND v[MyBFault] THEN { s[PCtlFault, H]; s[PCtlSelBFC, H]; s[PCtlReleaseP, H]; s[PCtlSelRplyData, H]; Jmp[IdlePC]; }; IF NOT v[NonFBTIP] AND NOT v[MyBFault] THEN { s[PCtlReleaseP, H]; s[PCtlSelRplyData, H]; Jmp[IdlePC]; }; }; = HandleMissPC => { IF TRUE THEN { s[PCtlFrzVictim, H]; Jmp[HM1PC]; }; }; = HM1PC => { IF TRUE THEN { ReadRCam1[SCmdLVM]; s[PCtlFrzVictim, H]; Jmp[HM2PC]; }; }; = HM2PC => { IF v[RCamForP] THEN { ReadRCam2[SCmdLVM]; Jmp[HM3PPC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[HM3nPPC]; }; }; = HM3PPC => { IF v[AVM] AND v[RCamForP] THEN { ReadRCam34[SCmdLVM]; Jmp[HMRRCVM4PC]; }; IF v[AVM] AND NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[HM3nPPC]; }; IF NOT v[AVM] THEN { ss[PCtlABusCmd, ABusIOAId]; s[PCtlWtMchVCam, H]; Jmp[HMnMPC]; }; }; = HMnMPC => { IF TRUE THEN { s[PCtlLdRBufHeader, H]; ss[PCtlBCmd, BCmdMap]; ss[PCtlABusCmd, ABusPAdd]; ReadRam1[SCmdLVM]; Jmp[HMnM11PC]; }; }; = HMnM11PC => { IF TRUE THEN { ReadRam2[SCmdLVM]; Jmp[HMnM12PC]; }; }; = HMnM12PC => { IF v[RamForP] THEN { s[PCtlSetNonFBTIP, H]; s[PCtlLdRBufDataLo, H]; s[PCtlLdRBufDataHi, H]; ReadRam3[SCmdLVM]; Jmp[HMnM3PC]; }; IF NOT v[RamForP] THEN { ReadRam1[SCmdLVM]; Jmp[HMnM11PC]; }; }; = HMnM3PC => { IF TRUE THEN { Jmp[HMnM4PC]; }; }; = HMnM4PC => { IF v[NonFBTIP] AND NOT v[TimeOut] THEN { s[PCtlFlagsForB, H]; Jmp[HMnM4PC]; }; IF v[NonFBTIP] AND v[TimeOut] THEN { Jmp[StoreBTimeOutFaultPC]; }; IF NOT v[NonFBTIP] AND v[MyBFault] THEN { s[PCtlFault, H]; s[PCtlSelBFC, H]; s[PCtlReleaseP, H]; Jmp[IdlePC]; }; IF NOT v[NonFBTIP] AND NOT v[MyBFault] THEN { s[PCtlLdRBufHeader, H]; ss[PCtlBCmd, BCmdRB]; ss[PCtlABusCmd, ABusCam]; ReadRCam1[SCmdVictim]; Jmp[HMRRCVct2PC]; }; }; = HM3nPPC => { IF v[AVM] AND v[RCamForP] THEN { ReadRCam2[SCmdLVM]; Jmp[HMRRCVM3PC]; }; IF v[AVM] AND NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[HM3nPPC]; }; IF NOT v[AVM] THEN { ss[PCtlABusCmd, ABusIOAId]; s[PCtlWtMchVCam, H]; Jmp[HMnMPC]; }; }; = HMRRCVM3PC => { IF v[RCamForP] THEN { ReadRCam34[SCmdLVM]; Jmp[HMRRCVM4PC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[HM3nPPC]; }; }; = HMRRCVM4PC => { IF v[RCamForP] THEN { ReadRCam34[SCmdLVM]; Jmp[HMRCamReadyPC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdLVM]; Jmp[HM3nPPC]; }; }; = HMRCamReadyPC => { IF v[PAccessPermission] THEN { s[PCtlLdRBufHeader, H]; ss[PCtlBCmd, BCmdRB]; ss[PCtlABusCmd, ABusCam]; ReadRCam1[SCmdVictim]; Jmp[HMRRCVct2PC]; }; IF NOT v[PAccessPermission] THEN { Jmp[StoreMemAccessFaultPC]; }; }; = HMRRCVct2PC => { IF v[RCamForP] THEN { ReadRCam2[SCmdVictim]; Jmp[HMRRCVct3PC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdVictim]; Jmp[HMRRCVct2PC]; }; }; = HMRRCVct3PC => { IF v[RCamForP] THEN { ReadRCam34[SCmdVictim]; Jmp[HMRRCVct4PC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdVictim]; Jmp[HMRRCVct2PC]; }; }; = HMRRCVct4PC => { IF v[RCamForP] THEN { ReadRCam34[SCmdVictim]; Jmp[HMReadRamPC]; }; IF NOT v[RCamForP] THEN { ReadRCam1[SCmdVictim]; Jmp[HMRRCVct2PC]; }; }; = HMReadRamPC => { IF TRUE THEN { ReadRam1[SCmdVictim, NoDBus]; ss[PCtlABusCmd, ABusRCam]; s[PCtlLdSnooper, H]; s[PCtlSetSnooperValid, H]; Jmp[HMRR2PC]; }; }; = HMRR2PC => { IF TRUE THEN { ReadRam2[SCmdVictim, NoDBus]; ss[PCtlDBusCmd, DBusABus]; s[PCtlLdRBufDataLo, H]; s[PCtlLdRBufDataHi, H]; Jmp[HMRR3PC]; }; }; = HMRR3PC => { IF v[RamForP] THEN { ReadRam3[SCmdVictim, NoDBus]; Jmp[HMRR4PC]; }; IF NOT v[RamForP] THEN { ReadRam1[SCmdVictim, NoDBus]; ss[PCtlABusCmd, ABusRCam]; Jmp[HMRR2PC]; }; }; = HMRR4PC => { IF TRUE THEN { Jmp[HMRR5PC]; }; }; = HMRR5PC => { IF v[AOw] AND v[RPValid] THEN { ss[PCtlBCmd, BCmdFB]; ss[PCtlABusCmd, ABusRCam]; s[PCtlSetFBTIP, H]; s[PCtlLdFIFO, H]; Jmp[HMRR6PC]; }; IF NOT v[AOw] THEN { s[PCtlSetNonFBTIP, H]; Jmp[HMReturn1PC]; }; IF NOT v[RPValid] THEN { s[PCtlSetNonFBTIP, H]; Jmp[HMReturn1PC]; }; }; = HMRR6PC => { IF TRUE THEN { s[PCtlSetNonFBTIP, H]; ss[PCtlABusCmd, ABusRqstBuf]; Jmp[HMReturn1PC]; }; }; = HMReturn1PC => { IF TRUE THEN { Jmp[HMReturn2PC]; } }; = HMReturn2PC => { IF v[NonFBTIP] AND NOT v[TimeOut] THEN { ss[PCtlABusCmd, ABusRqstBuf]; s[PCtlSelRplyData, H]; Jmp[HMReturn2PC]; }; IF v[NonFBTIP] AND v[TimeOut] THEN { s[PCtlSelRplyData, H]; Jmp[StoreBTimeOutFaultPC]; }; IF NOT v[NonFBTIP] AND v[MyBFault] THEN { s[PCtlFault, H]; s[PCtlSelBFC, H]; s[PCtlReleaseP, H]; s[PCtlSelRplyData, H]; Jmp[IdlePC]; -- check that fault code gets written automatically; if not, just do it in ucode by copying one of the store fault routines }; IF NOT v[NonFBTIP] AND NOT v[MyBFault] THEN { s[PCtlShftVictim, H]; SELECT vs[Stack] FROM =FromRead => { s[PCtlReleaseP, H]; s[PCtlSelRplyData, H]; Jmp[IdlePC]; }; = FromWrite => { s[PCtlWtMchVCam, H]; Jmp[PSRetryPC]; }; = FromCWS => { s[PCtlWtMchVCam, H]; Jmp[PCWSRetryPC]; }; ENDCASE => ERROR; }; }; = StoreMemAccessFaultPC => { IF TRUE THEN { WriteRam1[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultMemAccess]; Jmp[SMAF2PC]; }; }; = SMAF2PC => { IF TRUE THEN { WriteRam2[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultMemAccess]; Jmp[SMAF3PC]; }; }; = SMAF3PC => { IF v[RamForP] THEN { WriteRam3[SCmdLVM, DBusABus]; s[PCtlFault, H]; ss[PCtlFaultCode, FaultMemAccess]; s[PCtlReleaseP, H]; Jmp[IdlePC]; }; IF NOT v[RamForP] THEN { ss[PCtlDBusCmd, DBusABus]; WriteRam1[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultMemAccess]; Jmp[SMAF2PC]; }; }; = StoreBTimeOutFaultPC => { IF TRUE THEN { WriteRam1[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultBTimeOut]; Jmp[SBTOF2PC]; }; }; = SBTOF2PC => { IF TRUE THEN { WriteRam2[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultBTimeOut]; Jmp[SBTOF3PC]; }; }; = SBTOF3PC => { IF v[RamForP] THEN { WriteRam3[SCmdLVM, DBusABus]; s[PCtlFault, H]; ss[PCtlFaultCode, FaultBTimeOut]; s[PCtlReleaseP, H]; Jmp[IdlePC]; }; IF NOT v[RamForP] THEN { WriteRam1[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultBTimeOut]; Jmp[SBTOF2PC]; }; }; = StoreIOAccessFaultPC => { IF TRUE THEN { WriteRam1[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultIOAccess]; Jmp[SIOAF2PC]; }; }; = SIOAF2PC => { IF TRUE THEN { WriteRam2[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultIOAccess]; Jmp[SIOAF3PC]; }; }; = SIOAF3PC => { IF v[RamForP] THEN { WriteRam3[SCmdLVM, DBusABus]; s[PCtlFault, H]; ss[PCtlFaultCode, FaultIOAccess]; s[PCtlReleaseP, H]; Jmp[IdlePC]; }; IF NOT v[RamForP] THEN { ss[PCtlDBusCmd, DBusABus]; WriteRam1[SCmdLVM, DBusABus]; ss[PCtlABusCmd, ABusFault+FaultIOAccess]; Jmp[SIOAF2PC]; }; }; = TestReadRamPC => { IF TRUE THEN { s[PCtlForceWordAddress, H]; ReadRam1[SCmdVictim]; Jmp[TRR2PC]; }; }; = TRR2PC => { IF TRUE THEN { s[PCtlForceWordAddress, H]; ReadRam2[SCmdVictim]; Jmp[TRR3PC]; }; }; = TRR3PC => { IF TRUE THEN { s[PCtlForceWordAddress, H]; ReadRam3[SCmdVictim]; s[PCtlLdRBufDataHi, H]; Jmp[IdlePC]; }; }; = TestReadRCamPC => { IF TRUE THEN { ReadRCam1[SCmdVictim]; Jmp[TRRC2PC]; }; }; = TRRC2PC => { IF TRUE THEN { ReadRCam2[SCmdVictim]; Jmp[TRRC3PC]; }; }; = TRRC3PC => { IF TRUE THEN { ReadRCam34[SCmdVictim]; Jmp[TRRC4PC]; }; }; = TRRC4PC => { IF TRUE THEN { ReadRCam34[SCmdVictim]; Jmp[TRRC5PC]; }; }; = TRRC5PC => { IF TRUE THEN { ss[PCtlABusCmd, ABusRCam]; Jmp[TRRC6PC]; }; }; = TRRC6PC => { IF TRUE THEN { ss[PCtlDBusCmd, DBusABus]; s[PCtlLdRBufDataHi, H]; Jmp[IdlePC]; }; }; = TestReadVCamPC => { IF TRUE THEN { ReadVCam1[SCmdVictim]; Jmp[TRVC2PC]; }; }; = TRVC2PC => { IF TRUE THEN { ReadVCam2[SCmdVictim]; Jmp[TRVC3PC]; }; }; = TRVC3PC => { IF TRUE THEN { ReadVCam34[SCmdVictim]; Jmp[TRVC4PC]; }; }; = TRVC4PC => { IF TRUE THEN { ReadVCam34[SCmdVictim]; Jmp[TRVC5PC]; }; }; = TRVC5PC => { IF TRUE THEN { ss[PCtlABusCmd, ABusVCam]; Jmp[TRVC6PC]; }; }; = TRVC6PC => { IF TRUE THEN { ss[PCtlDBusCmd, DBusABus]; s[PCtlLdRBufDataHi, H]; Jmp[IdlePC]; }; }; = TestShiftVictimPC => { IF TRUE THEN { s[PCtlShftVictim, H]; Jmp[TSV2PC]; }; }; = TSV2PC => { IF TRUE THEN { s[PCtlFrzVictim, H]; Jmp[TSV3PC]; }; }; = TSV3PC => { IF TRUE THEN { s[PCtlFrzVictim, H]; Jmp[IdlePC]; }; }; = TestResetVictimPC => { IF TRUE THEN { s[PCtlResetVictim, H]; Jmp[TRV2PC]; }; }; = TRV2PC => { IF TRUE THEN { s[PCtlResetVictim, H]; Jmp[IdlePC]; }; }; ENDCASE => ERROR; -- End Transitions }; ENDCASE => ERROR; }; Next: PROC [it: IndexType] RETURNS [ix: NAT] = { ix _ index[it]; index[it] _ index[it]+1; }; index: ARRAY IndexType OF NAT _ ALL [0]; pmCodeName: ROPE = Rosemary.Register[roseClassName: "PmCode", init: Init, evalSimple: Simple]; END. ,‚SCPmCodeImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Created: Douady, Sindhu April 10, 1987 12:50:16 pm PDT Pradeep Sindhu October 27, 1987 12:15:49 pm PST Cesar Douady May 13, 1987 3:09:46 pm PDT This module defines the Processor-side microcode. Note that only the combinatorial part is modeled, and that the input, output, and feedback registers are within a higher level block defined by the schematic PCtl.sch. In writing the microcode, we have made the following assumption about the speed of this combinatorial block: signals can go through the block in under one clock cycle, so that inputs need to come directly from a clocked register, and outputs need to go directly to a clocked register, with no intervening logic. This structure implies that the minimum delay between the microcode asserting a signal, and that signal having an effect on the input, is two cycles. This minimum delay is, in fact, used for the signal PCtlSetNonFBTIP -> NonFBTIP. Type Defs and Constants Variable Defs Microcode Labels Microcode Return Addresses ABus Source Codes -- opCode 5 is forbidden by the hardware DBus Source Codes Array Multiplexer Select Codes PCmd Defs BCmd Defs Fault Code Defs Signal Defs Public Procs Internal Procs This corresponds to the ReadRCam command cycle This corresponds to the first cycle of RCam use This corresponds to the second and third cycles of RCam use (note they are the same) This corresponds to the ReadVCam command cycle This corresponds to the first cycle of VCam use This corresponds to the second and third cycles of VCam use (note they are the same) This corresponds to the ReadRam command cycle This corresponds to the first cycle of Ram use (note that ReadRam2 must follow ReadRam1 ss[PCtlRSCmd, sCmd]; This corresponds to the second cycle of Ram use This corresponds to the WriteRam command cycle This corresponds to the first cycle of Ram use (note that WriteRam2 must follow ReadRam1 This corresponds to the second cycle of Ram use The microcode Initiate Reset sequence: (empty for now) Wait for something to happen A hit: Everything is done automatically A miss: Do partial virtual match to find translation A hit: Check if shared bit is set; Wait for ASh to be available A miss: Do partial virtual match to find translation A hit: Good, get the old value A miss: Do partial virtual match to find translation A hit: Everything is done automatically A miss: Check if we have access permission; First match without flags A hit: Everything is done automatically A miss: Check if we have access permission; First match without flags This operation always misses: Load RqstBuf header with IO address; Send ArbRequest; Set NonFBTIP (continuation is the same as IOWrite) This operation always misses: Load RqstBuf header with IO address; Send ArbRequest; Set NonFBTIP (continuation is the same as IOWrite) Wait virtual match w/o flags to complete, 1 of 3 Wait virtual match w/o flags to complete, 2 of 3 Wait virtual match w/o flags to complete, 3 of 3 Partial match successful: an IO access permission fault, store it and return A miss. Generate IO(Read/Write) Rqst packet: Load RqstBuf header with IO address; Load RqstBuf data with PData (doesn't hurt for read); Send ArbRqst; Set NonFBTIP; Return when transaction completes (same as PS) Generate IOReadRqst Generate IOWriteRqst Wait for reply to come back A timeOut: Signal and store in the array (can be done after releasing processor) Reply came back with a fault, release processor and return Reply came back normally, release processor and return Wait for AVM, 1 of 3: Don't need Ram value, just want to verify a hit Wait for AVM, 2 of 3 Wait for AVM, 3 of 3: Read Ram to get the old value A hit: Wait for PCWSEq, 1 of 3; (Can't let the processor go, sample value may be wrong) A miss: Do partial virtual match to find translation Wait for PCWSEq, 2 of 3: Compare old and sample; Put old in RqstBuf in case shared is set Ratted! Just redo it: Read Ram to get the old value Wait for PCWSEq, 3 of 3 Read new value from the Ram, present IOAddress to VCam Not equal: Don't need to do anything Read new value from the Ram, send ReadRam pulse Wait for data to appear in RRdLatch, 1 of 2 Wait for data to appear in RRdLatch, 2 of 2: Start writing new data back; Load Rqst Buffer with new value in case shared bit is set Ratted! Re-read new value from scrtach; Present IOAddress to VCam Select RamReadLatch to go to the Ram, 1 of 2 Wait for Ash, 1 of 3 Select RamReadLatch to go to the Ram, 2 of 2; Wait for Ash, 2 of 3; Start RCam read in case of ASh Ratted! Re-read the new value from scratch; Present IOAddress to VCam Wait for Ash, 3 of 3; Read RCam, cycle 1 Data is shared, generate CWSRqst; Read RCam to get real address, cycle 2 Don't have RCam; Read RCam to get real address, cycle 1 Data is not shared, we are done First, read RCam to get the real address, cycle 2 First, read RCam to get the real address, cycle 1 Read RCam, cycle 3; We have the RCam, go to next cycle Read RCam, cycle 1; We don't have the RCam, return to cycle 2 Read RCam, cycle 4; RCam has been read; Send ArbRqst; Set NonFBTIP Read RCam, cycle 1; We don't have the RCam, return to cycle 2 Load RqstBuf header with real address Wait for AVM, 1 of 3; Write Ram in case of a match Wait for time to pass A miss: Do partial virtual match to find translation Wait for AVM, 2 of 3 Wait for AVM, 3 of 3 Ratted! Just redo it; Write the Ram in case of a match A hit: Check for shared bit; Wait for ASh to be available A miss: Do partial virtual match to find translation Data is shared, generate WSRqst; Read RCam to get the real address Data is not shared, everything is done automatically: Release processor Read RCam, cycle 2: We have RCam, go to next cycle Read RCam, cycle 1: We don't have RCam, return to cycle 2 Read RCam, cycle 3: We have RCam, go to next cycle Read RCam, cycle 1: We don't have RCam, return to cycle 2 Read RCam, cycle 4: RCam has been read; Send ArbRqst; Set NonFBTIP Read RCam, cycle 1: We don't have RCam, return to cycle 2 Load Rqst buffer header with real address Blow one cycle to give NonFBTIP time to be set Wait for WSRply, IOWRply, IORRply, BIOWRply, DeMapRply A timeOut: Signal and return WSRply has come back with a fault, release processor and return Reply has come back, release processor and return Wait for partial virtual match, 1 of 3: (Could begin the RCam read here at the expense of (~6) more lines) Freeze victim, Cycle 1 of 2 Note: The index i in HMiPC refers to time, not cycle number Wait for partial virtual match, 2 of 3: Initiate RCam read in case partial match succeeds, Read RCam cycle 1; Freeze victim, Cycle 2 of 2 Wait for partial virtual match, 3 of 3; Read RCam, cycle 2 Wait for partial virtual match, 3 of 3; Don't have RCam, Read RCam, cycle 1 Partial virtual match is successful; Read RCam, cycle 3 Partial virtual match is successful; Don't have RCam, Read RCam, cycle 1 Read AId from the Ram, first find it in the VCam Read AId from Ram, cycle 1; Load RqstBuf with MapRqst|myId|PAdd; Set NonFBTIP Read AId from Ram, cycle 2; Wait for AId to appear in the RRdLatch, 1 of 1 Load RBufLo with AId, RBufHi with garbage; Send ArbRqst Ratted, didn't have Ram! Just redo it Blow one cycle to let NonFBTIP get set Wait for MapRply to come back TimeOut : Signal and store the fault in the array MapCache fault: abort access Load Rqst buffer header with RealAddress; Read RCam using victim, cycle 1 For all jumps to this location except the one from HM2PC, we know that the AVM check will succeed since match is latched, and AVM was high earlier. Doing the check in all cases allows us to share this instruction, thereby eliminating waste. Partial virtual match is successful; Read RCam, cycle 2 Partial virtual match is successful; Didn't have RCam, Read RCam, cycle 1 Read AId from the Ram, first find it in the VCam Read RCam, cycle 3 Read RCam, cycle 1; Didn't have RCam, redo read Read RCam, cycle 4; RCam has been read Read RCam, cycle 1; Didn't have RCam, redo read We've read RPage from the RCam successfully Load RqstBuf header with RealAddress; Read RCam using victim, cycle 1 Fault: Signal and store in the array (can be done after releasing processor) Read RCam using victim, cycle 2 Read RCam, cycle 1; Didn't have RCam, return to cycle 2 Read RCam using victim, cycle 3 Read RCam, cycle 1; Didn't have RCam, return to cycle 2 Read RCam using victim, cycle 4 Read RCam, cycle 1; Didn't have RCam, return to cycle 2 Drive victim address onto ABus and load Snooper in case of FlushBlock; Set snooper valid to begin snooping now; Note that ABus contents automatically go into AToDPipe Reg Load RqstBufLo with victim address in AToDPipe; Load RqstBufHi with garbage; Wait for AOw; Read Ram cycle 2 Wait for AOw; Read Ram, cycle 3 Redo Ram Read; Also redrive victim address onto ABus so AToDPipe gets loaded again, and so we can test RPValid Wait for AOw. Read Ram, cycle 4 RPValid is on the ABus only while the Victim address is being read. Thus think about doing the RPValid check there. Also, it looks as though the ABus is not driven properly when the victim address is read. Generate FBRqst Send RBRqst, remember to set NonFBTIP Victim is not valid, don't flush it; Send RBRqst; Set NonFBTIP (this test could be done earlier with some care) Send RBRqst; Set NonFBTIP; Put RealAddress on ABus to load Snooper when FBRqst comes back Blow one cycle to let NonFBTIP get set Wait for rply; Put RealAddress on ABus to load Snooper when FBRqst comes back TimeOut : Signal and store the fault in the array Reply has come back with a fault, release processor and return Unfreeze victim and shift it to avoid victimizing the line just brought in Nothing else to do, just release the processor Check if address is in array Check if address is in array Write fault code into the RAM, cycle 1 Write fault code into the RAM, cycle 2 Write completed successfully. Go back to Idle loop Ratted! Redo the access Write fault code into the RAM, cycle 1 Write fault code into the RAM, cycle 2 Write completed successfully. Go back to Idle loop Ratted! Redo the access Write fault code into the RAM, cycle 1 Write fault code into the RAM, cycle 2 Write completed successfully. Go back to Idle loop Ratted! Redo the access Here begins the tests subroutines. They cannot be executed during normal operations. They are reached only by the mean of a PC forced by the DebugBus. It is assumed that the DynaBus is stopped during these operations. Read RCam using Victim, cycle 1 Read RCam using Victim, cycle 2 Read RCam using Victim, cycle 3 Read RCam using Victim, cycle 4 Put Victim into the ABus to DBus pipe (automatic) through the ABus Load RBufDataLo with the content of the RCam Read VCam using Victim, cycle 1 Read VCam using Victim, cycle 2 Read VCam using Victim, cycle 3 Read VCam using Victim, cycle 4 Put Victim into the ABus to DBus pipe (automatic) through the ABus Load RBufDataLo with the content of the VCam The victim is assumed to be waiting at some place The victim may point to a place where it wants to get out of Force it to stay there. Cycle 1 of 2 The victim may point to a place where it wants to get out of Force it to stay there. Cycle 2 of 2 Force the victim to point at the initial place. Cycle 1 of 2 Force the victim to point at the initial place. Cycle 2 of 2 The victim will not get out now that the used bit has been cleared ส.˜codešœฯgœ ™Kšœ ฯmœ1™Kšœ œ(˜3Kšœ  œ)˜5Kšœ  œ*˜7Kšœ  œ)˜5Kšœ  œ)˜5K˜Kšœ œ1˜8Kšœ œ7˜AKšœ œ'˜1K˜Kšœ  œ9˜IKšœ  œ0˜=Kšœ  œ+˜8Kšœ  œ7˜EKšœ  œ9˜IKšœ œ/˜@Kšœ œ2˜FKšœ  œ,˜:Kšœ œ4˜FKšœ œ0˜BKšœ œ7˜PKšœ œ/˜@Kšœ œ0˜BKšœ  œ-˜Jšœ คœ˜Jšœคœ˜Jšœคœ˜J˜Jšœ ฅ{˜ˆJ˜—š  œ œ  œ œ  œ˜-J™JJšœคœ˜š œ  ˜šœ˜J™.Jšœคœ˜J˜Jšœ ˜ J˜—šœ˜J™Jšœคœ˜Jšœ˜J˜—šœ˜J™Jšœคœ˜Jšœ˜J˜—Kš œ œ˜—J˜—J˜—šœ˜š œ œ œ˜J™&Jšœ˜Jšœ*˜*Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™&Jšœ˜Jšœ*˜*Jšœ ˜ J˜—J˜—šœ˜š œ  œ˜J™2Jšœ˜Jšœ คœ˜Jšœ"˜"Jšœคœ˜Jšœ ˜ J˜—š œ œ  œ˜J™Jšœ˜Jšœ˜Jšœ*˜*Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™&Jšœ˜Jšœ)˜)Jšœ˜J˜—J˜—šœ˜š œ œ œ˜J™&Jšœ˜Jšœ)˜)Jšœ˜J˜—J˜—šœ˜š œ  œ˜J™2Jšœ˜Jšœ คœ˜Jšœ!˜!Jšœคœ˜Jšœ ˜ J˜—š œ œ  œ˜J™Jšœ˜Jšœ)˜)Jšœ˜J˜—J˜—šœ˜š œ œ œ˜J™&Jšœ˜Jšœ)˜)Jšœ˜J˜—J˜—šœ˜š œ œ œ˜J™&Jšœ˜Jšœ)˜)Jšœ˜J˜—J˜—šœ˜š œ  œ˜J™2Jšœ˜Jšœ คœ˜Jšœ!˜!Jšœคœ˜Jšœ ˜ J˜—š œ œ  œ˜J™Jšœ˜Jšœ˜Jšœ)˜)Jšœ˜J˜—J˜—J™ูšœ˜š œ œ œ˜Jšœคœ˜Jšœ˜Jšœ ˜ J˜—J˜—šœ ˜ š œ œ œ˜Jšœคœ˜Jšœ˜Jšœ ˜ J˜—J˜—šœ ˜ š œ œ œ˜Jšœคœ˜Jšœ˜Jšœคœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™Jšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™Jšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™Jšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™Jšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™BJšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™,Jšœ˜Jšœคœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™Jšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™Jšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™Jšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™Jšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™BJšœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™,Jšœ˜Jšœคœ˜Jšœ ˜ J˜—J˜—šœ˜š œ œ œ˜J™1Jšœคœ˜Jšœ ˜ J˜—J˜—šœ ˜ š œ œ œ˜J™