HOW TO WRITE Q-BUS DRIVERS -------------------------- 1 INTRODUCTION This document details the differences between MicroVAX I Q-bus and UNIBUS drivers. It also describes how to modify a UNIBUS driver to make it drive a device on the MicroVAX I Q-bus. To use these notes effectively, you should be familiar with the Version 3 edition of the VAX/VMS Guide to Writing a Device Driver, and you should have available for reference the MicroVAX I Owner's Manual (EK-KD32A-UG-001), the MicroVAX I CPU Technical Description (EK-KD32A-TD-001), and the Microcomputer Interface Handbook. In addition, changes to VAX/VMS since Version 3 require that VAX/VMS drivers reflect the following items. o The base of the device-dependent UCB must be defined using a new symbol, UCB$K_LCL_DISK_LENGTH. This symbol replaces UCB$W_BCR+2 which has been used to define the base of the device-dependent UCB for disks. o For tape devices, the base of the device-dependent UCB must be defined using a new symbol, UCB$K_LCL_TAPE_LENGTH. This symbol replaces UCB$L_DPC+4 which has been used to define the base of the device-dependent UCB for tapes. For tape devices, the device-dependent field UCB$L_xx_RECORD has been replaced with a device-independent field, UCB$L_RECORD. In the past, drivers had to define a field named UCB$L_xx_RECORD, where xx was the device's mnemonic. This field contained the number of records between the beginning of the tape and the current position of the tape. This field had to be at a specific offset within the UCB (in Version 3 this offset was 0A4 from the UCB base). In Version 4, UCB$L_RECORD serves this function. o All device drivers must support the I/O functions IO$_PACKACK, IO$_AVAILABLE, and IO$_UNLOAD. The FDT routine EXE$LCLDSKVALID, supplied by VAX/VMS, must be the last FDT routine executed for all three functions. In addition, the driver's start-I/O routine must do the following. o Set the bit UCB$V_VALID in the field UCB$L_STS for the IO$_PACKACK function. o Clear the bit UCB$V_VALID in the field UCB$L_STS for the IO$_AVAILABLE and IO$_UNLOAD functions. 1 This represents the minimum support required for these functions. You can choose to have the functions provide other, additional services. For example, you might choose to have the IO$_UNLOAD function cause a drive to spin-down. o The following fields must now be invoked explicitly in order to define symbols for your driver. Customer-written device drivers can no longer depend upon SYS.STB to resolve these symbols. Macro Symbols Defined by It $DYNDEF Codes defining types of dynamic data structures $FCBDEF Offsets in the file-control block $IPLDEF VMS interrupt-priority levels (IPLs) $PCBDEF Offsets in the Process-control block $PRVDEF Bits that define process privileges $RSNDEF Codes that define resource-wait states $VADEF Virtual address structure o The macro TIMEDWAIT has been added to the system. This macro waits for a period of time for an event or condition to occur. You can specify up to six instructions for this macro to execute in a loop to determine whether the event has occurred. This macro does not read the processor's clock. The interval it waits is approximate and depends upon the processor and the set of instructions you choose for testing to see if the condition exists. This macro has the following parameters. Optional parameters are enclosed in square brackets. Parameter Meaning TIME The number of 10-microsecond intervals by which to multiply the processor-specific value in order to calculate the interval to wait. The processor-specific value is inversely proportional to the speed of the processor, but is never less than 1. 2 If you do not specify any imbedded instructions, increase the value of TIME by 25 percent. If you specify imbedded instructions that take longer to execute than the average, such as the POLYD instruction, they will cause TIMEDWAIT to wait proportionally longer. [INS1] The first instruction in the loop [INS2] The second instruction in the loop [INS3] The third instruction in the loop [INS4] The fourth instruction in the loop [INS5] The fifth instruction in the loop [INS6] The sixth instruction in the loop [DONELBL] The label placed at the address of the instruction at the end of the TIMEDWAIT loop; imbedded instructions can pass control to this label in order to pass control to the instruction following the invocation of the TIMEDWAIT macro [IMBEDLBL] The label placed at the first of the imbedded instructions; after executing a processor-specific delay, the macro passes control here to retest for the condition [UBLBL] The label placed at the instruction that performs the processor-specific delay after each execution of the loop of imbedded instructions; imbedded instructions can pass control here in order to skip the execution of the rest of the imbedded instructions in a given execution of the imbedded loop o The value of IPL$_SYNCH has changed from 7 to 8, and IPL 7 has become a fork IPL. o The EXEC routines ERL$RELEASEMB, EXE$FORKDSPTH, and IOC$ALTUBAMAP are no longer documented. o The EXEC routines EXE$ALOPHYCNTG, IOC$MOVFRUSER, and IOC$MOVTOUSER are now documented. 3 o The DDTAB macro nas a new, optional keyword, CLONEDUCB. It's default argument is IOC$RETURN. o The DDT has a new field, DDT$L_CLONEDUCB. o Appendix A describes the field IRPE$L_EXTEND. o The UCB has the new fields UCB$L_ORB, UCB$L_LOCKID, and UCB$W_QLEN. o The UCB field UCB$W_STS has become UCB$L_STS. The symbol UCB$W_STS still exists, and it points to the low-order word of UCB$L_STS. o The UCB no longer has fields UCB$L_VPROT or UCB$L_OWNUIC. o A description of a new data structure, the object-rights block (ORB), has been added to Appendix A. This structure contains the information that defines the protection of system objects such as the UCB. 2 A COMPARISON OF THE UNIBUS AND THE MICROVAX I Q-BUS The MicroVAX I Q-bus is very similar to the UNIBUS. Non-DMA transfers can be performed for a device on the MicroVAX I Q-bus by the same, unaltered driver that performs them for the equivalent device on the UNIBUS. Some differences exist between the busses, however, and these differences are of interest if you want to support a device on which DMA transfers are to be done. The following lists show the differences and similarities between the MicroVAX I Q-bus implementation and the UNIBUS. +---+ ! ! ! ! ! B +------------+ ! A ! ! ! C ! CPU ! ! K ! ! ! P +------------+ ! L ! +---+ +---+ +---+ ! A ! ! ! ! ! ! ! ! N +---------------+ ! D ! ! D ! ! D ! ! E ! ! ! E ! ! E ! ! E ! ! ! MEMORY ! ! V ! ! V ! ! V ! ! ! ! ! I ! ! I ! ! I ! ! +---------------+ ! C ! ! C ! ! C ! ! ! ! E ! ! E ! ! E ! 4 ! +-------+ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! +--------------------+---+-------+---+-------+---+--+ ! ! UBA ! UNIBUS ! ! ! +---------------------------------------------------+ ! ! ! ! +-------+ ! ! +---+ Figure 1: A UNIBUS System The characteristics of the UNIBUS system are listed below. o The UNIBUS uses 18-bit physical addresses. o The UNIBUS has an 8Kb I/O page. o The UNIBUS is connected to the CPU's backplane by means of the UNIBUS adaptor (UBA). o The UNIBUS adaptor contains 496 mapping registers, which are used to to map UNIBUS physical addresses to VAX/VMS virtual addresses. o The UNIBUS adaptor provides buffered data paths, which optimize CPU-to-UNIBUS data transfers. o UNIBUS adaptor has a byte-offset register, thus words that are not word-aligned can be transfered to and from any device on the UNIBUS regardless of whether the device supports non-word-aligned transfers. o The UNIBUS is one of the I/O buses available on a VAX-780, a VAX-11/750, and a VAX-11/730. In addition, each system has its own particular CPU backplane. o On a VAX-11/780, the UNIBUS uses indirect-vector interrupt dispatching; on VAX-11/750s and VAX-11/730s, the UNIBUS uses direct-vector interrupt dispatching. In each case, the vector addresses can range from 0 to 777 (octal). o The UNIBUS provides four device IPLs (BR4-BR7) on which device priority is based. These device IPLs are independent of the position of the devices on the UNIBUS. +---+ +---+ +---+ ! D ! ! D ! ! D ! ! E ! ! E ! ! E ! +--------------+ ! V ! ! V ! ! V ! +-------+ ! ! ! I ! ! I ! ! I ! 5 ! ! ! MEMORY ! ! C ! ! C ! ! C ! ! CPU ! ! ! ! E ! ! E ! ! E ! ! ! ! ! ! ! ! ! ! ! +-+-------+---+--------------+-------+---+-------+---+-------+---+---+ ! MicroVAX I Q-bus ! +--------------------------------------------------------------------+ Figure 2: A MicroVAX I System The characteristics of the MicroVAX I Q-bus are listed below. o The MicroVAX I Q-bus uses 22-bit physical addresses. It supports only those DMA controllers that are capable of 22-bit addressing. o Both the UNIBUS and the Q-bus have an 8Kb I/O page. o The MicroVAX I Q-bus connects memory to the MicroVAX I CPU and to each peripheral device, hence no adaptor is required. o The MicroVAX I Q-bus has no map registers, so no mapping of physical bus addresses to virtual memory addresses is possible. Thus data transferred to or from contiguous bus addresses must be transferred from or to contiguous physical addresses in MicroVAX I memory. Note, however, that some controllers that can do DMA transfers on the MicroVAX I Q-bus have microcode that allows the controller to do physical-to-virtual address mapping. This allows such controllers to do scatter-gather mapping, eliminating the need for transfers to be made to or from physically contiguous main memory. The RD/RX controller, which MicroVAX I uses for its system disk, uses such a controller. o The MicroVAX I Q-bus has no buffered data paths. o The MicroVAX I Q-bus has no byte-offset register, so, on devices that are only capable of word-aligned transfers, only word-aligned transfers are possible. o The MicroVAX I Q-bus has an address space with 22-bit physical addresses. Furthermore, the MicroVAX I Q-bus serves as both the system's I/O bus and backplane. o The MicroVAX I Q-bus provides direct-vector interrupt dispatching, and the vector addresses can range from 0 to 777 (octal). o The MicroVAX I Q-bus provides 4 device IPLs (BR4-BR7). Devices with higher IPL must be configured closer to the CPU than devices with lower IPL. 6 The MicroVAX architecture specifies 31 IPLs. Their uses are listed below. IPL Interrupt 1F unused 1E power failure 1D memory write error 18 to 1C unused 17 Q22 bus IRQ7 16 interval timer and Q22 IRQ6 15 Q22 bus IRQ5 14 console receive, console transmit, and Q22 bus IRQ4 10 to 13 unused 01 to 0F software interrupts Interrupts from devices on the Q-bus are arbitrated by comparing the level of the interrupting device to the current processor IPL. But when an interrupt from a device is serviced, the IPL is raised to 17 (hex). Subsequent interrupts lower than the current IPL of the processor are blocked, including other interrupts from the device being serviced. Note that the interval timer interrupts at IPL 16 (hex). Because of this, the driver of a Q-bus device that raises IPL to 16 (hex) or above must lower IPL below 16 (hex) before 10 milliseconds elapses. Executing at IPL 16 (hex) or above can cause interrupts from the interval timer to be lost. 3 A COMPARISON OF MICROVAX I Q-BUS AND UNIBUS DRIVERS This comparison is divided into two parts. The first describes the drivers that handle non-DMA transfers. The second part describes the drivers that handle DMA transfers. 7 3.1 Non-DMA Transfers In non-DMA transfers, the driver reads from and writes into the device's registers, and in this manner moves a word of data to or from the device. Non-DMA devices do not use mapping registers, so drivers of such UNIBUS devices will drive equivalent devices on the MicroVAX I Q-bus. The driver of a UNIBUS device needs no modification to make it drive the equivalent device on a MicroVAX I Q-bus. Non-DMA devices do not use data paths, so the lack of data paths in the MicroVAX I Q-bus has no impact on the drivers of such devices. Examples of UNIBUS devices that do non-DMA transfers are the LP-11 and the DZ-11. Corresponding Q-bus devices that do non-DMA transfers are, respectively, the LPV-11 and the DZV-11. 3.2 DMA Transfers When a UNIBUS device driver does a DMA transfer, it allocates mapping registers and, optionally, a data path, and sets up the transfer by means of the device's registers. The device then accesses memory directly by means of the UNIBUS, transferring all the data requested. When the transfer is complete, the device notifies the driver by requesting an interrupt. The device can access memory directly by means of the UNIBUS because the UNIBUS adaptor contains mapping registers, which allow the device to access scattered, physical memory addresses as contiguous, physical UNIBUS addresses. Take a buffer, for example, that consists of virtual pages 400, 401, 402, and 403, which are physical pages 1003, 204, 1190, and 240, respectively. For a UNIBUS device to access this buffer, the driver requests four mapping registers, then places the physical addresses of these pages in the mapping registers. Assume the driver has allocated four mapping registers, 127 through 130. The driver loads them as follows: Mapping Contents Register (Physical Address) 127 1003 128 204 129 1190 130 240 The device and the UNIBUS can transfer data into or out of these physical pages without intervention by the driver. The device requests an interrupt only when all the data in these four pages have been transferred. 8 The MicroVAX I Q-bus has no data paths and no mapping registers, so drivers of MicroVAX I Q-bus devices must use a different strategy from the one UNIBUS drivers use. The lack of data paths does not require Q-bus drivers to take any special action; the lack of mapping registers does. The Q-bus device must use physical addresses to access the pages in the user's buffer. Because the device has no mapping registers, the buffer's physical pages must be contiguous. There is no guarantee that this is the state of the user's buffer. So the driver must allocate an intermediate buffer consisting of contiguous physical pages. The driver never deallocates this buffer unless the driver is being unloaded (by means of SYSGEN's UNLOAD command.) The best time to allocate such a buffer is during the device's initialization. Unallocated non-paged pool is contiguous at that time. Later it will be much more difficult to obtain a buffer that is physically contiguous. To be sure that the buffer you allocate to the driver is contiguous, use the VAX/VMS routine EXE$ALOPHYCNTG. This routine, defined in module MEMORYALC, expects R1 to contain the number of physically contiguous pages to allocate. This routine must be called at IPL$_SYNCH. When EXE$ALOPHYCNTG returns control to its caller, R0 contains a status code (SUCCESS, ISSFMEM, or INSFSPTS), and, if the allocation succeeds, R2 contains the system virtual address of the first allocated block. It preserves the contents of all other registers, and returns control to its caller at the caller's IPL. The size of the buffer must depend on the device's characteristics and the size of the transfers requested on the device. A buffer of four pages is likely to be large enough for most disk transfers, for example; but if you have enough memory on your system, you might want to make your buffer the size of a disk track in order to reduce disk latency. In any event, large transfers to the device can be segmented into transfers the size of your intermediate buffer. When a user requests a transfer to a MicroVAX I Q-bus device, the driver copies the data from the user's buffer into the intermediate, physically contiguous buffer by means of the routine IOC$MOVFRUSER. The driver then sets up the device for the DMA transfer from the intermediate, physically contiguous buffer to the device, and starts the device. When a user requests a transfer from a MicroVAX I Q-bus device, the driver moves the data from the device to the intermediate, physically contiguous buffer by means of a DMA transfer, then calls IOC$MOVTOUSER to copy the data into the user's buffer. 9