Specifications
PCI Bus Support
13.8 Finding the PCI Physical Addresses Assigned to a Device
These routines acquire the MCHECK spinlock (raising IPL to 31) to assure that
they are single threaded. This is necessary because Configuration Space access
involves manipulation of hardware registers in the host PCI interface. You must
use these routines to access Configuration Space. Do not be tempted to use the
Config Space base VA from the bus array. Also note that IOC$WRITE_PCI_
CONFIG issues a memory barrier instruction.
These routines do not do any byte lane alignment of the data. For reads, data
is returned in its natural byte lane. For writes, data must be positioned in its
natural byte lane. In this context, natural byte lane means:
31 24 23 16 15 8 7 0
+----------+----------+----------+----------+
| byte 3 | byte 2 | byte 1 | byte 0 |
+----------+----------+----------+----------+
This means, for example, if you read a field of length 2 bytes from offset 2 in the
Configuration Space header, the data will be returned in bits 31:16.
You should use IOC$READ_PCI_CONFIG to read the PCI physical address
from the Base Address register(s) in your device’s Configuration Space.
Your device specification should indicate which Base Address registers are
actually implemented by your device, and should give you their offsets in the
Configuration Space header for the device.
The following example shows a call to IOC$READ_PCI_CONFIG that reads the
Vendor ID from PCI configuration space:
int vendor_id;
int status;
status = ioc$read_pci_config (pci_adp,
crb->crb$l_node,
0, /* vendor id offset */
2, /* vendor id is 2 bytes */
&vendor_id);
The vendor ID will be returned in bits 15:0 of the vendor_id longword (the Vendor
ID is a 2 byte field starting at Configuration Space offset 0).
13.9 Mapping a PCI Physical Address
Once you have obtained the PCI physical address, you must map it into the
processor’s virtual address space.
The correspondence between PCI physical address and platform physical address
is different depending on whether you want the address to be mapped in PCI I/O
space, PCI swizzled memory space, or PCI dense memory space. The platform
physical address regions corresponding to each of the PCI address spaces are
different from platform to platform. In order to abstract these differences,
OpenVMS AXP provides a platform independent I/O bus mapping routine called
IOC$MAP_IO. IOC$MAP_IO allows a programmer to express a mapping request
in terms of the device and desired access characteristics, without regard to the
underlying platform address map and address tricks. The prototype for the
IOC$MAP_IO routine is as follows:
int ioc$map_io (ADP *adp,
int node,
uint64 *physical_offset,
int num_bytes,
int attributes,
uint64 *iohandle)
13–6