<> <> <> <> <> <<>> <> <<>> DIRECTORY Process USING [Abort, Detach, PauseMsec, Milliseconds, InvalidProcess], SparcSoftcardOps, SoftcardMonitorExch, SoftcardUtil; SoftcardMonitorExchImpl: CEDAR MONITOR IMPORTS Process, SparcSoftcardOps, SoftcardUtil EXPORTS SoftcardMonitorExch ~ BEGIN <> Address: TYPE ~ SoftcardUtil.Address; HeaderRec: TYPE ~ RECORD [ size: CARD32, --4 bytes type: CARD32, --4 bytes data1: CARD32, --4 bytes data2: CARD32 --4 bytes ]; Zone: TYPE ~ Address; <> <> <> <> <> <> <<];>> zoneSize: CARD32 = 512;-- in words lastWritten: CARD32 = 0; lastRed: CARD32 = lastWritten+2; header: CARD32 = lastRed+2; buffer: CARD32 = header+SIZE[HeaderRec]; msgSize: CARD32 = 2*(zoneSize-buffer); backDoorAddress: Address _ [1E2000h]; BiZone: TYPE ~ RECORD[hisZone, myZone: Zone]; data: BiZone _ [backDoorAddress, [backDoorAddress.a+zoneSize]]; watchingProcess: PROCESS _ NIL; <> Error: ERROR ~ CODE; FillZones: PROC [w: UNSPECIFIED _ 0] ~ TRUSTED { SoftcardUtil.FillZones[backDoorAddress, 2*zoneSize]; }; Restart: PUBLIC PROC ~ TRUSTED { IF watchingProcess#NIL THEN Process.Abort[watchingProcess ! Process.InvalidProcess => CONTINUE]; FillZones[0]; watchingProcess _ FORK WatchPacketsIn[]; Process.Detach[watchingProcess]; }; GetLastRed: PROC [zone: Zone] RETURNS [msgNo: CARD32] ~ TRUSTED INLINE { RETURN[SoftcardUtil.GetCard32[[zone.a+lastRed]]]; }; GetLastWritten: PROC [zone: Zone] RETURNS [msgNo: CARD32] ~ TRUSTED INLINE { RETURN[SoftcardUtil.GetCard32[[zone.a+lastWritten]]]; }; PutLastRed: PROC [zone: Zone, msgNo: CARD32] ~ TRUSTED INLINE { SoftcardUtil.PutCard32[[zone.a+lastRed], msgNo]; }; PutLastWritten: PROC [zone: Zone, msgNo: CARD32] ~ TRUSTED INLINE { SoftcardUtil.PutCard32[[zone.a+lastWritten], msgNo]; }; GetHeaderRec: PROC [zone: Zone] RETURNS [hr: HeaderRec] ~ TRUSTED { base: CARD32 _ zone.a+header; hr.size _ SoftcardUtil.GetCard32[[base]]; hr.type _ SoftcardUtil.GetCard32[[base+2]]; hr.data1 _ SoftcardUtil.GetCard32[[base+4]]; hr.data2 _ SoftcardUtil.GetCard32[[base+6]]; }; PutHeaderRec: PROC [zone: Zone, size, type, data1, data2: CARD32] ~ TRUSTED { base: CARD32 _ zone.a+header; SoftcardUtil.PutCard32[[base], size]; SoftcardUtil.PutCard32[[base+2], type]; SoftcardUtil.PutCard32[[base+4], data1]; SoftcardUtil.PutCard32[[base+6], data2]; }; <> outputWaitingTime: Process.Milliseconds _ 10; --ms PutPacket: PUBLIC ENTRY PROC [type, data1, data2: CARD32 _ 0, r: REF TEXT _ NIL] ~ { h: CARD32 _ GetLastWritten[data.myZone]; len: CARD32 _ IF r#NIL THEN r.length ELSE 0; IF len>msgSize THEN Error; --oversized msg WHILE h>GetLastRed[data.hisZone] DO -- wait for him to read the previous one Process.PauseMsec[ms: outputWaitingTime] ENDLOOP; PutHeaderRec[data.myZone, len, type, data1, data2]; IF len>0 THEN TRUSTED { SoftcardUtil.CopyTo[r, 0, len, [data.myZone.a+buffer]]; }; PutLastWritten[data.myZone, h+1]; }; <> inputWaitingTime: Process.Milliseconds _ 10; --ms WatchPacketsIn: PUBLIC PROC ~ { <> oldSparcError: BOOLEAN _ TRUE; DO r: REF TEXT; proc: SoftcardMonitorExch.ActionProc; hVal: HeaderRec; sparcError: BOOLEAN; WHILE GetLastWritten[data.hisZone]=GetLastRed[data.myZone] DO TRUSTED { sparcError _ SparcSoftcardOps.TestSparcError[]; IF (sparcError AND ((NOT oldSparcError) AND SparcSoftcardOps.TestSparcError[])) THEN { -- triggers on active edge only + spurious error detection proc _ GetRegProc[0].a; proc[NIL, 0, 0, 0]; watchingProcess _ NIL; RETURN; }; }; oldSparcError _ sparcError; Process.PauseMsec[ms: inputWaitingTime]; ENDLOOP; hVal _ GetHeaderRec[data.hisZone]; [proc, r] _ GetRegProc[hVal.type]; IF r#NIL THEN { r.length _ hVal.size; IF hVal.size #0 THEN TRUSTED { SoftcardUtil.CopyFrom[r, 0, hVal.size, [data.hisZone.a+buffer]]; }; }; proc[r, hVal.type, hVal.data1, hVal.data2]; PutLastRed[data.myZone, GetLastWritten[data.hisZone]]; ENDLOOP; }; <<>> typeMask: CARD32 = 31; registration: ARRAY [0..typeMask] OF RECORD[a: SoftcardMonitorExch.ActionProc, r: REF TEXT]; GetRegProc: PROC [type: CARD32] RETURNS [a: SoftcardMonitorExch.ActionProc, r: REF TEXT] ~ { <<Description of the procedure.>> a _ registration[type].a; r _ registration[type].r; }; Register: PUBLIC PROC [type: CARD32, proc: SoftcardMonitorExch.ActionProc, buff: REF TEXT _ NIL] ~ { registration[type] _ [proc, buff]; }; END.