SoftcardOps.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Willie-Sue, March 5, 1987 10:20:43 am PST
DIRECTORY
RapunzelP2200V2 USING [SeqShort],
Rope USING [ROPE];
SoftcardOps: CEDAR DEFINITIONS
= BEGIN OPEN Rapunzel: RapunzelP2200V2;
ROPE: TYPE = Rope.ROPE;
Addr: TYPE = CARD32;
SeqShort: TYPE = Rapunzel.SeqShort;
SeqLong: TYPE = REF SeqLongObject;
SeqLongObject: TYPE ~ MACHINE DEPENDENT RECORD [
body: PACKED SEQUENCE length: CARD16 OF CARD32
];
EUInternal: TYPE = MACHINE DEPENDENT {
left(0), right (1),  -- operands for ALU and field unit
st2A (2), st2B (3), st3A (4), -- pipeline for the data to be sent to Cache (store)
kReg (5),    -- a collection of control bits sent by the IFU
field (6),   -- the field descriptor
r2B (7), r3A (8), r3B (9),  -- pipeline for the output of the ALU
dataIn (10)   -- data back from the Cache
};
All registers are 32-bits; all except kReg & field are interpreted as 32-bit values
FieldDesc: TYPE = MACHINE DEPENDENT RECORD[
insert (0: 0..0): [0..1],
mask (0: 1..6): [0..37B],
shift (0: 7..12): [0..77B],
reserved (0: 13..15): [0..7B] ← 0,
reserved1 (1: 0..15): [0..177777B] ← 0
];
KReg: TYPE = MACHINE DEPENDENT RECORD[
aAddr (0: 0..7): [0..377B],  -- A address for the register file (left read port)
bAddr (0: 8..15): [0..377B], -- B address for the register file (right read port)
cAddr (1: 0..7): [0..377B],  -- C address for the register file (write port)
leftSrc (1: 8..9): [0..3B],  -- source for the `left' register (2 bits)
rightSrc (1: 10..12): [0..7B], -- source for the `right' register (3 bits)
st2ASrc (1: 13..14): [0..3B], -- source for the `st2A' register (2 bits)
st3ASrc (1: 15..15): [0..1]  -- source for the `st3A' register (1 bit)
];
EURegister: TYPE = RECORD[
val: SELECT tag: * FROM
regular => [rVal: CARD32],
kReg => [kVal: KReg],
field => [fVal: FieldDesc],
ENDCASE
];
EUPBusCmd: TYPE = MACHINE DEPENDENT RECORD[ -- tbd
unused (0: 0..6): [0..177B] ← 0,
userMode (0: 7..7): BOOLFALSE,
unspecifiedAsYet (0: 8..15): [0..377B] ← 0
];
IFUPBusCmd: TYPE = MACHINE DEPENDENT {noAccess (0), access (1)};
numIFUBits: CARD16 = 30 * 16;  -- for debugging at the moment
IFUInternalState: TYPE = PACKED ARRAY [0..numIFUBits) OF [0..1];
EstablishConnection: PROC[host: ROPE] RETURNS[ok: BOOL];
CloseConnection: PROC;
SCError: SIGNAL[code: ATOM, explanation: ROPENIL];
SetEUBrkPtAddr: PROC[addr: Addr]; -- EU will brkpt when this address is accessed
SetIFUBrkPtAddr: PROC[addr: Addr]; -- IFU will brkpt when this address is accessed
ReadEUCmd: PROC RETURNS[euPBusCmd: EUPBusCmd];
ReadIFUCmd: PROC RETURNS[ifuPBusCmd: IFUPBusCmd];
ReadEUPBusData: PROC RETURNS[value: CARD32];
ReadIFUPBusData: PROC RETURNS[value: CARD32];
ReadClock: PROC RETURNS[value: CARD32];
*************************
ReadEURegister: PROC[which: EUInternal] RETURNS[value: CARD32];
WriteEURegister: PROC[which: EUInternal, value: CARD32];
ReadIFUState: PROC RETURNS[ifuState: IFUInternalState];
the IFU has only one internal state register
WriteIFUState: PROC[ifuState: IFUInternalState];
the IFU has only one internal state register
*************************
ReadShort: PROC[addr: Addr] RETURNS[val: CARD16];
ReadLong: PROC[addr: Addr] RETURNS[value: CARD32];
raises an error if addr is odd
WriteShort: PROC[addr: Addr, value: CARD16];
WriteLong: PROC[addr: Addr, value: CARD32];
raises an error if addr is odd
DumpShort: PROC[addr: Addr, num: CARD16] RETURNS[SeqShort];
DumpLong: PROC[addr: Addr, num: CARD16] RETURNS[SeqLong];
raises an error if addr is odd
*************************
ClockControl: TYPE = MACHINE DEPENDENT RECORD[
reserved (0: 0..7): [0..377B],
freqSelect (0: 8..9): [0..3],  -- choice of four frequencies for the Dragon clock
0 => not running
1 => 6.6 mhz
2 => 10 mhz
3 => 5 mhz
phaseAdjust (0: 10..12): [0..7], -- adjust phase between Dragon and Softcard
delay (0: 13..15): [0..7]  -- adjust the delay between FA and FB
];
ReadClockControl: PROC RETURNS[clockControl: ClockControl];
WriteClockControl: PROC[clockControl: ClockControl];
*************************
Control and status bits.
NOTE: virtualMemAccessXX:
if TRUE, the XX accesses to Dragon memory are using virtual addresses; if FALSE, physical addresses are being used
ControlBit: TYPE = {
resetDragon,
interruptDragonToIOP,
interruptDragonToMesa,
dragonRun,
dragonStep,
writeParity,
allows selection of even or odd parity for subsequent writes; reads are always done with TDB parity; thus one can create a parity error
virtualMemAccessIOP,
virtualMemAccessMesa,
virtualMemAccessIFU,
virtualMemAccessEU,
resetIFUCacheStateMachine,
notResetIFUCache,
ifuBreakpointEnabled,
resetEUCacheStateMachine,
notResetEUCache,
euBreakpointEnabled,
iopIntToDragon,
mesaIntToDragon,
notResetClock
};
DragonPhase: TYPE = MACHINE DEPENDENT
{ phaseB(0), betweenBandA(1), phaseA(2), betweenAandB(3)};
Notation: Fx/Fy => between Fx and Fy
DragonStepSize: TYPE = MACHINE DEPENDENT {quarter(1), half(2), full(4)};
ReadControlBit: PROC[which: ControlBit] RETURNS[current: BOOL];
SetControlBit: PROC[which: ControlBit] RETURNS[previous: BOOL];
ResetControlBit: PROC[which: ControlBit] RETURNS[previous: BOOL];
ResetIFUCacheStateMachine: PROC;
ResetEUCacheStateMachine: PROC;
DisableIFUCache: PROC;
enable by doing a FlushIFUCache
DisableEUCache: PROC;
enable by doing a FlushEUCache
FlushIFUCache: PROC;
FlushEUCache: PROC;
DragonHaltInPhase: PROC[phase: DragonPhase ← phaseA];
halt the dragon in the specified phase; if already halted, moves the Dragon to the specified phase
DragonStep: PROC[size: DragonStepSize ← half] RETURNS[ok: BOOL];
returns FALSE if the dragon is running, mkaing a specified step difficult
DragonRun: PROC;
no-op if Dragon is already running
DragonStop: PROC;
no-op if Dragon is already stopped
ResetClock: PROC;
ResetBoard: PROC;
resets the entire dragon state on the softcard board
CurrentDragonPhase: PROC RETURNS[phase: DragonPhase, ok: BOOL];
returns ok = FALSE if dragon is running
StatusBit: TYPE = {
dOutIFU,
dOutEU,
phaseA,
The following status bits can be read & reset
periodicIntToDragon, -- 16HZ periodic interrupt
notMemoryError, -- IOP access to Dragon memory caused a parity error
euBkptReached,
ifuBkptReached,
mapError
};
ReadStatusBit: PROC[which: StatusBit] RETURNS[current: BOOL];
ResetStatusBit: PROC[which: StatusBit] RETURNS[previous: BOOL];
*************************
Mapping between 2 megabytes of Daybreak physical address space and Dragon memory
MesaMapEntry: TYPE = MACHINE DEPENDENT RECORD[
unused (0: 0..11): [0..3777B] ← 0,
dp (0: 12..14): [0..7B] ← 0,
ignored (0: 15..15): [0..1] ← 0
];
MesaMapIndex: TYPE = [0..3];
ReadMesaMap: PROC[index: MesaMapIndex] RETURNS[value: MesaMapEntry];
WriteMesaMap: PROC[index: MesaMapIndex, value: MesaMapEntry];
*************************
Access to the Dragon Map
DragonMapEntry: TYPE = MACHINE DEPENDENT RECORD[
fault (0: 0..0): BOOLTRUE,
unused (0: 1..5): [0..37B] ← 0,
rp (0: 6..15): [0..1777B] ← 0
];
DragonMapIndex: TYPE = [0..37777B];
ReadDragonMap: PROC[index: DragonMapIndex] RETURNS[value: DragonMapEntry];
WriteDragonMap: PROC[index: DragonMapIndex, value: DragonMapEntry];
END.