FPGA 设备特性列表 (DFL) 框架概述

作者

设备特性列表 (DFL) FPGA 框架(以及符合此框架的驱动程序)隐藏了底层硬件的诸多细节,并为用户空间提供了统一的接口。应用程序可以使用这些接口来配置、枚举、打开和访问在设备内存中实现 DFL 的平台上的 FPGA 加速器。除此之外,DFL 框架还支持系统级管理功能,例如 FPGA 重新配置。

设备特性列表 (DFL) 概述

设备特性列表 (DFL) 在设备 MMIO 空间内定义了一个特性头部的链表,以提供一种可扩展的方式来添加特性。软件可以遍历这些预定义的数据结构来枚举 FPGA 特性:FPGA 接口单元 (FIU)、加速功能单元 (AFU) 和私有特性,如下图所示

   Header            Header            Header            Header
+----------+  +-->+----------+  +-->+----------+  +-->+----------+
|   Type   |  |   |  Type    |  |   |  Type    |  |   |  Type    |
|   FIU    |  |   | Private  |  |   | Private  |  |   | Private  |
+----------+  |   | Feature  |  |   | Feature  |  |   | Feature  |
| Next_DFH |--+   +----------+  |   +----------+  |   +----------+
+----------+      | Next_DFH |--+   | Next_DFH |--+   | Next_DFH |--> NULL
|    ID    |      +----------+      +----------+      +----------+
+----------+      |    ID    |      |    ID    |      |    ID    |
| Next_AFU |--+   +----------+      +----------+      +----------+
+----------+  |   | Feature  |      | Feature  |      | Feature  |
|  Header  |  |   | Register |      | Register |      | Register |
| Register |  |   |   Set    |      |   Set    |      |   Set    |
|   Set    |  |   +----------+      +----------+      +----------+
+----------+  |      Header
              +-->+----------+
                  |   Type   |
                  |   AFU    |
                  +----------+
                  | Next_DFH |--> NULL
                  +----------+
                  |   GUID   |
                  +----------+
                  |  Header  |
                  | Register |
                  |   Set    |
                  +----------+

FPGA 接口单元 (FIU) 表示一个独立的、用于与 FPGA 接口的功能单元,例如 FPGA 管理引擎 (FME) 和端口(在后续章节中将更详细地介绍 FME 和端口)。

加速功能单元 (AFU) 表示一个 FPGA 可编程区域,并且始终作为子项连接到 FIU(例如,端口),如上图所示。

私有特性表示 FIU 和 AFU 的子特性。它们可以是具有不同 ID 的各种功能块,但是属于同一 FIU 或 AFU 的所有私有特性必须通过下一个设备特性头部 (Next_DFH) 指针链接到一个列表。

每个 FIU、AFU 和私有特性都可以实现其自己的功能寄存器。FIU 和 AFU 的功能寄存器集被称为头部寄存器集,例如 FME 头部寄存器集;私有特性的功能寄存器集被称为特性寄存器集,例如 FME 部分重新配置特性寄存器集。

此设备特性列表提供了一种将特性链接在一起的方式,方便软件通过遍历此列表来定位每个特性,并且可以在任何 FPGA 设备的寄存器区域中实现。

设备特性头部 - 版本 0

版本 0 (DFHv0) 是设备特性头部的原始版本。DFHv0 中的所有多字节数量均为小端字节序。DFHv0 的格式如下所示

+-----------------------------------------------------------------------+
|63 Type 60|59 DFH VER 52|51 Rsvd 41|40 EOL|39 Next 16|15 REV 12|11 ID 0| 0x00
+-----------------------------------------------------------------------+
|63                                 GUID_L                             0| 0x08
+-----------------------------------------------------------------------+
|63                                 GUID_H                             0| 0x10
+-----------------------------------------------------------------------+
  • 偏移量 0x00

    • 类型 - DFH 的类型(例如 FME、AFU 或私有特性)。

    • DFH VER - DFH 的版本。

    • Rsvd - 当前未使用。

    • EOL - 如果 DFH 是设备特性列表 (DFL) 的结尾,则设置此项。

    • Next - DFL 中下一个 DFH 的字节偏移量(从 DFH 开始计算),并且 DFH 的起始地址必须与 8 字节边界对齐。如果设置了 EOL,则 Next 是列表中最后一个特性的 MMIO 大小。

    • REV - 与此头部关联的特性的修订号。

    • ID - 如果类型为私有特性,则为特性 ID。

  • 偏移量 0x08

    • GUID_L - 128 位全局唯一标识符的最低有效 64 位(仅当类型为 FME 或 AFU 时才存在)。

  • 偏移量 0x10

    • GUID_H - 128 位全局唯一标识符的最高有效 64 位(仅当类型为 FME 或 AFU 时才存在)。

设备特性头部 - 版本 1

设备特性头部的版本 1 (DFHv1) 添加了以下功能

  • 为特性提供了一种标准化机制,用于向软件描述参数/功能。

  • 标准化了所有 DFHv1 类型使用 GUID 的方式。

  • 将 DFH 位置与特性本身的寄存器空间分离。

DFHv1 中的所有多字节数量均为小端字节序。设备特性头部 (DFH) 版本 1 的格式如下所示

+-----------------------------------------------------------------------+
|63 Type 60|59 DFH VER 52|51 Rsvd 41|40 EOL|39 Next 16|15 REV 12|11 ID 0| 0x00
+-----------------------------------------------------------------------+
|63                                 GUID_L                             0| 0x08
+-----------------------------------------------------------------------+
|63                                 GUID_H                             0| 0x10
+-----------------------------------------------------------------------+
|63                   Reg Address/Offset                      1|  Rel  0| 0x18
+-----------------------------------------------------------------------+
|63        Reg Size       32|Params 31|30 Group    16|15 Instance      0| 0x20
+-----------------------------------------------------------------------+
|63 Next    35|34RSV33|EOP32|31 Param Version 16|15 Param ID           0| 0x28
+-----------------------------------------------------------------------+
|63                 Parameter Data                                     0| 0x30
+-----------------------------------------------------------------------+

                              ...

+-----------------------------------------------------------------------+
|63 Next    35|34RSV33|EOP32|31 Param Version 16|15 Param ID           0|
+-----------------------------------------------------------------------+
|63                 Parameter Data                                     0|
+-----------------------------------------------------------------------+
  • 偏移量 0x00

    • 类型 - DFH 的类型(例如 FME、AFU 或私有特性)。

    • DFH VER - DFH 的版本。

    • Rsvd - 当前未使用。

    • EOL - 如果 DFH 是设备特性列表 (DFL) 的结尾,则设置此项。

    • Next - DFL 中下一个 DFH 的字节偏移量(从 DFH 开始计算),并且 DFH 的起始地址必须与 8 字节边界对齐。如果设置了 EOL,则 Next 是列表中最后一个特性的 MMIO 大小。

    • REV - 与此头部关联的特性的修订号。

    • ID - 如果类型为私有特性,则为特性 ID。

  • 偏移量 0x08

    • GUID_L - 128 位全局唯一标识符的最低有效 64 位。

  • 偏移量 0x10

    • GUID_H - 128 位全局唯一标识符的最高有效 64 位。

  • 偏移量 0x18

    • Reg Address/Offset - 如果设置了 Rel 位,则该值是特性寄存器的 16 位对齐绝对地址的高 63 位。否则,该值是特性寄存器相对于 DFH 起始位置的偏移量。

  • 偏移量 0x20

    • Reg Size - 特性寄存器集的大小(以字节为单位)。

    • Params - 如果 DFH 具有参数块列表,则设置此项。

    • Group - 如果特性是组的一部分,则为组的 ID。

    • Instance - 组内特性实例的 ID。

  • 偏移量 0x28 (如果特性具有参数)

    • Next - 下一个参数块的偏移量,以 8 字节为单位。如果设置了 EOP,则为最后一个参数的大小,以 8 字节为单位。

    • Param Version - Param ID 的版本。

    • Param ID - 参数的 ID。

  • 偏移量 0x30

    • Parameter Data - 参数数据,其大小和格式由参数的版本和 ID 定义。

FIU - FME (FPGA 管理引擎)

FPGA 管理引擎执行重新配置和其他基础设施功能。每个 FPGA 设备只有一个 FME。

用户空间应用程序可以使用 open() 获取 FME 的独占访问权限,并使用 close() 释放它。

以下函数通过 ioctl 公开

  • 获取驱动 API 版本 (DFL_FPGA_GET_API_VERSION)

  • 检查扩展 (DFL_FPGA_CHECK_EXTENSION)

  • 编程比特流 (DFL_FPGA_FME_PORT_PR)

  • 将端口分配给 PF (DFL_FPGA_FME_PORT_ASSIGN)

  • 从 PF 释放端口 (DFL_FPGA_FME_PORT_RELEASE)

  • 获取 FME 全局错误的 irq 数量 (DFL_FPGA_FME_ERR_GET_IRQ_NUM)

  • 设置 FME 错误的 interrupts 触发 (DFL_FPGA_FME_ERR_SET_IRQ)

更多函数通过 sysfs 公开 (/sys/class/fpga_region/regionX/dfl-fme.n/)

读取比特流 ID (bitstream_id)

bitstream_id 指示静态 FPGA 区域的版本。

读取比特流元数据 (bitstream_metadata)

bitstream_metadata 包含静态 FPGA 区域的详细信息,例如合成日期和种子。

读取端口数量 (ports_num)

一个 FPGA 设备可能具有多个端口,此 sysfs 接口指示 FPGA 设备具有多少个端口。

全局错误报告管理 (errors/)

错误报告 sysfs 接口允许用户读取硬件检测到的错误,并清除记录的错误。

电源管理 (dfl_fme_power hwmon)

电源管理 hwmon sysfs 接口允许用户读取电源管理信息(功耗、阈值、阈值状态、限制等),并配置不同节流级别的电源阈值。

热管理 (dfl_fme_thermal hwmon)

热管理 hwmon sysfs 接口允许用户读取热管理信息(当前温度、阈值、阈值状态等)。

性能报告

性能计数器通过 perf PMU API 公开。标准 perf 工具可用于监视所有可用的 perf 事件。请参阅下面的性能计数器部分以获取更多详细信息。

FIU - 端口

端口表示静态 FPGA 结构和包含 AFU 的部分可重新配置区域之间的接口。它控制从 SW 到加速器的通信,并公开重置和调试等功能。每个 FPGA 设备可以有多个端口,但每个端口始终只有一个 AFU。

AFU

AFU 连接到端口 FIU,并公开一个固定长度的 MMIO 区域,用于特定于加速器的控制寄存器。

用户空间应用程序可以通过在端口设备节点上使用 open() 来获取连接到端口的 AFU 的独占访问权限,并使用 close() 释放它。

以下函数通过 ioctl 公开

  • 获取驱动 API 版本 (DFL_FPGA_GET_API_VERSION)

  • 检查扩展 (DFL_FPGA_CHECK_EXTENSION)

  • 获取端口信息 (DFL_FPGA_PORT_GET_INFO)

  • 获取 MMIO 区域信息 (DFL_FPGA_PORT_GET_REGION_INFO)

  • 映射 DMA 缓冲区 (DFL_FPGA_PORT_DMA_MAP)

  • 取消映射 DMA 缓冲区 (DFL_FPGA_PORT_DMA_UNMAP)

  • 重置 AFU (DFL_FPGA_PORT_RESET)

  • 获取端口错误的 irq 数量 (DFL_FPGA_PORT_ERR_GET_IRQ_NUM)

  • 设置端口错误的 interrupts 触发 (DFL_FPGA_PORT_ERR_SET_IRQ)

  • 获取 UINT 的 irq 数量 (DFL_FPGA_PORT_UINT_GET_IRQ_NUM)

  • 设置 UINT 的 interrupts 触发 (DFL_FPGA_PORT_UINT_SET_IRQ)

DFL_FPGA_PORT_RESET

重置 FPGA 端口及其 AFU。用户空间可以随时执行端口重置,例如在 DMA 或部分重新配置期间。但是,它绝不应导致任何系统级问题,只会导致功能故障(例如,DMA 或 PR 操作失败),并且可以从故障中恢复。

用户空间应用程序还可以 mmap() 加速器 MMIO 区域。

更多函数通过 sysfs 公开:(/sys/class/fpga_region/<regionX>/<dfl-port.m>/)

读取加速器 GUID (afu_id)

afu_id 指示已编程到此 AFU 的 PR 比特流。

错误报告 (errors/)

错误报告 sysfs 接口允许用户读取硬件检测到的端口/afu 错误,并清除记录的错误。

DFL 框架概述

       +----------+    +--------+ +--------+ +--------+
       |   FME    |    |  AFU   | |  AFU   | |  AFU   |
       |  Module  |    | Module | | Module | | Module |
       +----------+    +--------+ +--------+ +--------+
               +-----------------------+
               | FPGA Container Device |    Device Feature List
               |  (FPGA Base Region)   |         Framework
               +-----------------------+
------------------------------------------------------------------
             +----------------------------+
             |   FPGA DFL Device Module   |
             | (e.g. PCIE/Platform Device)|
             +----------------------------+
               +------------------------+
               |  FPGA Hardware Device  |
               +------------------------+

内核中的 DFL 框架提供了通用接口来创建容器设备(FPGA 基本区域),从给定的设备特性列表发现特性设备及其私有特性,并使用相关资源在容器设备下为特性设备(例如,FME、端口和 AFU)创建平台设备。它还抽象了私有特性的操作,并向特性设备驱动程序公开通用操作。

FPGA DFL 设备可以是不同的硬件,例如 PCIe 设备、平台设备等。一旦系统创建设备,其驱动程序模块始终首先加载。此驱动程序在驱动程序体系结构中起着基础设施作用。它定位设备内存中的 DFL,将它们及其相关资源传递给 DFL 框架的通用接口以进行枚举。(有关详细的枚举 API,请参阅 drivers/fpga/dfl.c)。

FPGA 管理引擎 (FME) 驱动程序是一个平台驱动程序,在从 DFL 设备模块创建 FME 平台设备后会自动加载。它为 FPGA 管理提供关键特性,包括

  1. 公开静态 FPGA 区域信息,例如版本和元数据。用户可以通过 FME 驱动程序公开的 sysfs 接口读取相关信息。

  2. 部分重新配置。FME 驱动程序在 PR 子特性初始化期间创建 FPGA 管理器、FPGA 桥接器和 FPGA 区域。一旦它从用户收到 DFL_FPGA_FME_PORT_PR ioctl,它就会调用 FPGA 区域的通用接口函数来完成 PR 比特流到给定端口的部分重新配置。

与 FME 驱动程序类似,一旦创建 AFU 平台设备,FPGA 加速功能单元 (AFU) 驱动程序就会被探测。此模块的主要功能是为用户空间应用程序提供访问各个加速器的接口,包括端口上的基本重置控制、AFU MMIO 区域导出、DMA 缓冲区映射服务函数。

创建特性平台设备后,会自动加载匹配的平台驱动程序来处理不同的功能。有关已在此 DFL 框架下实现的各个功能单元的详细信息,请参阅下一节。

部分重新配置

如上所述,可以通过 PR 比特流文件的部分重新配置来重新配置加速器。PR 比特流文件必须是为 FPGA 的确切静态 FPGA 区域和目标可重新配置区域(端口)生成的,否则,重新配置操作将失败并可能导致系统不稳定。可以通过比较 PR 比特流文件头部中记录的兼容性 ID 与目标 FPGA 区域公开的 compat_id 来检查此兼容性。此检查通常由用户空间在调用重新配置 IOCTL 之前完成。

FPGA 虚拟化 - PCIe SRIOV

本节介绍基于 DFL 的 FPGA 设备上的虚拟化支持,以允许从虚拟机 (VM) 中运行的应用程序访问加速器。本节仅介绍具有 SRIOV 支持的基于 PCIe 的 FPGA 设备。

特定 FPGA 设备支持的特性通过设备特性列表公开,如下图所示

  +-------------------------------+  +-------------+
  |              PF               |  |     VF      |
  +-------------------------------+  +-------------+
      ^            ^         ^              ^
      |            |         |              |
+-----|------------|---------|--------------|-------+
|     |            |         |              |       |
|  +-----+     +-------+ +-------+      +-------+   |
|  | FME |     | Port0 | | Port1 |      | Port2 |   |
|  +-----+     +-------+ +-------+      +-------+   |
|                  ^         ^              ^       |
|                  |         |              |       |
|              +-------+ +------+       +-------+   |
|              |  AFU  | |  AFU |       |  AFU  |   |
|              +-------+ +------+       +-------+   |
|                                                   |
|            DFL based FPGA PCIe Device             |
+---------------------------------------------------+

始终通过物理功能 (PF) 访问 FME。

端口(以及相关的 AFU)默认通过 PF 访问,但可以通过 PCIe SRIOV 通过虚拟功能 (VF) 设备公开。每个 VF 仅包含 1 个端口和 1 个 AFU 以进行隔离。用户可以将通过 PCIe SRIOV 接口创建的各个 VF(加速器)分配给虚拟机。

虚拟化情况下的驱动程序组织如下图所示

 +-------++------++------+             |
 | FME   || FME  || FME  |             |
 | FPGA  || FPGA || FPGA |             |
 |Manager||Bridge||Region|             |
 +-------++------++------+             |
 +-----------------------+  +--------+ |             +--------+
 |          FME          |  |  AFU   | |             |  AFU   |
 |         Module        |  | Module | |             | Module |
 +-----------------------+  +--------+ |             +--------+
       +-----------------------+       |       +-----------------------+
       | FPGA Container Device |       |       | FPGA Container Device |
       |  (FPGA Base Region)   |       |       |  (FPGA Base Region)   |
       +-----------------------+       |       +-----------------------+
         +------------------+          |         +------------------+
         | FPGA PCIE Module |          | Virtual | FPGA PCIE Module |
         +------------------+   Host   | Machine +------------------+
-------------------------------------- | ------------------------------
          +---------------+            |          +---------------+
          | PCI PF Device |            |          | PCI VF Device |
          +---------------+            |          +---------------+

一旦检测到 FPGA PCIe PF 或 VF 设备,FPGA PCIe 设备驱动程序始终首先加载。

  • 使用 DFL 框架的通用接口完成 FPGA PCIe PF 和 VF 设备上的枚举。

  • 支持 SRIOV。

FME 设备驱动程序在此驱动程序体系结构中起着管理作用,它提供 ioctl 来从 PF 释放端口并将端口分配给 PF。从 PF 释放端口后,通过 PCIe SRIOV sysfs 接口通过 VF 公开此端口是安全的。

要允许从 VM 中运行的应用程序访问加速器,需要使用以下步骤将各个 AFU 的端口分配给 VF

  1. 默认情况下,PF 拥有所有 AFU 端口。任何需要重新分配给 VF 的端口必须首先通过 FME 设备上的 DFL_FPGA_FME_PORT_RELEASE ioctl 释放。

  2. 一旦从 PF 释放了 N 个端口,用户就可以使用下面的命令来启用 SRIOV 和 VF。每个 VF 仅拥有一个带有 AFU 的端口。

    echo N > $PCI_DEVICE_PATH/sriov_numvfs
    
  3. 将 VF 传递给 VM

  4. VF 下的 AFU 可以从 VM 中的应用程序访问(在 VF 中使用相同的驱动程序)。

请注意,FME 不能分配给 VF,因此 PR 和其他管理功能只能通过 PF 使用。

设备枚举

本节介绍应用程序如何从 /sys/class/fpga_region 下的 sysfs 层次结构中枚举 fpga 设备。

在下面的示例中,主机中安装了两个基于 DFL 的 FPGA 设备。每个 fpga 设备都有一个 FME 和两个端口 (AFU)。

FPGA 区域在 /sys/class/fpga_region/ 下创建

/sys/class/fpga_region/region0
/sys/class/fpga_region/region1
/sys/class/fpga_region/region2
...

应用程序需要搜索每个 regionX 文件夹,如果找到特性设备(例如找到“dfl-port.n”或“dfl-fme.m”),则它是表示 FPGA 设备的基本 fpga 区域。

每个基本区域都有一个 FME 和两个端口 (AFU) 作为子设备

/sys/class/fpga_region/region0/dfl-fme.0
/sys/class/fpga_region/region0/dfl-port.0
/sys/class/fpga_region/region0/dfl-port.1
...

/sys/class/fpga_region/region3/dfl-fme.1
/sys/class/fpga_region/region3/dfl-port.2
/sys/class/fpga_region/region3/dfl-port.3
...

通常,FME/AFU sysfs 接口的命名如下

/sys/class/fpga_region/<regionX>/<dfl-fme.n>/
/sys/class/fpga_region/<regionX>/<dfl-port.m>/

其中“n”连续编号所有 FME,“m”连续编号所有端口。

用于 ioctl() 或 mmap() 的设备节点可以通过以下方式引用

/sys/class/fpga_region/<regionX>/<dfl-fme.n>/dev
/sys/class/fpga_region/<regionX>/<dfl-port.n>/dev

性能计数器

性能报告是在 FME 中实现的一个私有特性。它可以在硬件中支持多个独立的、系统范围的设备计数器集,以监视和计数性能事件,包括“basic”、“cache”、“fabric”、“vtd”和“vtd_sip”计数器。用户可以使用标准 perf 工具来监视 FPGA 缓存命中/未命中率、事务数量、AFU 的接口时钟计数器和其他 FPGA 性能事件。

不同的 FPGA 设备可能具有不同的计数器集,具体取决于硬件实现。例如,某些独立 FPGA 卡没有任何缓存。用户可以使用“perf list”来检查目标硬件支持哪些 perf 事件。

为了允许用户使用标准 perf API 来访问这些性能计数器,驱动程序创建了一个 perf PMU,并在 /sys/bus/event_source/devices/dfl_fme* 中创建了相关的 sysfs 接口来描述可用的 perf 事件和配置选项。

“format”目录描述了 struct perf_event_attr 的 config 字段的格式。config 有 3 个位域:“evtype”定义 perf 事件所属的类型;“event”是其类别中事件的标识;引入“portid”来决定要监视 FPGA 总体数据或特定端口的计数器集。

“events”目录描述了可直接与 perf 工具一起使用的所有可用事件的配置模板。例如,fab_mmio_read 具有配置“event=0x06,evtype=0x02,portid=0xff”,这表明此事件属于 fabric 类型 (0x02),本地事件 ID 为 0x06,并且它用于总体监视 (portid=0xff)。

perf 的示例用法

$# perf list |grep dfl_fme

dfl_fme0/fab_mmio_read/                              [Kernel PMU event]
<...>
dfl_fme0/fab_port_mmio_read,portid=?/                [Kernel PMU event]
<...>

$# perf stat -a -e dfl_fme0/fab_mmio_read/ <command>
or
$# perf stat -a -e dfl_fme0/event=0x06,evtype=0x02,portid=0xff/ <command>
or
$# perf stat -a -e dfl_fme0/config=0xff2006/ <command>

另一个示例,fab_port_mmio_read 监视特定端口的 mmio 读取。因此其配置模板为“event=0x06,evtype=0x01,portid=?”。应显式设置 portid。

其 perf 用法

$# perf stat -a -e dfl_fme0/fab_port_mmio_read,portid=0x0/ <command>
or
$# perf stat -a -e dfl_fme0/event=0x06,evtype=0x02,portid=0x0/ <command>
or
$# perf stat -a -e dfl_fme0/config=0x2006/ <command>

请注意,对于 fabric 计数器,总体 perf 事件 (fab_*) 和端口 perf 事件 (fab_port_*) 实际上在硬件中共享一组计数器,因此它们不能同时监视。如果将此计数器集配置为监视总体数据,则不支持每个端口的 perf 数据。请参见以下示例

$# perf stat -e dfl_fme0/fab_mmio_read/,dfl_fme0/fab_port_mmio_write,\
                                                  portid=0/ sleep 1

Performance counter stats for 'system wide':

               3      dfl_fme0/fab_mmio_read/
 <not supported>      dfl_fme0/fab_port_mmio_write,portid=0x0/

     1.001750904 seconds time elapsed

驱动程序还提供了一个“cpumask”sysfs 属性,其中仅包含用于访问这些 perf 事件的一个 CPU id。不允许在多个 CPU 上进行计数,因为它们是 FPGA 设备上的系统范围的计数器。

当前的驱动程序不支持采样。因此不支持“perf record”。

中断支持

某些 FME 和 AFU 私有特性能够生成中断。如上所述,用户可以调用 ioctl (DFL_FPGA_*_GET_IRQ_NUM) 来了解此私有特性是否支持中断或支持多少个中断。驱动程序还为用户实现了一个基于 eventfd 的中断处理机制,以便在发生中断时收到通知。用户可以通过 ioctl (DFL_FPGA_*_SET_IRQ) 将 eventfds 设置为驱动程序,然后在这些 eventfds 上轮询/选择以等待通知。在当前的 DFL 中,3 个子特性(端口错误、FME 全局错误和 AFU 中断)支持中断。

添加新 FIU 支持

开发人员可能在此 DFL 框架下制作了一些新的功能块 (FIU),那么需要为新特性设备 (FIU) 开发新的平台设备驱动程序,其方式与现有特性设备驱动程序(例如 FME 和端口/AFU 平台设备驱动程序)相同。除此之外,它还需要修改 DFL 框架枚举代码,以进行新的 FIU 类型检测和相关的平台设备创建。

添加新的私有特性支持

在某些情况下,我们可能需要向现有 FIU(例如 FME 或端口)添加一些新的私有特性。开发人员无需修改 DFL 框架中的枚举代码,因为每个私有特性都会自动解析,并且可以在 DFL 框架创建的 FIU 平台设备下找到相关的 mmio 资源。开发人员只需要提供一个具有匹配特性 ID 的子特性驱动程序。FME 部分重新配置子特性驱动程序(请参阅 drivers/fpga/dfl-fme-pr.c)可以作为参考。

请参阅下面的链接,以获取现有特性 ID 表和新特性 ID 应用程序的指南。 https://github.com/OPAE/dfl-feature-id

PCI 设备上 DFL 的位置

在 PCI 设备上查找 DFL 的原始方法假定第一个 DFL 的起始位置是 bar 0 的偏移量 0。如果 DFL 的第一个节点是 FME,则在 FME 头部寄存器中指定端口中的进一步 DFL。或者,可以使用 PCIe 供应商特定功能结构来指定设备上所有 DFL 的位置,从而为 DFL 中的起始节点类型提供灵活性。Intel 为此目的保留了 VSEC ID 0x43。供应商特定数据以 4 字节供应商特定寄存器开始,用于表示 DFL 的数量,然后是每个 DFL 的 4 字节偏移量/BIR 供应商特定寄存器。偏移量/BIR 寄存器的位 2:0 指示 BAR,位 31:3 形成 8 字节对齐的偏移量,其中位 2:0 为零。

+----------------------------+
|31     Number of DFLS      0|
+----------------------------+
|31     Offset     3|2 BIR  0|
+----------------------------+
              . . .
+----------------------------+
|31     Offset     3|2 BIR  0|
+----------------------------+

已经考虑过能够为每个 BAR 指定多个 DFL,但是确定该用例没有提供价值。为每个 BAR 指定单个 DFL 简化了实现并允许进行额外的错误检查。

DFL 设备的用户空间驱动程序支持

FPGA 的目的是使用新开发的硬件组件进行重新编程。新硬件可以在 DFL 中实例化一个新的私有特性,然后在系统中呈现 DFL 设备。在某些情况下,用户可能需要 DFL 设备的用户空间驱动程序

  • 用户可能需要为其硬件运行一些诊断测试。

  • 用户可以在用户空间中原型化内核驱动程序。

  • 某些硬件是为特定目的而设计的,并且不适合标准内核子系统之一。

这需要从用户空间直接访问 MMIO 空间和中断处理。uio_dfl 模块为此目的公开了 UIO 设备接口。

当前,uio_dfl 驱动程序仅支持 Ether Group 子特性,该子特性在硬件中没有 irq。因此,此驱动程序中未添加中断处理。

应选择 UIO_DFL 以启用 uio_dfl 模块驱动程序。要通过 UIO 直接访问来支持新的 DFL 特性,应将其特性 ID 添加到驱动程序的 id_table 中。

公开讨论

FME 驱动程序现在导出一个 ioctl (DFL_FPGA_FME_PORT_PR) 用于部分重新配置给用户。将来,如果添加了统一的重新配置用户接口,则 FME 驱动程序应从 ioctl 接口切换到它们。