162306a36Sopenharmony_ci======================================================== 262306a36Sopenharmony_ciOpenCAPI (Open Coherent Accelerator Processor Interface) 362306a36Sopenharmony_ci======================================================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciOpenCAPI is an interface between processors and accelerators. It aims 662306a36Sopenharmony_ciat being low-latency and high-bandwidth. The specification is 762306a36Sopenharmony_cideveloped by the `OpenCAPI Consortium <http://opencapi.org/>`_. 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciIt allows an accelerator (which could be an FPGA, ASICs, ...) to access 1062306a36Sopenharmony_cithe host memory coherently, using virtual addresses. An OpenCAPI 1162306a36Sopenharmony_cidevice can also host its own memory, that can be accessed from the 1262306a36Sopenharmony_cihost. 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciOpenCAPI is known in linux as 'ocxl', as the open, processor-agnostic 1562306a36Sopenharmony_cievolution of 'cxl' (the driver for the IBM CAPI interface for 1662306a36Sopenharmony_cipowerpc), which was named that way to avoid confusion with the ISDN 1762306a36Sopenharmony_ciCAPI subsystem. 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ciHigh-level view 2162306a36Sopenharmony_ci=============== 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciOpenCAPI defines a Data Link Layer (DL) and Transaction Layer (TL), to 2462306a36Sopenharmony_cibe implemented on top of a physical link. Any processor or device 2562306a36Sopenharmony_ciimplementing the DL and TL can start sharing memory. 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci:: 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci +-----------+ +-------------+ 3062306a36Sopenharmony_ci | | | | 3162306a36Sopenharmony_ci | | | Accelerated | 3262306a36Sopenharmony_ci | Processor | | Function | 3362306a36Sopenharmony_ci | | +--------+ | Unit | +--------+ 3462306a36Sopenharmony_ci | |--| Memory | | (AFU) |--| Memory | 3562306a36Sopenharmony_ci | | +--------+ | | +--------+ 3662306a36Sopenharmony_ci +-----------+ +-------------+ 3762306a36Sopenharmony_ci | | 3862306a36Sopenharmony_ci +-----------+ +-------------+ 3962306a36Sopenharmony_ci | TL | | TLX | 4062306a36Sopenharmony_ci +-----------+ +-------------+ 4162306a36Sopenharmony_ci | | 4262306a36Sopenharmony_ci +-----------+ +-------------+ 4362306a36Sopenharmony_ci | DL | | DLX | 4462306a36Sopenharmony_ci +-----------+ +-------------+ 4562306a36Sopenharmony_ci | | 4662306a36Sopenharmony_ci | PHY | 4762306a36Sopenharmony_ci +---------------------------------------+ 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ciDevice discovery 5262306a36Sopenharmony_ci================ 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciOpenCAPI relies on a PCI-like configuration space, implemented on the 5562306a36Sopenharmony_cidevice. So the host can discover AFUs by querying the config space. 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ciOpenCAPI devices in Linux are treated like PCI devices (with a few 5862306a36Sopenharmony_cicaveats). The firmware is expected to abstract the hardware as if it 5962306a36Sopenharmony_ciwas a PCI link. A lot of the existing PCI infrastructure is reused: 6062306a36Sopenharmony_cidevices are scanned and BARs are assigned during the standard PCI 6162306a36Sopenharmony_cienumeration. Commands like 'lspci' can therefore be used to see what 6262306a36Sopenharmony_cidevices are available. 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ciThe configuration space defines the AFU(s) that can be found on the 6562306a36Sopenharmony_ciphysical adapter, such as its name, how many memory contexts it can 6662306a36Sopenharmony_ciwork with, the size of its MMIO areas, ... 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ciMMIO 7162306a36Sopenharmony_ci==== 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciOpenCAPI defines two MMIO areas for each AFU: 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci* the global MMIO area, with registers pertinent to the whole AFU. 7662306a36Sopenharmony_ci* a per-process MMIO area, which has a fixed size for each context. 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ciAFU interrupts 8162306a36Sopenharmony_ci============== 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ciOpenCAPI includes the possibility for an AFU to send an interrupt to a 8462306a36Sopenharmony_cihost process. It is done through a 'intrp_req' defined in the 8562306a36Sopenharmony_ciTransaction Layer, specifying a 64-bit object handle which defines the 8662306a36Sopenharmony_ciinterrupt. 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ciThe driver allows a process to allocate an interrupt and obtain its 8962306a36Sopenharmony_ci64-bit object handle, that can be passed to the AFU. 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cichar devices 9462306a36Sopenharmony_ci============ 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ciThe driver creates one char device per AFU found on the physical 9762306a36Sopenharmony_cidevice. A physical device may have multiple functions and each 9862306a36Sopenharmony_cifunction can have multiple AFUs. At the time of this writing though, 9962306a36Sopenharmony_ciit has only been tested with devices exporting only one AFU. 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ciChar devices can be found in /dev/ocxl/ and are named as: 10262306a36Sopenharmony_ci/dev/ocxl/<AFU name>.<location>.<index> 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciwhere <AFU name> is a max 20-character long name, as found in the 10562306a36Sopenharmony_ciconfig space of the AFU. 10662306a36Sopenharmony_ci<location> is added by the driver and can help distinguish devices 10762306a36Sopenharmony_ciwhen a system has more than one instance of the same OpenCAPI device. 10862306a36Sopenharmony_ci<index> is also to help distinguish AFUs in the unlikely case where a 10962306a36Sopenharmony_cidevice carries multiple copies of the same AFU. 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ciSysfs class 11462306a36Sopenharmony_ci=========== 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ciAn ocxl class is added for the devices representing the AFUs. See 11762306a36Sopenharmony_ci/sys/class/ocxl. The layout is described in 11862306a36Sopenharmony_ciDocumentation/ABI/testing/sysfs-class-ocxl 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ciUser API 12362306a36Sopenharmony_ci======== 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ciopen 12662306a36Sopenharmony_ci---- 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciBased on the AFU definition found in the config space, an AFU may 12962306a36Sopenharmony_cisupport working with more than one memory context, in which case the 13062306a36Sopenharmony_ciassociated char device may be opened multiple times by different 13162306a36Sopenharmony_ciprocesses. 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ciioctl 13562306a36Sopenharmony_ci----- 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ciOCXL_IOCTL_ATTACH: 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci Attach the memory context of the calling process to the AFU so that 14062306a36Sopenharmony_ci the AFU can access its memory. 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ciOCXL_IOCTL_IRQ_ALLOC: 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci Allocate an AFU interrupt and return an identifier. 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ciOCXL_IOCTL_IRQ_FREE: 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci Free a previously allocated AFU interrupt. 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ciOCXL_IOCTL_IRQ_SET_FD: 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci Associate an event fd to an AFU interrupt so that the user process 15362306a36Sopenharmony_ci can be notified when the AFU sends an interrupt. 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ciOCXL_IOCTL_GET_METADATA: 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci Obtains configuration information from the card, such at the size of 15862306a36Sopenharmony_ci MMIO areas, the AFU version, and the PASID for the current context. 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ciOCXL_IOCTL_ENABLE_P9_WAIT: 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci Allows the AFU to wake a userspace thread executing 'wait'. Returns 16362306a36Sopenharmony_ci information to userspace to allow it to configure the AFU. Note that 16462306a36Sopenharmony_ci this is only available on POWER9. 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ciOCXL_IOCTL_GET_FEATURES: 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci Reports on which CPU features that affect OpenCAPI are usable from 16962306a36Sopenharmony_ci userspace. 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cimmap 17362306a36Sopenharmony_ci---- 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ciA process can mmap the per-process MMIO area for interactions with the 17662306a36Sopenharmony_ciAFU. 177