SoftcardMonitorExchImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
written by Ch. Le Cocq, August 4, 1988
Christian Le Cocq October 25, 1988 5:32:44 pm PDT
Christophe Cuenod October 19, 1988 4:45:49 pm PDT
Packet exchange mechanism between CP (6085 mesa processor) and Sparc.
DIRECTORY
Process USING [Abort, Detach, PauseMsec, Milliseconds, InvalidProcess],
SparcSoftcardOps,
SoftcardMonitorExch,
SoftcardUtil;
SoftcardMonitorExchImpl: CEDAR MONITOR
IMPORTS Process, SparcSoftcardOps, SoftcardUtil
EXPORTS SoftcardMonitorExch
~ BEGIN
Types & Constants
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;
IOZone: TYPE ~ REF IOZoneRec;
IOZoneRec: TYPE ~ RECORD [
lastWrittenPacket, --4 bytes
lastRedPacket: Header, --4 bytes
header: HeaderRec, --16 bytes
buffer: PACKED ARRAY[0..msgSize) OF CHAR -- 1024 -24 bytes
];
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: PROCESSNIL;
Utilities
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];
};
Packet out
outputWaitingTime: Process.Milliseconds ← 10; --ms
PutPacket: PUBLIC ENTRY PROC [type, data1, data2: CARD32 ← 0, r: REF TEXT ← NIL] ~ {
h: CARD32 ← GetLastWritten[data.myZone];
len: CARD32IF 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];
};
Packets In
inputWaitingTime: Process.Milliseconds ← 10; --ms
WatchPacketsIn: PUBLIC PROC ~ {
Service daemon
oldSparcError: BOOLEANTRUE;
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.