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.