PMAP(4)

NAME
pmap - map physical addresses into process's virtual address space

SYNOPSIS
pseudo-device pmap

DESCRIPTION
The pmap device driver is used in conjuction with the mmap(2) system call to map arbitrary physical addresses into a process's virtual address space. The driver supports 65535 minor devices, each of which represents a specified region of the physical address space. The region associated with each device is defined at kernel build time in the file /sys/conf/conf_pmap.c, and can be altered at run time by the superuser via the pmap(8) utility or the ioctls described in this manual entry. By default, the first 64 minor devices are associated with the files alm00 through alm63 in the /dev/alm directory. These files correspond to 64 1-Kbyte regions that make up Atomic Lock Memory on MULTIBUS adapter board 0. Atomic Lock Memory provides a hardware-based mutual exclusion facility for user-level programs, and is described in the Balance 8000 Guide to Parallel Programming.

The pmap driver can support both physical devices (such as MULTIBUS address space, including Atomic Lock Memory) and non-paged memory devices (such as special areas of memory reserved for accelerators).

In /sys/conf/conf_pmap.c, the boot-time parameters of the minor devices are defined as an array of struct pmap_unit, which is defined as follows:

struct	pmap_unit {
	u_long		pm_paddr;	/* start physical (byte) address */
	u_long		pm_size;	/* size (in physical pages) */
	u_char		pm_flags;	/* flags (see below) */
	<other fields>			/* not user visible, initially zero */
};

The pm_paddr field must be a multiple of the system page size (see getpagesize(2)), and the pm_size field must be a multiple of (system page size)/(hardware page size). The hardware page size is defined as NBPG in /usr/include/machine/param.h. There are three flags:

#define	PMAP_EXCL	0x01	/* exclusive access */
#define	PMAP_MAPPED	0x02	/* is currently mapped */
#define	PMAP_NPMEM	0x04	/* non-paged memory, else physical */

The PMAP_EXCL and PMAP_MAPPED flags should not be set in conf_pmap.c. PMAP_NPMEM should be set if the associated device is of the non-paged memory variety. However, these requirements are not checked.

There is no read or write system call interface to this driver.

IOCTLS
The pmap driver supports the following ioctls. (Refer to /usr/include/sys/ioctl.h for information on ioctl calling parameters.) Some ioctls use the following structure, which is defined in /usr/include/machine/pmap.h:

struct	pmap_ioc {
	u_long	pi_paddr;	/* start physical (byte) address */
	u_long	pi_size;	/* size (bytes) */
	u_char	pi_flags;	/* flags (see above) */
};

Note that in the pmap_ioc structure, the size is specified in bytes, while in the pmap_unit structure it is specified in hardware pages.

ioctl(fd, PMAPIOCGETP, pmap_data)
int		fd;
struct	pmap_ioc *pmap_data;

Returns the current parameters from the pmap_unit table for the open unit referenced by fd. Any process can execute this call. EFAULT results for unreasonable values of pmap_data. The flags bits are as defined above: PMAP_MAPPED tells if the unit is currently mapped, PMAP_EXCL indicates that exclusive use is currently in effect, and PMAP_NPMEM indicates that fd is configured as a non-paged memory device.

ioctl(fd, PMAPIOCSETP, pmap_data)
int		fd;
struct	pmap_ioc *pmap_data;

PMAPIOCSETP allows a root process to set entries in the driver's pmap_unit table. EPERM results if the caller is not root. EFAULT results for unreasonable values of pmap_data. EBUSY results if the unit is mapped at the time of this call. EINVAL results if pi_paddr or pi_size is not a multiple of the system page size. The driver cannot verify the legality of the physical addresses passed in: user beware.

Only the PMAP_NPMEM flag bit is copied from pi_flags to pm_flags. Use PMAPIOCEXCL or PMAPIOCNXCL to set or clear the PMAP_EXCL bit.

NOTE: This ioctl allows the superuser to associate a file with any range of physical addresses, including MULTIBUS mapping registers, nonexistent memory, etc. Specifying incorrect values for pi_paddr or pi_size can lead to catastrophic results.

ioctl(fd, PMAPIOCEXCL, 0)
int	fd;

PMAPIOCEXCL verifies that there is at most one open at the time of the ioctl, and ensures that no further (non-superuser) opens are allowed on the unit until it is closed or the PMAPIOCNXCL ioctl is called. PMAPIOCEXCL fails (returning EBUSY) if there is already more than one open. Any process may execute this call. Note that the semantics are similar, but not identical, to TIOCEXCL in the terminal driver.

ioctl(fd, PMAPIOCNXCL, 0)
int	fd;

PMAPIOCNXCL disables exclusive use of the unit, thus allowing further opens. Any process may execute this call.

SEE ALSO
mmap(2), pmap(8), getpagesize(2), Guide to Parallel Programming