pci-tool

Updated: April 19, 2023

Display PCI information

Note: You must be root in order to use this utility.

Syntax:

Interactive mode:

pci-tool -i [-M]

Non-interactive mode:

pci-tool [-C class[,subclass][,reg_if]] [-D device_id] [-d Bx:Dy:Fz | Bx:Fz]
         [-r reset_type] [-t] [-V vendor_id] [-v[v[v[v[...]]]]] [--full]
         [--read=CFG|BARn:offset_from[-offset_to][,size]] [--reset=reset_type]
         [--write=CFG|BARn:offset_from[-offset_to][,size][&|]=[~]value]
         [--strip] 

Runs on:

QNX Neutrino

Options:

-C class[,subclass][,reg_if]
Display all devices with the specified class, subclass, and register interface values. The subclass and register interface are optional, in which case all subclass and register interface values match. You can independently use -1 as a wildcard for the subclass and register interface; for example -C 0x10,-1,1 displays all devices of class 16 and register interface 1.
-D device_id
Display all devices with the specified device ID (e.g., 0x1234).
-d Bx:Dy:Fz | Bx:Fz
Select a specific device to display using the Bus:Device:Function numbers Bx, Dy, and Fz for normal PCI devices, or Bus:Function numbers Bx and Fz for ARI devices, respectively.
-i
Use interactive mode. Any other options are ignored.

If you're using interactive mode, you can use h or ? at any time to get help. The help menu also provides any context-specific functionality that's available (e.g., reset or virtual hot plug).

If you specify -i, you can also use the following suboption:

  • -M — use monitor mode; update the display every 100 msec. Using this mode puts a constant load on the system, but it's useful for monitoring device state changes.
    Note:
    • Any cursor movement causes states to be updated.
    • Events such as topology changes related to live insertion and removal don't require monitor mode if the appropriate server modules are loaded.
    • You can use the m command to toggle monitor mode on and off while the tool is running, but the -M option must be present for monitor mode to function at all.
-r reset_type or --reset=reset_type
Issue the specified reset_type to the device identified with the -d option.
Note: Use this option with caution, because it can affect more than just the identified device. For more information, see the entry for pci_device_reset() in the PCI Server User's Guide.

The reset_type can be one of the following:

  • 1 or bus to issue a reset of type pci_resetType_e_BUS
  • 2 or function to issue a reset of type pci_resetType_e_FUNCTION
  • 3 and above to issue a hardware-specific reset. See the use information in the hardware module for your platform for the supported reset types.
-t
Display the device topology (hierarchy); produce an indented output that highlights the hierarchical relationship of devices. You can use ths in conjunction with other selection options.
-V vendor_id
Display all devices with the specified vendor ID (e.g., 0x8086).
-v[v[v[v[...]]]
Cumulatively increase the verbosity of displayed detail.

The fifth v causes the device-specific configuration space to be dumped. You can control the format of the dumped value by specifying a ,1, ,2, or ,4 after the fifth v in order to dump the registers as 8, 16 or 32 bits. The default is 32 bits. For example:

pci-tool -vvvvv,2    (works)
pci-tool -vv -vvv,2  (works)
pci-tool -vvv,2 -vv  (doesn't work)
--full
Normally, when registers or memory are displayed with either the -vvvvv (5 v characters) or --read options, duplicate lines are filtered so that the output is more concise. If you wish the full contents to be displayed, include this qualifier in conjunction with these options.
--read=CFG|BARn:offset_from[-offset_to][,size]
--write=CFG|BARn:offset_from[-offset_to][,size][&|]=[~]value
Access to a device's configuration space registers (with CFG) and memory and I/O spaces (with BARn). The case of the CFG and BAR address space designators is ignored. See also the --full option.

The -d option is required in order to specify the device to access. For read/write accesses, you can specify only one device per invocation of pci-tool.

You can specify these options multiple times; they're performed in the order specified, but all accesses are performed on the same device (specified with the -d option).

To specify the size of the access, include a comma (,) followed by a size value of 1, 2 or 4 to access as 8-, 16- or 32-bit, respectively. If you don't specify a size, 32-bit accesses are performed.

You can specify a range of accesses by providing a hyphen (-) and an offset_to parameter. All offsets must be size bytes-aligned, or the entire argument is ignored. The offset_from may be less than offset_to, but all offsets must be positive values and lie within the range of the corresponding address space when size is taken into account.

For example, to display the entire configuration space for a PCI and PCIe device respectively (the later in reverse order), the following command line arguments are valid:

  • PCI device: pci-tool -d0:1:0 --read=CFG:0x0-0xFE,2
  • PCIe device: pci-tool -d0:2:0 --read=CFG:0xFFC-0x0
Note: All registers are accessed with the same access size.

For write accesses, identify the value to be written with the = operator. You can optionally use a & or | qualifier to implement AND and OR read-modify-write operations for which value is treated as a mask. You can additionally use an optional ~ character to specify the 1's complement of value. This can be useful for bit field modifications.

Note: If you use & or |, you'll likely need to enclose the entire parameter list in quotation marks in order to avoid having these symbols processed by the shell. For example, to set and clear bit 2 of a device;s command register:
--write="CFG:0x4,2|=4"
--write='CFG:0x4,2&=~4'
  

For CFG space accesses, offset_from and offset_to specify a register between 0 and 255 for PCI devices, or 0 and 4095 for PCIe devices.

Note: Take care when writing to configuration space registers, as incorrect values can have undesirable side effects on individual devices or the system as a whole.

For device address space accesses, BARn specifies the Base Address Register to use for the access. BARs are numbered 0 through 6, with values 0 through 5 specifying the standard 6 device BARs (only 0 and 1 apply to bridge devices), and value 6 specifying the ROM.

Specify the offset_from and offset_to parameters as an offset within the space, not as an absolute address. A range check is performed to ensure that the provided offset is within the range covered by the BAR. The appropriate access (MMIO or IO) is performed, depending on the address space type for the specified BAR.

Note: Take care when reading and writing the memory and I/O spaces of devices, as not only will incorrect written values have undesirable side effects, even read operations on some device registers could cause loss of data (clear-on-read registers have this behavior).

Other things to note:

  • All accesses are performed as individual size-width uncached operations.
  • Some registers and/or bits within registers may be read-only and therefore can't be modified.
  • You can specify the offset, size, n, and value paremeters in any radix.
--strip
This option is intended to assist with scripting. When you use pci-tool to list devices (whether using search criteria or not), the output is of the form:

Bxxx:Dyy:Fzz @ idx n

The --strip option removes the B, D, and F from the output, so that you can use the result as input to another invocation of pci-tool with the -d option in order to act on a specific instance of a device.

For example, let's say that we have a system with 4 PCI-to-PCI bridges (specifically PCIe Root Ports), all with different device IDs, and we wish to clear the Bridge Control Register (at offset 0x3e) but only for the third instance of the device. Without needing to know the vendor or device IDs, we could use the class code as the search criteria to identify the devices, as follows:

pci-tool -C6,4,0

B000:D01:F00 @ idx 0
B000:D21:F00 @ idx 1
B000:D21:F01 @ idx 2
B000:D21:F02 @ idx 3
  

If we use the above command with the --strip option, we get:

pci-tool -C6,4,0 --strip

000:01:00 @ idx 0
000:21:00 @ idx 1
000:21:01 @ idx 2
000:21:02 @ idx 3
  

To select the third instance of this device, we can filter with a utility such as grep:

pci-tool -C6,4,0 --strip | grep "idx 2"

000:21:01 @ idx 2
  

and we can now send this output to another invocation of pci-tool in order to perform the desired operation:

pci-tool -d `pci-tool -C6,4,0 --strip | grep "idx 2"` --write=cfg:0x3e,2=0 
  

Description:

The pci-tool utility displays PCI information. This utility operates in these modes:

Unless otherwise stated, all numeric arguments can be provided in any base.

Interactive mode takes precedence. If you select it, only the listed interactive mode suboptions are applicable, and all others are ignored.

A note regarding the displayed idx value

The pci-tool utility displays an idx value for each device that it finds, based on the current search criteria. If the search criteria changes, the same device (BDF) may be found at a different idx value. For more information about the reporting of the idx value, see the entry for pci_device_find() in the PCI Server User's Guide. This is worth noting because:

Examples:

Here's some sample output from pci-tool:

B00:D00:F00 @ idx 0
B00:D01:F00 @ idx 1
B00:D07:F00 @ idx 2
B00:D07:F01 @ idx 3
B00:D07:F03 @ idx 4
B00:D07:F07 @ idx 5
B00:D15:F00 @ idx 6
B00:D16:F00 @ idx 7
B00:D17:F00 @ idx 8
B00:D21:F00 @ idx 9
B00:D21:F01 @ idx 10
B00:D21:F02 @ idx 11

If you specify the -v option, the output for the first device could look like this:

B00:D00:F00 @ idx 0
        vid/did: 8086/7190
                Intel Corporation, 82443BX/ZX 440BX/ZX AGPset Host Bridge
        class/subclass/reg: 06/00/00
                Host-to-PCI Bridge Device

If you specify -vv, the output for the first device could look like this:

B00:D00:F00 @ idx 0
        vid/did: 8086/7190
                Intel Corporation, 82443BX/ZX 440BX/ZX AGPset Host Bridge
        class/subclass/reg: 06/00/00
                Host-to-PCI Bridge Device
        revid: 1
        cmd/status registers: 6/200
        Capabilities: *
        Address Space list - 0 assigned
        Interrupt list - 0 assigned
        hdrType: 0
                ssid/ssvid: 1976/15ad

If you specify -vvvvv, the output for the first device could look like this:

B00:D00:F00 @ idx 0
        vid/did: 8086/7190
                Intel Corporation, 82443BX/ZX 440BX/ZX AGPset Host Bridge
        class/subclass/reg: 06/00/00
                Host-to-PCI Bridge Device
        revid: 1
        cmd/status registers: 6/200
        Capabilities: *
        Address Space list - 0 assigned
        Interrupt list - 0 assigned
        hdrType: 0
                ssid/ssvid: 1976/15ad

        Device Dependent Registers
                [40] 00001061  c8200008  00000000  00000000  
                [50] ff008008  00000000  01111003  11333000  
                [60] 20202010  20202020  00000000  00000000  
                [70] 00080000  00000000  00000000  00000000  
                [80] 00000000  00000000  00000000  00000000  
                  :
                [c0] 00000013  e0000001  00000000  00000000  
                [d0] 00000000  00000000  00000000  00000000  
                  :
                [f0] 00000000  00000000  00000000  00010000  

Exit status:

In non-interactive mode, the exit code is 0 if at least one device was found using the current search criteria. A nonzero value is returned otherwise. You can use the return code to determine whether or not specific BDFs exist.