|
Packit |
534379 |
# OPAE C API Programming Guide #
|
|
Packit |
534379 |
|
|
Packit |
534379 |
.. toctree::
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Overview ##
|
|
Packit |
534379 |
The OPAE C library (*libopae-c*) is a lightweight user-space library that
|
|
Packit |
534379 |
provides abstractions for FPGA resources in a compute environment. The OPAE C library
|
|
Packit |
534379 |
builds on the driver stack that supports the FPGA device, abstracting
|
|
Packit |
534379 |
hardware- and OS-specific details. It provides access to the underlying FPGA
|
|
Packit |
534379 |
resources as a set of features available to software programs
|
|
Packit |
534379 |
running on the host. These features include the acceleration logic
|
|
Packit |
534379 |
preconfigured on the FPGA and functions to manage and reconfigure
|
|
Packit |
534379 |
the FPGA. The library enables your applications to
|
|
Packit |
534379 |
transparently and seamlessly benefit from FPGA-based acceleration.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
![Layered architecture](./FPGA-lib-1.png "A user space library built on top of FPGA driver stack")
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
By providing a unified C API, the library supports different FPGA
|
|
Packit |
534379 |
integration and deployment models, ranging from single-node systems with one or
|
|
Packit |
534379 |
a few FPGA devices to large-scale FPGA deployments in a data center.
|
|
Packit |
534379 |
At one end of the spectrum, the API supports a simple application using a PCIe link to reconfigure
|
|
Packit |
534379 |
the FPGA with different accelerator functions. At the other end of the spectrum, resource
|
|
Packit |
534379 |
management and orchestration services in a data center can use this API to
|
|
Packit |
534379 |
discover and select FPGA resources and then allocate them for use by acceleration workloads.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## OPAE Role ##
|
|
Packit |
534379 |
|
|
Packit |
534379 |
The OPAE provides a common base layer for a wide range of
|
|
Packit |
534379 |
applications without sacrificing performance or efficiency. The abstraction layer limits
|
|
Packit |
534379 |
the details of the FPGA hardware that software applications must handle.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
The OPAE provides consistent interfaces to crucial components of the platform. The OPAE does not constrain
|
|
Packit |
534379 |
frameworks and applications by making optimizations with limited applicability. When the OPAE does
|
|
Packit |
534379 |
provide convenience functions or optimizations, they are optional.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
For example, the OPAE provides an interface to allocate physically contiguous
|
|
Packit |
534379 |
buffers in system memory that user-space software and an accelerator can share.
|
|
Packit |
534379 |
This interface enables the most basic feature set of
|
|
Packit |
534379 |
allocating and sharing a large page of memory in one API call. However, it
|
|
Packit |
534379 |
does *not* provide a malloc()-like interface backed by a memory pool or slab
|
|
Packit |
534379 |
allocator. Higher layers of the software stack can make such
|
|
Packit |
534379 |
domain-specific optimizations.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Intel Accelerator Stack Hardware Terminology ##
|
|
Packit |
534379 |
|
|
Packit |
534379 |
The following terms define the hardware and hardware processes involved in creating an accelerator function.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
* FPGA: [Field Programmable Gate Array](https://en.wikipedia.org/wiki/Field-programmable_gate_array)
|
|
Packit |
534379 |
is a discrete or integrated device connecting to a host CPU via PCIe or other type of interconnects.
|
|
Packit |
534379 |
* Accelerator Function Unit (AFU): The AFU is the supplied implementation of an accelerator, typically
|
|
Packit |
534379 |
in HDL. AFUs implement a function such as compression, encryption, or mathematical operations.
|
|
Packit |
534379 |
The Quartus Prime Pro software synthesizes the RTL logic into a bitstream.
|
|
Packit |
534379 |
* Accelerator Function (AF): The AF is the compiled binary for an AFU. An AF is a raw binary file (.rbf)
|
|
Packit |
534379 |
bitstream. A tool (_fpgaconf_) reconfigures the FPGA using an AF bitstream.
|
|
Packit |
534379 |
* Reconfiguration: The process of reprogramming the FPGA with a different AF.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## OPAE Software Concepts Reflected in the C API ##
|
|
Packit |
534379 |
|
|
Packit |
534379 |
The following OPAE data structures and functions integrate AFUs into the OPAE environment.
|
|
Packit |
534379 |
The OPAE C API models these data structures and functions. For more information on the object
|
|
Packit |
534379 |
models refer to the [Object model](#object-models) section.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
* Accelerator: An accelerator is an allocable accelerator function implemented in an FPGA.
|
|
Packit |
534379 |
An accelerator tracks the _ownership_ of an AFU (or part of it) for a process that uses it.
|
|
Packit |
534379 |
Multiple processes can share an accelerator.
|
|
Packit |
534379 |
* Device: The OPAE enumerates and models two device types: the FPGA and the AFU.
|
|
Packit |
534379 |
* Events: Events are asynchronous notifications. The FPGA driver
|
|
Packit |
534379 |
triggers particular events to indicate error conditions. Accelerator logic can also
|
|
Packit |
534379 |
define its own events. User applications can choose to be
|
|
Packit |
534379 |
notified when particular events occur and respond appropriately.
|
|
Packit |
534379 |
* Shared memory buffers: Software allocates shared memory buffers in user process memory
|
|
Packit |
534379 |
on the host. Shared memory buffers facilitate data transfers between the user process and the
|
|
Packit |
534379 |
accelerator that it owns.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## OPAE Library ##
|
|
Packit |
534379 |
Linking with this library is straightforward.
|
|
Packit |
534379 |
Code using the OPAE library should include the header file `fpga.h`. Taking the GCC
|
|
Packit |
534379 |
compiler on Linux as an example, here is the simplest compile and link command:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
`gcc myprog.c -I</path/to/fpga.h> -L</path/to/libopae-c.so> -lopae-c -luuid -ljson-c -lpthread`
|
|
Packit |
534379 |
|
|
Packit |
534379 |
.. note::
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
The OPAE library uses the third-party `libuuid` and `libjson-c` libraries that are not distributed with
|
|
Packit |
534379 |
the OPAE library. Make sure to install these libraries.
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Sample Code ##
|
|
Packit |
534379 |
The library source includes two code samples. Use these samples
|
|
Packit |
534379 |
to learn how to call functions in the library. Build and run these samples
|
|
Packit |
534379 |
to determine if your installation and environment are set up properly.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
Refer to the [Running the Hello FPGA Example](https://www.altera.com/content/altera-www/global/en_us/index/documentation/dnv1485190478614.html#vks1498593668425) chapter in the _Intel® Acceleration Stack
|
|
Packit |
534379 |
Quick Start Guide for for Intel Programmable Acceleration Card with Intel Arria® 10 GX FPGA_ for more information about using the sample code.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## High-Level Directory Structure ##
|
|
Packit |
534379 |
Building and installing the OPAE library results in the following directory structure on the Linux OS.
|
|
Packit |
534379 |
Windows and MacOS have similar directories and files.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|Directory & Files |Contents |
|
|
Packit |
534379 |
|------------------|---------|
|
|
Packit |
534379 |
|include/opae |Directory containing all header files|
|
|
Packit |
534379 |
|include/opae/fpga.h |Top-level header for user code to include|
|
|
Packit |
534379 |
|include/opae/access.h |Header file for accelerator acquire/release, MMIO, memory management, event handling, and so on |
|
|
Packit |
534379 |
|include/opae/bitstream.h |Header file for bitstream manipulation functions |
|
|
Packit |
534379 |
|include/opae/common.h |Header file for error reporting functions |
|
|
Packit |
534379 |
|include/opae/enum.h |Header file for AFU enumeration functions |
|
|
Packit |
534379 |
|include/opae/manage.h |Header file for FPGA management functions |
|
|
Packit |
534379 |
|include/opae/types.h |Various type definitions |
|
|
Packit |
534379 |
|lib |Directory containing shared library files |
|
|
Packit |
534379 |
|lib/libopae-c.so |The shared dynamic library for linking with the user application |
|
|
Packit |
534379 |
|doc |Directory containing API documentation |
|
|
Packit |
534379 |
|doc/html |Directory for documentation of HTML format
|
|
Packit |
534379 |
|doc/latex |Directory for documentation of LaTex format
|
|
Packit |
534379 |
|doc/man |Directory for documentation of Unix man page format
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Basic Application Flow ##
|
|
Packit |
534379 |
The figure below shows the basic application flow from the
|
|
Packit |
534379 |
viewpoint of a user-process.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
![Basic flow](./FPGA-lib-3.PNG "Basic application flow")
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## API Components ##
|
|
Packit |
534379 |
The API object model abstracts the physical FPGA device and
|
|
Packit |
534379 |
available functions. It is a generalized model and extends to
|
|
Packit |
534379 |
describe any FPGA type.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
### Object Models ###
|
|
Packit |
534379 |
* `fpga_objtype`: An enum type that represents the type of an FPGA resource, either `FPGA_DEVICE` or `FPGA_ACCELERATOR`.
|
|
Packit |
534379 |
An `FPGA_DEVICE` object corresponds to a physical FPGA device. Only `FPGA_DEVICE` objects can invoke management functions.
|
|
Packit |
534379 |
The `FPGA_ACCELERATOR` represents an instance of an AFU.
|
|
Packit |
534379 |
* `fpga_token`: An opaque type that represents a resource known to, but not
|
|
Packit |
534379 |
necessarily owned by, the calling process. The calling process must own a
|
|
Packit |
534379 |
resource before it can invoke functions of the resource.
|
|
Packit |
534379 |
* `fpga_handle`: An opaque type that represents a resource owned by the
|
|
Packit |
534379 |
calling process. The API functions `fpgaOpen()` and `fpgaClose()` acquire and release ownership of a resource that an `fpga_handle` represents. (Refer to the [Functions](#functions) section for more information.)
|
|
Packit |
534379 |
* `fpga_properties`: An opaque type for a properties object. Your
|
|
Packit |
534379 |
applications use these properties to query and search for appropriate resources. The
|
|
Packit |
534379 |
[FPGA Resource Properties](#fpga-resource-properties) section documents properties visible to your
|
|
Packit |
534379 |
applications.
|
|
Packit |
534379 |
* `fpga_event_handle`: An opaque handle the FPGA driver uses to notify your
|
|
Packit |
534379 |
application about an event.
|
|
Packit |
534379 |
* `fpga_event_type`: An enum type that represents the types of events. The following are valid values:
|
|
Packit |
534379 |
`FPGA_EVENT_INTERRUPT`, `FPGA_EVENT_ERROR`, and `FPGA_EVENT_POWER_THERMAL`. (The Intel Programmable Acceleration Card (PAC) with
|
|
Packit |
534379 |
Intel Arria 10 GX FPGA does not handle thermal and power events.)
|
|
Packit |
534379 |
* `fpga_result`: An enum type to represent the result of an API function. If the
|
|
Packit |
534379 |
function returns successfully the result is `FPGA_OK`. Otherwise, the result is
|
|
Packit |
534379 |
the appropriate error codes. Function `fpgaErrStr()` translates an error code
|
|
Packit |
534379 |
into human-readable strings.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
### Functions ###
|
|
Packit |
534379 |
The table below groups important API calls by their functionality. For more information about each of the functions, refer to the
|
|
Packit |
534379 |
[OPAE C API reference manual](https://opae.github.io/0.13.0/docs/fpga_api/fpga_api.html).
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|Functionality |API Call |FPGA |Accelerator|Description |
|
|
Packit |
534379 |
|:--------|:----------|:-----:|:-----:|:-----------------------|
|
|
Packit |
534379 |
|Enumeration | ```fpgaEnumerate()``` |Yes| Yes| Query FPGA resources that match certain properties |
|
|
Packit |
534379 |
|Enumeration: Properties | ```fpga[Get, Update, Clear, Clone, Destroy Properties]()``` |Yes| Yes| Manage ```fpga_properties``` life cycle |
|
|
Packit |
534379 |
| | ```fpgaPropertiesGet[Prop]()``` | Yes| Yes|Get the specified property *Prop*, from the [FPGA Resource Properties](#fpga-resource-properties) table |
|
|
Packit |
534379 |
| | ```fpgaPropertiesSet[Prop]()``` | Yes| Yes|Set the specified property *Prop*, from the [FPGA Resource Properties](#fpga-resource-properties) table |
|
|
Packit |
534379 |
|Access: Ownership | ```fpga[Open, Close]()``` | Yes| Yes|Acquire/release ownership |
|
|
Packit |
534379 |
|Access: Reset | ```fpgaReset()``` |Yes| Yes| Reset an accelerator |
|
|
Packit |
534379 |
|Access: Event handling | ```fpga[Register, Unregister]Event()``` |Yes| Yes| Register/unregister an event to be notified about |
|
|
Packit |
534379 |
| | ```fpga[Create, Destroy]EventHandle()```|Yes| Yes| Manage ```fpga_event_handle``` life cycle |
|
|
Packit |
534379 |
|Access: UMsg | ```fpgaGetNumUmsg()```, ```fpgaSetUmsgAttributes()```, ```fpgaTriggerUmsg()```, ```fpgaGetUmsgPtr()``` | No|Yes| Low-latency accelerator notification mechanism.|
|
|
Packit |
534379 |
|Access: MMIO | ```fpgaMapMMIO()```, ```fpgaUnMapMMIO()``` |Yes| Yes| Map/unmap MMIO space |
|
|
Packit |
534379 |
| | ```fpgaGetMMIOInfo()``` |Yes| Yes| Get information about the specified MMIO space |
|
|
Packit |
534379 |
| | ```fpgaReadMMIO[32, 64]()``` | Yes| Yes|Read a 32-bit or 64-bit value from MMIO space |
|
|
Packit |
534379 |
| | ```fpgaWriteMMIO[32, 64]()``` |Yes| Yes| Write a 32-bit or 64-bit value to MMIO space |
|
|
Packit |
534379 |
|Memory management: Shared memory | ```fpga[Prepare, Release]Buffer()``` |Yes| Yes| Manage memory buffer shared between the calling process and an accelerator |
|
|
Packit |
534379 |
| | ```fpgaGetIOAddress()``` | Yes| Yes|Return the device I/O address of a shared memory buffer |
|
|
Packit |
534379 |
|Management: Reconfiguration | ```fpgaReconfigureSlot()``` | Yes | No | Replace an existing AFU with a new one |
|
|
Packit |
534379 |
|Error report | ```fpgaErrStr()``` | Yes| Yes|Map an error code to a human readable string |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
### FPGA Resource Properties ###
|
|
Packit |
534379 |
Applications query resource properties by specifying the property name for `Prop` in the
|
|
Packit |
534379 |
`fpgaPropertiesGet[Prop]()` and `fpgaPropertiesSet[Prop]()` functions. The FPGA and Accelerator
|
|
Packit |
534379 |
columns state whether or not the Property is available for the FPGA or Accelerator objects.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|Property |FPGA |Accelerator |Description |
|
|
Packit |
534379 |
|:---------|:-----:|:----:|:-----|
|
|
Packit |
534379 |
|Parent |No |Yes |`fpga_token` of the parent object |
|
|
Packit |
534379 |
|ObjectType |Yes |Yes |The type of the resource: either `FPGA_DEVICE` or `FPGA_ACCELERATOR` |
|
|
Packit |
534379 |
|Bus |Yes |Yes |The bus number |
|
|
Packit |
534379 |
|Device |Yes |Yes |The PCI device number |
|
|
Packit |
534379 |
|Function |Yes |Yes |The PCI function number |
|
|
Packit |
534379 |
|SocketId |Yes |Yes |The socket ID |
|
|
Packit |
534379 |
|DeviceId |Yes |Yes |The device ID |
|
|
Packit |
534379 |
|NumSlots |Yes |No |Number of AFU slots available on an `FPGA_DEVICE` resource |
|
|
Packit |
534379 |
|BBSID |Yes |No |The FPGA Interface Manager (FIM) ID of an `FPGA_DEVICE` resource |
|
|
Packit |
534379 |
|BBSVersion |Yes |No |The FIM version of an `FPGA_DEVICE` resource |
|
|
Packit |
534379 |
|VendorId |Yes |No |The vendor ID of an `FPGA_DEVICE` resource |
|
|
Packit |
534379 |
|Model |Yes |No |The model of an `FPGA_DEVICE` resource |
|
|
Packit |
534379 |
|LocalMemorySize |Yes |No |The local memory size of an `FPGA_DEVICE` resource |
|
|
Packit |
534379 |
|Capabilities |Yes |No |The capabilities of an `FPGA_DEVICE` resource |
|
|
Packit |
534379 |
|GUID |Yes |Yes |The GUID of an `FPGA_DEVICE` or `FPGA_ACCELERATOR` resource |
|
|
Packit |
534379 |
|NumMMIO |No |Yes |The number of MMIO space of an `FPGA_ACCELERATOR` resource |
|
|
Packit |
534379 |
|NumInterrupts |No |Yes |The number of interrupts of an `FPGA_ACCELERATOR` resource |
|
|
Packit |
534379 |
|AcceleratorState |No |Yes |The state of an `FPGA_ACCELERATOR` resource: either `FPGA_ACCELERATOR_ASSIGNED` or `FPGA_ACCELERATOR_UNASSIGNED`|
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## OPAE C API Return Codes ##
|
|
Packit |
534379 |
The OPAE C library returns a code for every exported public API function. `FPGA_OK` indicates successful completion
|
|
Packit |
534379 |
of the requested operation. Any return code other than `FPGA_OK` indicates an error or unexpected
|
|
Packit |
534379 |
behavior. When using the OPAE C API, always check the API return codes.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|Error Code|Description|
|
|
Packit |
534379 |
|----------|-----------|
|
|
Packit |
534379 |
|`FPGA_OK`|Operation completed successfully|
|
|
Packit |
534379 |
|`FPGA_INVALID_PARAM`|Invalid parameter supplied|
|
|
Packit |
534379 |
|`FPGA_BUSY`|Resource is busy|
|
|
Packit |
534379 |
|`FPGA_EXCEPTION`|An exception occurred|
|
|
Packit |
534379 |
|`FPGA_NOT_FOUND`|A required resource was not found|
|
|
Packit |
534379 |
|`FPGA_NO_MEMORY`|Not enough memory to complete operation|
|
|
Packit |
534379 |
|`FPGA_NOT_SUPPORTED`|Requested operation is not supported|
|
|
Packit |
534379 |
|`FPGA_NO_DRIVER`|Driver is not loaded|
|
|
Packit |
534379 |
|`FPGA_NO_DAEMON`|FPGA Daemon (`fpgad`) is not running|
|
|
Packit |
534379 |
|`FPGA_NO_ACCESS`|Insufficient privileges or permissions|
|
|
Packit |
534379 |
|`FPGA_RECONF_ERROR`|Error while reconfiguring FPGA|
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Usage Models ##
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
### Query and Search for a Resource ###
|
|
Packit |
534379 |
The user-code first populates an `fpga_properties` object with the required properties.
|
|
Packit |
534379 |
Then, `fpgaEnumerate()` searches for matching resources. `fpgaEnumerate()` may return more
|
|
Packit |
534379 |
than one matching resource.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include "fpga/fpga.h"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_guid guid;
|
|
Packit |
534379 |
fpga_properties filter = NULL;
|
|
Packit |
534379 |
fpga_result res;
|
|
Packit |
534379 |
fpga_token tokens[MAX_NUM_TOKENS];
|
|
Packit |
534379 |
uint32_t num_matches = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Start with an empty properties object */
|
|
Packit |
534379 |
res = fpgaGetProperties(NULL, &filter);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Populate the properties object with required values.
|
|
Packit |
534379 |
In this case, search for accelerators that matches
|
|
Packit |
534379 |
the specified GUID.
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
uuid_parse(GUID, guid);
|
|
Packit |
534379 |
res = fpgaPropertiesSetObjectType(filter, FPGA_ACCELERATOR);
|
|
Packit |
534379 |
res = fpgaPropertiesSetGuid(filter, guid);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Query the number of matching resources */
|
|
Packit |
534379 |
res = fpgaEnumerate(&filter, 1, NULL, 1, &num_matches);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Return tokens for all matching resources */
|
|
Packit |
534379 |
res = fpgaEnumerate(&filter, 1, tokens, num_matches, &num_matches);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Destroy the properties object */
|
|
Packit |
534379 |
res = fpgaDestroyProperties(&filter);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* More code */
|
|
Packit |
534379 |
......
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Destroy tokens */
|
|
Packit |
534379 |
for (uint32_t i = 0; i < num_matches; ++i) {
|
|
Packit |
534379 |
res = fpgaDestroyToken(tokens[i]);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
The ```fpgaEnumerate()``` function can take multiple ```fpga_properties```objects in an array. In such cases,
|
|
Packit |
534379 |
the function performs a logical OR of the properties object and returns resources that match any of
|
|
Packit |
534379 |
the multiple properties. The ```fpga_token``` objects that ```fpgaEnumerate()``` returns, do not signify
|
|
Packit |
534379 |
ownership. To acquire ownership of a resource represented by a token, pass the token to `fpgaOpen()`.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
### Acquire and Release a Resource ###
|
|
Packit |
534379 |
Use `fpgaOpen()` and `fpgaClose()` to acquire and release ownership of a resource.
|
|
Packit |
534379 |
The calling process must own the resource before it can initiate MMIO, access share memory buffers,
|
|
Packit |
534379 |
and use functions offered by the resource.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```c
|
|
Packit |
534379 |
#include "fpga/fpga.h"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_handle handle;
|
|
Packit |
534379 |
fpga_result res;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Acquire ownership of a resource that
|
|
Packit |
534379 |
`fpgaEnumerate()` previously returned as a token */
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaOpen(token, &handle);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* More code */
|
|
Packit |
534379 |
......
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Release the ownership */
|
|
Packit |
534379 |
res = fpgaClose(handle);
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
### Shared Memory Buffer ###
|
|
Packit |
534379 |
This code snippet shows how to prepare a memory buffer to be shared between the
|
|
Packit |
534379 |
calling process and an accelerator.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```c
|
|
Packit |
534379 |
#include "fpga/fpga.h"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_handle handle;
|
|
Packit |
534379 |
fpga_result res;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Hint for the virtual address of the buffer */
|
|
Packit |
534379 |
volatile uint64_t *addr_hint;
|
|
Packit |
534379 |
/* An ID we can use to reference the buffer later */
|
|
Packit |
534379 |
uint32_t bufid;
|
|
Packit |
534379 |
/* Flag to indicate whether or not the buffer is preallocated */
|
|
Packit |
534379 |
int flag = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Allocate (if necessary), pin, and map a buffer to be accessible
|
|
Packit |
534379 |
by an accelerator
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
res = fpgaPrepareBuffer(handle, BUF_SIZE, (void **) &addr_hint,
|
|
Packit |
534379 |
&bufid, flag);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* The actual address mapped to the buffer */
|
|
Packit |
534379 |
uint64_t iova;
|
|
Packit |
534379 |
/* Get the IO virtual address for the buffer */
|
|
Packit |
534379 |
res = fpgaGetIOAddress(handle, bufid, &iova);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Inform the accelerator about the virtual address by writing to its mapped
|
|
Packit |
534379 |
register file
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
......
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* More code */
|
|
Packit |
534379 |
......
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Release the shared buffer */
|
|
Packit |
534379 |
res = fpgaReleaseBuffer(handle, bufid);
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
.. note::
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
The `flag` variable can take a constant `FPGA_BUF_PREALLOCATED` to
|
|
Packit |
534379 |
indicate that the calling process has already allocated the address space
|
|
Packit |
534379 |
that `addr_hint` points to.
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
### MMIO ###
|
|
Packit |
534379 |
This code snippet shows how to map and unmap the register file of an accelerator into the
|
|
Packit |
534379 |
calling process's virtual memory space.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```c
|
|
Packit |
534379 |
#include "fpga/fpga.h"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_handle handle;
|
|
Packit |
534379 |
fpga_result res;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Index of the MMIO space. There might be multiple spaces on an accelerator */
|
|
Packit |
534379 |
uint32_t mmio_num = 0;
|
|
Packit |
534379 |
/* Mapped address */
|
|
Packit |
534379 |
uint64_t mmio_addr;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Map MMIO */
|
|
Packit |
534379 |
res = fpgaMapMMIO(handle, mmio_num, &mmio_addr);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Write to a 32-bit value to the mapped register file at a certain byte
|
|
Packit |
534379 |
offset.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
CSR_CTL is the offset in the mapped space to where the value will be
|
|
Packit |
534379 |
written. It's defined elsewhere.
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
res = fpgaWriteMMIO32(handle, mmio_num, CSR_CTL, value);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* More code */
|
|
Packit |
534379 |
......
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Unmap MMIO */
|
|
Packit |
534379 |
res = fpgaUnmapMMIO(handle, mmio_num);
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
.. Note::
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
Every AFU has its own register adress space and its own protocol to control operation through
|
|
Packit |
534379 |
the registers.
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|