pci_device_map_as()

Updated: April 19, 2023

Get the translation between CPU memory addresses and PCI addresses

Synopsis:

#include <pci/pci.h>

pci_err_t pci_device_map_as( pci_devhdl_t hdl,
                             const pci_ba_t * const as,
                             pci_ba_t *as_xlate );

Arguments:

hdl
The handle of the device, obtained by calling pci_device_attach().
as
A pointer to a pci_ba_t structure that describes the address space.
as_xlate
A pointer to a pci_ba_t structure where the function can store the translation.

Library:

libpci

Use the -l pci option to qcc to link against this library.

Description:

The pci_device_map_as() function is used by driver software to obtain the required translations between CPU memory addresses and PCI addresses. It's used (for example) when you've allocated a set of memory buffers that a PCI device should transfer in to. In this case, you need to program the PCI device with the inbound physical addresses of the memory buffers, but depending on how the hardware is configured, there may be translation hardware that maps the PCI address that must be targeted in order to resolve to the memory buffer addresses.

You should always call this function in this or any other similar scenario. If there's no translation required, as_xlate will effectively be the same as as.

The pci_ba_t structure is defined as follows:

typedef struct
{
        pci_ba_val_t addr;
        uint64_t size;
        pci_asType_e type;
        pci_asAttr_e attr;
        int_t bar_num;
} pci_ba_t;

The members include:

addr
The physical address of a memory buffer.
size
The size of the buffer, in bytes.
type
One of the following:
  • pci_asType_e_NONE
  • pci_asType_e_MEM
  • pci_asType_e_IO
attr
A bitwise OR of attribute flags. You must specify one of the following:
  • pci_asAttr_e_INBOUND — transfers from PCI space to CPU space.
  • pci_asAttr_e_OUTBOUND — transfers from CPU space to PCI space. You generally don't need this type of translation.

You can also OR in any of the following:

  • pci_asAttr_e_16BIT, pci_asAttr_e_32BIT, pci_asAttr_e_64BIT — a 2-bit field that indicates whether to encode the address space size as 16, 32, or 64 bit.
  • pci_asAttr_e_PREFETCH
  • pci_asAttr_e_CONTIG
  • pci_asAttr_e_EXPANSION_ROM
  • pci_asAttr_e_ENABLED — applicable to expansion ROM.
  • pci_asAttr_e_SHARED — otherwise reserved (applicable to slot aspace reservations).
bar_num
The Base Address Register number.

The as attributes (defined in <pci/pci.h> as type pci_asAttr_e) should fully specify in the as->attr field whether the driver is requesting translation for an outbound transfer (from CPU memory to PCI device) or inbound transfer (from PCI device to CPU memory). You should also specify other attributes, such as pci_asAttr_e_CONTIG, the alignment requirements, and so on. In addition to the as->attr field, you should also properly initialize the type, size, and addr fields. Note that all addresses are specified as physical addresses.

Returns:

PCI_ERR_OK
Success.
PCI_ERR_ENODEV
The device identified by hdl doesn't exist. Note that this error can also be returned if a device that supports live removal is removed after a successful call to pci_device_find().
PCI_ERR_EINVAL
The hdl doesn't refer to a valid device that you attached to, or other parameters are otherwise invalid. This error can also be returned from the hardware-dependent module.
PCI_ERR_ASPACE_INVALID
The address provided couldn't be translated into usable values.

If any error occurs, you should assume that storage you provided for as_xlate contains invalid data.

Classification:

QNX Neutrino

Safety:  
Cancellation point No
Interrupt handler No
Signal handler No
Thread Yes