DRAGON I/O INTERFACE: THE IOBRIDGE
DRAGON I/O INTERFACE: THE IOBRIDGE
DRAGON I/O INTERFACE: THE IOBRIDGE
DRAGON PROJECT — FOR INTERNAL XEROX USE ONLY
DRAGON PROJECT — FOR INTERNAL XEROX USE ONLY
DRAGON PROJECT — FOR INTERNAL XEROX USE ONLY
DRAGON I/O Interface: the IOBridge
IOBridge Data sheet and IOBus interface
Jean-Marc Frailong
Dragon-86-xx Written September 2, 1986 Revised Month, Year
© Copyright 1986 Xerox Corporation. All rights reserved.
Abstract: This document describes the basic architecture of the Dragon I/O interface designed for the June87 machine. It contains an overview of the functional requirements, a complete description of the hardware interface, a description of the programming interface, a brief description of the internal structure and notes on interface to the IOBridge.
Keywords: IOBridge, IOBus, June87
FileName: [Indigo]<Dragon>IOBridge>IOBridgeDoc.tioga, .interpress
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304



Dragon Project - For Internal Xerox Use Only
Contents
1. Functional requirements
1.1. The IOBus
1.2. Bus interface functions of the IOBridge
1.3. Special I/O devices in the IOBridge
2. Programming information from DynaBus side
2.1 IOBridge internal registers
2.1.1. Clock support
2.1.2. IOBus interrupt management
2.1.3. IOBridge internal register addresses
2.2 Requests from DynaBus
2.2.1. Byte ordering problems
2.2.2. Access to the IOBus memory space
2.2.3. Access to the IOBus I/O space
2.2.4. Access to the IOBridge internal registers
2.2.5. Summary
2.2.6. Protection
2.3. Loopback mode: access from DynaBus to IOBus-side registers
2.4. Special conditions
3. Programming information from IOBus side
3.1. IOBridge internal registers
3.1.1. DynaBus general control
3.1.2. Identification and DynaBus control
3.1.3. DBus master interface
3.1.4. DynaBus exerciser
3.1.5. Mapping registers
3.1.6. IOBridge internal register addresses
3.2. Requests from IOBus
3.2.1. Requests to DynaBus memory
3.3.2. Requests to IOBridge registers
4. Hardware interface to the IOBus
4.1. Signals
4.2. Timing
4.2.1. IOBridge as Master device
4.2.2. IOBridge as Slave device
4.2.3. Bus ownership timing
5. Hardware interface to the DynaBus
Appendix A. Overview of the internal structure of the IOBridge
Appendix B. Simplified application schematics for the IOBridge
ChangeLog
1. Functional requirements
The I/O for the June87 Dragon machine is mostly to be handled by commercial VLSI running on a close relative of standard microprocessor bus, the IOBus. A special VLSI chip, the IOBridge, is required to interface the IOBus, with the high speed system bus, the DynaBus, and to handle a few specific functions that have no other place in the system.
1.1. The IOBus
IOBus is a generic name for slow-to-medium speed buses used for I/O in the June87 machine. The current implementation of the June87 machine uses for IOBus a very close derivative of the PC/AT backpanel bus. A few control lines are added to the standard PC/AT bus to improve efficiency for disk, Ethernet and processor access to the DynaBus, but any PC/AT compatible board may be connected to the IOBus (including DMAs).
The PC/AT bus is based on the Intel 80286 microprocesor. It offers two byte-addressable address spaces, memory and I/O. The memory address space has 24 address bits (extended on the IOBus to 32 bits, but the disk controller is the only peripheral expected to generate 32-bit addresses). The I/O address space has 16 address bits.
A major source of trouble is matching addresses on the IOBus and on the DynaBus: the IOBus is byte-oriented and little-endian, whereas the DynaBus is 32-bit word-oriented and big-endian. Since the IOBus will be used mostly for I/O processing, the natural choice is to make byte streams compatible between the two buses. Hence, transfering a 16-bit or 32-bit integer between IOBus and DynaBus will involve byte swapping, as detailed in sections 2 and 3.
In the remainder of this document, a half-word designates 2 bytes of data and a word designates 32-bits of data. A half-word is said to be aligned if its (byte) address on the IOBus is a multiple of 2. A word is said to be aligned if its (byte) address on the IOBus is a multiple of 4.
1.2. Bus interface functions of the IOBridge
The IOBridge is mostly a bridge between two buses having different protocols and speeds. The following types of transactions must be supported:
- Originating from IOBus
- Memory Read/Write: converted to DynaBus BlockRead/BlockWrite through a cache for blocking/deblocking
- I/O Read/Write: access to internal IOBridge registers. A special register allows to generate any DynaBus I/O transactions or memory access.
- Interrupts: converted to DynaBus interrupts (I/O transactions with small caches)
- Originating from DynaBus
- I/O Read/Write: converted to IOBus read/writes through a FIFO (the IOBus allows only one transaction at a time). IOBus memory reads, memory writes, I/O reads, I/O writes are supported. DynaBus I/O transactions also allow access to internal IOBridge registers.
- BlockReadReplies/BlockWriteReplies/WriteSingleReplies are used by the cache mechanism both as results of its actions in case of misses and also to do the snooping.
1.3. Special I/O devices in the IOBridge
The IOBridge also contains a few special devices used by various components of the machine. Most of these devices are in the IOBridge for no good reason but the lack of any other place to put them.
- Accessible through the DynaBus:
- a permanent 32-bit clock (tick counter) running at 1 MHz
- an interval timer running at 1 kHz
- a time-of-day clock running at 10 Hz
- support of interrupts generated by the IOBus or internally
- some of the IOBus-controlled registers are accessible from the DynaBus side (refer to section 2.3).
- Accessible through the IOBus:
- a DBus master controller, with address and data registers and automata to generate all DBus signals
- special registers to extend DynaBus access capability: general IO and memory reference
- DynaBus exerciser for testing and debugging
- possibly, a simplified map cache interface providing identity map, 1-entry map and access to a cache sitting on the IOBus. If this is implemented, it must be possible to disable it.
It must be noticed that the set of internal registers visible from the IOBus and from the DynaBus are disjoint. If it is necessary, the IOBus may access the DynaBus oriented registers of the IOBridge by going through the general DynaBus IO mechanism. This is rather heavyweight, but it is expected to be very little used and simplifies considerably the structure of the IOBridge chip.
2. Programming information from DynaBus side
The IOBridge may be accessed from the DynaBus, to either generate a transaction on the IOBus or reference internal registers of the IOBridge.
2.1. IOBridge internal registers
The IOBridge has a set of internal registers visible from the DynaBus through I/O transactions. Those registers may be written into only in Kernel mode. They may be read in Kernel and User modes.
2.1.1. Clock support
The IOBridge supports a 1 MHz permanent clock and two identical interrupt timers.. Those clocks are described by three registers:
- PermanentClock: read-write 32 bits register. Set to 0 upon DynaBus Reset. Clock frequency is 1 MHz, i.e. ticks are 1 ms. The clock wraps around from 232-1 to 0. Although writing into this register is permitted to make chip testing easier, it is expected that it will never be written into.
- Timer1: read-write 32 bits register. Clock frequency is 1 MHz, i.e. ticks are 1 ms. The clock wraps around from 232-1 to 0. An interrupt is generated (if the corresponding interrupt mask bit is set) when this timer wraps around (exactly when it reaches the value 0) to signal expiration of the delay. The timer is not initialized during reset.
- Timer2: read-write 32 bits register. Clock frequency is 1 MHz, i.e. ticks are 1 ms. The clock wraps around from 232-1 to 0. An interrupt is generated (if the corresponding interrupt mask bit is set) when this timer wraps around (exactly when it reaches the value 0) to signal expiration of the delay. The timer is not initialized during reset. Timer2 is exactly a copy of Timer1.
NOTE: The clock period is not strictly 1MHz. It is derived from the IOBus clock by dividing it by a constant loaded through the DBus. Refer to DBus constants section in this document.
2.1.2. IOBus interrupt management
The IOBridge supports 1 interrupt signal coming from the IOBus and 2 internal interrupts (PermanentClock wrap-around and IntervalTimer completion) . Those interrupt lines are converted to interrupt transactions on the DynaBus directed to a specific Dragon CPU (its EU cache in fact) or broadcasted to all CPUs. The interrupt bit set in the Dragon does not depend on the specific interrupts, but only on the IOBridge. Interrupts may be individually masked (without loosing pending interrupts).
The interrupt bits are allocated as follows:
INTR0 : IOBus interrupt
INTR1 : Interval timer 1 wrapped around
INTR2 : Interval timer 2 wrapped around
The interrupt processing is managed through 3 registers accessible from DynaBus:
- INTRReason:
Interrupt reason register. R/W. Only the high-order 16 bits are used, with the bit pattern LLLLLBIIIIIIIIII, where LLLLL (5 bits) is the interrupt reason to be reflected (0 to 31), B (1 bit) is set to 1 for broadcast interrupts and to 0 for directed interrupts, and IIIIIIIIII (10 bits) is the DynaBus ID of the processor EU cache to which the interrupt should be reflected (should be set to all 1's when B=1). The top 16 bits are ignored on writes and return 0 on reads. These registers are not initialized during reset.
- INTRMask:
Interrupt mask. R/W. Only the high-order 3 bits are significant. If bits are numbered LSB first (LSB=bit 0), bit i (i IN [0..3) ) is set to 0 to ignore INTRi and to 1 to allow it. This register is initialized to 0 (all interrupts masked) upon reset. Low-order bits are ignored on writes and return 0 on read.
- INTRStatus:
Pending interrupt status. R/W. Only the high-order 3 bits are significant. Reading this register returns a 1 at bit positions corresponding to pending interrupts, whether masked or not (INTR0 is MSB), and 0 in the low-order 29 bits. Writing into this register a 1 at bit position 0 or 1 removes the corresponding internal interrupt. Writing a 0 at bit position 0 or 1 has no effect. Writing into all other bits is just ignored.
Internal processing of interrupts works in 2 stages:
1. Status
The IOBus interrupt line is just synchronized to the DynaBus clock to present a stable signal. The value read for this interrupt in the INTRStatus register is a strict copy of the wire on the IOBus (except for a few cycles of delay).
Internal (clock and timer) interrupts are stored internally in a flip-flop that may be cleared only by writing a 1 onto the corresponding position of INTRStatus.
2. Transmission
The set of visible interrupts (INTRStatus AND INTRMask) is computed at each cycle and compared to its previous value. If any new interrupt is visible (whether because the status went active or because a previously masked interrupt is now unmasked), an interrupt transaction is sent as required per the INTRReason register. A new interrupt transaction is also sent when the INTRReason register is modified, so that currently pending interrupts may be processed by the new processor(s).
The interrupt handler should take care that the removal of the interrupt source has been taken in account when it clears the interrupt pending bit, as some devices may take some time to deassert their interrupt signal.
NOTE: Since the timers are not initialized by hardware at Reset time, special care must be taken when initializing interrupt processing at bootstrap time. The correct sequence is:
- clear both timers
- remove all possible interrupts from IOBus if necessary (application dependant)
- clear interrupt status register to remove any pending IT due to random values in timers
- setup the interrupt mask as required
Only then may processor interrupts be enabled again.
IOBus interrupts are only summarized inside the IOBridge due to pin-count limitations. More extensive support of interrupts is provided by an external interrupt controller that catches all interrupts from the external bus (PC bus) and presents only a summary status. Under the curently planned external hardware, a pair of Intel interrupt controllers are used (8259A). Managing an IOBus interrupt consists in the following steps (assuming that the 8259As have been properly initialized):
WHILE INTRStatus.bit2 DO {
IT number ← send INTA cycle -- Refer to following sections for details
Perform action for IT number -- such as signalling a condition variable
};
The programmer has to be aware that no new interrupt will be signalled on the DynaBus as long as all the IOBus interrupts have not been sampled. Thus, the loop outlined above must be performed until INTRStatus bit 2 goes inactive.
2.1.3. IOBridge internal register addresses
Each DynaBus-visible IOBridge internal register has a 3 bit internal adddress that is used to access it from the DynaBus. The addresses currently allocated are (in hexadecimal):
Address Register name
00 PermanentClock
01 Interval timer 1
02 Interval timer 2
03 INTRStatus
04 INTRMask
05 INTRReason
06 -- Unspecified -- NO-OP on write, garbage on read
07 -- Unspecified -- NO-OP on write, garbage on read
2.2 Requests from DynaBus
Requests from the DynaBus allow access to the IOBus (memory or I/O space) and to the internal registers of the IOBridge. The IOBridge uses multiple device types on the DynaBus to describe the various types of access possible. Each IOBridge is identified in the I/O address space by a 4 bit device number N. This allows to support up to 16 IOBridges in a machine. This IOBridge number is equal to the low-order 4-bits of the IOBridge DynaBus DeviceID. All IOBridges in a system must have different low-order 4-bits of DeviceID. This may be achieved by allocating DeviceID's for IOBridge chips within a range of 16 (e.g. [0..16) ).
2.2.1. Byte ordering problems
Access to the IOBus from the DynaBus is achieved by DynaBus I/O transactions that carry IOBus byte addresses and a byte, half-word or full-word of data in the least significant byte(s). Byte ordering matters for non-byte access.The solutions retained, although it looks cumbersome, offers all the required flexibility. Let (D0, D1, D2, D3) denote a DynaBus data word (D0 is the MSB, D3 the LSB), and (A, A1, A0) the address specified where A is 22 bits, and A1, A0 1 bit (A0 is the least significant bit). Then IOBus access performs as follows:
- Byte access: IOBus address will be (A, A1, A0)
- Write: write D3 at the addressed location
- Read: return (0, 0, 0, X) where X is the addressed byte
- Half-word access: IOBus address will be (A, A1, 0)
- A0 = 0: INT16 order
- write results in D3 written at (A, A1, 0), D2 written at (A, A1, 1)
- read returns (0, 0, D2, D3) with D3 read from (A, A1, 0), D2 read from (A, A1, 1)
- A0 = 1: byte-stream order
- write results in D2 written at (A, A1, 0), D3 written at (A, A1, 1)
- read returns (0, 0, D2, D3) with D2 read from (A, A1, 0), D3 read from (A, A1, 1)
- Full-word access: IOBus address will be (A, 0, 0)
- (A1, A0) = (0, 0) : INT32 order
- write results in D3 written at (A, 0, 0), D2 written at (A, 0, 1), D1 written at (A, 1, 0), D0 written at (A, 1, 1)
- read returns (D0, D1, D2, D3) with D3 read from (A, 0, 0), D2 read from (A, 0, 1), D1 read from (A, 1, 0), D0 read from (A, 1, 1)
- (A1, A0) = (0, 1) : probably useless order ...
- write results in D2 written at (A, 0, 0), D3 written at (A, 0, 1), D0 written at (A, 1, 0), D1 written at (A, 1, 1)
- read returns (D0, D1, D2, D3) with D2 read from (A, 0, 0), D3 read from (A, 0, 1), D0 read from (A, 1, 0), D1 read from (A, 1, 1)
- (A1, A0) = (1, 0) : double INT16 order
- write results in D1 written at (A, 0, 0), D0 written at (A, 0, 1), D3 written at (A, 1, 0), D2 written at (A, 1, 1)
- read returns (D0, D1, D2, D3) with D1 read from (A, 0, 0), D0 read from (A, 0, 1), D3 read from (A, 1, 0), D2 read from (A, 1, 1)
- (A1, A0) = (1, 1) : byte-stream order
- write results in D0 written at (A, 0, 0), D1 written at (A, 0, 1), D2 written at (A, 1, 0), D3 written at (A, 1, 1)
- read returns (D0, D1, D2, D3) with D0 read from (A, 0, 0), D1 read from (A, 0, 1), D2 read from (A, 1, 0), D3 read from (A, 1, 1)
A simple model of the byte swapping mechanism is that:
- accessing an address multiple of the access quantum results in correct order for the corresponding INT size (8, 16 or 32 bits)
- accessing an address multiple of the access quantum minus 1 results byte-stream ordering
- accessing with A0=1 for half/full word swaps the low-order bytes of each half-word
- accessing with A1=1 for full word swaps the two half-words
In terms of Dragon (or in general big-endian) programmer, 3 access modes are expected to be really used:
- byte-stream mode: preserves character-string ordering. Requires the address specified to be a multiple of the access quantum minus 1 (i.e. 2n+1 for half-word and 4n+3 for full word)
- INT16 mode: Only half-word access should be used, with 2n as address: 16-bit integers must lie on an even 16-bit boundary.
- INT32 mode: Only full-word access should be used, with 4n as address: 32-bit integers must lie on an even 32-bit boundary.
2.2.2. Access to the IOBus memory space
Accesses from the DynaBus to the IOBus memory space supports only 24 bit byte-addresses, although the IOBus supports up to 34 bit byte-addresses. The binary encoding of the DynaBus I/O address (low 32 bits, top 16 are 0) is as follows, where NNNN is the device number of the IOBridge considered:
0010NNNNAAAAAAAAAAAAAAAAAAAAAAAA IOBus byte memory space at AA...AAA
0011NNNNAAAAAAAAAAAAAAAAAAAAAAAA IOBus half-word (16 bits) memory space at AA...AA0
0100NNNNAAAAAAAAAAAAAAAAAAAAAAAA IOBus full-word (32 bits) memory space at AA...A00
Hence, the IOBridge behaves as 2 large devices types numbered 2, 3 and 4. The corresponding hexadecimal encoding is:
2NAAAAAA Byte access
3NAAAAAA Half-word access
4NAAAAAA Full-word access
2.2.3. Access to the IOBus I/O space
Accesses from the DynaBus to the IOBus I/O space supports only 16 bit byte-addresses, according to Intel conventions, although the IOBus supports up to 34 bit byte-addresses. The binary encoding of the DynaBus I/O address (low 32 bits, top 16 are 0) is as follows, where NNNN is the device number of the IOBridge considered:
00000010NNNN0000AAAAAAAAAAAAAAAA IOBus byte I/O space at AA...AAA
00000010NNNN0001AAAAAAAAAAAAAAAA IOBus half-word (16 bits) I/O space at AA...AA0
00000010NNNN0010AAAAAAAAAAAAAAAA IOBus full-word (32 bits) I/O space at AA...A00
00000010NNNN0011................ IOBus interrupt acknowledge (low bits ignored).
Hence, the IOBridge behaves as medium device type 2. The corresponding hexadecimal encoding is:
02N0AAAA Byte access
02N1AAAA Half-word access
02N2AAAA Full-word access
02N3AAAA IT acknowledge
An interrupt acknowledge cycle performs exactly as a byte I/O read and will return a byte in the LSB position indicating the number of one of the currently pending IOBus interrupts (depending on the initialization of the 8259As).
2.2.4. Access to the IOBridge internal registers
Accesses from the DynaBus to the IOBridge internal registers uses a 3-bit subaddress, as described in section 2.1. The binary encoding of the DynaBus I/O address (low 32 bits, top 16 are 0) is as follows, where NNNN is the device number of the IOBridge considered:
00000010NNNN01000000000000000AAA IOBridge internal register (full word) at AAA
Thus, accesses to the IOBridge internal register also use medium device type #2. The corresponding hexadecimal encoding is:
02N4000A IOBridge internal register access
NOTE: Only certain values of AA are defined. Refer to section 2.1.4 for IOBridge I/O register addresses.
NOTE: Of course, there is no problem in this case about byte ordering.
2.2.5. Summary
The following DynaBus I/O addresses (in hexadecimal notation) are decoded by the IOBridge:
2NAAAAAA IOBus memory byte access
3NAAAAAA IOBus memory half-word access
4NAAAAAA IOBus memory half-word access
02N0AAAA IOBus I/O byte access
02N1AAAA IOBus I/O half-word access
02N2AAAA IOBus I/O half-word access
02N3.... IOBus interrupt acknowledge
02N4...A IOBridge internal register access (the dots are not decoded)
02NXYYYYUndefined -- where X#0,1,2,3
2.2.6. Protection
The IOBridge accepts read requests in User and Kernel modes, but rejects all write requests in User mode.
NOTE: This means that writing a new device handler will require to work in Kernel mode. Although this may be an inconvenience, the number of pins of the IOBridge is a severe limitation that does not permit, as was initially planned, to let an external address decoder allow certain IOBus writes in User mode. A possible fix to the problem is to add a status bit in the internal registers that allows/forbids User mode writes to the IOBus. This would be very easy, but is a Pandora box insofar as OS security is concerned.
2.3. Loopback mode: access from DynaBus to IOBus-side registers
It is possible to access through DynaBus requests some of the registers that are controlled by the IOBus side. Such accesses are achieved by doing a normal access to the IOBus memory space at the address that will be decoded by the IOBus as corresponding to the IOBus-side IOBridge registers (this address is chosen by external hardware, and is thus not specified in this document). When such an access is made, the cycle is done internally in the IOBridge instead of going through the IOBus (only the external address decoding logic is used). The reader is refered to section 3 for more information on IOBus-controlled registers.
Since uncontrolled access to all IOBus-side registers may result in hardware deadlocks (e.g., initiating a DynaBus IO transaction directed to the same IOBridge...), some of the registers are disabled in this special loopback mode.
Only the following IOBus-controlled registers are accessible through DynaBus requests:
- all three address maps (48 32-bit registers)
2.4. Special conditions
The IOBridge will abort prematurely any DynaBus to IOBus transaction active when the system switches to the frozen state (DynaBus Error signal or DBus Freeze signal active). Writes may or may not be completed, reads will return random data. The reason for this exceptional behaviour is that the IOBus is also used by the debug processor to communicate with the DBus. Thus, it is not possible to freeze the IOBus state. This also means that single-stepping IOBus transactions will not work properly.
It is expected that this will not raise a serious problem, since the machine should turn into the frozen state only upon occurence of a serious hardware problem or during hardware debugging.
3. Programming information from IOBus side
The IOBridge may also be accessed from the IOBus, to either generate a transaction on the DynaBus or reference internal registers of the IOBridge.
3.1. IOBridge internal registers
The IOBridge has a set of internal registers visible from the IOBus. When accessed through the IOBus, all those registers follow the correct IOBus byte ordering for their size, i.e. byte 0 of the register always contains the least-significant byte. This implies that 16 bits registers may be accessed as 16 bits integers from IOBus, and 32 bits registers as 32 bits integers. In the same way, bits inside a byte are numbered with LSB being bit 0.
3.1.1. DynaBus general control
A set of registers allow the IOBus processor to perform all the DynaBus actions available to a regular processor by exercising the cache's PBus interface. The IOBus has access to a PBus address register, a PBus data register, a PBus command register and a PBus fault register:
- PBusData: 32 bits register, read/write. Contains data to be sent over the DynaBus or data received from the DynaBus. Byte order is swapped: byte 0 of the register is mapped to byte 3 on the DynaBus. This means that access to 32-bit integers is consistent, but that byte-stream access needs swapping.
- PBusAddr: 32 bits register, read/write. Contains address to be sent over the DynaBus.
- PBusCmd: 8 bits register, read/write. Writing into this register initiates the cache transaction exactly as a Dragon processor would in Kernel mode. For a write PBusCmd, the contents of PBusData are sent to the cache. For a read PBusCmd, the value returned by the cache will be stored upon completion into PBusData. The IOBus write to PBusCmd will be completed only when the cache has finished its processing. Reading PBusCmd will return the last command completed. The reader is referred to DOCUMENTATION for exact PBusCmd values.
- PBusFault: 8 bits register, read/write. The low-order bit is set to 1 when a PBus fault is detected, and is cleared by writing any value into this register. When a fault occurs, an interrupt is reflected on the IOBus, and the request that resuklted in a fault is recorded in the PBusErrData, PBusErrAddr and PBusErrCmd registers. The processor should clear the fault bit to remove the interrupt condition. All other bits of the register return 0 on a read.
- PBusErrData: 32-bit register, contains the data emitted by the IOBridge during the last PBus operation that resulted in a fault (not significant if operation was a read), whether through explicit write into PBusCmd or by memory-mapped access.
- PBusErrAddr: 32-bit register, contains the address emitted by the IOBridge during the last PBus operation that resulted in a fault, whether through explicit write into PBusCmd or by memory-mapped access.
- PBusErrCmd: 8-bit register, contains the command emitted by the IOBridge during the last PBus operation that resulted in a fault, whether through explicit write into PBusCmd or by memory-mapped access. The format is the same as for PBusCmd.
3.1.2. Identification and DynaBus control
A register is available to read the DynaBus DeviceID of the IOBridge:
- DevID: 16-bits register, read-only. When read, this register will return the DynaBus DeviceID of the IOBridge in the low-order 10 bits, and 0 in the 6 most significant bits. This register is provided both for debugging purposes and to simplify addressing of IOBridge DynaBus-addressable registers from the IOBus.
A 1-bit register allows to control the Stop bit on the DynaBus (when this bit is on, arbiters will hold further requests):
- DynaBusStopCtl: 1-byte register. The bits are:
<AssertStop><CurrentStop> <R> <R> <R> <R> <R> <R>
- AssertStop : RW. The value of this flip-flop is emitted as StopOut to the DynaBus.
- CurrentStop : RO. Reads as the current value of StopIn from the DynaBus. When AssertStop is modified, it will take some time (~ 10 DynaBus cycles) for CurrentStop be modified. CurrentStop may read `on' although AssertStop is `off' since another DynaBus component may be asserting its StopOut line.
3.1.3. DBus master interface -- Not implemented --
The DBus master interface allows the IOBus processor to control the DBus during bootstrap and system debugging. It contains the following registers:
- DBusData: 32-bit register, read/write. Contains the data to be sent over the DBus and the data received from the DBus. It should be setup before initiation of a DBus shift cycle, and its new contents stored upon completion of the shift cycle. The register should not be accessed (read or write) during a DBus shift cycle.
- DBusAddr: 16-bit register, read/write. Contains the DBus address of the component to be selected. The component will become selected only when the corresponding command is sent on DBusControl. The register should not be accessed (read or write) while the address is being sent over the DBus.
- DBusDataLength: 8-bit register, read/write. The 5 least significant bits indicate the length of the DBus shift cycle to be performed (0 for 1 bit, 31 for 32 bits). The 3 most significant bits are ignored on write and read as zeroes. Writing into this register initiates the shift cycle: current contents of the DBusData register are shifted out MSB first whereas bits received from the DBus are shifted into LSB of the register, for the number of bits specified. reading this register returns zeroes. The register should not be written into during a DBus shift cycle.
- DBusControl: 8-bit register, read/write. Writing into this register initiates DBus transactions, reading from this register returns information on the current state of the DBus interface. The register supports three active commands (DBCExecute, DBCSelect and DBCShift). A new command requested while the DBus master controller is still processing a previous one will be ignored. If multiple commands are requested, only one will be executed, with priority (highest to lowest) being DBCSelect, DBCExecute, DBCShift. The structure of the DBusControl register is (bit 0 is LSB, Intel conventions!):
- DBCReset (bit 0 - LSB): read/write. DBus Reset signal is a copy of this bit. Hence, writing 1 in this bit resets all DBus-connected devices.
- DBCFreeze (bit 1): read/write. DBus Freeze signal is asserted when this bit is 1. Hence, writing 1 in this bit freezes all DBus-connected devices.
- DBCFrozen (bit 2): read only. This bit indicates the current state of the DBus Freeze line. It will be asserted (1) when DBCFreeze is asserted (after a few DynaBus cycles of pipeline delay), but it may be asserted because some other device pulled the DynaBus ErrorOut line.
- DBCCommand (bit 3 & 4): read/write. This field is used to initiate new DBus commands. A new command will be accepted only if a command is not currently under progress, as indicated in the DBCBusy status bit. Upon reading, the code for the currently executing command will be returned, or 00 if no command is currently being executed. The encoding of the filed is:
00B : No new command.
01B : Initiate an Execute DBus cycle. The currently selected component will execute a device-dependant action.
10B : Initiate an address selection DBus cycle. The address in DBusAddr is used to select a component on the DBus.
11B : Initiate a data shift DBus cycle. Current contents of the DBusData register are shifted out MSB first whereas bits received from the DBus are shifted into LSB of the register, for the number of bits specified in DBusDataLength (+1).
- Bits 5 & 6 are currently unused and read as 0.
- DBCBusy (bit 7 - MSB): read only. This bit is asserted (1) if the DBus controller is currently busy on one of the three DBus commands specified in DBCCommand. In fact, this bit is exactly equal to DBCCommand#00B.
NOTE: Implementing the DBus master interface through the IOBus has consequences on the management of the DBus Freeze signal in the IOBridge board. The basic problem lies in the semantics of Freeze for the IOBus. The only reasonnable answer is that Freeze should allow the IOBus to be allocated only to the debug processor, and not to any of the I/O controllers. In this way, all devices will be in effect stopped, since they will not be able to access the IOBus, and the debug processor will still be able to use the IOBus to perform its debug tasks, including driving the DBus master interface in the IOBridge through the IOBus. The practical implementation depends on the way the IOBridge board is designed. For a new design, the right solution is to have Freeze be an input of the IOBus allocator that denies all allocations except to the debug processor. For designs where the allocator is not available on the IOBridge board (such as reusing the 6085 reduced-cost IOP), the only possible solution is to stop from the debug processor all I/O devices. This will result in a non-restartable error, but at least it will be possible to debug something...
3.1.4. DynaBus exerciser
The DynaBus exerciser allows to test the functionnality of the DynaBus by sending any request and receiving any reply. The DynaBus exerciser consists mainly of a 5-word queue and associated control logic. In order to send a DynaBus packet, the user must push 5 64-bits words of data into the queue (even to send only a 2-word packet: the remaining 3 words are then ignored). In the same way, when a reply is received, 5 cycles worth of data are pushed into the same queue and may be recovered by the user. Communication with the queue is through the PBusAddr register for the most-significant half and the PBusData register for the least-significant half. Due to the encoding of IOBridge internal register addresses, this means that (PBusData, PBusAddr) form a 64-bit register with the expected byte ordering. The DynaBus exerciser contains the following registers:
- DynaBusExerciserDeviceID: 16-bit register, read/write. Contains the DeviceID (10 LSB) used to match replies received on the DynaBus. When reception is armed, any reply packet matching this ID will be stored in the DynaBusExerciser FIFO.
- DynaBusExerciserControl: 8 bit register, read/write. This register allows to control the DynaBus exerciser and to check its current status. It contains the following bits (bit 0 is LSB, Intel conventions):
- MSW (bit 0 - LSB): write-only. Selects whether the most significant or least significant half of the queue will be affected. 1 specifies the most significant half, 0 the least significant half.
- QueueOp (bit 1-2): write-only. Describes a command to be performed on the Exerciser queue. Only the half of the queue specified by MSW is affected. The following commands are recognized:
- 00: No operation
- 01: Push PBusAddr on queue (last value of queue is discarded)
- 10: Pop queue into PBusAddr (random value pushed on top)
- 11: Rotate (PBusAddr, queue). Equivalent to simultaneous Push & Pop
- Emit (bit 3): read/write. Writing a 1 in this bit location initiates the transmission on the DynaBus of the current contents of the queue. A new command will be ignored if one is currently active. When read, 1 indicates that emission is active or pending, 0 that the emitter is idle. When a packet has been succesfully sent, bit Emitted will be set to 1 (refer to this bit for more information). Five 64-bit words are always emitted. Due tot the bus protocol, using a 5-cycle slot to transmit a 2-cycle transaction is valid if HeaderCycleOut is asserted only once (which the IOB hardware does).
- Emitted (bit 4): read/write. This bit is set to 1 when a packet has been succesfully emited through an Emit command. It is also modified by writing 0 or 1 into it. It is used as an enable of reception: reception will occur only if Emitted and ArmReception are both set to 1. This allows not to receive spurious answers to an emission. To send a packet and receive the corresponding reply, one should setup the exerciser queue and DynaBusExerciserDeviceID, then write DynaBusExerciserControl to 00101000, i.e. set ArmReception, clear Emitted and set Emit (the register should not be written into again until ArmReception reads again as 0, indicating successfull reception). On the contrary, snooping may be achieved by writing 00110000 into the register, i.e. set ArmReception, set Emitted.
- ArmReception (bit 5): read/write. Writing a 1 into this register will enable the reception of the first DynaBus reply packet that matches the contents of DynaBusExerciserDeviceID, provided that Emitted is also set to 1. The bit will read as one as long as a valid packet has not been received, and will be cleared automatically when a reply has been received. It is possible to clear it to cancel a reception.
- bits 6, 7 are not used and read as 0.
3.1.5. Mapping registers
As explained below in section 3.2., the IOBridge contains 3 address maps, each being used for a specific address range. Each map has 16 entries, considered to occupy a full 32-bit word (although entry size is smaller for all of the maps). Each entry of each map may be read/written using byte or word accesses. Thus, the map registers occupy 48 long words of address space, i.e. 192 bytes.
The data used when reading or writing the address maps is the DynaBus physical address (32-bit word address) of the first word of the page (a 32-bit quantity). Reading and writing address maps may be done on a byte basis. Described according to each address map, this means:
- Small address map: only the 22 MSB of data are taken into account. When reading, the 10 LSB are returned as 0 and the 22 LSB are the value of the map entry.
- Large address map: only the 14 MSB of data are taken into account. When reading, the 18 LSB are returned as 0 and the 14 LSB are the value of the map entry.
- Extra address map: only the 6 MSB of data are taken into account. When reading, the 26 LSB are returned as 0 and the 6 LSB are the value of the map entry.
The maps are not initialized upon reset. Bootstrap software should initialize them as early as possible.
3.1.6. IOBridge internal register addresses
Each IOBridge internal register has a 9 bit internal adddress that is used to access it from the IOBus. The address map is (in hexadecimal):
Address Register name
00-03 PBusData (0 is LSB, 3 is MSB)
04-07 PBusAddr (4 is LSB, 7 is MSB)
08-0B PBusResult (RO, 8 is LSB, B is MSB)
0C PBusCmd (WO)
0D IOBusInt (RO)
0E IOBusSetInt (WO)
0F IOBusClrInt (WO)
10-13 PBusErrData (RO, 10 is LSB, 13 is MSB)
14-17 PBusErrAddr (RO, 14 is LSB, 17 is MSB)
18 PBusErrCmd (RO)
19 PBusFault (RW)
1A-1B DynaBus ID (RO, 1A is LSB, 1B is MSB, zero-extended to 16 bits)
1C-1E-- Unused --
1F DynaBusStopCtl (RW) This register should be moved to the DBus area ASAP because the IOBusCKCtl automaton is disabled by Reset...
20-27 Exerciser data register (RO/WO) (20 is LSB, 27 is MSB)
28 Exerciser data control (WO)
29-- Unused --
2A-2B Exerciser DynaBus ID (RW) (2A is LSB, 2B is MSB, zero-extended to 16 bits)
2C-2F-- Unused --
30-3F-- Unused --
40-43 Small map, entry 0
44-47 Small map, entry 1
48-4B Small map, entry 2
4C-4F Small map, entry 3
50-53 Small map, entry 4
54-57 Small map, entry 5
58-5B Small map, entry 6
5C-5F Small map, entry 7
60-63 Small map, entry 8
64-67 Small map, entry 9
68-6B Small map, entry A
6C-6F Small map, entry B
70-73 Small map, entry C
74-77 Small map, entry D
78-7B Small map, entry E
7C-7F Small map, entry F
80-83 Large map, entry 0
84-87 Large map, entry 1
88-8B Large map, entry 2
8C-8F Large map, entry 3
90-93 Large map, entry 4
94-97 Large map, entry 5
98-9B Large map, entry 6
9C-9F Large map, entry 7
A0-A3 Large map, entry 8
A4-A7 Large map, entry 9
A8-AB Large map, entry A
AC-AF Large map, entry B
B0-B3 Large map, entry C
B4-B7 Large map, entry D
B8-BB Large map, entry E
BC-BF Large map, entry F
C0-C3 Extra map, entry 0
C4-C7 Extra map, entry 1
C8-CB Extra map, entry 2
CC-CF Extra map, entry 3
D0-D3 Extra map, entry 4
D4-D7 Extra map, entry 5
D8-DB Extra map, entry 6
DC-DF Extra map, entry 7
E0-E3 Extra map, entry 8
E4-E7 Extra map, entry 9
E8-EB Extra map, entry A
EC-EF Extra map, entry B
F0-F3 Extra map, entry C
F4-F7 Extra map, entry D
F8-FB Extra map, entry E
FC-FF Extra map, entry F
100-1FF DBus controller, TBD
All other values are undefined. The IOBridge may either not recognize them at all or act as NO-OP. Reads of undefined locations will return random results.
3.2. Requests from IOBus
IOBus requests to the IOBridge may use either memory space or I/O space (nRD/nWR or nIOR/nIOW). Memory space requests are transformed (through the external cache) into DynaBus memory references with a byte granularity. I/O space requests are transformed in accesses to the IOBridge internal registers (as a side effect, a DynaBus transaction might be generated as mentionned in the previous section). It must be noticed that all DynaBus accesses are made as if from a processor running in Kernel mode, disabling all protection.
3.2.1. Requests to DynaBus memory
When a IOBus memory space transaction (nRD or nWR with MemCS asserted) occurs in the address range to which the IOBridge responds (this range is decoded by external hardware), it is transformed into a request on the DynaBus through the IOBridge cache after suitable address mapping.
Address mapping is supported through 3 different maps according to the addressing range. Each map has 16 entries. IOBus addresses are mapped into 32-bit DynaBus word addresses plus byte select control lines. The two low order bits of the IOBus address are decoded to provide byte selection.
- Small map: if the address is below 1M (20 bits), only the low 16 address bits are considered (it is assumed that external hardware decodes a single 64K byte chunk of addresses in that range). Those 64K bytes are mapped in 16 pages of 4K bytes. Each page has a base address on an even 4K byte (1K 32-bit word) boundary. The base address is thus 22 bits long.
- Large map: if the address is between 1M and 16 M (24 bits), only the low 24 address bits are considered. Those 16M bytes are mapped in 16 pages of 1M bytes. Each page has a base address on an even 1M byte (256K 32-bit word) boundary. The base address is thus 14 bits long.
- Extra map: if the address is above 16 M (32 bits), it is mapped in 16 pages of 256M bytes. Each page has a base address on an even 256M byte (64M 32-bit word) boundary. The base address is thus 6 bits long.
The small map will normally be used for 80286 CPU access (MSDOS currently runs only in 8086 emulation mode, and generates addresses below 1M). The large map will normally be used for DMA peripherals on the IOBus (they may generate any 24-bit address). The extra map is intended to be used only by the disk controller, which is able to generate full 32-bit addresses.
The mapped address is used as the physical DynaBus memory address. The low 2 IOBus address bits and nBHE act as byte selectors and allow byte or aligned half-word accesses (unaligned half-word transactions are not permited on the IOBus). The byte ordering maintains consistency for byte-streams, i.e. the MSB of a DynaBus word is mapped to a IOBus address of the form 4*n and the LSB to an address of the form 4*n+3. This means that it is necessary to swap bytes when accessing half-word or word integers on the DynaBus.
If the DynaBus reference fails, a flag will be set in the PBusFault register and an interrupt will be raised on the IOBus. In such a case, random data will be returned for a read. The issuer of the command should read the cache fault register to get the exact fault reason.
3.3.2. Requests to IOBridge registers
When a IOBus I/O space transaction (nIOR or nIOW) occurs in the address range to which the IOBridge responds (this range is decoded by external hardware), it is transformed into a request to the IOBridge internal registers. Only the low-order 8 address bits are decoded.
4. Hardware interface to the IOBus
To be written
5. Hardware interface to the DynaBus
To be written
Appendix A. Overview of the internal structure of the IOBridge
Appendix B. Simplified application schematics for the IOBridge
ChangeLog
Jean-Marc Frailong September 3, 1986 4:13:26 pm PDT
Changed IOCLK and IT names to SloCLK and INTR. Added description of IOBridge internal registers, IOBus accesses and DynaBus accesses.
changes to: Section 2 (written), Section 3.1 (signal names changed).