Next | Prev | Up | Top | Contents | Index

Using mmap

After you have reconfigured the system correctly, the user-level driver can open the special file for a generic VME device /dev/vme/vme*. To map in the device, the user program must use the mmap() system call. For example:

#include "fcntl.h"
#include "sys/mman.h"
fd = open("/dev/vme/vme0a16s", O_RDWR);
addr = mmap(
         0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, off);
The mmap() routine maps len bytes starting at (VME-bus) address off to the user virtual address addr. The prot argument is a bit mask that indicates the protection that the operating system enforces on access to the device memory. Thus, PROT_WRITE allows writing; PROT_READ allows reading. The flags argument can be either MAP_PRIVATE or MAP_SHARED when used with hardware devices (currently, /dev/vme/vme* makes no distinction between the two). These symbolic constants are defined in sys/mman.h. See the mmap(D2) man page for further information on the use of this system call.

Once the mmap call succeeds, reads and writes from the user virtual address addr for a length of len bytes result in the appropriate reads and writes for the VME device pointed to by the file descriptor fd.

Note: There is protection on a page boundary only. Even if the user-level program maps in less than a page, the entire page of device registers remains accessible to the user program. Use getpagesize(2) to determine the page size of the system. The amount of VME address space that can be mapped into user address space depends on two factors:

For VME A16 address space, the entire 64 KB of A16-VME address space is mappable to user virtual address space.

For A24 address space, only 8 MB of the 16 MB of address space, starting at VME address 0x80000000, is mappable to the user virtual address space. The kernel reserves the remaining 8 MB of address space to support DMA transfers from A24 masters.

For A32 address space, there is some variation according to hardware platform.

CHALLENGE/Onyx systems support up to five VME buses. Users can map in a maximum of 96 MB of A32 address space on each VME bus.

Note: Mapping should be performed in 8 MB increments: Each mmap() system call can map a maximum of 8 MB of VME address space into user virtual address space, so eight such mmap() calls are needed to map the entire 96 MB of VME address space available. This 96 MB of VME address space is shared between the kernel and user-level device drivers. Any installed kernel-level VME device drivers that use VME address space reduce the amount of VME address space available for mapping by the user-level drivers.

On other IRIS platforms (IP5/7/9/17), a maximum of 256 MB can be mapped into user virtual address space. On these platforms, mmap() can support mapping in the entire 256 MB of VME address space in a single system call. On systems with dual VME buses, however, the amount of VME address space available for mapping is reduced by half.

See Appendix A for further details of what A32 address space is available for customer boards.


Accessing Mapped Space

VME accesses are sensitive to the access size, so extra caution is called for once VME address space is mapped into a user's virtual space. For example, A16D8 boards may support only 8-bit accesses, while A16D16 boards may support both 8-bit and 16-bit accesses. Similarly, A32D32 may support only 32-bit accesses or may support 8-bit, 16-bit, 32-bit accesses. User-level device drivers should ensure that the data structures onto which the VME address space is mapped generate the proper size of transaction on the VME bus.


VME-bus Error Handling for User-level Device Drivers

Bus errors can occur when a read or write on the VME times out. This can be triggered by user-level drivers accessing a mapped VME space for which no controller exists, or if the controller fails to respond.

Caution: If the kernel cannot determine whether the bus error is harmless to the system, the system panics. Read Errors

If a VME-bus read error is triggered by a user-level VME driver, the driver process receives a SIGBUS signal. If the driver needs to be aware of the error, then it can catch the signal and take appropriate action. Read errors are synchronous, so the user process can get a definite idea of what PC or routine caused the error.

Write Errors

VME-bus write errors are asynchronous: when a user-level driver writes to the mapped VME address space, the CPU does not stall at that address, but continues executing further instructions. Since the write error time-out bus takes up to 80 microseconds on a VME bus and another finite amount of time for handling the error interrupt from the VME bus, handling write errors can be complicated.

A bad VME write error results in a SIGBUS signal being sent to the offending process, if that process is still running on the system. Since it takes a finite amount of time to send the signal to the user-level driver process that triggers a bad VME write, it is essential for the user-level driver to wait for up to 10 milliseconds before exiting. However, this is only necessary before exiting the system (to allow for the handling of the last few bad writes) or when the user process wants to assure that the write completed. It is not necessary to wait for 10 milliseconds after every VME write.


Next | Prev | Up | Top | Contents | Index