# dfx-mgr **Repository Path**: mirrors_Xilinx/dfx-mgr ## Basic Information - **Project Name**: dfx-mgr - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-04-20 - **Last Updated**: 2026-09-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #### Copyright (c) 2022 - 2026, Advanced Micro Devices, Inc. and Contributors. All rights reserved. #### SPDX-License-Identifier: MIT ## Overview DFX-MGR provides infrastructure to abstract configuration and hardware resource management for dynamic deployment of Xilinx based accelerators across different platforms. DFX-MGR is merged in Yocto Project meta-xilinx layer 2021.1 onwards and the recipe is called `dfx-mgr`. The recipe is not enabled by default and user is expected to enable it. As of today, DFX-MGR can be used for dynamic loading/unloading of accelerators to PL (Programmable Logic). The functionality is tested for loading/unloading of Flat shell (i.e. shell which does not have any reconfigurable partitions) and DFX shell (i.e. shell which contains static and dynamic region). As you can see in the diagram below DFX-MGR can load a 3RP design and a 2RP design with the corresponding accelerators dynamically without having to reboot the board. DFX-MGR now supports lightweight use cases. User can load PL bitstream alone or along with device tree overlay from any path. User can provide the absolute path of bitstream and overlay file as command line options. See Usage guidelines for more details. Once you compile Yocto Project meta-xilinx layer by enabling the dfx-mgr recipe, you should have dfx-mgrd and dfx-mgr-client in `/usr/bin` of rootfs and libdfx-mgr.so in `/usr/lib`. The config file `daemon.conf` can be found in `/etc/dfx-mgrd/`. Config file is mandatory, refer the files section for details of it. A default daemon.conf will be copied by the recipe and the users are expected to update as required. ![Screenshot](https://media.gitenterprise.xilinx.com/user/978/files/c2254180-9d53-11eb-9371-ad2d44922a8b) ## Files required DFX-MGR recognizes the designs under `/lib/firmware/xilinx` on device filesystem, location can be updated in `daemon.conf`. Designs could be downloaded using dnf or any other package manager or manually copied to the previously mentioned location. Each sub-folder upto 5 hierarchical levels under `/lib/firmware/xilinx` will be treated as a base/static shell design if it contain a shell.json file, or the sub-folder name is `rpu` or `RPU`. On Versal and Versal gen2 the base is instead detected by a PDI in the folder and shell.json is ignored. base/static design folder can then have sub-folder for each of the accelerators. Each accelerator is expected to have a accel.json, or on Versal is derived from the partial PDI in its slot directory (accel.json ignored). Have a look at below folder structure for more understanding and the details of json config files. The expected directory structure under `/lib/firmware/xilinx` which contains a 2x1 PL shell design, and a flat shell design. 2x1 `base_design` shell has an accelerator which contains two different partial bitstreams for two slots of base/static shell. `base_design` needs to have base/static shell bitstream and shell.json. DFX-MGR expects '_slot#' as subfolders for each of the accelerators for DFX designs. Place the bitstream corresponding to that slot in the respective subfolder along with accel.json file. It is not mandatory to have all the partial bitstreams for each slot, but DFX-MGR will fail to load an accelerator to the slot if no partial design is found. ### Directory Structure #### DFX, Seg+DFX Designs ``` /lib/firmware/xilinx/ └── ├── shell.json # Base/Static design configuration ├── .pdi/.bit.bin # Static base bitstream ├── .dtbo # Base device tree overlay └── / ├── _slot0/ │ ├── accel.json # Accelerator configuration │ ├── .pdi/.bit.bin # Partial bitstream for slot 0 │ └── .dtbo # Device tree overlay for slot 0 └── _slot1/ ├── accel.json ├── .pdi/.bit.bin # Partial bitstream for slot 1 └── .dtbo ``` #### Flat Designs ``` /lib/firmware/xilinx/ └── / # Flat design structure ├── .pdi # Flat bitstream ├── .dtbo # Flat device tree overlay └── shell.json # Flat design configuration ``` #### RPU Designs (New Structure - Recommended) ``` /lib/firmware/xilinx/ └── / └── rpu/ # RPU base (recognized by directory name) ├── 0/ # Slot 0 directory │ ├── .elf # Each .elf = separate accelerator │ └── .elf ``` #### RPU Designs (Old Structure - Will be deprecated in a future release) ``` /lib/firmware/xilinx/ └── rpu/ # RPU directory structure (case-insensitive) └── / └── _slot0/ └── .elf # RPU firmware file ``` **Key Requirements:** - Base/static design directory must contain `shell.json` (not required for RPU bases, which are detected by directory name `rpu`/`RPU`). On Versal the base is instead detected by the presence of a PDI and `shell.json` is ignored. - PL DFX accelerator subdirectories must follow `_slot` naming convention. New RPU structure uses numeric slot directories (`0/`, `1/`, ...). - Each PL slot directory must contain `accel.json` for proper recognition. On Versal the accelerator is derived from the partial PDI in the slot directory and `accel.json` is not required. - Supports up to 5 hierarchical directory levels under `/lib/firmware/xilinx` #### Versal designs - PDI-based discovery On Versal and Versal gen2, PL design metadata comes from the PDI metaheader rather than from `shell.json`/`accel.json`, which are ignored. The same `//_slot` directory layout applies; DFX-MGR derives the metadata as follows: - **Base design** is recognized by a PDI in the base directory. - **Slot count** is taken from the highest `_slot` index found, so a partially-populated design keeps its upper slots reachable. - **Accelerator type** is derived from the PDI image class: an accelerator whose PDI contains an AIE image is typed `XRT_AIE_DFX`, otherwise `XRT_PL_DFX`. AIE overlays are not supported. - A `_slot` directory is only registered as a loadable slot when it actually contains a partial PDI. - **Design visibility** is enforced by the PLM: it rejects a PDI built for another device, so that design is never listed by `-listPackage`. The daemon log records the failure. The `rpu`/`RPU` directory convention and RPU firmware handling are unchanged on Versal. ### daemon.conf DFX-MGR is started on Linux bootup and reads the config file `/etc/dfx-mgrd/daemon.conf` from device for any config settings. Any change to daemon.conf will need a restart of the `/usr/bin/dfx-mgrd` on target. **Example:** ```json { "default_accel": "/etc/dfx-mgrd/default_firmware", "firmware_location": ["/lib/firmware/xilinx"], "cma_path": "/dev/dma_heap/cma_reserved", "rpu_fw_uptime_msec": 0, "eeprom_location": [ "/sys/bus/i2c/devices/*/eeprom_cc*/nvmem", "/sys/bus/i2c/devices/*50/eeprom", "/sys/bus/i2c/devices/*54/eeprom" ] } ``` **Configuration fields:** | Field | Required | Description | |-------|----------|-------------| | `firmware_location` | Yes | Array of directories where DFX-MGR looks for accelerator packages. The directory structure rules described above apply to each location. | | `default_accel` | No | Path to a file containing the package name to auto-load on daemon startup. Echo the desired package name into this file. | | `cma_path` | No | CMA device path for DMA buffer allocation (e.g., `/dev/dma_heap/cma_reserved`). If not specified, default system CMA paths are used. Can be overridden per-command using the `-cma` option. | | `rpu_fw_uptime_msec` | No | Time in milliseconds to wait for RPU firmware initialization after loading. Default: 0. | | `eeprom_location` | No | Array of sysfs glob paths to I2C EEPROM devices used for board name detection. The detected board name is used by `dfx-mgr-client -listPackage -filter` to show only packages matching the current board. Run `ls /sys/bus/i2c/devices/` on your target to discover available devices. Wildcards are supported for bus number portability. If omitted, EEPROM board detection is skipped and `-filter` has no effect. | ### shell.json shell.json describes the base/static shell configuration information. Optional fields can be skipped if not desired. > **Note:** `shell.json` is ignored on Versal and Versal gen2, where the base > design is discovered from its PDI instead. See *Versal designs - PDI-based > discovery* above. One of the below type should be used for shell_type as per your design. * XRT_FLAT: dfx-mgr will program the PL and update /etc/vart.conf on target with the path to the active xclbin on success. * PL_FLAT: dfx-mgr will program the PL bitstream and treat the design as static. * PL_DFX: dfx-mgr will treat the design as DFX with number of slots as mentioned in json. #### KRIA Designs. ``` $ cat shell.json { "shell_type" : "PL_DFX",// Required: valid values are XRT_FLAT/PL_FLAT/PL_DFX "num_pl_slots": 3, //Required: Number of pl slots in your base shell design "num_aie_slots":1, //Required: Number of aie slots in your base shell design "load_base_design": "no" //Optional : Default is "yes". Set to "no" to skip loading base design "device_name" : "a0010000.dfx_manager", //optional: IP name "reg_base" : "", //Optional: IP device base address "reg_size" : "", //Optional "clock_device_name" : "a0000000.clk_wiz", //optional "clock_reg_base" : "",//optional "clock_reg_size" : "" //optional } ``` > **Note:** The [AIE](https://www.xilinx.com/products/technology/ai-engine.html) > support in dfx-mgr is preliminary and for a future production enablement capability. > [KRIA](https://www.xilinx.com/products/som/kria.html) devices do not have AIE. #### FLAT, DFX, Segmented and Segmented+DFX Designs. ``` { "shell_type": "PL_DFX", //"Supported types are XRT_FLAT/PL_FLAT/PL_DFX" "num_pl_slots": 2, // Required for PL_DFX: Number of pl slots in your static shell design "num_aie_slots":1, //Optional: Default is 0, Set Number of aie slots in your base shell design if present "load_base_design": "no" //Optional : Default is "yes". Set to "no" to skip loading base design } ``` ### accel.json accel.json describes the accelerator configuration. Optional fields can be skipped if not desired. Flat shell designs are not required to have accel.json since they do not have reconfigurable partition. > **Note:** `accel.json` is ignored on Versal and Versal gen2, where each > accelerator (including its type) is derived from the partial PDI in its slot > directory. See *Versal designs - PDI-based discovery* above. * XRT_PL_DFX: Use this option for XRT based PL accelerator. #### KRIA Designs. ``` $ cat accel.json { "accel_type": "", // Required: supported types are XRT_AIE_DFX / XRT_PL_DFX "accel_devices":[ // Optional: list of IP devices corresponding to this slot design { "dev_name": "20100000000.accel", "reg_base":"", "reg_size":"" }], "sharedMemoryConfig": { "sizeInKB": "", "sharedMemType" : ""}, "dataMoverConfig": { // Optional: skip this if application handles its own dma "dma_dev_name":"a4000000.dma", "dma_driver":"vfio-platform", "dma_reg_base":"", "dma_reg_size":"", "iommu_group":"0", "Bus": "platform", "HWType": "mcdma", "max_buf_size":"8388608", "dataMoverCacheCoherent": "Yes", "dataMoverVirtualAddress": "Yes", "dataMoverChnls":[ {"chnl_id": 0, "chnl_dir":"ACAPD_DMA_DEV_W" }, { "chnl_id": 0, "chnl_dir": "ACAPD_DMA_DEV_R" }] }, "AccelHandshakeType": "", "fallbackBehaviour": "software" // Optional: If hw accelerator fails to load, //DFX-MGR will try software fallback } ``` #### DFX, Segmented and Segmented+DFX Designs ``` { "accel_type": "XRT_PL_DFX" // Required: supported types are // XRT_AIE_DFX/XRT_PL_DFX } ``` ## How to build DFX-MGR depends on external libraries/frameworks such as [libdfx](https://github.com/Xilinx/libdfx), [XRT](https://github.com/Xilinx/XRT), [inotify](https://en.wikipedia.org/wiki/Inotify), etc. The recommended way to compile this repo is using yocto where the required dependency are taken care of in the recipe. If not using yocto then dependent libraries will need to be provided to cmake using appropriate -DCMAKE_LIBRARY_PATH. ### How to build using yocto To compile using yocto in 2021.1 onwards, do `bitbake dfx-mgr`. ### How to build using cmake You would need to provide dependency libraries using -DCMAKE_LIBRARY_PATH for cmake. There is generic cmake toolchain file for generic Linux which is in `cmake/platforms/cross-linux-gcc.cmake` Set the path where you have all the dependent libraries in build.sh. ``` $ cd dfx-mgr $ mkdir build $ cd build $ ../build.sh ``` After build successfully completes, libdfx-mgr.so can be found under `build/usr/local/lib` and binary under `build/usr/local/bin`. ## Usage guidelines ### Using command line The dfx-mgrd daemon should mostly be running on linux startup. Assuming it is running, you can use below commands from command line to load/unload accelerators. ### Command to list the packages This command will list all packages present on target filesystem under /lib/firmware/xilinx. ``` $ dfx-mgr-client -listPackage [-all] [-filter] ``` **Options:** - `-all` - Show all columns (default shows simplified view) - `-filter` - Filter packages by board name from EEPROM (shows only matching designs) Both views print the boot PDI's PL UUID above the package table. **Default Simplified View:** ``` $ dfx-mgr-client -listPackage boot.pdi PL UUID: 657c3dde ID accelType Base slotLoc Accelerator -- ----------- ----------- ------- ----------- 1 RPU rpu -1 vek280-r5-0-matrix-multiply 2 XRT_FLAT vek280-p... -1 vek280-pl-bram-gpio-fw 3 XRT_FLAT vek280-p... -1 vek280-pl-bram-uart-gpio-fw 4 XRT_PL_DFX static -1 rp1rm0 5 XRT_PL_DFX static -1 rp0rm0 ``` **Full View with -all flag:** ``` $ dfx-mgr-client -listPackage -all boot.pdi PL UUID: 657c3dde ID accelType userLoad userLoad Base UUID Parent Pid #slots slot load Accelerator type Region UUID (RPU+PL+AIE) Location Handle -- ----------- --------- --------- ----------- --------- --------- ----- ------------ -------- ------ ----------- 1 RPU - - rpu N/A N/A no_id (2+0+0) -1 -1 vek280-r5-0-matrix-multiply 2 XRT_FLAT - - vek280-p... 383b25cf 657c3dde id_ok (0+0+0) -1 -1 vek280-pl-bram-gpio-fw 3 XRT_FLAT - - vek280-p... 4a1c9f22 657c3dde id_ok (0+0+0) -1 -1 vek280-pl-bram-uart-gpio-fw 4 XRT_PL_DFX - - static 7b3e01a5 1f2e3d4c id_ok (0+2+0) -1 -1 rp1rm0 5 XRT_PL_DFX - - static 9d82c4f0 1f2e3d4c id_ok (0+2+0) -1 -1 rp0rm0 ``` In the output, the **ID** column is a identifier used by `-load` and `-unload` commands. XRT_FLAT designs show flat shell designs that do not have dynamic reconfigurable partitions. XRT_PL_DFX designs show DFX-based accelerators with reconfigurable partitions. The slotLoc column shows -1 when no accelerator is currently loaded to any slot. RPU entries show RPU firmware applications. **UID, PID information** (visible in full view with -all flag) for tracking parent-to-child relationships is in the "Pid" column: * "id_ok" - When PID and the base UID are present and match as expected * "id_err" - When PID and the base UID are present but do not match * "no_id" - When either PID or UID are not present **Package UUID** (the "UUID" column, visible in full view with -all flag) shows each design's own UUID: * On Versal it is read from the PL PDI metaheader at package-discovery time. * On other platforms it is taken from the `uid` field in shell.json/accel.json. * It shows `N/A` when no UUID is available (e.g. RPU firmware or user-managed loads). **Parent UUID** (the "Parent"/"UUID" column, visible in full view with -all flag) shows each design's parent UUID: * For a DFX accelerator it is the UID of its parent shell (the "Pid" column reports `id_ok` when it matches the base). * On Versal it is read from the PDI metaheader; on other platforms from the `pid` field in accel.json. > **Note:** For DFX designs, an accelerator's Parent UUID corresponds to the > base shell UUID, not directly to the boot.pdi PL UUID. The base shell's PUID > matches the boot.pdi PL UUID. Because only the accelerator is shown in the > listing, the Parent UUID does not represent the complete > accelerator -> base -> boot.pdi relationship. **boot.pdi PL UUID** (header line, shown in both views) reports the UUID of the PL image in the boot PDI: * It is queried from the platform firmware (PLM) once at daemon startup, before any accelerator is loaded. * Versal-only: it shows `N/A` on ZynqMP/Zynq-7000. **Board Filtering** (using -filter flag) shows only the packages that match the current board. * Board name is read at daemon startup from the EEPROM paths configured via `eeprom_location` in `daemon.conf`. * If `eeprom_location` is not configured or the board name cannot be read, `-filter` returns an error indicating that a valid board name is required * Supported on Zynq UltraScale+ MPSoC (ZynqMP) and Versal Gen1/Gen2 platforms * Not supported on legacy Zynq-7000 platforms (e.g., ZC702, ZC706), as these older boards EEPROMs are not flashed in FRU format. Here is an example of 2-partition designs (see: [kria-dfx-hw](https://github.com/Xilinx/kria-dfx-hw), [kria-apps-firmware](https://github.com/Xilinx/kria-apps-firmware)) from KR260 board with Ubuntu 22.04:
``` $ tree /lib/firmware/xilinx /lib/firmware/xilinx |-- k26-starter-kits | |-- k26_starter_kits.bit.bin | |-- k26_starter_kits.dtbo | `-- shell.json |-- k26_2rp_1409 | |-- AES128 | | |-- AES128_slot0 | | | |-- accel.json | | | |-- opendfx_shell_i_RP_0_AES128_inst_0_partial.bit.bin | | | |-- opendfx_shell_i_RP_0_AES128_inst_0_partial.bit.bin_i.dtbo | | | `-- opendfx_shell_i_RP_0_AES128_inst_0_partial.bit.bin_i.dtsi | | `-- AES128_slot1 | | |-- accel.json | | |-- opendfx_shell_i_RP_1_AES128_inst_1_partial.bit.bin | | |-- opendfx_shell_i_RP_1_AES128_inst_1_partial.bit.bin_i.dtbo | | `-- opendfx_shell_i_RP_1_AES128_inst_1_partial.bit.bin_i.dtsi | |-- AES192 | | |-- AES192_slot0 | | | |-- accel.json | | | |-- opendfx_shell_i_RP_0_AES192_inst_0_partial.bit.bin | | | |-- opendfx_shell_i_RP_0_AES192_inst_0_partial.bit.bin_i.dtbo | | | `-- opendfx_shell_i_RP_0_AES192_inst_0_partial.bit.bin_i.dtsi | | `-- AES192_slot1 | | |-- accel.json | | |-- opendfx_shell_i_RP_1_AES192_inst_1_partial.bit.bin | | |-- opendfx_shell_i_RP_1_AES192_inst_1_partial.bit.bin_i.dtbo | | `-- opendfx_shell_i_RP_1_AES192_inst_1_partial.bit.bin_i.dtsi | |-- DPU | | |-- DPU_slot0 | | | |-- accel.json | | | |-- opendfx_shell_i_RP_0_DPU_512_inst_0_partial.bit.bin | | | |-- opendfx_shell_i_RP_0_DPU_512_inst_0_partial.bit.bin_i.dtbo | | | `-- opendfx_shell_i_RP_0_DPU_512_inst_0_partial.bit.bin_i.dtsi | | `-- DPU_slot1 | | |-- accel.json | | |-- opendfx_shell_i_RP_1_DPU_512_inst_1_partial.bit.bin | | |-- opendfx_shell_i_RP_1_DPU_512_inst_1_partial.bit.bin_i.dtbo | | `-- opendfx_shell_i_RP_1_DPU_512_inst_1_partial.bit.bin_i.dtsi | |-- FFT | | |-- FFT_slot0 | | | |-- accel.json | | | |-- opendfx_shell_i_RP_0_FFT_4channel_inst_0_partial.bit.bin | | | |-- opendfx_shell_i_RP_0_FFT_4channel_inst_0_partial.bit.bin_i.dtbo | | | `-- opendfx_shell_i_RP_0_FFT_4channel_inst_0_partial.bit.bin_i.dtsi | | `-- FFT_slot1 | | |-- accel.json | | |-- opendfx_shell_i_RP_1_FFT_4channel_inst_1_partial.bit.bin | | |-- opendfx_shell_i_RP_1_FFT_4channel_inst_1_partial.bit.bin_i.dtbo | | `-- opendfx_shell_i_RP_1_FFT_4channel_inst_1_partial.bit.bin_i.dtsi | |-- FIR | | |-- FIR_slot0 | | | |-- accel.json | | | |-- opendfx_shell_i_RP_0_FIR_compiler_inst_0_partial.bit.bin | | | |-- opendfx_shell_i_RP_0_FIR_compiler_inst_0_partial.bit.bin_i.dtbo | | | `-- opendfx_shell_i_RP_0_FIR_compiler_inst_0_partial.bit.bin_i.dtsi | | `-- FIR_slot1 | | |-- accel.json | | |-- opendfx_shell_i_RP_1_FIR_compiler_inst_1_partial.bit.bin | | |-- opendfx_shell_i_RP_1_FIR_compiler_inst_1_partial.bit.bin_i.dtbo | | `-- opendfx_shell_i_RP_1_FIR_compiler_inst_1_partial.bit.bin_i.dtsi | |-- PP_PIPELINE | | |-- PP_PIPELINE_slot0 | | | |-- accel.json | | | |-- opendfx_shell_i_RP_0_pp_pipeline_inst_0_partial.bit.bin | | | |-- opendfx_shell_i_RP_0_pp_pipeline_inst_0_partial.bit.bin_i.dtbo | | | `-- opendfx_shell_i_RP_0_pp_pipeline_inst_0_partial.bit.bin_i.dtsi | | `-- PP_PIPELINE_slot1 | | |-- accel.json | | |-- opendfx_shell_i_RP_1_pp_pipeline_inst_1_partial.bit.bin | | |-- opendfx_shell_i_RP_1_pp_pipeline_inst_1_partial.bit.bin_i.dtbo | | `-- opendfx_shell_i_RP_1_pp_pipeline_inst_1_partial.bit.bin_i.dtsi | |-- opendfx_shell_wrapper.bit.bin | |-- pl.dtbo | |-- pl.dtsi | `-- shell.json `-- kr260-tsn-rs485pmod |-- kr260-tsn-rs485pmod.bin |-- kr260-tsn-rs485pmod.dtbo `-- shell.json ```
### Command to load accelerator. For DFX designs, the base/static shell will be loaded automatically if not already loaded when loading an accelerator. The accelerator will then be loaded to one of the free slots. If the device tree overlay (.dtbo) file contains **external-fpga-config** string the dfx-mgrd will use DFX_EXTERNAL_CONFIG_EN instead of the default DFX_NORMAL_EN flag when calling [libdfx](https://github.com/Xilinx/libdfx) fetch function. ``` $ dfx-mgr-client -load [-cma ] $ dfx-mgr-client -loadByName [-cma ] ``` **Options:** - `` - Numeric ID from `-listPackage` output - `` - Accelerator package name (as shown in the **Accelerator** column of `-listPackage`) - `-cma ` - Optional: Specify a custom CMA device path for DMA buffer allocations (e.g., `/dev/dma_heap/cma_reserved`) **Examples:** ``` $ dfx-mgr-client -load 4 $ dfx-mgr-client -load 4 -cma /dev/dma_heap/cma_reserved $ dfx-mgr-client -loadByName rp0rm0 $ dfx-mgr-client -loadByName rp0rm0 -cma /dev/dma_heap/cma_reserved ``` When DFX-MGR successfully loads an accelerator to one of the slots, `-listPackage` output would show the active slot and handle. **CMA Path Priority:** 1. Command-line argument (`-cma` option) - highest priority 2. Global configuration (`cma_path` in `daemon.conf`) 3. Default to standard paths: "/dev/dma_heap/reserved" or "/dev/dma_heap/cma_reserved@800000000" ### Command to unload accelerator. ``` $ dfx-mgr-client -unload $ dfx-mgr-client -unloadByName ``` **Options:** - `` - Numeric ID from `-listPackage` output. Use `0` to unload the base design. - `` - Name of the currently loaded accelerator to unload. The daemon searches active RPU base slots, user-loaded entries, and PL base slots for the first loaded instance matching the given name. **Examples:** ``` $ dfx-mgr-client -unload 4 $ dfx-mgr-client -unload 0 # unload base design $ dfx-mgr-client -unloadByName rp0rm0 ``` ## Lightweight use cases 1. Command to load PL bitstream alone from any path. ``` dfx-mgr-client -b -f where is the absolute path for PL bitstream file is the bitstream type. Acceptable values : Full | Partial ``` 2. Command to load PL bitstream along with device tree overlay. ``` dfx-mgr-client -b -f -o -n where is the absolute path for PL bitstream file is the bitstream type. Acceptable values : Full | Partial is the absolute path for device tree overlay file is the Full or Partial reconfiguration region of FPGA (max 8 characters) ``` 3. Command for unloading device tree overlay alone. ``` dfx-mgr-client -R [-n ] where is the device tree overlay region to be removed (defaults to "full" if omitted) ``` 4. Command for unloading bitstream. ``` dfx-mgr-client -unload where is the numeric ID from -listPackage output ``` 5. Command for PL configuration readback (ZynqMP only). ``` dfx-mgr-client -r [name] -t <0|1> where [name] is the output file base name; ".bin" is always appended (defaults to "readback", i.e. readback.bin) <0|1> selects the readback type: 0 = configuration registers, 1 = configuration data frames ``` The file is written relative to the directory where dfx-mgr-client is run; pass an absolute path for to write elsewhere. 6. Command to load a secure PL bitstream (ZynqMP only). ``` dfx-mgr-client -b -f -s where is the absolute path for PL bitstream file is the bitstream type. Acceptable values : Full | Partial selects the secure-load mode. Acceptable values: AuthDDR | AuthOCM | EnUsrKey | EnDevKey | AuthEnUsrKeyDDR | AuthEnUsrKeyOCM | AuthEnDevKeyDDR | AuthEnDevKeyOCM ``` The secure flag is combined with -f and may also be used with -o/-n to load a secure bitstream together with a device tree overlay. 7. Command to load an encrypted PL bitstream with an AES user key (ZynqMP only). ``` dfx-mgr-client -b -f -s EnUsrKey -k where is the raw AES user key value for the encrypted bitstream -k requires -s EnUsrKey (or a secure flag combo containing it); the key is ignored otherwise ``` For example: ``` dfx-mgr-client -b top.bit.bin -o pl.dtbo -f Partial -n -s EnUsrKey -k ``` ### Using library API Users can write applications to interact with daemon. Refer to example source code in `example/sys/linux/load_accel.c` for a simple example how to load an accelerator. The applications, including dfx-mgr-client connect to the daemon via `/var/run/dfx-mgrd.socket` file. This allows a client running in a docker container to connect to the dfx-mgrd running outside the container. ## Known limitations 1. DFX-MGR uses inotify for firmware file updates and inotify doesn't work with network filesystem. Hence it is recommended to NOT boot linux over NFS for correct functionality of DFX-MGR daemon. 2. DFX-MGR package names i.e. firmware folder names are limited to 127 character currently and absolute path lengths are limited to 512 char. Hence avoid creating long filenames. - Names exceeding the limit are filtered out and will not appear in `-listPackage`. 3. I/O nodes don't support zero copy. 4. DFX-MGR supports Zynq-7000, Zynq UltraScale+MPSoC, Versal, and Versal Gen2 platforms. ## How to contribute Contributions are welcome. You can send a patch directly; opening an issue first is optional. Please keep each pull request focused on a single logical change. ### Coding style The C sources and example applications follow a single, reproducible style defined by the committed [`.clang-format`](.clang-format) file (Google base, tabs at width 4, 100-column limit). Run `clang-format` over your changes before submitting; CMake provides two convenience targets: ``` $ cd build $ cmake .. # configure (detects clang-format) $ cmake --build . --target format # rewrite first-party sources in place $ cmake --build . --target format-check # CI-friendly dry-run, fails if reformatting is needed ``` The `format` target rewrites the `src/` and `example/` trees in place; the `format-check` target performs a non-modifying dry-run and exits non-zero when any file would change. Both require `clang-format` >= 12 (needed by the style's alignment options) and report a clear error when the tool is missing or too old. Make sure `format-check` is clean before opening a pull request. ### Commit guidelines - Keep each commit tied to a single functionality; do not mix unrelated changes. - Use an imperative subject line prefixed with the component, e.g. `dfx-mgr: add board-name filtering to -listPackage`. - Explain the *what* and *why* in the body, not an exhaustive list of every line touched. For pure refactors or formatting commits, note `No functional change.` - Sign off every commit by adding a `Signed-off-by:` trailer (`git commit -s`): ``` Signed-off-by: Your Name ``` ### Submitting changes 1. Fork the repository and create a topic branch for your change. 2. Build the project and verify your change (see *How to build*). 3. Run `cmake --build . --target format-check` and fix any reported formatting. 4. Push your branch and open a pull request describing the change and how you tested it. ## Glossary ### dfx-mgr Concepts - **Accelerator** — A loadable hardware or firmware module (PL partial bitstream or RPU firmware) that can be dynamically deployed to a slot. - **Base Design (Shell)** — The static PL design that defines the platform's slot layout. It is loaded automatically before accelerators and identified by `shell.json`. - **Package** — A firmware directory under `/lib/firmware/xilinx` containing a base design and/or its accelerators, as recognized by dfx-mgr. - **Slot** — A reconfigurable region in PL (partial reconfiguration region) or an RPU core index where an accelerator can be loaded. - **Slot Handle** — A runtime identifier assigned by dfx-mgr when an accelerator is loaded into a slot; used for unload and query operations. - **Flat Shell/Design** — A base design with no reconfigurable partitions; the entire PL is programmed as one unit. - **DFX (Dynamic Function eXchange)** — AMD/Xilinx technology for partial reconfiguration, allowing portions of the FPGA to be reprogrammed at runtime while the rest continues operating.