Traditional DEC PDP-11 and VAX-11 hardware, whether using the UNIBUS or the Q-bus, share a common layout for interrupt vectors and control register addresses for expansion boards. There are a number of addresses and vectors that are exclusively allocated to specific devices, but in order to make room for a large number of potential device types, extensive use is made of so-called "floating" addresses and vectors, which are allocated to devices as they are added to the machine.
For such devices to be used, UNIX has traditionally required the sysadmin to configure and build a kernel explicitly for the chosen hardware. Some operating systems and diagnostic tools from DEC, though, have a special algorithm they use when probing for devices at boot, and if you configure your hardware according to this, the system can correctly find and recognize each device.
I have written a tool that helps you configure your hardware so that DEC's autoconfiguration will find all your devices. For info on my "sysgen" tool, see below, but first, a few words about the autoconfiguration algorithm.
A device falls into one of several classes. First, each device type may have one or more explicitly allocated CSR/vector pairs. In this case, the first device or devices of the type added to the system should be configured with these.
Next, a device may need to use a floating interrupt vector. This could be true for all instances of the device type, or just for those that are added after the above, explicitly configured, ones.
Finally, a device that uses a floating vector may also have to use a floating CSR address. Again, this may be true for all instances, or only for those that are added after all the explicit addresses for this device type have been taken.
No device type ever has a floating CSR and a fixed vector.
All existing device types are sorted by DEC into an ordered list, where the above categories have separate entries, so that for each device type, those with fixed addresses (if such allocations exist) come first, then any with floating vectors only, and finally those that have both vectors and CSR in the floating space. For all device types with floating addresses, the ordering of the list defines the order in which the device types may allocate these.
In addition to fixed allocations of CSR and vector addresses, the list holds information about the number of registers and vectors the device uses, and the alignment requirements of each.
When device boards are configured, DIP switches or jumpers are used to set the vectors and CSR addresses. Each board may use one or more of each, and will have some alignment requirement for each, as well. At minimum, a CSR must be aligned at an even address, and an interrupt vector at a multiple of 4, due to their minimum size. Thus, the lowest address bit for the CSR, and the two lowest for the vector, will never have a switch or jumper, and the next bit or bits may be missing, as well. Typically, a device using multiple registers or vectors will want the block aligned so that it can use the lowest address lines exclusively for choosing between them, and not have to calculate the address by adding to a configured base.
During autoconfiguration, the above mentioned list of device types is gone through, and each one probed for on the bus. The ones that have explicit CSR and vector addresses are straightforward enough, but when vectors, or vectors and CSR addresses, are floating, care must be taken. In particular, floating CSR addresses must not be probed by the wrong device driver, with possibly unwanted effects. Avoiding this is done by making sure that each device can, in a given configuration, only be present at a very specific address.
Floating CSR addresses are probed starting after 0760000, which is initially noted as the last already probed address. When the autoconfiguration algorithm scans the table of possible devices, every time it hits a device with floating CSR, it starts by taking the last probed address, adding 2 to it, and rounding the result up, if needed, according to the alignment requirement of the device now to be probed for.
Interrupt vectors are then prepared for the device, and it is probed at the above calculated address. If it responds, the CSR and vector addresses it needs are allocated to it in the configuration, and another probe is set up, for a possible further device of the same type, at the next CSR address consistent with the device's alignment requirement. This continues until no device is found. At this point, the "last probed address" is set to the one we failed to find anything at.
The scan then continues with the next candidate from the ordered list. In this way, no two device types are ever probed for at the same address: types not found are allocated one word of (unused) floating address space, while those found get what they need. The available address space is large enough that this always works.
Floating interrupt vectors are allocated from address 0300 onward, the first one being at 0300. Every time a device is probed for, following the above algorithm for CSR addresses, the vector or vectors it needs are expected to be as follows:
The next free vector address (initially 0300) is rounded up, if necessary, to match the alignment requirements of the device. Then, the needed number of vectors are allocated, starting at this address.
If the device being probed for isn't there, the above vector allocation is freed up again, but if the device is present, the next vector address, following the ones now allocated to the found device, is marked as the next free one.
VMS has an application called SYSGEN, that is used to configure various aspects of the operating system itself. SYSGEN has a number of modules, one of which is CONFIG, which is used to calculate the correct configuration of devices, so that the above described autoconfigure mechanism will work.
CONFIG accepts a list of devices on standard input, each device name optionally followed by a comma and a number. The number, if given, indicates the number of occurrences of the named device.
The output is a table of the same devices, with CSR and vector assignments according to DEC standards. Floating assignments are flagged with asterisks. VMS device names are also shown, along with information about whether the device is supported by the version of VMS you are running.
My sysgen tool is an emulation of CONFIG, modulo the VMS device names and support info. Here's a sample run:
% cat devlist tsv05 delqa dhv11 tk50,2 rqdx3,2 kda50 % sysgen < devlist Table of standard DEC assignments for configuration: DEVICE CSR VECTOR ------------------------- TSV05 772520 224 DELQA 774440 120 DHV11 760500* 320* TK50 774500 260 TK50 760444* 310* RQDX3 772150 154 RQDX3 760334* 300* KDA50 760340* 304* CSRs and vectors marked '*' are in floating space. %
The CONFIG run corresponding to the above looks like this:
$ MCR SYSGEN SYSGEN> CONFIG DEVICE> ts11 DEVICE> qna DEVICE> dhv11 DEVICE> tu81,2 DEVICE> uda,3 DEVICE> ^Z Device: TS11 Name: MSA CSR: 772520 Vector: 224 Support: yes Device: UDA Name: PUA CSR: 772150 Vector: 154 Support: yes Device: TU81 Name: PTA CSR: 774500 Vector: 260 Support: yes Device: QNA Name: XQA CSR: 774440 Vector: 120 Support: yes Device: UDA Name: PUB CSR: 760334* Vector: 300* Support: yes Device: UDA Name: PUC CSR: 760340* Vector: 304* Support: yes Device: TU81 Name: PTB CSR: 760444* Vector: 310* Support: yes Device: DHV11 Name: TXA CSR: 760500* Vector: 320* Support: yes SYSGEN>
The data contained in my tool's ranking table was taken from the documentation for VMS 5.5 (aka "the Grey Wall"), with a few corrections made where the printed manuals disagreed with the actual output of the VMS SYSGEN command, in which case SYSGEN was assumed to be right. These instances are noted in the source. The trust in the actual SYSGEN program may be misplaced: when I later did some spot checks against the VMS 7.1 SYSGEN, I found a couple of alignment discrepancies where SYSGEN's calculation was almost certainly wrong, as it contradicted the documentation for the devices in question.