← Documents Documentation/fpga/dfl.rst GitHub 원문 ↗

Linux 6.18.37 · FPGA

FPGA Device Feature List (DFL) Framework Overview

DFL header, FME·Port·AFU, reconfiguration, SRIOV, perf와 userspace interface를 다루는 전문 번역입니다.

Source pathDocumentation/fpga/dfl.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

dfl.rst:1-687

DFL은 FPGA MMIO 안의 FIU·AFU·Private Feature header를 linked list로 기술하고 kernel framework가 이를 enumerate해 FME와 Port/AFU platform device를 만드는 규약이다. DFHv0는 기본 list와 GUID를 제공하고 DFHv1은 register 위치·크기·group·parameter block을 표준화한다.

FME는 device-wide management와 Partial Reconfiguration을 담당하고 Port는 static fabric과 AFU 사이를 연결한다. AFU는 accelerator MMIO·DMA·reset을 사용자 공간에 제공한다. PCIe SRIOV에서는 FME가 PF에 남고 release된 Port/AFU 하나씩만 VF에 assign된다.

Sysfs enumeration, perf PMU, eventfd interrupt, PCI VSEC 0x43 DFL 위치, uio_dfl userspace access까지 같은 framework 위에 연결된다. Bitstream `compat_id`, Port ownership, shared performance counter 같은 제약을 지키는 것이 system stability와 격리에 중요하다.

DFL 핵심 계층
계층핵심 책임
DFH/DFLMMIO feature description과 linked-list enumeration
DFL frameworkContainer·feature platform device 생성
FMEManagement, PR, global error, perf
Port/AFUAccelerator MMIO, DMA, reset, interrupt
Userspaceioctl, mmap, sysfs, perf, UIO

Hardware description부터 사용자 공간 interface까지의 책임을 요약한다.

DFL end-to-end 흐름
PCIe/Platform DFL device 발견DFL header와 Private Feature enumerateFPGA base region과 FME/Port/AFU device 생성Matched platform driver probe사용자 공간에 sysfs·ioctl·mmap·perf interface 제공

Device 발견부터 accelerator 사용까지의 전체 경로다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 =================================================
2 FPGA Device Feature List (DFL) Framework Overview
3 =================================================
4
5 Authors:
6
7 - Enno Luebbers <[email protected]>
8 - Xiao Guangrong <[email protected]>
9 - Wu Hao <[email protected]>
10 - Xu Yilun <[email protected]>
11
12 The Device Feature List (DFL) FPGA framework (and drivers according to
13 this framework) hides the very details of low layer hardware and provides
14 unified interfaces to userspace. Applications could use these interfaces to
15 configure, enumerate, open and access FPGA accelerators on platforms which
16 implement the DFL in the device memory. Besides this, the DFL framework
17 enables system level management functions such as FPGA reconfiguration.
18
19
20 Device Feature List (DFL) Overview
21 ==================================
22 Device Feature List (DFL) defines a linked list of feature headers within the
23 device MMIO space to provide an extensible way of adding features. Software can
24 walk through these predefined data structures to enumerate FPGA features:
25 FPGA Interface Unit (FIU), Accelerated Function Unit (AFU) and Private Features,
26 as illustrated below::
27
28 Header Header Header Header
29 +----------+ +-->+----------+ +-->+----------+ +-->+----------+
30 | Type | | | Type | | | Type | | | Type |
31 | FIU | | | Private | | | Private | | | Private |
32 +----------+ | | Feature | | | Feature | | | Feature |
33 | Next_DFH |--+ +----------+ | +----------+ | +----------+
34 +----------+ | Next_DFH |--+ | Next_DFH |--+ | Next_DFH |--> NULL
35 | ID | +----------+ +----------+ +----------+
36 +----------+ | ID | | ID | | ID |
37 | Next_AFU |--+ +----------+ +----------+ +----------+
38 +----------+ | | Feature | | Feature | | Feature |
39 | Header | | | Register | | Register | | Register |
40 | Register | | | Set | | Set | | Set |
41 | Set | | +----------+ +----------+ +----------+
42 +----------+ | Header
43 +-->+----------+
44 | Type |
45 | AFU |
46 +----------+
47 | Next_DFH |--> NULL
48 +----------+
49 | GUID |
50 +----------+
51 | Header |
52 | Register |
53 | Set |
54 +----------+
55
56 FPGA Interface Unit (FIU) represents a standalone functional unit for the
57 interface to FPGA, e.g. the FPGA Management Engine (FME) and Port (more
58 descriptions on FME and Port in later sections).
59
60 Accelerated Function Unit (AFU) represents an FPGA programmable region and
61 always connects to a FIU (e.g. a Port) as its child as illustrated above.
62
63 Private Features represent sub features of the FIU and AFU. They could be
64 various function blocks with different IDs, but all private features which
65 belong to the same FIU or AFU, must be linked to one list via the Next Device
66 Feature Header (Next_DFH) pointer.
67
68 Each FIU, AFU and Private Feature could implement its own functional registers.
69 The functional register set for FIU and AFU, is named as Header Register Set,
70 e.g. FME Header Register Set, and the one for Private Feature, is named as
71 Feature Register Set, e.g. FME Partial Reconfiguration Feature Register Set.
72
73 This Device Feature List provides a way of linking features together, it's
74 convenient for software to locate each feature by walking through this list,
75 and can be implemented in register regions of any FPGA device.
76
77
78 Device Feature Header - Version 0
79 =================================
80 Version 0 (DFHv0) is the original version of the Device Feature Header.
81 All multi-byte quantities in DFHv0 are little-endian.
82 The format of DFHv0 is shown below::
83
84 +-----------------------------------------------------------------------+
85 |63 Type 60|59 DFH VER 52|51 Rsvd 41|40 EOL|39 Next 16|15 REV 12|11 ID 0| 0x00
86 +-----------------------------------------------------------------------+
87 |63 GUID_L 0| 0x08
88 +-----------------------------------------------------------------------+
89 |63 GUID_H 0| 0x10
90 +-----------------------------------------------------------------------+
91
92 - Offset 0x00
93
94 * Type - The type of DFH (e.g. FME, AFU, or private feature).
95 * DFH VER - The version of the DFH.
96 * Rsvd - Currently unused.
97 * EOL - Set if the DFH is the end of the Device Feature List (DFL).
98 * Next - The offset in bytes of the next DFH in the DFL from the DFH start,
99 and the start of a DFH must be aligned to an 8 byte boundary.
100 If EOL is set, Next is the size of MMIO of the last feature in the list.
101 * REV - The revision of the feature associated with this header.
102 * ID - The feature ID if Type is private feature.
103
104 - Offset 0x08
105
106 * GUID_L - Least significant 64 bits of a 128-bit Globally Unique Identifier
107 (present only if Type is FME or AFU).
108
109 - Offset 0x10
110
111 * GUID_H - Most significant 64 bits of a 128-bit Globally Unique Identifier
112 (present only if Type is FME or AFU).
113
114
115 Device Feature Header - Version 1
116 =================================
117 Version 1 (DFHv1) of the Device Feature Header adds the following functionality:
118
119 * Provides a standardized mechanism for features to describe
120 parameters/capabilities to software.
121 * Standardize the use of a GUID for all DFHv1 types.
122 * Decouples the DFH location from the register space of the feature itself.
123
124 All multi-byte quantities in DFHv1 are little-endian.
125 The format of Version 1 of the Device Feature Header (DFH) is shown below::
126
127 +-----------------------------------------------------------------------+
128 |63 Type 60|59 DFH VER 52|51 Rsvd 41|40 EOL|39 Next 16|15 REV 12|11 ID 0| 0x00
129 +-----------------------------------------------------------------------+
130 |63 GUID_L 0| 0x08
131 +-----------------------------------------------------------------------+
132 |63 GUID_H 0| 0x10
133 +-----------------------------------------------------------------------+
134 |63 Reg Address/Offset 1| Rel 0| 0x18
135 +-----------------------------------------------------------------------+
136 |63 Reg Size 32|Params 31|30 Group 16|15 Instance 0| 0x20
137 +-----------------------------------------------------------------------+
138 |63 Next 35|34RSV33|EOP32|31 Param Version 16|15 Param ID 0| 0x28
139 +-----------------------------------------------------------------------+
140 |63 Parameter Data 0| 0x30
141 +-----------------------------------------------------------------------+
142
143 ...
144
145 +-----------------------------------------------------------------------+
146 |63 Next 35|34RSV33|EOP32|31 Param Version 16|15 Param ID 0|
147 +-----------------------------------------------------------------------+
148 |63 Parameter Data 0|
149 +-----------------------------------------------------------------------+
150
151 - Offset 0x00
152
153 * Type - The type of DFH (e.g. FME, AFU, or private feature).
154 * DFH VER - The version of the DFH.
155 * Rsvd - Currently unused.
156 * EOL - Set if the DFH is the end of the Device Feature List (DFL).
157 * Next - The offset in bytes of the next DFH in the DFL from the DFH start,
158 and the start of a DFH must be aligned to an 8 byte boundary.
159 If EOL is set, Next is the size of MMIO of the last feature in the list.
160 * REV - The revision of the feature associated with this header.
161 * ID - The feature ID if Type is private feature.
162
163 - Offset 0x08
164
165 * GUID_L - Least significant 64 bits of a 128-bit Globally Unique Identifier.
166
167 - Offset 0x10
168
169 * GUID_H - Most significant 64 bits of a 128-bit Globally Unique Identifier.
170
171 - Offset 0x18
172
173 * Reg Address/Offset - If Rel bit is set, then the value is the high 63 bits
174 of a 16-bit aligned absolute address of the feature's registers. Otherwise
175 the value is the offset from the start of the DFH of the feature's registers.
176
177 - Offset 0x20
178
179 * Reg Size - Size of feature's register set in bytes.
180 * Params - Set if DFH has a list of parameter blocks.
181 * Group - Id of group if feature is part of a group.
182 * Instance - Id of feature instance within a group.
183
184 - Offset 0x28 if feature has parameters
185
186 * Next - Offset to the next parameter block in 8 byte words. If EOP set,
187 size in 8 byte words of last parameter.
188 * Param Version - Version of Param ID.
189 * Param ID - ID of parameter.
190
191 - Offset 0x30
192
193 * Parameter Data - Parameter data whose size and format is defined by
194 version and ID of the parameter.
195
196
197 FIU - FME (FPGA Management Engine)
198 ==================================
199 The FPGA Management Engine performs reconfiguration and other infrastructure
200 functions. Each FPGA device only has one FME.
201
202 User-space applications can acquire exclusive access to the FME using open(),
203 and release it using close().
204
205 The following functions are exposed through ioctls:
206
207 - Get driver API version (DFL_FPGA_GET_API_VERSION)
208 - Check for extensions (DFL_FPGA_CHECK_EXTENSION)
209 - Program bitstream (DFL_FPGA_FME_PORT_PR)
210 - Assign port to PF (DFL_FPGA_FME_PORT_ASSIGN)
211 - Release port from PF (DFL_FPGA_FME_PORT_RELEASE)
212 - Get number of irqs of FME global error (DFL_FPGA_FME_ERR_GET_IRQ_NUM)
213 - Set interrupt trigger for FME error (DFL_FPGA_FME_ERR_SET_IRQ)
214
215 More functions are exposed through sysfs
216 (/sys/class/fpga_region/regionX/dfl-fme.n/):
217
218 Read bitstream ID (bitstream_id)
219 bitstream_id indicates version of the static FPGA region.
220
221 Read bitstream metadata (bitstream_metadata)
222 bitstream_metadata includes detailed information of static FPGA region,
223 e.g. synthesis date and seed.
224
225 Read number of ports (ports_num)
226 one FPGA device may have more than one port, this sysfs interface indicates
227 how many ports the FPGA device has.
228
229 Global error reporting management (errors/)
230 error reporting sysfs interfaces allow user to read errors detected by the
231 hardware, and clear the logged errors.
232
233 Power management (dfl_fme_power hwmon)
234 power management hwmon sysfs interfaces allow user to read power management
235 information (power consumption, thresholds, threshold status, limits, etc.)
236 and configure power thresholds for different throttling levels.
237
238 Thermal management (dfl_fme_thermal hwmon)
239 thermal management hwmon sysfs interfaces allow user to read thermal
240 management information (current temperature, thresholds, threshold status,
241 etc.).
242
243 Performance reporting
244 performance counters are exposed through perf PMU APIs. Standard perf tool
245 can be used to monitor all available perf events. Please see performance
246 counter section below for more detailed information.
247
248
249 FIU - PORT
250 ==========
251 A port represents the interface between the static FPGA fabric and a partially
252 reconfigurable region containing an AFU. It controls the communication from SW
253 to the accelerator and exposes features such as reset and debug. Each FPGA
254 device may have more than one port, but always one AFU per port.
255
256
257 AFU
258 ===
259 An AFU is attached to a port FIU and exposes a fixed length MMIO region to be
260 used for accelerator-specific control registers.
261
262 User-space applications can acquire exclusive access to an AFU attached to a
263 port by using open() on the port device node and release it using close().
264
265 The following functions are exposed through ioctls:
266
267 - Get driver API version (DFL_FPGA_GET_API_VERSION)
268 - Check for extensions (DFL_FPGA_CHECK_EXTENSION)
269 - Get port info (DFL_FPGA_PORT_GET_INFO)
270 - Get MMIO region info (DFL_FPGA_PORT_GET_REGION_INFO)
271 - Map DMA buffer (DFL_FPGA_PORT_DMA_MAP)
272 - Unmap DMA buffer (DFL_FPGA_PORT_DMA_UNMAP)
273 - Reset AFU (DFL_FPGA_PORT_RESET)
274 - Get number of irqs of port error (DFL_FPGA_PORT_ERR_GET_IRQ_NUM)
275 - Set interrupt trigger for port error (DFL_FPGA_PORT_ERR_SET_IRQ)
276 - Get number of irqs of UINT (DFL_FPGA_PORT_UINT_GET_IRQ_NUM)
277 - Set interrupt trigger for UINT (DFL_FPGA_PORT_UINT_SET_IRQ)
278
279 DFL_FPGA_PORT_RESET:
280 reset the FPGA Port and its AFU. Userspace can do Port
281 reset at any time, e.g. during DMA or Partial Reconfiguration. But it should
282 never cause any system level issue, only functional failure (e.g. DMA or PR
283 operation failure) and be recoverable from the failure.
284
285 User-space applications can also mmap() accelerator MMIO regions.
286
287 More functions are exposed through sysfs:
288 (/sys/class/fpga_region/<regionX>/<dfl-port.m>/):
289
290 Read Accelerator GUID (afu_id)
291 afu_id indicates which PR bitstream is programmed to this AFU.
292
293 Error reporting (errors/)
294 error reporting sysfs interfaces allow user to read port/afu errors
295 detected by the hardware, and clear the logged errors.
296
297
298 DFL Framework Overview
299 ======================
300
301 ::
302
303 +----------+ +--------+ +--------+ +--------+
304 | FME | | AFU | | AFU | | AFU |
305 | Module | | Module | | Module | | Module |
306 +----------+ +--------+ +--------+ +--------+
307 +-----------------------+
308 | FPGA Container Device | Device Feature List
309 | (FPGA Base Region) | Framework
310 +-----------------------+
311 ------------------------------------------------------------------
312 +----------------------------+
313 | FPGA DFL Device Module |
314 | (e.g. PCIE/Platform Device)|
315 +----------------------------+
316 +------------------------+
317 | FPGA Hardware Device |
318 +------------------------+
319
320 DFL framework in kernel provides common interfaces to create container device
321 (FPGA base region), discover feature devices and their private features from the
322 given Device Feature Lists and create platform devices for feature devices
323 (e.g. FME, Port and AFU) with related resources under the container device. It
324 also abstracts operations for the private features and exposes common ops to
325 feature device drivers.
326
327 The FPGA DFL Device could be different hardware, e.g. PCIe device, platform
328 device and etc. Its driver module is always loaded first once the device is
329 created by the system. This driver plays an infrastructural role in the
330 driver architecture. It locates the DFLs in the device memory, handles them
331 and related resources to common interfaces from DFL framework for enumeration.
332 (Please refer to drivers/fpga/dfl.c for detailed enumeration APIs).
333
334 The FPGA Management Engine (FME) driver is a platform driver which is loaded
335 automatically after FME platform device creation from the DFL device module. It
336 provides the key features for FPGA management, including:
337
338 a) Expose static FPGA region information, e.g. version and metadata.
339 Users can read related information via sysfs interfaces exposed
340 by FME driver.
341
342 b) Partial Reconfiguration. The FME driver creates FPGA manager, FPGA
343 bridges and FPGA regions during PR sub feature initialization. Once
344 it receives a DFL_FPGA_FME_PORT_PR ioctl from user, it invokes the
345 common interface function from FPGA Region to complete the partial
346 reconfiguration of the PR bitstream to the given port.
347
348 Similar to the FME driver, the FPGA Accelerated Function Unit (AFU) driver is
349 probed once the AFU platform device is created. The main function of this module
350 is to provide an interface for userspace applications to access the individual
351 accelerators, including basic reset control on port, AFU MMIO region export, dma
352 buffer mapping service functions.
353
354 After feature platform devices creation, matched platform drivers will be loaded
355 automatically to handle different functionalities. Please refer to next sections
356 for detailed information on functional units which have been already implemented
357 under this DFL framework.
358
359
360 Partial Reconfiguration
361 =======================
362 As mentioned above, accelerators can be reconfigured through partial
363 reconfiguration of a PR bitstream file. The PR bitstream file must have been
364 generated for the exact static FPGA region and targeted reconfigurable region
365 (port) of the FPGA, otherwise, the reconfiguration operation will fail and
366 possibly cause system instability. This compatibility can be checked by
367 comparing the compatibility ID noted in the header of PR bitstream file against
368 the compat_id exposed by the target FPGA region. This check is usually done by
369 userspace before calling the reconfiguration IOCTL.
370
371
372 FPGA virtualization - PCIe SRIOV
373 ================================
374 This section describes the virtualization support on DFL based FPGA device to
375 enable accessing an accelerator from applications running in a virtual machine
376 (VM). This section only describes the PCIe based FPGA device with SRIOV support.
377
378 Features supported by the particular FPGA device are exposed through Device
379 Feature Lists, as illustrated below:
380
381 ::
382
383 +-------------------------------+ +-------------+
384 | PF | | VF |
385 +-------------------------------+ +-------------+
386 ^ ^ ^ ^
387 | | | |
388 +-----|------------|---------|--------------|-------+
389 | | | | | |
390 | +-----+ +-------+ +-------+ +-------+ |
391 | | FME | | Port0 | | Port1 | | Port2 | |
392 | +-----+ +-------+ +-------+ +-------+ |
393 | ^ ^ ^ |
394 | | | | |
395 | +-------+ +------+ +-------+ |
396 | | AFU | | AFU | | AFU | |
397 | +-------+ +------+ +-------+ |
398 | |
399 | DFL based FPGA PCIe Device |
400 +---------------------------------------------------+
401
402 FME is always accessed through the physical function (PF).
403
404 Ports (and related AFUs) are accessed via PF by default, but could be exposed
405 through virtual function (VF) devices via PCIe SRIOV. Each VF only contains
406 1 Port and 1 AFU for isolation. Users could assign individual VFs (accelerators)
407 created via PCIe SRIOV interface, to virtual machines.
408
409 The driver organization in virtualization case is illustrated below:
410 ::
411
412 +-------++------++------+ |
413 | FME || FME || FME | |
414 | FPGA || FPGA || FPGA | |
415 |Manager||Bridge||Region| |
416 +-------++------++------+ |
417 +-----------------------+ +--------+ | +--------+
418 | FME | | AFU | | | AFU |
419 | Module | | Module | | | Module |
420 +-----------------------+ +--------+ | +--------+
421 +-----------------------+ | +-----------------------+
422 | FPGA Container Device | | | FPGA Container Device |
423 | (FPGA Base Region) | | | (FPGA Base Region) |
424 +-----------------------+ | +-----------------------+
425 +------------------+ | +------------------+
426 | FPGA PCIE Module | | Virtual | FPGA PCIE Module |
427 +------------------+ Host | Machine +------------------+
428 -------------------------------------- | ------------------------------
429 +---------------+ | +---------------+
430 | PCI PF Device | | | PCI VF Device |
431 +---------------+ | +---------------+
432
433 FPGA PCIe device driver is always loaded first once an FPGA PCIe PF or VF device
434 is detected. It:
435
436 * Finishes enumeration on both FPGA PCIe PF and VF device using common
437 interfaces from DFL framework.
438 * Supports SRIOV.
439
440 The FME device driver plays a management role in this driver architecture, it
441 provides ioctls to release Port from PF and assign Port to PF. After release
442 a port from PF, then it's safe to expose this port through a VF via PCIe SRIOV
443 sysfs interface.
444
445 To enable accessing an accelerator from applications running in a VM, the
446 respective AFU's port needs to be assigned to a VF using the following steps:
447
448 #. The PF owns all AFU ports by default. Any port that needs to be
449 reassigned to a VF must first be released through the
450 DFL_FPGA_FME_PORT_RELEASE ioctl on the FME device.
451
452 #. Once N ports are released from PF, then user can use command below
453 to enable SRIOV and VFs. Each VF owns only one Port with AFU.
454
455 ::
456
457 echo N > $PCI_DEVICE_PATH/sriov_numvfs
458
459 #. Pass through the VFs to VMs
460
461 #. The AFU under VF is accessible from applications in VM (using the
462 same driver inside the VF).
463
464 Note that an FME can't be assigned to a VF, thus PR and other management
465 functions are only available via the PF.
466
467 Device enumeration
468 ==================
469 This section introduces how applications enumerate the fpga device from
470 the sysfs hierarchy under /sys/class/fpga_region.
471
472 In the example below, two DFL based FPGA devices are installed in the host. Each
473 fpga device has one FME and two ports (AFUs).
474
475 FPGA regions are created under /sys/class/fpga_region/::
476
477 /sys/class/fpga_region/region0
478 /sys/class/fpga_region/region1
479 /sys/class/fpga_region/region2
480 ...
481
482 Application needs to search each regionX folder, if feature device is found,
483 (e.g. "dfl-port.n" or "dfl-fme.m" is found), then it's the base
484 fpga region which represents the FPGA device.
485
486 Each base region has one FME and two ports (AFUs) as child devices::
487
488 /sys/class/fpga_region/region0/dfl-fme.0
489 /sys/class/fpga_region/region0/dfl-port.0
490 /sys/class/fpga_region/region0/dfl-port.1
491 ...
492
493 /sys/class/fpga_region/region3/dfl-fme.1
494 /sys/class/fpga_region/region3/dfl-port.2
495 /sys/class/fpga_region/region3/dfl-port.3
496 ...
497
498 In general, the FME/AFU sysfs interfaces are named as follows::
499
500 /sys/class/fpga_region/<regionX>/<dfl-fme.n>/
501 /sys/class/fpga_region/<regionX>/<dfl-port.m>/
502
503 with 'n' consecutively numbering all FMEs and 'm' consecutively numbering all
504 ports.
505
506 The device nodes used for ioctl() or mmap() can be referenced through::
507
508 /sys/class/fpga_region/<regionX>/<dfl-fme.n>/dev
509 /sys/class/fpga_region/<regionX>/<dfl-port.n>/dev
510
511
512 Performance Counters
513 ====================
514 Performance reporting is one private feature implemented in FME. It could
515 supports several independent, system-wide, device counter sets in hardware to
516 monitor and count for performance events, including "basic", "cache", "fabric",
517 "vtd" and "vtd_sip" counters. Users could use standard perf tool to monitor
518 FPGA cache hit/miss rate, transaction number, interface clock counter of AFU
519 and other FPGA performance events.
520
521 Different FPGA devices may have different counter sets, depending on hardware
522 implementation. E.g., some discrete FPGA cards don't have any cache. User could
523 use "perf list" to check which perf events are supported by target hardware.
524
525 In order to allow user to use standard perf API to access these performance
526 counters, driver creates a perf PMU, and related sysfs interfaces in
527 /sys/bus/event_source/devices/dfl_fme* to describe available perf events and
528 configuration options.
529
530 The "format" directory describes the format of the config field of struct
531 perf_event_attr. There are 3 bitfields for config: "evtype" defines which type
532 the perf event belongs to; "event" is the identity of the event within its
533 category; "portid" is introduced to decide counters set to monitor on FPGA
534 overall data or a specific port.
535
536 The "events" directory describes the configuration templates for all available
537 events which can be used with perf tool directly. For example, fab_mmio_read
538 has the configuration "event=0x06,evtype=0x02,portid=0xff", which shows this
539 event belongs to fabric type (0x02), the local event id is 0x06 and it is for
540 overall monitoring (portid=0xff).
541
542 Example usage of perf::
543
544 $# perf list |grep dfl_fme
545
546 dfl_fme0/fab_mmio_read/ [Kernel PMU event]
547 <...>
548 dfl_fme0/fab_port_mmio_read,portid=?/ [Kernel PMU event]
549 <...>
550
551 $# perf stat -a -e dfl_fme0/fab_mmio_read/ <command>
552 or
553 $# perf stat -a -e dfl_fme0/event=0x06,evtype=0x02,portid=0xff/ <command>
554 or
555 $# perf stat -a -e dfl_fme0/config=0xff2006/ <command>
556
557 Another example, fab_port_mmio_read monitors mmio read of a specific port. So
558 its configuration template is "event=0x06,evtype=0x01,portid=?". The portid
559 should be explicitly set.
560
561 Its usage of perf::
562
563 $# perf stat -a -e dfl_fme0/fab_port_mmio_read,portid=0x0/ <command>
564 or
565 $# perf stat -a -e dfl_fme0/event=0x06,evtype=0x02,portid=0x0/ <command>
566 or
567 $# perf stat -a -e dfl_fme0/config=0x2006/ <command>
568
569 Please note for fabric counters, overall perf events (fab_*) and port perf
570 events (fab_port_*) actually share one set of counters in hardware, so it can't
571 monitor both at the same time. If this set of counters is configured to monitor
572 overall data, then per port perf data is not supported. See below example::
573
574 $# perf stat -e dfl_fme0/fab_mmio_read/,dfl_fme0/fab_port_mmio_write,\
575 portid=0/ sleep 1
576
577 Performance counter stats for 'system wide':
578
579 3 dfl_fme0/fab_mmio_read/
580 <not supported> dfl_fme0/fab_port_mmio_write,portid=0x0/
581
582 1.001750904 seconds time elapsed
583
584 The driver also provides a "cpumask" sysfs attribute, which contains only one
585 CPU id used to access these perf events. Counting on multiple CPU is not allowed
586 since they are system-wide counters on FPGA device.
587
588 The current driver does not support sampling. So "perf record" is unsupported.
589
590
591 Interrupt support
592 =================
593 Some FME and AFU private features are able to generate interrupts. As mentioned
594 above, users could call ioctl (DFL_FPGA_*_GET_IRQ_NUM) to know whether or how
595 many interrupts are supported for this private feature. Drivers also implement
596 an eventfd based interrupt handling mechanism for users to get notified when
597 interrupt happens. Users could set eventfds to driver via
598 ioctl (DFL_FPGA_*_SET_IRQ), and then poll/select on these eventfds waiting for
599 notification.
600 In Current DFL, 3 sub features (Port error, FME global error and AFU interrupt)
601 support interrupts.
602
603
604 Add new FIUs support
605 ====================
606 It's possible that developers made some new function blocks (FIUs) under this
607 DFL framework, then new platform device driver needs to be developed for the
608 new feature dev (FIU) following the same way as existing feature dev drivers
609 (e.g. FME and Port/AFU platform device driver). Besides that, it requires
610 modification on DFL framework enumeration code too, for new FIU type detection
611 and related platform devices creation.
612
613
614 Add new private features support
615 ================================
616 In some cases, we may need to add some new private features to existing FIUs
617 (e.g. FME or Port). Developers don't need to touch enumeration code in DFL
618 framework, as each private feature will be parsed automatically and related
619 mmio resources can be found under FIU platform device created by DFL framework.
620 Developer only needs to provide a sub feature driver with matched feature id.
621 FME Partial Reconfiguration Sub Feature driver (see drivers/fpga/dfl-fme-pr.c)
622 could be a reference.
623
624 Please refer to below link to existing feature id table and guide for new feature
625 ids application.
626 https://github.com/OPAE/dfl-feature-id
627
628
629 Location of DFLs on a PCI Device
630 ================================
631 The original method for finding a DFL on a PCI device assumed the start of the
632 first DFL to offset 0 of bar 0. If the first node of the DFL is an FME,
633 then further DFLs in the port(s) are specified in FME header registers.
634 Alternatively, a PCIe vendor specific capability structure can be used to
635 specify the location of all the DFLs on the device, providing flexibility
636 for the type of starting node in the DFL. Intel has reserved the
637 VSEC ID of 0x43 for this purpose. The vendor specific
638 data begins with a 4 byte vendor specific register for the number of DFLs followed 4 byte
639 Offset/BIR vendor specific registers for each DFL. Bits 2:0 of Offset/BIR register
640 indicates the BAR, and bits 31:3 form the 8 byte aligned offset where bits 2:0 are
641 zero.
642 ::
643
644 +----------------------------+
645 |31 Number of DFLS 0|
646 +----------------------------+
647 |31 Offset 3|2 BIR 0|
648 +----------------------------+
649 . . .
650 +----------------------------+
651 |31 Offset 3|2 BIR 0|
652 +----------------------------+
653
654 Being able to specify more than one DFL per BAR has been considered, but it
655 was determined the use case did not provide value. Specifying a single DFL
656 per BAR simplifies the implementation and allows for extra error checking.
657
658
659 Userspace driver support for DFL devices
660 ========================================
661 The purpose of an FPGA is to be reprogrammed with newly developed hardware
662 components. New hardware can instantiate a new private feature in the DFL, and
663 then present a DFL device in the system. In some cases users may need a
664 userspace driver for the DFL device:
665
666 * Users may need to run some diagnostic test for their hardware.
667 * Users may prototype the kernel driver in user space.
668 * Some hardware is designed for specific purposes and does not fit into one of
669 the standard kernel subsystems.
670
671 This requires direct access to MMIO space and interrupt handling from
672 userspace. The uio_dfl module exposes the UIO device interfaces for this
673 purpose.
674
675 Currently the uio_dfl driver only supports the Ether Group sub feature, which
676 has no irq in hardware. So the interrupt handling is not added in this driver.
677
678 UIO_DFL should be selected to enable the uio_dfl module driver. To support a
679 new DFL feature via UIO direct access, its feature id should be added to the
680 driver's id_table.
681
682
683 Open discussion
684 ===============
685 FME driver exports one ioctl (DFL_FPGA_FME_PORT_PR) for partial reconfiguration
686 to user now. In the future, if unified user interfaces for reconfiguration are
687 added, FME driver should switch to them from ioctl interface.
688

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

DFL framework의 목적

1-19

Device Feature List(DFL) FPGA framework와 그 규약을 따르는 driver는 하위 hardware 세부를 감추고 사용자 공간에 통합 interface를 제공한다. Application은 device memory에 DFL을 구현한 platform에서 이 interface로 FPGA accelerator를 구성하고, 열거하고, 열고, 접근할 수 있다.

DFL framework는 accelerator 접근뿐 아니라 FPGA reconfiguration 같은 system-level management 기능도 제공한다. 따라서 하나의 고정 accelerator API가 아니라 hardware feature 발견, management unit, programmable region, 사용자 공간 access를 연결하는 공통 기반으로 이해해야 한다.

문서 저자는 Enno Luebbers, Xiao Guangrong, Wu Hao, Xu Yilun이며 각 이름과 email은 원문에 보존되어 있다.

DFL framework가 통합하는 작업
영역제공 기능
Accelerator accessconfigure, enumerate, open, access
System managementFPGA reconfiguration과 infrastructure 관리
Hardware abstraction하위 register 배치와 device 차이를 공통 interface로 은닉

사용자 공간 기능과 system management 기능을 구분한다.

=================================================
FPGA Device Feature List (DFL) Framework Overview
=================================================

Authors:

- Enno Luebbers <[email protected]>
- Xiao Guangrong <[email protected]>
- Wu Hao <[email protected]>
- Xu Yilun <[email protected]>

The Device Feature List (DFL) FPGA framework (and drivers according to
this framework) hides the very details of low layer hardware and provides
unified interfaces to userspace. Applications could use these interfaces to
configure, enumerate, open and access FPGA accelerators on platforms which
implement the DFL in the device memory. Besides this, the DFL framework
enables system level management functions such as FPGA reconfiguration.

Device Feature List 구조

20-77

DFL은 device MMIO space 안의 feature header를 linked list로 연결해 새 기능을 확장 가능하게 추가하는 형식이다. Software는 미리 정의된 구조를 순회하여 FPGA Interface Unit(FIU), Accelerated Function Unit(AFU), Private Feature를 열거한다.

FIU는 FPGA와의 interface를 제공하는 독립 functional unit이며 대표적으로 FPGA Management Engine(FME)과 Port가 있다. AFU는 FPGA programmable region을 나타내며 항상 Port 같은 FIU의 child로 연결된다. Private Feature는 FIU 또는 AFU 내부의 sub-feature로, 서로 다른 ID를 가진 function block일 수 있다.

같은 FIU나 AFU에 속한 Private Feature는 `Next_DFH` pointer를 통해 하나의 list로 연결되어야 한다. FIU와 AFU의 functional register 집합은 Header Register Set, Private Feature의 register 집합은 Feature Register Set이라 부른다. 예로 FME Header Register Set과 FME Partial Reconfiguration Feature Register Set이 있다.

원문의 ASCII 도식은 첫 FIU header에서 `Next_DFH`로 여러 Private Feature를 순회하고, 별도의 `Next_AFU`가 AFU header를 가리키는 관계를 보여 준다.

DFL linked list
FIU Header: Type·ID·Header Register SetNext_DFHPrivate Feature 1: ID·Feature Register SetNext_DFHPrivate Feature 2Next_DFH ... EOL/NULL

원문 ASCII 도식의 header 연결을 구조화했다.

DFL feature type
Type역할관계
FIUFPGA interface를 제공하는 standalone unitFME 또는 Port
AFUAccelerator용 programmable regionFIU의 child
Private FeatureFIU/AFU 내부 function blockNext_DFH list로 연결

상위 unit과 programmable region, sub-feature의 역할을 비교한다.

Device Feature List (DFL) Overview
==================================
Device Feature List (DFL) defines a linked list of feature headers within the
device MMIO space to provide an extensible way of adding features. Software can
walk through these predefined data structures to enumerate FPGA features:
FPGA Interface Unit (FIU), Accelerated Function Unit (AFU) and Private Features,
as illustrated below::

    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 Interface Unit (FIU) represents a standalone functional unit for the
interface to FPGA, e.g. the FPGA Management Engine (FME) and Port (more
descriptions on FME and Port in later sections).

Accelerated Function Unit (AFU) represents an FPGA programmable region and
always connects to a FIU (e.g. a Port) as its child as illustrated above.

Private Features represent sub features of the FIU and AFU. They could be
various function blocks with different IDs, but all private features which
belong to the same FIU or AFU, must be linked to one list via the Next Device
Feature Header (Next_DFH) pointer.

Each FIU, AFU and Private Feature could implement its own functional registers.
The functional register set for FIU and AFU, is named as Header Register Set,
e.g. FME Header Register Set, and the one for Private Feature, is named as
Feature Register Set, e.g. FME Partial Reconfiguration Feature Register Set.

This Device Feature List provides a way of linking features together, it's
convenient for software to locate each feature by walking through this list,
and can be implemented in register regions of any FPGA device.

Device Feature Header Version 0

78-114

DFHv0는 원래 Device Feature Header 형식이며 모든 multi-byte quantity는 little-endian이다. Offset `0x00`의 64-bit word에는 `Type`, `DFH VER`, reserved field, `EOL`, `Next`, `REV`, `ID`가 배치된다.

`Type`은 FME·AFU·Private Feature를 구분하고 `DFH VER`는 header version이다. `EOL`은 현재 DFH가 DFL 끝임을 나타낸다. `Next`는 현재 DFH 시작점에서 다음 DFH까지의 byte offset이며 DFH 시작 주소는 8-byte boundary에 정렬되어야 한다. EOL이면 `Next`는 마지막 feature의 MMIO 크기다.

`REV`는 이 header와 연관된 feature revision이고 `ID`는 Type이 Private Feature일 때의 feature ID다. Offset `0x08`의 `GUID_L`과 `0x10`의 `GUID_H`는 Type이 FME 또는 AFU일 때만 존재하며 128-bit GUID의 하위·상위 64 bit를 담는다.

DFHv0 register layout
OffsetFields범위
0x00Type, DFH VER, Rsvd, EOL, Next, REV, ID63..0
0x08GUID_LGUID 63..0
0x10GUID_HGUID 127..64

원문 bit-field ASCII 도식을 offset 단위로 정리한다.

DFHv0 순회 규칙
8-byte aligned DFH에서 시작Type·REV·ID 해석EOL = 0이면 Next byte offset만큼 이동EOL = 1이면 Next를 마지막 feature MMIO size로 해석DFL 순회 종료

Next와 EOL을 사용해 MMIO list를 걷는 과정이다.

Device Feature Header - Version 0
=================================
Version 0 (DFHv0) is the original version of the Device Feature Header.
All multi-byte quantities in DFHv0 are little-endian.
The format of DFHv0 is shown below::

    +-----------------------------------------------------------------------+
    |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
    +-----------------------------------------------------------------------+

- Offset 0x00

  * Type - The type of DFH (e.g. FME, AFU, or private feature).
  * DFH VER - The version of the DFH.
  * Rsvd - Currently unused.
  * EOL - Set if the DFH is the end of the Device Feature List (DFL).
  * Next - The offset in bytes of the next DFH in the DFL from the DFH start,
    and the start of a DFH must be aligned to an 8 byte boundary.
    If EOL is set, Next is the size of MMIO of the last feature in the list.
  * REV - The revision of the feature associated with this header.
  * ID - The feature ID if Type is private feature.

- Offset 0x08

  * GUID_L - Least significant 64 bits of a 128-bit Globally Unique Identifier
    (present only if Type is FME or AFU).

- Offset 0x10

  * GUID_H - Most significant 64 bits of a 128-bit Globally Unique Identifier
    (present only if Type is FME or AFU).

Device Feature Header Version 1

115-196

DFHv1은 feature가 parameter와 capability를 software에 설명하는 표준 mechanism을 추가하고, 모든 type에서 GUID 사용을 표준화하며, DFH 위치와 feature register space 위치를 분리한다. 모든 multi-byte quantity는 DFHv0와 마찬가지로 little-endian이다.

Offset `0x00`, `0x08`, `0x10`의 기본 field는 DFHv0와 같지만 GUID는 모든 DFHv1 type에 적용된다. Offset `0x18`은 `Reg Address/Offset`과 `Rel` bit를 가진다. `Rel`이 설정되면 값은 feature register의 16-bit aligned absolute address 상위 63 bit이고, 그렇지 않으면 DFH 시작점 기준 offset이다.

Offset `0x20`에는 register set byte 크기인 `Reg Size`, parameter block list 존재 여부인 `Params`, feature group ID인 `Group`, group 안의 feature instance ID인 `Instance`가 있다.

Parameter가 있으면 offset `0x28`부터 block을 읽는다. `Next`는 다음 parameter block까지의 8-byte word offset이며 `EOP`가 설정되면 마지막 parameter 크기다. `Param Version`과 `Param ID`가 data format을 식별하고, offset `0x30` 이후 `Parameter Data`의 크기와 형식은 이 version과 ID로 정의된다.

DFHv1 header layout
OffsetFields핵심 의미
0x00Type·DFH VER·EOL·Next·REV·IDList와 feature 기본 정보
0x08GUID_L128-bit GUID 하위 64 bit
0x10GUID_H128-bit GUID 상위 64 bit
0x18Reg Address/Offset·RelRegister 위치 지정
0x20Reg Size·Params·Group·Instance크기와 grouping

DFHv1의 고정 header를 offset별로 정리한다.

DFHv1 parameter block
OffsetFields단위
0x28Next·Rsvd·EOP·Param Version·Param IDNext는 8-byte words
0x30Parameter DataVersion과 ID가 크기·형식 정의

반복 가능한 parameter header와 data의 관계다.

DFHv1 register 주소 해석
Offset 0x18의 Rel 확인Rel = 1: 16-bit aligned absolute address의 상위 63 bitRel = 0: DFH 시작 기준 register offsetReg Size로 register set 범위 확정

Rel bit에 따라 같은 field를 다르게 해석한다.

Device Feature Header - Version 1
=================================
Version 1 (DFHv1) of the Device Feature Header adds the following functionality:

* Provides a standardized mechanism for features to describe
  parameters/capabilities to software.
* Standardize the use of a GUID for all DFHv1 types.
* Decouples the DFH location from the register space of the feature itself.

All multi-byte quantities in DFHv1 are little-endian.
The format of Version 1 of the Device Feature Header (DFH) is shown below::

    +-----------------------------------------------------------------------+
    |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|
    +-----------------------------------------------------------------------+

- Offset 0x00

  * Type - The type of DFH (e.g. FME, AFU, or private feature).
  * DFH VER - The version of the DFH.
  * Rsvd - Currently unused.
  * EOL - Set if the DFH is the end of the Device Feature List (DFL).
  * Next - The offset in bytes of the next DFH in the DFL from the DFH start,
    and the start of a DFH must be aligned to an 8 byte boundary.
    If EOL is set, Next is the size of MMIO of the last feature in the list.
  * REV - The revision of the feature associated with this header.
  * ID - The feature ID if Type is private feature.

- Offset 0x08

  * GUID_L - Least significant 64 bits of a 128-bit Globally Unique Identifier.

- Offset 0x10

  * GUID_H - Most significant 64 bits of a 128-bit Globally Unique Identifier.

- Offset 0x18

  * Reg Address/Offset - If Rel bit is set, then the value is the high 63 bits
    of a 16-bit aligned absolute address of the feature's registers. Otherwise
    the value is the offset from the start of the DFH of the feature's registers.

- Offset 0x20

  * Reg Size - Size of feature's register set in bytes.
  * Params - Set if DFH has a list of parameter blocks.
  * Group - Id of group if feature is part of a group.
  * Instance - Id of feature instance within a group.

- Offset 0x28 if feature has parameters

  * Next - Offset to the next parameter block in 8 byte words. If EOP set,
    size in 8 byte words of last parameter.
  * Param Version - Version of Param ID.
  * Param ID - ID of parameter.

- Offset 0x30

  * Parameter Data - Parameter data whose size and format is defined by
    version and ID of the parameter.

FIU FME 관리 기능

197-248

FPGA Management Engine(FME)은 reconfiguration과 기타 infrastructure 기능을 수행하며 FPGA device마다 하나만 존재한다. 사용자 공간 application은 `open()`으로 FME에 exclusive access를 얻고 `close()`로 해제한다.

Ioctl은 API version 조회, extension 확인, bitstream programming, Port의 PF assign·release, FME global error interrupt 개수 조회와 trigger 설정을 제공한다. Symbol은 각각 `DFL_FPGA_GET_API_VERSION`, `DFL_FPGA_CHECK_EXTENSION`, `DFL_FPGA_FME_PORT_PR`, `DFL_FPGA_FME_PORT_ASSIGN`, `DFL_FPGA_FME_PORT_RELEASE`, `DFL_FPGA_FME_ERR_GET_IRQ_NUM`, `DFL_FPGA_FME_ERR_SET_IRQ`다.

Sysfs 경로 `/sys/class/fpga_region/regionX/dfl-fme.n/`에서는 `bitstream_id`, `bitstream_metadata`, `ports_num`, `errors/`를 제공한다. `dfl_fme_power`와 `dfl_fme_thermal` hwmon interface는 전력·온도·threshold 정보를 노출하며, performance counter는 perf PMU API로 제공한다.

FME ioctl
기능Ioctl
Driver API versionDFL_FPGA_GET_API_VERSION
Extension 확인DFL_FPGA_CHECK_EXTENSION
Bitstream programmingDFL_FPGA_FME_PORT_PR
Port를 PF에 assignDFL_FPGA_FME_PORT_ASSIGN
Port를 PF에서 releaseDFL_FPGA_FME_PORT_RELEASE
Global error IRQ 개수DFL_FPGA_FME_ERR_GET_IRQ_NUM
Global error triggerDFL_FPGA_FME_ERR_SET_IRQ

FME device node의 관리 command를 그대로 보존한다.

FME sysfs와 reporting
Entry제공 정보
bitstream_idStatic FPGA region version
bitstream_metadataSynthesis date·seed 등 metadata
ports_numFPGA device의 Port 수
errors/Hardware error 조회·clear
dfl_fme_power전력·limit·throttling threshold
dfl_fme_thermal온도·threshold·status
perf PMUPerformance counter events

Static region 정보와 management interface를 분리한다.

FIU - FME (FPGA Management Engine)
==================================
The FPGA Management Engine performs reconfiguration and other infrastructure
functions. Each FPGA device only has one FME.

User-space applications can acquire exclusive access to the FME using open(),
and release it using close().

The following functions are exposed through ioctls:

- Get driver API version (DFL_FPGA_GET_API_VERSION)
- Check for extensions (DFL_FPGA_CHECK_EXTENSION)
- Program bitstream (DFL_FPGA_FME_PORT_PR)
- Assign port to PF (DFL_FPGA_FME_PORT_ASSIGN)
- Release port from PF (DFL_FPGA_FME_PORT_RELEASE)
- Get number of irqs of FME global error (DFL_FPGA_FME_ERR_GET_IRQ_NUM)
- Set interrupt trigger for FME error (DFL_FPGA_FME_ERR_SET_IRQ)

More functions are exposed through sysfs
(/sys/class/fpga_region/regionX/dfl-fme.n/):

 Read bitstream ID (bitstream_id)
     bitstream_id indicates version of the static FPGA region.

 Read bitstream metadata (bitstream_metadata)
     bitstream_metadata includes detailed information of static FPGA region,
     e.g. synthesis date and seed.

 Read number of ports (ports_num)
     one FPGA device may have more than one port, this sysfs interface indicates
     how many ports the FPGA device has.

 Global error reporting management (errors/)
     error reporting sysfs interfaces allow user to read errors detected by the
     hardware, and clear the logged errors.

 Power management (dfl_fme_power hwmon)
     power management hwmon sysfs interfaces allow user to read power management
     information (power consumption, thresholds, threshold status, limits, etc.)
     and configure power thresholds for different throttling levels.

 Thermal management (dfl_fme_thermal hwmon)
     thermal management hwmon sysfs interfaces allow user to read thermal
     management information (current temperature, thresholds, threshold status,
     etc.).

 Performance reporting
     performance counters are exposed through perf PMU APIs. Standard perf tool
     can be used to monitor all available perf events. Please see performance
     counter section below for more detailed information.

FIU Port

249-256

Port는 static FPGA fabric과 AFU를 포함한 partially reconfigurable region 사이의 interface다. Software에서 accelerator로 향하는 communication을 제어하며 reset과 debug 같은 기능을 노출한다.

하나의 FPGA device에는 Port가 여러 개 있을 수 있지만 Port 하나에는 항상 AFU 하나만 연결된다. 이 일대일 관계는 SRIOV 격리와 sysfs enumeration에서도 유지되는 핵심 단위다.

Port의 경계
측면연결 대상
상위Static FPGA fabric
하위Partially reconfigurable region의 AFU 1개
제어SW communication, reset, debug

Static fabric과 reconfigurable accelerator 영역 사이의 책임을 나타낸다.

FIU - PORT
==========
A port represents the interface between the static FPGA fabric and a partially
reconfigurable region containing an AFU. It controls the communication from SW
to the accelerator and exposes features such as reset and debug. Each FPGA
device may have more than one port, but always one AFU per port.

AFU 사용자 공간 interface

257-297

AFU는 Port FIU에 연결되고 accelerator-specific control register에 사용할 고정 길이 MMIO region을 노출한다. 사용자 공간 application은 Port device node를 `open()`해 해당 AFU의 exclusive access를 얻고 `close()`로 해제한다. Accelerator MMIO region은 `mmap()`할 수도 있다.

Port ioctl은 API version과 extension 확인, Port 정보·MMIO region 정보 조회, DMA buffer map·unmap, AFU reset, Port error와 UINT interrupt 수 조회 및 trigger 설정을 제공한다.

`DFL_FPGA_PORT_RESET`은 FPGA Port와 AFU를 reset한다. DMA나 Partial Reconfiguration 중에도 언제든 실행할 수 있지만 system-level 문제를 일으켜서는 안 된다. DMA 또는 PR operation failure 같은 functional failure는 가능하되 복구 가능해야 한다.

Sysfs `/sys/class/fpga_region/<regionX>/<dfl-port.m>/`의 `afu_id`는 어떤 PR bitstream이 AFU에 programming되었는지 나타내고, `errors/`는 Port/AFU error를 읽고 clear하게 한다.

AFU와 Port ioctl
기능군Ioctl
VersionDFL_FPGA_GET_API_VERSION, DFL_FPGA_CHECK_EXTENSION
정보DFL_FPGA_PORT_GET_INFO, DFL_FPGA_PORT_GET_REGION_INFO
DMADFL_FPGA_PORT_DMA_MAP, DFL_FPGA_PORT_DMA_UNMAP
ResetDFL_FPGA_PORT_RESET
Port error IRQDFL_FPGA_PORT_ERR_GET_IRQ_NUM, DFL_FPGA_PORT_ERR_SET_IRQ
UINT IRQDFL_FPGA_PORT_UINT_GET_IRQ_NUM, DFL_FPGA_PORT_UINT_SET_IRQ

사용자 공간 accelerator access command를 기능군으로 묶는다.

AFU access lifecycle
Port device node open()Exclusive AFU access 획득Region info 조회 및 mmap() 또는 DMA mapAccelerator-specific register 제어필요 시 recoverable Port resetclose()로 access 해제

Exclusive access부터 MMIO 사용과 해제까지의 흐름이다.

AFU
===
An AFU is attached to a port FIU and exposes a fixed length MMIO region to be
used for accelerator-specific control registers.

User-space applications can acquire exclusive access to an AFU attached to a
port by using open() on the port device node and release it using close().

The following functions are exposed through ioctls:

- Get driver API version (DFL_FPGA_GET_API_VERSION)
- Check for extensions (DFL_FPGA_CHECK_EXTENSION)
- Get port info (DFL_FPGA_PORT_GET_INFO)
- Get MMIO region info (DFL_FPGA_PORT_GET_REGION_INFO)
- Map DMA buffer (DFL_FPGA_PORT_DMA_MAP)
- Unmap DMA buffer (DFL_FPGA_PORT_DMA_UNMAP)
- Reset AFU (DFL_FPGA_PORT_RESET)
- Get number of irqs of port error (DFL_FPGA_PORT_ERR_GET_IRQ_NUM)
- Set interrupt trigger for port error (DFL_FPGA_PORT_ERR_SET_IRQ)
- Get number of irqs of UINT (DFL_FPGA_PORT_UINT_GET_IRQ_NUM)
- Set interrupt trigger for UINT (DFL_FPGA_PORT_UINT_SET_IRQ)

DFL_FPGA_PORT_RESET:
  reset the FPGA Port and its AFU. Userspace can do Port
  reset at any time, e.g. during DMA or Partial Reconfiguration. But it should
  never cause any system level issue, only functional failure (e.g. DMA or PR
  operation failure) and be recoverable from the failure.

User-space applications can also mmap() accelerator MMIO regions.

More functions are exposed through sysfs:
(/sys/class/fpga_region/<regionX>/<dfl-port.m>/):

 Read Accelerator GUID (afu_id)
     afu_id indicates which PR bitstream is programmed to this AFU.

 Error reporting (errors/)
     error reporting sysfs interfaces allow user to read port/afu errors
     detected by the hardware, and clear the logged errors.

Kernel DFL framework와 driver 계층

298-359

Kernel DFL framework는 container device인 FPGA base region을 만들고, 주어진 DFL에서 feature device와 Private Feature를 발견하며, FME·Port·AFU용 resource를 가진 platform device를 container 아래에 생성한다. Private Feature operation을 추상화해 feature device driver에 common operation도 제공한다.

FPGA DFL Device는 PCIe device나 platform device 등 서로 다른 hardware일 수 있다. System이 device를 만들면 해당 device driver module이 먼저 load되어 memory에서 DFL 위치를 찾고, resource와 함께 `drivers/fpga/dfl.c`의 common enumeration API에 넘긴다.

FME platform driver는 FME device 생성 뒤 자동으로 load된다. Static region version·metadata를 sysfs로 노출하고, PR sub-feature 초기화 때 FPGA manager·bridge·region을 생성한다. `DFL_FPGA_FME_PORT_PR` ioctl을 받으면 FPGA Region common interface를 호출해 대상 Port에 PR bitstream을 적용한다.

AFU driver는 AFU platform device가 만들어지면 probe되며 Port reset, AFU MMIO export, DMA buffer mapping을 사용자 공간에 제공한다. Feature platform device 생성 뒤에는 match되는 platform driver가 자동 load되어 각 기능을 처리한다.

DFL kernel driver stack
FME Module | AFU ModulesFPGA Container Device (FPGA Base Region)DFL Framework common interfacesFPGA DFL Device Module (PCIe/Platform)FPGA Hardware Device

원문 architecture ASCII 도식을 위에서 아래 순서로 다시 그렸다.

DFL driver 역할
계층역할
DFL device driverDFL 위치·resource 발견 후 common API에 전달
DFL frameworkContainer·platform device 생성, common ops 제공
FME driverStatic region 관리와 Partial Reconfiguration
AFU driverReset, MMIO export, DMA mapping

Enumeration과 feature handling의 소유자를 구분한다.

DFL Framework Overview
======================

::

         +----------+    +--------+ +--------+ +--------+
         |   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 framework in kernel provides common interfaces to create container device
(FPGA base region), discover feature devices and their private features from the
given Device Feature Lists and create platform devices for feature devices
(e.g. FME, Port and AFU) with related resources under the container device. It
also abstracts operations for the private features and exposes common ops to
feature device drivers.

The FPGA DFL Device could be different hardware, e.g. PCIe device, platform
device and etc. Its driver module is always loaded first once the device is
created by the system. This driver plays an infrastructural role in the
driver architecture. It locates the DFLs in the device memory, handles them
and related resources to common interfaces from DFL framework for enumeration.
(Please refer to drivers/fpga/dfl.c for detailed enumeration APIs).

The FPGA Management Engine (FME) driver is a platform driver which is loaded
automatically after FME platform device creation from the DFL device module. It
provides the key features for FPGA management, including:

        a) Expose static FPGA region information, e.g. version and metadata.
           Users can read related information via sysfs interfaces exposed
           by FME driver.

        b) Partial Reconfiguration. The FME driver creates FPGA manager, FPGA
           bridges and FPGA regions during PR sub feature initialization. Once
           it receives a DFL_FPGA_FME_PORT_PR ioctl from user, it invokes the
           common interface function from FPGA Region to complete the partial
           reconfiguration of the PR bitstream to the given port.

Similar to the FME driver, the FPGA Accelerated Function Unit (AFU) driver is
probed once the AFU platform device is created. The main function of this module
is to provide an interface for userspace applications to access the individual
accelerators, including basic reset control on port, AFU MMIO region export, dma
buffer mapping service functions.

After feature platform devices creation, matched platform drivers will be loaded
automatically to handle different functionalities. Please refer to next sections
for detailed information on functional units which have been already implemented
under this DFL framework.

Partial Reconfiguration 호환성

360-371

Accelerator는 PR bitstream file을 사용한 partial reconfiguration으로 다시 구성할 수 있다. 이 file은 정확히 같은 static FPGA region과 대상 reconfigurable region인 Port를 위해 생성된 것이어야 한다.

호환되지 않는 bitstream을 사용하면 operation이 실패하고 system instability까지 일으킬 수 있다. 사용자 공간은 보통 reconfiguration ioctl을 호출하기 전에 PR bitstream header의 compatibility ID와 대상 FPGA region이 노출하는 `compat_id`를 비교해 검증한다.

안전한 Partial Reconfiguration
PR bitstream header의 compatibility ID 읽기Target FPGA region의 compat_id 읽기두 ID와 target Port 일치 확인불일치 시 중단일치 시 reconfiguration IOCTL 호출

Bitstream 적용 전에 compatibility를 확인하는 순서다.

Partial Reconfiguration
=======================
As mentioned above, accelerators can be reconfigured through partial
reconfiguration of a PR bitstream file. The PR bitstream file must have been
generated for the exact static FPGA region and targeted reconfigurable region
(port) of the FPGA, otherwise, the reconfiguration operation will fail and
possibly cause system instability. This compatibility can be checked by
comparing the compatibility ID noted in the header of PR bitstream file against
the compat_id exposed by the target FPGA region. This check is usually done by
userspace before calling the reconfiguration IOCTL.

PCIe SRIOV virtualization

372-466

이 절은 DFL 기반 PCIe FPGA device의 SRIOV 지원을 사용해 VM application에서 accelerator에 접근하는 방법을 설명한다. FME는 항상 physical function(PF)을 통해 접근한다. Port와 AFU도 기본적으로 PF에 속하지만 PCIe SRIOV로 virtual function(VF)에 노출할 수 있다.

격리를 위해 VF 하나에는 Port 하나와 AFU 하나만 들어간다. 개별 VF를 VM에 assign하면 VM 안의 application이 같은 VF driver를 통해 AFU를 사용할 수 있다. FME는 VF에 assign할 수 없으므로 PR과 기타 management 기능은 PF에서만 가능하다.

FPGA PCIe driver는 PF나 VF를 발견하면 항상 먼저 load되어 DFL common interface로 양쪽 device를 enumerate하고 SRIOV를 지원한다. FME driver는 Port를 PF에서 release하거나 다시 PF에 assign하는 ioctl을 제공한다. PF에서 release한 뒤에만 SRIOV sysfs로 해당 Port를 VF에 안전하게 노출할 수 있다.

절차는 PF가 기본 소유한 Port를 FME device의 `DFL_FPGA_FME_PORT_RELEASE`로 release하고, N개 Port가 release되면 `echo N > $PCI_DEVICE_PATH/sriov_numvfs`로 VF를 enable한 다음 VM에 pass-through하는 순서다.

PF와 VF의 DFL unit 소유
FunctionFMEPortAFUManagement
PF항상 포함기본 소유, 여러 개 가능Port별 1개PR·assign·release
VF포함 불가정확히 1개정확히 1개Accelerator access

원문 device topology ASCII 도식의 소유 관계를 구조화한다.

Port를 VF에 assign하는 절차
PF가 모든 AFU Port를 기본 소유DFL_FPGA_FME_PORT_RELEASE ioctlecho N > $PCI_DEVICE_PATH/sriov_numvfs생성된 VF를 VM에 pass-throughVM 내부 VF driver로 AFU access

PF 소유권 release부터 VM access까지의 순서다.

Virtualization driver stack
Host PF: FME Module + AFU ModuleHost FPGA Container DeviceHost FPGA PCIe Module -> PCI PF DevicePCIe SRIOV / VF pass-throughVM: AFU Module -> FPGA Container DeviceVM FPGA PCIe Module -> PCI VF Device

원문 host/VM ASCII 도식을 두 stack으로 나타낸다.

FPGA virtualization - PCIe SRIOV
================================
This section describes the virtualization support on DFL based FPGA device to
enable accessing an accelerator from applications running in a virtual machine
(VM). This section only describes the PCIe based FPGA device with SRIOV support.

Features supported by the particular FPGA device are exposed through Device
Feature Lists, as illustrated below:

::

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

FME is always accessed through the physical function (PF).

Ports (and related AFUs) are accessed via PF by default, but could be exposed
through virtual function (VF) devices via PCIe SRIOV. Each VF only contains
1 Port and 1 AFU for isolation. Users could assign individual VFs (accelerators)
created via PCIe SRIOV interface, to virtual machines.

The driver organization in virtualization case is illustrated below:
::

    +-------++------++------+             |
    | 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 device driver is always loaded first once an FPGA PCIe PF or VF device
is detected. It:

* Finishes enumeration on both FPGA PCIe PF and VF device using common
  interfaces from DFL framework.
* Supports SRIOV.

The FME device driver plays a management role in this driver architecture, it
provides ioctls to release Port from PF and assign Port to PF. After release
a port from PF, then it's safe to expose this port through a VF via PCIe SRIOV
sysfs interface.

To enable accessing an accelerator from applications running in a VM, the
respective AFU's port needs to be assigned to a VF using the following steps:

#. The PF owns all AFU ports by default. Any port that needs to be
   reassigned to a VF must first be released through the
   DFL_FPGA_FME_PORT_RELEASE ioctl on the FME device.

#. Once N ports are released from PF, then user can use command below
   to enable SRIOV and VFs. Each VF owns only one Port with AFU.

   ::

      echo N > $PCI_DEVICE_PATH/sriov_numvfs

#. Pass through the VFs to VMs

#. The AFU under VF is accessible from applications in VM (using the
   same driver inside the VF).

Note that an FME can't be assigned to a VF, thus PR and other management
functions are only available via the PF.

Sysfs device enumeration

467-511

Application은 `/sys/class/fpga_region` 아래 hierarchy에서 FPGA device를 enumerate한다. 예제 host에는 DFL FPGA device 두 개가 있고 각 device는 FME 하나와 Port/AFU 두 개를 가진다. FPGA region은 `region0`, `region1`, `region2`처럼 생성된다.

각 `regionX` folder를 검색해 `dfl-port.n` 또는 `dfl-fme.m` feature device가 있으면 그 region이 FPGA device를 나타내는 base region이다. Child는 `region0/dfl-fme.0`, `region0/dfl-port.0`, `region0/dfl-port.1` 같은 형태다.

일반 형식은 `/sys/class/fpga_region/<regionX>/<dfl-fme.n>/`과 `/sys/class/fpga_region/<regionX>/<dfl-port.m>/`이다. `n`은 모든 FME를 연속 번호화하고 `m`은 모든 Port를 연속 번호화한다. `ioctl()` 또는 `mmap()` device node는 각 directory의 `dev` entry를 통해 참조한다.

DFL sysfs naming
대상Path
Base region/sys/class/fpga_region/regionX
FME/sys/class/fpga_region/<regionX>/<dfl-fme.n>/
Port/AFU/sys/class/fpga_region/<regionX>/<dfl-port.m>/
FME dev<dfl-fme.n>/dev
Port dev<dfl-port.n>/dev

Base region과 child feature path 형식을 정리한다.

Application enumeration
/sys/class/fpga_region의 regionX 순회dfl-fme.* 또는 dfl-port.* child 검색발견한 regionX를 FPGA base region으로 식별FME와 Port child 목록 구성dev entry로 ioctl/mmap device 참조

Sysfs에서 실제 FPGA base region을 찾는 과정이다.

Device enumeration
==================
This section introduces how applications enumerate the fpga device from
the sysfs hierarchy under /sys/class/fpga_region.

In the example below, two DFL based FPGA devices are installed in the host. Each
fpga device has one FME and two ports (AFUs).

FPGA regions are created under /sys/class/fpga_region/::

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

Application needs to search each regionX folder, if feature device is found,
(e.g. "dfl-port.n" or "dfl-fme.m" is found), then it's the base
fpga region which represents the FPGA device.

Each base region has one FME and two ports (AFUs) as child devices::

        /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
        ...

In general, the FME/AFU sysfs interfaces are named as follows::

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

with 'n' consecutively numbering all FMEs and 'm' consecutively numbering all
ports.

The device nodes used for ioctl() or mmap() can be referenced through::

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

FME Performance Counters

512-590

Performance reporting은 FME에 구현된 Private Feature다. Hardware는 `basic`, `cache`, `fabric`, `vtd`, `vtd_sip` 같은 독립적인 system-wide counter set을 제공할 수 있다. 사용자는 표준 perf tool로 cache hit/miss, transaction 수, AFU interface clock 등 지원 event를 감시한다.

Hardware별 counter set은 다르므로 `perf list`로 대상 device의 event를 확인해야 한다. Driver는 perf PMU와 `/sys/bus/event_source/devices/dfl_fme*` 아래 sysfs interface를 만들어 event와 option을 설명한다.

`format` directory는 `struct perf_event_attr.config`의 세 bitfield를 정의한다. `evtype`은 event category, `event`는 category 안의 event ID, `portid`는 전체 FPGA와 특정 Port 중 감시 대상을 정한다. `events` directory는 perf에서 바로 쓸 configuration template를 제공한다.

예를 들어 `fab_mmio_read`는 `event=0x06,evtype=0x02,portid=0xff`이며 전체 fabric을 감시한다. `fab_port_mmio_read`는 특정 Port를 위해 `portid=?`를 명시해야 한다. Symbolic event, field expression, raw `config` 세 방식으로 같은 event를 지정할 수 있다.

Fabric overall event인 `fab_*`와 per-Port event인 `fab_port_*`는 hardware counter set 하나를 공유하므로 동시에 감시할 수 없다. `cpumask`에는 system-wide counter를 access할 CPU ID 하나만 들어가며 multi-CPU counting은 허용되지 않는다. 현재 driver는 sampling을 지원하지 않아 `perf record`도 지원하지 않는다.

DFL perf config bitfield
Field의미예제
evtypeEvent categoryfabric = 0x02
eventCategory 내부 event IDMMIO read = 0x06
portid전체 또는 특정 Portoverall = 0xff

perf_event_attr.config를 구성하는 세 field다.

Performance event 사용
perf list에서 dfl_fme event 확인Symbolic template 또는 evtype/event/portid 선택필요한 경우 특정 portid 지정perf stat -a -e ... 실행Counter 공유와 cpumask 제한 확인

Hardware 지원 확인부터 perf stat까지의 흐름이다.

Performance counter 제약
제약결과
fab_*와 fab_port_*같은 hardware counter set이라 동시 감시 불가
cpumaskAccess CPU 하나만 허용
System-wide counterMultiple CPU counting 불가
Sampling미지원, perf record 사용 불가

동시 사용과 sampling 제한을 구분한다.

Performance Counters
====================
Performance reporting is one private feature implemented in FME. It could
supports several independent, system-wide, device counter sets in hardware to
monitor and count for performance events, including "basic", "cache", "fabric",
"vtd" and "vtd_sip" counters. Users could use standard perf tool to monitor
FPGA cache hit/miss rate, transaction number, interface clock counter of AFU
and other FPGA performance events.

Different FPGA devices may have different counter sets, depending on hardware
implementation. E.g., some discrete FPGA cards don't have any cache. User could
use "perf list" to check which perf events are supported by target hardware.

In order to allow user to use standard perf API to access these performance
counters, driver creates a perf PMU, and related sysfs interfaces in
/sys/bus/event_source/devices/dfl_fme* to describe available perf events and
configuration options.

The "format" directory describes the format of the config field of struct
perf_event_attr. There are 3 bitfields for config: "evtype" defines which type
the perf event belongs to; "event" is the identity of the event within its
category; "portid" is introduced to decide counters set to monitor on FPGA
overall data or a specific port.

The "events" directory describes the configuration templates for all available
events which can be used with perf tool directly. For example, fab_mmio_read
has the configuration "event=0x06,evtype=0x02,portid=0xff", which shows this
event belongs to fabric type (0x02), the local event id is 0x06 and it is for
overall monitoring (portid=0xff).

Example usage of 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>

Another example, fab_port_mmio_read monitors mmio read of a specific port. So
its configuration template is "event=0x06,evtype=0x01,portid=?". The portid
should be explicitly set.

Its usage of 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>

Please note for fabric counters, overall perf events (fab_*) and port perf
events (fab_port_*) actually share one set of counters in hardware, so it can't
monitor both at the same time. If this set of counters is configured to monitor
overall data, then per port perf data is not supported. See below example::

  $# 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

The driver also provides a "cpumask" sysfs attribute, which contains only one
CPU id used to access these perf events. Counting on multiple CPU is not allowed
since they are system-wide counters on FPGA device.

The current driver does not support sampling. So "perf record" is unsupported.

Interrupt 지원

591-603

일부 FME와 AFU Private Feature는 interrupt를 생성할 수 있다. 사용자는 `DFL_FPGA_*_GET_IRQ_NUM` ioctl로 해당 feature의 interrupt 지원 여부와 개수를 확인한다.

Driver는 eventfd 기반 interrupt handling을 구현한다. 사용자는 `DFL_FPGA_*_SET_IRQ` ioctl로 eventfd를 driver에 설정하고 `poll()` 또는 `select()`로 notification을 기다린다. 현재 DFL에서 interrupt를 지원하는 sub-feature는 Port error, FME global error, AFU interrupt 세 가지다.

Interrupt 지원 sub-feature
Sub-feature범위
Port errorPort fault notification
FME global errorDevice management global fault
AFU interruptAccelerator UINT

현재 구현된 세 interrupt source를 정리한다.

Eventfd interrupt 처리
DFL_FPGA_*_GET_IRQ_NUM 호출지원 IRQ 개수 확인eventfd 생성DFL_FPGA_*_SET_IRQ로 driver에 등록poll/select로 interrupt notification 대기

IRQ capability 확인부터 사용자 공간 notification까지다.

Interrupt support
=================
Some FME and AFU private features are able to generate interrupts. As mentioned
above, users could call ioctl (DFL_FPGA_*_GET_IRQ_NUM) to know whether or how
many interrupts are supported for this private feature. Drivers also implement
an eventfd based interrupt handling mechanism for users to get notified when
interrupt happens. Users could set eventfds to driver via
ioctl (DFL_FPGA_*_SET_IRQ), and then poll/select on these eventfds waiting for
notification.
In Current DFL, 3 sub features (Port error, FME global error and AFU interrupt)
support interrupts.

새 FIU 지원 추가

604-613

DFL framework 아래에 새 functional block인 FIU를 추가하면 기존 FME와 Port/AFU driver와 같은 방식의 새 platform device driver가 필요하다.

새 FIU type을 발견하고 관련 platform device를 생성해야 하므로 DFL framework enumeration code도 수정해야 한다. 새 FIU는 기존 Private Feature 추가와 달리 상위 feature device type 자체를 확장하기 때문이다.

새 FIU 구현
새 FIU type과 register contract 정의DFL enumeration code에 type detection 추가관련 platform device 생성 지원새 FIU platform driver 구현기존 FME/Port 방식으로 probe와 resource 검증

Framework와 driver 양쪽에 필요한 변경이다.

Add new FIUs support
====================
It's possible that developers made some new function blocks (FIUs) under this
DFL framework, then new platform device driver needs to be developed for the
new feature dev (FIU) following the same way as existing feature dev drivers
(e.g. FME and Port/AFU platform device driver). Besides that, it requires
modification on DFL framework enumeration code too, for new FIU type detection
and related platform devices creation.

새 Private Feature 지원 추가

614-628

기존 FME 또는 Port에 새 Private Feature를 추가할 때는 DFL framework enumeration code를 수정할 필요가 없다. 각 Private Feature는 자동 parse되고 MMIO resource는 framework가 만든 FIU platform device 아래에서 찾을 수 있다.

Developer는 일치하는 feature ID를 가진 sub-feature driver만 제공하면 된다. `drivers/fpga/dfl-fme-pr.c`의 FME Partial Reconfiguration Sub Feature driver를 참고할 수 있다. 기존 feature ID table과 신규 ID 신청 안내는 `https://github.com/OPAE/dfl-feature-id`에 있다.

FIU와 Private Feature 확장 비교
확장 대상Enumeration 수정필요 driver
새 FIU필요새 platform device driver
새 Private Feature불필요, 자동 parseMatched feature ID의 sub-feature driver

Enumeration code 수정 필요 여부가 핵심 차이다.

Add new private features support
================================
In some cases, we may need to add some new private features to existing FIUs
(e.g. FME or Port). Developers don't need to touch enumeration code in DFL
framework, as each private feature will be parsed automatically and related
mmio resources can be found under FIU platform device created by DFL framework.
Developer only needs to provide a sub feature driver with matched feature id.
FME Partial Reconfiguration Sub Feature driver (see drivers/fpga/dfl-fme-pr.c)
could be a reference.

Please refer to below link to existing feature id table and guide for new feature
ids application.
https://github.com/OPAE/dfl-feature-id

PCI device에서 DFL 위치 찾기

629-658

원래 방식은 첫 DFL이 BAR 0의 offset 0에서 시작한다고 가정했다. 첫 node가 FME이면 추가 DFL 위치는 FME header register의 Port 정보로 지정한다. 더 유연한 방식으로 PCIe vendor-specific capability structure가 device의 모든 DFL 위치를 지정할 수 있다.

Intel은 이 용도로 VSEC ID `0x43`을 예약했다. Vendor-specific data는 DFL 개수를 담은 4-byte register 하나와 각 DFL의 위치를 담은 4-byte `Offset/BIR` register로 구성된다. `Offset/BIR`의 bit `2:0`은 BAR indicator이고 bit `31:3`은 8-byte aligned offset이며 하위 세 bit는 0이다.

한 BAR에 DFL 여러 개를 지정하는 방식도 검토했지만 가치가 없다고 판단했다. BAR 하나당 DFL 하나로 제한하면 구현이 단순해지고 추가 error checking이 가능하다.

PCI VSEC 0x43 layout
RegisterBits내용
DFL count31:0Number of DFLs
Offset/BIR2:0BAR Indicator Register
Offset/BIR31:38-byte aligned DFL offset

원문 register ASCII 도식을 4-byte field 단위로 재구성한다.

PCI DFL 위치 결정
PCIe VSEC ID 0x43 존재 여부 확인있음: DFL count와 각 Offset/BIR 해석없음: BAR 0 offset 0에서 첫 DFL 가정첫 node가 FME면 FME header에서 Port DFL 탐색BAR당 DFL 하나 규칙으로 범위 검증

Legacy BAR0 방식과 VSEC 방식의 선택지를 보여 준다.

Location of DFLs on a PCI Device
================================
The original method for finding a DFL on a PCI device assumed the start of the
first DFL to offset 0 of bar 0.  If the first node of the DFL is an FME,
then further DFLs in the port(s) are specified in FME header registers.
Alternatively, a PCIe vendor specific capability structure can be used to
specify the location of all the DFLs on the device, providing flexibility
for the type of starting node in the DFL.  Intel has reserved the
VSEC ID of 0x43 for this purpose.  The vendor specific
data begins with a 4 byte vendor specific register for the number of DFLs followed 4 byte
Offset/BIR vendor specific registers for each DFL. Bits 2:0 of Offset/BIR register
indicates the BAR, and bits 31:3 form the 8 byte aligned offset where bits 2:0 are
zero.
::

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

Being able to specify more than one DFL per BAR has been considered, but it
was determined the use case did not provide value.  Specifying a single DFL
per BAR simplifies the implementation and allows for extra error checking.

DFL device용 userspace driver

659-682

FPGA는 새 hardware component로 reprogram할 수 있으므로 새 bitstream이 새 Private Feature와 DFL device를 system에 제시할 수 있다. Diagnostic test, kernel driver의 사용자 공간 prototype, 표준 kernel subsystem에 맞지 않는 전용 hardware에는 userspace driver가 필요할 수 있다.

이 용도는 사용자 공간의 직접 MMIO access와 interrupt handling을 요구한다. `uio_dfl` module은 이를 위한 UIO device interface를 노출한다. 현재 driver는 hardware IRQ가 없는 Ether Group sub-feature만 지원하므로 interrupt handling은 아직 추가되지 않았다.

`UIO_DFL`을 선택하면 `uio_dfl` module driver를 enable한다. 새 DFL feature를 UIO direct access로 지원하려면 feature ID를 driver의 `id_table`에 추가해야 한다.

Userspace driver 사용 사례
사례목적
Diagnostic test새 hardware 검증
Kernel driver prototype사용자 공간에서 초기 구현
Special-purpose hardware표준 kernel subsystem에 부적합

Kernel subsystem 밖에서 직접 access가 필요한 이유다.

uio_dfl 확장
Kconfig에서 UIO_DFL 선택uio_dfl module enable지원할 feature ID를 id_table에 추가UIO device를 통해 MMIO direct accessIRQ 지원은 feature와 driver 구현 여부를 별도 확인

새 feature를 UIO로 노출하는 최소 변경 흐름이다.

Userspace driver support for DFL devices
========================================
The purpose of an FPGA is to be reprogrammed with newly developed hardware
components. New hardware can instantiate a new private feature in the DFL, and
then present a DFL device in the system. In some cases users may need a
userspace driver for the DFL device:

* Users may need to run some diagnostic test for their hardware.
* Users may prototype the kernel driver in user space.
* Some hardware is designed for specific purposes and does not fit into one of
  the standard kernel subsystems.

This requires direct access to MMIO space and interrupt handling from
userspace. The uio_dfl module exposes the UIO device interfaces for this
purpose.

Currently the uio_dfl driver only supports the Ether Group sub feature, which
has no irq in hardware. So the interrupt handling is not added in this driver.

UIO_DFL should be selected to enable the uio_dfl module driver. To support a
new DFL feature via UIO direct access, its feature id should be added to the
driver's id_table.

Reconfiguration interface의 향후 과제

683-687

현재 FME driver는 partial reconfiguration을 위해 `DFL_FPGA_FME_PORT_PR` ioctl 하나를 사용자 공간에 제공한다.

향후 통합 reconfiguration user interface가 추가되면 FME driver는 전용 ioctl interface에서 그 공통 interface로 전환해야 한다는 것이 문서의 open discussion이다.

Reconfiguration API 전환 방향
현재: DFL_FPGA_FME_PORT_PR ioctl향후: unified reconfiguration userspace interface 도입FME driver가 전용 ioctl에서 공통 interface로 전환

현재 전용 command에서 향후 공통 interface로 이동하는 목표다.

Open discussion
===============
FME driver exports one ioctl (DFL_FPGA_FME_PORT_PR) for partial reconfiguration
to user now. In the future, if unified user interfaces for reconfiguration are
added, FME driver should switch to them from ioctl interface.