opae.io¶
SYNOPSIS¶
opae.io ls [-v,--viddid VID:DID]
opae.io init [-d PCI_ADDR USER[:GROUP]]
opae.io release [-d PCI_ADDR]
opae.io [-d PCI_ADDR] [-r REGION] walk OFFSET [-u,--show-uuid]
opae.io [-d PCI_ADDR] [-r REGION] peek OFFSET
opae.io [-d PCI_ADDR] [-r REGION] poke OFFSET VALUE
opae.io [-d PCI_ADDR] [-r REGION] SCRIPT ARG1 ARG2 ... ARGN
opae.io [-d PCI_ADDR] [-r REGION]
DESCRIPTION¶
opae.io is an interactive Python environment packaged on top of
libopaevfio.so, which provides user space access to PCIe devices
via the vfio-pci driver. The main feature of opae.io is its built-in
Python command interpreter, along with some Python bindings that provide
a means to access Configuration and Status Registers (CSRs) that reside
on the PCIe device.
opae.io has two operating modes: command line mode and interactive
mode.
COMMAND LINE MODE¶
To view the accelerator devices that are present on the system, opae.io
provides the ls command option.
opae.io ls [-v,--viddid VID:DID]
Each accelerator device is listed along with the PCIe address, the PCIe vendor/device ID, a brief description of the device, and the driver to which the device is currently bound.
opae.io provide an option to initialize a PCIe device for use with
the vfio-pci driver. In order for the device CSRs to be accessed from
user space, the device must first be bound to the vfio-pci driver. This
is the job of the init command option.
opae.io init [-d PCI_ADDR USER:[GROUP]]
The init command unbinds the specified device from its current
driver and binds it to vfio-pci. This creates a new vfio group under
/dev/vfio. This group path is then used by the libopaevfio.so
library to interact with the device.
To release the PCIe device from vfio-pci and return it to use with its
previous driver, the release command option is used.
opae.io release [-d PCI_ADDR]
The release command option reverses the actions of the last
init command, releasing the device from vfio-pci and binding
it to the driver which was bound at the time the init command
was issued.
The walk command option traverses and displays the Device
Feature List of the given region.
opae.io walk [-d PCI_ADDR] [-r REGION] [OFFSET] [-u,--show-uuid]
The various fields of each Device Feature Header are displayed. The
--show-uuid option additionally displays the GUID for each feature.
OFFSET can be used to specify the beginning of the DFL in the MMIO
region.
The peek command option reads and displays a CSR value.
opae.io peek [-d PCI_ADDR] [-r REGION] OFFSET
The poke command option writes a given value to a CSR.
opae.io poke [-d PCI_ADDR] [-r REGION] OFFSET VALUE
opae.io can also execute Python scripts from the command line.
These Python scripts may contain calls to the device built-in
functions that are available during an interactive session. Refer
to the description of interactive mode for details.
opae.io [-d PCI_ADDR] [-r REGION] myscript.py a b c
In order to enter the interactive mode of opae.io, simply
invoke it and optionally pass the desired device address and
MMIO region options.
opae.io [-d PCI_ADDR] [-r REGION]
INTERACTIVE MODE¶
Upon entering interactive mode, opae.io begins a Python
interpreter session and displays the command prompt shown below:
0000:3f:00.0[0]>>
The first portion of the prompt shows the address of the active PCIe device, here 0000:3f:00.0. The part in square brackets shows the active MMIO region, here [0].
The interpreter waits for a valid Python command, then attempts
to execute the given command in the usual way. The only
differences between the traditional Python command intepreter and
opae.io are that opae.io provides 1) the notion of an active
PCIe device and MMIO region and 2) several built-in functions and
objects that allow manipulating the active device and MMIO region.
BUILT-IN FUNCTIONS¶
The opae.io built-in functions assume an active device and
MMIO region. Attempting to use the built-in functions without first
opening a device and region will result in errors.
peek(OFFSET)
The peek built-in function reads and displays a CSR value from
the active device and region, at the offset supplied by its argument.
0000:3f:00.0[0]>> peek(0x28)
0xdeadbeef
poke(OFFSET, VALUE)
The poke built-in function writes the given VALUE to the current
MMIO region at the given OFFSET.
0000:3f:00.0[0]>> poke(0x28, 0xdeadbeef)
read_csr(OFFSET)
The read_csr built-in function returns the value of the CSR at
the active MMIO region and the given OFFSET.
0000:3f:00.0[0]>> print(‘0x{:0x}’.format(read_csr(0x28)))
0xdeadbeef
write_csr(OFFSET, VALUE)
The write_csr built-in function writes the given VALUE to
the current MMIO region at the given OFFSET.
0000:3f:00.0[0]>> write_csr(0x28, 0xdeadbeef)
device(PCI_ADDR)
The device built-in function allows changing the active
PCIe device.
0000:3f:00.0[0]>> device(‘0000:2b:00.0’)
0000:2b:00.0>>
region(REGION)
The region built-in function allows changing the active
MMIO region.
0000:2b:00.0>> region(0)
0000:2b:00.0[0]>>
allocate_buffer(SIZE)
The allocate_buffer built-in function creates and returns
a DMA buffer object. The underlying buffer will be SIZE bytes
in length.
0000:2b:00.0[0]>> b1 = allocate_buffer(4096)
0000:2b:00.0[0]>> print(b1.size, ‘0x{:0x}’.format(b1.address), b1.io_address)
4096 0x7f9361c66000 0
version()
The version built-in function returns a tuple containing
the four components used to identify the opae.io version:
0000:2b:00.0[0]>> print(version())
(‘opae.io’, 0, 2, 0)
BUILT-IN OBJECTS¶
opae.io interactive mode provides two global objects
corresponding to the current device and that device’s current
MMIO region. These objects are referred to by global variables
the_device and the_region, respectively.
The device class:
the_device.descriptor() : method that returns the integer file
descriptor of the VFIO container.
0000:2b:00.0[0]>> print(the_device.descriptor())
5
the_device.repr() : method that is invoked when a device
object is printed.
0000:2b:00.0[0]>> print(the_device)
0000:2b:00.0
the_device.allocate(SIZE) : method that allocates and returns a
system_buffer object. The buffer will be mapped into the
DMA space of the_device.
0000:2b:00.0[0]>> b1 = the_device.allocate(4096)
the_device.pci_address() : read-only property that returns the
PCIe address of the_device.
0000:2b:00.0[0]>> print(the_device.pci_address)
0000:2b:00.0
the_device.num_regions : read-only property that returns the
number of MMIO regions in the_device.
0000:2b:00.0[0]>> print(the_device.num_regions)
2
the_device.regions : read-only property that returns a list
of the active MMIO regions of the_device:
0000:2b:00.0[0]>> print(the_device.regions)
[0, 2]
The region class:
the_region.write32(OFFSET, VALUE) : method that writes a 32-bit VALUE to the CSR at OFFSET.
the_region.read32(OFFSET) : method that returns a 32-bit CSR at the given OFFSET.
0000:2b:00.0[0]>> the_region.write32(0x28, 0xdeadbeef)
0000:2b:00.0[0]>> print(‘0x{:0x}’.format(the_region.read32(0x28)))
0xdeadbeef
the_region.write64(OFFSET, VALUE): method that writes a 64-bit VALUE to the CSR at OFFSET.
the_region.read64(OFFSET): method that returns a 64-bit CSR at the given OFFSET.
0000:2b:00.0[0]>> the_region.write64(0x28, 0xbaddecaf)
0000:2b:00.0[0]>> print(‘0x{:0x}’.format(the_region.read64(0x28)))
0xbaddecaf
the_region.index(): method that returns the MMIO index
of the_region.
0000:2b:00.0[0]>> print(the_region.index())
0
the_region.repr(): method that is invoked when a region
object is printed.
0000:2b:00.0[0]>> print(the_region)
0
the_region.len(): method that is invoked to determine the MMIO region size.
0000:2b:00.0[0]>> print(len(the_region))
524288
The allocate_buffer() built-in function and the
device.allocate() method return objects of type system_buffer.
The system_buffer class is as follows:
buf.size: read-only property that gives the buffer size.
0000:2b:00.0[0]>> print(b1.size)
4096
buf.address: read-only property that gives the buffer’s
user mode virtual address.
0000:2b:00.0[0]>> print(‘0x{:0x}’.format(b1.address))
0x7f2c15d8200
buf.io_address: read-only property that gives the buffer’s
IO address.
0000:2b:00.0[0]>> print(‘0x{:0x}’.format(b1.io_address))
0x0
buf.__getitem__ and buf.__setitem__: indexing get/set
of 64-bit data item.
0000:2b:00.0[0]>> b1[0] = 0xdecafbad
0000:2b:00.0[0]>> print(‘0x{:0x}’.format(b1[0]))
0xdecafbad
buf.read8(OFFSET)
buf.read16(OFFSET)
buf.read32(OFFSET)
buf.read64(OFFSET) : methods that read the given size
data item from the given buffer OFFSET.
buf.fill8(VALUE)
buf.fill16(VALUE)
buf.fill32(VALUE)
buf.fill64(VALUE) : methods that fill the buffer with
the given VALUE, using the given size.
b1.compare(b2): method that compares buffers.
The method returns the index of the first byte that miscompares,
or the length of b1.
Revision History¶
Document Version | Intel Acceleration Stack Version | Changes —————–|———————————-|——– 2021.01.25 | IOFS EA | Initial release.