DIRECTORY SoftcardOps USING [ Addr, DragonMapEntry, DragonMapIndex, MesaMapEntry, MesaMapIndex]; SoftcardPrivate: CEDAR DEFINITIONS = BEGIN Addr: TYPE = SoftcardOps.Addr; OneBit: TYPE = [0..1]; SCBaseAddr: Addr = (LONG[28]*256*256); -- 3.5MB; BkptEUH: Addr = SCBaseAddr+0b800h; -- W [8..16); MS-part of brkp register for EU BkptEUL: Addr = SCBaseAddr+0b000h; -- W [16..32); LS-part of brkp register for EU BkptIFUH: Addr = SCBaseAddr+0a800h; -- W [8..16); MS-part of brkp register for IFU BkptIFUL: Addr = SCBaseAddr+0a000h; -- W[16..32); LS-part of brkp register for IFU SpyCmd1: Addr = SCBaseAddr+9800h; -- R [0..8); 8-bit PBus command of the EU SpyCmd2: Addr = SCBaseAddr+8800h; -- R [0..8); 2 bits used SpyEUDataH: Addr = SCBaseAddr+9000h; -- R [0..16); MS-part of PBus data of the EU SpyEUDataL: Addr = SCBaseAddr+9001h; -- R [16..32); LS-part of PBus data of the EU SpyIFUDataH: Addr = SCBaseAddr+8000h; -- R [0..16); MS-part of PBus data of the IFU SpyIFUDataL: Addr = SCBaseAddr+8001h; -- R [16..32); LS-part of PBus data of the IFU ClockH: Addr = SCBaseAddr+7800h; -- R [0..16); MS-part of Clock ClockL: Addr = SCBaseAddr+7801h; -- R [16..32); LS-part of Clock DebugShiftEU: Addr = SCBaseAddr+17; -- shift one bit of EU internal state into/outof EU register DebugExecuteEU: Addr = SCBaseAddr+18; -- Cause the EU to read its internal register and do a command DebugReadIFU: Addr = SCBaseAddr+1800h; -- Read IFU internal state into IFU register DebugWriteIFU: Addr = SCBaseAddr+1000h; -- Write IFU register into IFU DebugShiftA: Addr = SCBaseAddr+4000h; DebugShiftB: Addr = SCBaseAddr+4800h; DebugInfo: Addr = SCBaseAddr+2001h; -- RW [0..8); 8-bits of debugging info DebugInfoEntry: TYPE = MACHINE DEPENDENT RECORD[ debugInIFU (0: 0..0): OneBit _ 0, -- bit to shift into the IFU shift register debugInEU (0: 1..1): OneBit _ 0, -- bit to shift into the EU shift register unused (0: 2..7): [0..77B] _ 0, reserved (0: 8..15): [0..377B] _ 0 ]; ClockControlAddr: Addr = SCBaseAddr+3001h; -- RW [8..16); 8-bits of clock control info Control1Bits: TYPE = MACHINE DEPENDENT RECORD [ resetDragon(0: 0..0): BOOL, interrurptDragonToIOP(0: 1..1): BOOL _ FALSE, interrurptDragonToMesa(0: 2..2): BOOL _ FALSE, dragonRun(0: 3..3): BOOL _ FALSE, dragonStep(0: 4..4): BOOL _ FALSE, writeParity(0: 5..5): BOOL _ FALSE, virtualMemAccessIOP(0: 6..6): BOOL _ FALSE, virtualMemAccessMesa(0: 7..7): BOOL _ FALSE, resetIFUCacheStateMachine(0: 8..8): BOOL _ FALSE, resetIFUCache(0: 9..9): BOOL _ FALSE, enableIFUBkpt(0: 10..10): BOOL _ FALSE, virtualMemAccessIFU(0: 11..11): BOOL _ FALSE, resetEUCacheStateMachine(0: 12..12): BOOL _ FALSE, resetEUCache(0: 13..13): BOOL _ FALSE, enableEUBkpt(0: 14..14): BOOL _ FALSE, virtualMemAccessEU(0: 15..15): BOOL _ FALSE ]; Control2Bits: TYPE = MACHINE DEPENDENT RECORD[ reserved (0: 0..7): [0..377B], iopIntToDragon (0: 8..8): BOOL, mesaIntToDragon (0: 9..9): BOOL, resetCounter (0: 10..10): BOOL, unused (0: 11..15): [0..37B] _ 0 ]; ControlBits1Addr: Addr = SCBaseAddr+128 + 1; -- read the control1 bits Consult1: Addr = ControlBits1Addr; ConsultAndChange1Base: Addr = ControlBits1Addr + 64; CarDragon: Addr = ConsultAndChange1Base+0; CarInterrurptDragonToIOP: Addr = ConsultAndChange1Base+4; CarInterruptDragonToMesa: Addr = ConsultAndChange1Base+8; CarDragonRun: Addr = ConsultAndChange1Base+12; CarDragonStep: Addr = ConsultAndChange1Base+16; CarWriteParity: Addr = ConsultAndChange1Base+20; CarVirtualMemAccessIOP: Addr = ConsultAndChange1Base+24; CarVirtualMemAccessMesa: Addr = ConsultAndChange1Base+28; CarIFUCacheStateMachine: Addr = ConsultAndChange1Base+32; CasIFUCacheStateMachine: Addr = CarIFUCacheStateMachine+2; CarIFUCache: Addr = ConsultAndChange1Base+36; CasIFUCache: Addr = CarIFUCache+2; CarEnableIFUBkpt: Addr = ConsultAndChange1Base+40; CarVirtualMemAccessIFU: Addr = ConsultAndChange1Base+44; CarEUCacheStateMachine: Addr = ConsultAndChange1Base+48; CasEUCacheStateMachine: Addr = CarEUCacheStateMachine+2; CarEUCache: Addr = ConsultAndChange1Base+52; CasEUCache: Addr = CarEUCache+2; CarEnableEUBkpt: Addr = ConsultAndChange1Base+56; CarVirtualMemAccessEU: Addr = ConsultAndChange1Base+60; ControlBits2Entry: TYPE = MACHINE DEPENDENT RECORD[ reserved (0: 0..7): [0..377B], iopIntToDragon (0: 8..8): BOOL, mesaIntToDragon (0: 9..9): BOOL, resetCounter (0: 10..10): BOOL, debugSelectEU (0: 11..11): BOOL, debugFreeze (0: 12..12): BOOL, unused (0: 13..15): [0..7B] _ 0 ]; ControlBits2Addr: Addr = SCBaseAddr + 256 + 1; -- read the control2 bits Consult2: Addr = ControlBits2Addr; ConsultAndChange2Base: Addr = ControlBits2Addr + 32; CarIOPIntToDragon: Addr = ConsultAndChange2Base+0; CarMesaIntToDragon: Addr = ConsultAndChange2Base+4; CarCounter: Addr = ConsultAndChange2Base+8; CarDebugSelectEU: Addr = ConsultAndChange2Base+10; CarDebugFreeze: Addr = ConsultAndChange2Base+12; StatusBits: TYPE = MACHINE DEPENDENT RECORD[ dOutIFU (0: 0..0): OneBit, -- bit shifted out of the IFU shift register dOutEU (0: 1..1): OneBit, -- bit shifted out of the EU shift register phaseA (0: 2..2): BOOL, -- is the Dragon in FA periodicIntToDragon (0: 3..3): BOOL, -- 16HZ periodic interrupt memoryError (0: 4..4): BOOL, -- IOP access to Dragon memory saw a parity error euBkptReached (0: 5..5): BOOL, ifuBkptReached (0: 6..6): BOOL, mapError (0: 7..7): BOOL, reserved (0: 8..15): [0..377B] ]; ConsultStatusAddr: Addr = SCBaseAddr+256+64+1; -- R, 1 MOD 64 CarStatusBase: Addr = ConsultStatusAddr+32; CarPeriodicIntToDragon: Addr = CarStatusBase+0; CarMemoryError: Addr = CarStatusBase+2; CarEUBrkptReached: Addr = CarStatusBase+4; CarIFUBrkptReached: Addr = CarStatusBase+6; CarMapError: Addr = CarStatusBase+8; MesaMapEntry: TYPE = SoftcardOps.MesaMapEntry; MesaMapIndex: TYPE = SoftcardOps.MesaMapIndex; MesaMapRec: TYPE = MACHINE DEPENDENT RECORD[ reserved (0: 0..15): [0..177777B], mapEntry (1: 0..15): MesaMapEntry ]; MesaMapAddr: Addr = SCBaseAddr + 512; -- RW, 8 locations MesaMap: TYPE = ARRAY MesaMapIndex OF MesaMapRec; MesaMapBase: LONG POINTER TO MesaMap = LOOPHOLE[MesaMapAddr]; DragonMapEntry: TYPE = SoftcardOps.DragonMapEntry; DragonMapIndex: TYPE = SoftcardOps.DragonMapIndex; DragonMapRec: TYPE = MACHINE DEPENDENT RECORD[ reserved (0: 0..15): [0..177777B], mapEntry (1: 0..15): DragonMapEntry ]; DragonMapAddr: Addr = SCBaseAddr+LONG[256]*256; -- RW, 16K locations -- actually, 2*16K locations are allocated but only the odd locations are used DragonMap: TYPE = ARRAY DragonMapIndex OF DragonMapRec; DragonMapBase: LONG POINTER TO DragonMap = LOOPHOLE[DragonMapAddr]; END. ήNewSoftcardPrivate.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Willie-Sue, October 13, 1986 2:46:56 pm PDT Defs used by SoftcardOpsImpl to access the appropriate addresses Christophe Cuenod February 3, 1987 7:34:08 pm PST SCBaseAddr: Addr = 0; -- for testing conventions for the comments following the addresses R = ReadOnly register W = WriteOnly register RW = Read/Write register MS-part = most significant part LS-part = least significant part bit numbers refer to bits in a Dragon word (a) when bits indicated are fewer than 16, only those bits get used - others are ignored (b) The Softcard ignores the 8 most significant bits of the MS-part of a Dragon address e.g. the value written into BkptEUH is 16 bits, but the high 8 bits are ignored The dragon memory is "mapped" into 2 Megabytes of the Daybreak physical address space, at addresses 1.5 to 3.5 megabytes. The next .5 megabytes of Daybreak physical address space are used for memory-mapped I/O. addresses for accessing registers of the Dragon bit 3: 1-bit PBus command of the IFU (cache access in this cycle or not) bit 7: User Mode (part of EU PBus command) Note: since the 32-bits of the clock cannot be read atomically (by the mesa processor), care must be taken ************************* The Debug operations allow one to read or write the internal registers of the EU and the IFU. For IFU: Reading: the internal register is transfered to a shift register internal to the chip, then the bits are shifted out one bit at a time. Writing: the bits are shifted one at a time into the shift register internal to the chip and then written into the internal register. While the Softcard is shifting bits into or outof the IFU internal registers, the Dragon may be running. But to read or write the internal register, the Dragon must be stopped. The EU has up to 16 addressable internal registers (details to be supplied later). To access the EU internal registers for reading or writing, one must assert (set) DebugFreeze. Then one must assert DebugSelectEU. Then one shifts bits into the EU internal shift register using (reading) DebugShiftEU; these bits include the command, address, and data (if writing). Reading DebugExecuteEU causes the EU to do the command in its shift register. If the command was read, one then shifts the bits out by accessing DebugShiftEU. Finally one drops (resets) DebugSelectEU, then drops DebugFreeze. (Whew) The 3 commands are: Read => copy the specified internal state of the chip into the chip shift register Write => write the chip shift register into the internal state of the chip Shift => shift one bit into or out of the chip shift register (depends on previous operation) The shift operations must be done in two steps (ShiftA & ShiftB) ************************* 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 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 ]; ************************* Control and status bits. These are accessed only through Read operations. Some locations allow one to read a word of (up to) 16 of those bits without changing any of the bits. Reading other locations allows one to set or reset one particular bit, while returning the previous value of all the bits. CarXXX => ConsultAndResetXXX The set address for a bit is always the reset address + 2. this address must be 1 MOD 128 setting this bit allows the Dragon to run; resetting it stops the processor and enables you to then single step it. Certain other operations can only be done when the Dragon is halted. setting this bit moves the Dragon to FA or FB; resetting this bit moves the Dragon to between FA/FB or FB/FA allows selection of even or odd parity for subsequent writes; reads are always done with TDB parity; thus one can create a parity error if set, the IOP accesses to Dragon memory are using virtual addresses; if reset, physical addresses are being used if set, the Mesa processor accesses to Dragon memory are using virtual addresses; if reset, physical addresses are being used a reset and set flushes the IFU cache if set, the IFU accesses to Dragon memory are using virtual addresses; if reset, physical addresses are being used a reset and set flushes the EU cache if set, the EU accesses to Dragon memory are using virtual addresses; if reset, physical addresses are being used this address must be 1 MOD 64 ************************* The status bits are similar to the control bits, except that some of them are readOnly and the others can be reset but not set. ************************* The mapping between 2 megabytes of daybreak physical address space and Dragon memory MesaMapEntry: TYPE = MACHINE DEPENDENT RECORD[ reserved (0: 0..15): [0..177777B], unused (1: 0..11): [0..3777B] _ 0, dp (1: 12..15): [0..17B] _ 0 ]; MesaMapIndex: TYPE = [0..7]; actually 2*8 locations are allocated but only the odd locations only used ************************* Access to the Dragon Map DragonMapEntry: TYPE = MACHINE DEPENDENT RECORD[ fault (1: 0..0): BOOL _ TRUE, unused (1: 1..5): [0..37B] _ 0, rp (1: 6..15): [0..1777B] _ 0 ]; DragonMapIndex: TYPE = [0..37777B]; Κ X˜codešœ™KšœB™BK™+K™@K™1—K™šΟk ˜ šœ œ˜KšœB˜B——K˜šΟnœœ œ˜*K˜Kšœœœ˜Kšœœ ˜K˜Kšž œ œΟc ˜1Kšž œŸ™&K˜™4K™K™K™K™K™ K™*K™K™XK™šœ/ŸœŸœ™WKšœžœ,™O—K™™ΣK™——K™KšΟb/™/K™KšžœŸ-˜PKšžœŸ.˜QKšžœŸ.˜RKšžœŸ.˜RK˜KšžœŸ*˜LšžœŸ˜;KšœH™HKšœŸ œ™*—K˜Kšž œŸ0˜TKšž œŸ1˜UKšž œŸ/˜UKšž œŸ0˜VK˜KšžœŸ˜@šžœŸ ˜AKš œf™j—K˜K™K™]šœœ™K™‡K™…—K™±K™™RKšœ‰™‰—K™™K™RK™J™=K™—K™@—K˜šž œ˜#KšœŸ<˜=—šžœ˜%KšœŸ>˜?—K˜K˜Kšž œŸ,˜TKšž œŸ˜GKšž œ˜%Kšž œ˜%K˜Kšž œŸ'˜KK˜š œœœ œœ˜0Kšœ"Ÿ+˜MKšœ!Ÿ*˜KK˜K˜"K˜—K™K™K™KšžœŸ,˜WJ˜š œœœ œœ™.Kšœ™KšœŸ2™QKšœ!Ÿ+™LKšœŸΠcgŸ‘Ÿ™@K™—J˜K˜K™Kšœ: œο™­K™K™:K˜š œœœ œœ˜/Kšœœ˜Kšœ œœ˜-Kšœ!œœ˜.Kšœœœ˜!Kšœœœ˜"Kšœœœ˜#Kšœœœ˜+Kšœœœ˜,Kšœ$œœ˜1Kšœœœ˜%Kšœœœ˜'Kšœ œœ˜-Kšœ%œœ˜2Kšœœœ˜&Kšœœœ˜&Kšœœ˜+K˜K˜—š œœœ œœ˜.Kšœ˜Kšœœ˜Kšœœ˜ Kšœœ˜Kšœ ˜ K˜—K˜šžœŸ˜FK™!—Kšžœ˜"Kšžœ˜4K˜Kšž œ!˜*K˜KšžΟtœ’˜9K˜Kšž’œ’˜9K˜šž ’œ’˜.K™sK™D—K˜šž ’œ’˜/KšŸ%‘Ÿ‘Ÿœ1Οgœ£œ£œ£œ™l—K˜šž’œ’˜0KšŸ<œM™‰—K˜šž’œ’˜8K™r—K˜šž’œ’˜9K™}—K˜Kšž’œ’˜9Kšž’œ’˜:K˜Kšž ’œ’˜-šž ’œ’˜"K™%—K˜Kšž’œ’˜2K˜šž’œ’˜8K™r—K˜Kšž’œ’˜8Kšž’œ’˜8K˜Kšž ’œ’˜,šž ’œ’˜ K™$—K˜Kšž’œ’˜1K˜šž’œ’˜7K™q—K˜š œœœ œœ˜3Kšœ˜Kšœœ˜Kšœœ˜ Kšœœ˜Kšœœ˜ Kšœœ˜Kšœ˜K˜—K˜šžœŸ˜HK™ —Kšžœ˜"Kšžœ˜4K˜Kšž’!˜2K˜Kšž’!˜3K˜Kšž ’!˜+K˜Kšž’"˜2K˜Kšž’"˜0K˜K™K™K™K™š œ œœ œœ˜,KšœŸ,˜GKšœŸ,˜FKšœœŸ‘Ÿ˜0KšœœŸ˜?KšœœŸ1˜NKšœœ˜Kšœœ˜Kšœœ˜Kšœ˜K˜—K˜KšžœŸ˜=K˜Kšž œ˜+K˜Kšžœ˜/KšžΠnt ’˜'Kšž€’˜*Kšž€’˜+Kšž€’˜$K˜K™K™K™TK˜Kšœœ˜.Kšœœ˜.K˜š œœœ œœ™.Kšœ"™"K™"K™K™—Kšœœ ™K˜š œ œœ œœ˜,Kšœ"˜"Kšœ!˜!K˜—K˜šž œŸ˜8KšœI™I—K˜Kšœ œœœ ˜1Kš ž œœœœ œ˜=K™K™K™K™Kšœœ˜2Kšœœ˜2K˜š œœœ œœ™0Kšœœœ™K™K™K™—Kšœœ™#K˜š œœœ œœ˜.Kšœ"˜"Kšœ#˜#K˜—K˜šž œœ Ÿ˜DKšŸN˜N—K˜Kšœ œœœ˜7Kš ž œœœœ œ˜CK˜K™Kšœ˜K˜—J˜—…—Π8