Skip to content

Commit 663ab46

Browse files
committed
docs: fill in missing gaps for dfx-mgr changes
Signed-off-by: Artie Poole <stuart.poole@canonical.com>
1 parent d3006bf commit 663ab46

5 files changed

Lines changed: 258 additions & 0 deletions

File tree

daemon/src/platforms/platform.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,39 @@ pub trait Platform: Any {
266266
/// * `Err(FpgadError::Argument)` - Invalid overlay handle or configfs not available
267267
fn overlay_handler(&self, overlay_handle: &str) -> Result<&dyn OverlayHandler, FpgadError>;
268268

269+
/// Get a formatted status message for this platform.
270+
///
271+
/// Returns a human-readable status message containing information about devices,
272+
/// overlays, and platform-specific state. The format and content are platform-specific.
273+
///
274+
/// # Returns: `Result<String, FpgadError>`
275+
/// * `Ok(String)` - Formatted status message
276+
/// * `Err(FpgadError)` - Failed to gather status information
277+
///
278+
/// # Examples
279+
///
280+
/// For the Universal platform, this returns a table of devices and overlays.
281+
/// For Xilinx DFX Manager, this returns the output of `dfx-mgr-client -listPackage`.
269282
fn status_message(&self) -> Result<String, FpgadError>;
270283

284+
/// Get the platform compatibility string.
285+
///
286+
/// Returns the compatibility string that this platform implementation is registered
287+
/// with. This string matches against device tree compatible properties to determine
288+
/// which platform to use for a device.
289+
///
290+
/// # Returns: `String`
291+
/// * The platform compatibility string (e.g., "universal", "xlnx,zynqmp-pcap-fpga")
292+
///
293+
/// # Examples
294+
///
295+
/// ```rust,no_run
296+
/// # use daemon::platforms::platform::Platform;
297+
/// # fn example(platform: &dyn Platform) {
298+
/// let compat = platform.platform_compat_string();
299+
/// println!("Platform: {}", compat);
300+
/// # }
301+
/// ```
271302
fn platform_compat_string(&self) -> String;
272303
}
273304

daemon/src/softeners/xilinx_dfx_mgr.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,51 @@
1010
//
1111
// You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
1212

13+
//! Xilinx DFX Manager platform implementation.
14+
//!
15+
//! This module provides the Xilinx DFX Manager (dfx-mgr) platform, which is a vendor-specific
16+
//! "softener" implementation for managing Xilinx FPGA devices. It wraps the Xilinx dfx-mgr-client
17+
//! command-line tool to provide enhanced functionality for Xilinx devices including:
18+
//! - Dynamic function exchange (DFX) / partial reconfiguration
19+
//! - Accelerator package management
20+
//! - Multi-slot FPGA management
21+
//! - UIO (User I/O) interface management
22+
//! - Inter-region buffer management
23+
//!
24+
//! # Platform Support
25+
//!
26+
//! This platform registers itself for Xilinx device compatibility strings:
27+
//! - `xlnx,zynqmp-pcap-fpga` - Zynq UltraScale+ MPSoC
28+
//! - `versal-fpga` - Versal ACAP devices
29+
//! - `zynq-devcfg-1.0` - Zynq-7000 devices
30+
//!
31+
//! # DFX Manager Integration
32+
//!
33+
//! The platform communicates with the dfx-mgrd daemon (started via snap daemon wrapper)
34+
//! through the dfx-mgr-client CLI tool. The dfx-mgr-client binary must be available at
35+
//! `$SNAP/usr/bin/dfx-mgr-client`.
36+
//!
37+
//! # Architecture
38+
//!
39+
//! The platform uses lazy initialization via `OnceLock` to create component instances:
40+
//! - [`XilinxDfxMgrFPGA`] - Manages FPGA device operations via dfx-mgr
41+
//! - [`XilinxDfxMgrOverlayHandler`] - Manages overlay operations with bitstream coordination
42+
//!
43+
//! # Feature Flag
44+
//!
45+
//! This module is only compiled when the `xilinx-dfx-mgr` feature is enabled.
46+
//!
47+
//! # Examples
48+
//!
49+
//! ```rust,no_run
50+
//! # use daemon::platforms::platform::platform_for_known_platform;
51+
//! # fn example() -> Result<(), daemon::error::FpgadError> {
52+
//! let platform = platform_for_known_platform("xlnx,zynqmp-pcap-fpga")?;
53+
//! let fpga = platform.fpga("fpga0")?;
54+
//! # Ok(())
55+
//! # }
56+
//! ```
57+
1358
use std::env;
1459
use std::path::Path;
1560
use std::sync::OnceLock;
@@ -22,6 +67,25 @@ use crate::softeners::xilinx_dfx_mgr_overlay_handler::XilinxDfxMgrOverlayHandler
2267
use fpgad_macros::platform;
2368
use log::trace;
2469

70+
/// Xilinx DFX Manager platform implementation for managing Xilinx FPGA devices.
71+
///
72+
/// This struct provides the platform implementation for Xilinx devices using the
73+
/// dfx-mgr backend. It uses lazy initialization to create FPGA and overlay handler
74+
/// instances on first access.
75+
///
76+
/// The `#[platform]` macro automatically registers this platform with the Xilinx-specific
77+
/// compatibility strings, making it available for matching against Xilinx device tree
78+
/// compatible properties.
79+
///
80+
/// # Fields
81+
///
82+
/// * `fpga` - Lazily initialized Xilinx FPGA device instance
83+
/// * `overlay_handler` - Lazily initialized Xilinx overlay handler instance
84+
///
85+
/// # Thread Safety
86+
///
87+
/// This struct is thread-safe thanks to `OnceLock`, which ensures that initialization
88+
/// happens exactly once even with concurrent access.
2589
#[platform(compat_string = "xlnx,zynqmp-pcap-fpga,versal-fpga,zynq-devcfg-1.0")]
2690
pub struct XilinxDfxMgrPlatform {
2791
fpga: OnceLock<XilinxDfxMgrFPGA>,
@@ -35,6 +99,22 @@ impl Default for XilinxDfxMgrPlatform {
3599
}
36100

37101
impl XilinxDfxMgrPlatform {
102+
/// Create a new Xilinx DFX Manager platform instance.
103+
///
104+
/// Creates an empty platform with uninitialized FPGA and overlay handler instances.
105+
/// The actual components will be lazily initialized on first access through the
106+
/// [`Platform`] trait methods.
107+
///
108+
/// # Returns: `Self`
109+
/// * New XilinxDfxMgrPlatform instance ready for use
110+
///
111+
/// # Examples
112+
///
113+
/// ```rust,no_run
114+
/// use daemon::softeners::xilinx_dfx_mgr::XilinxDfxMgrPlatform;
115+
///
116+
/// let platform = XilinxDfxMgrPlatform::new();
117+
/// ```
38118
pub fn new() -> Self {
39119
trace!("creating new XilinxDfxMgrPlatform");
40120
XilinxDfxMgrPlatform {

daemon/src/softeners/xilinx_dfx_mgr_fpga.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,33 @@
1010
//
1111
// You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
1212

13+
//! Xilinx DFX Manager FPGA device implementation.
14+
//!
15+
//! This module provides the [`XilinxDfxMgrFPGA`] struct, which implements the [`Fpga`] trait
16+
//! for Xilinx FPGA devices using the dfx-mgr backend. It provides a hybrid approach that:
17+
//! - Uses standard sysfs for reading flags
18+
//! - Uses dfx-mgr-client for bitstream loading and package management
19+
//! - Supports dfx-mgr's slot-based management
20+
//!
21+
//! # Key Differences from Universal Platform
22+
//!
23+
//! - **State Query**: Returns dfx-mgr package listing instead of simple sysfs state
24+
//! - **Bitstream Loading**: Uses `dfx-mgr-client -b` instead of direct firmware loading due to snap confinement
25+
//! limitations (temporary?)
26+
//! - **Firmware Removal**: Supports slot-based removal via `dfx-mgr-client -remove`
27+
//!
28+
//! # Examples
29+
//!
30+
//! ```rust,no_run
31+
//! # use daemon::platforms::platform::platform_for_known_platform;
32+
//! # fn example() -> Result<(), daemon::error::FpgadError> {
33+
//! let platform = platform_for_known_platform("xlnx,zynqmp-pcap-fpga")?;
34+
//! let fpga = platform.fpga("fpga0")?;
35+
//! let state = fpga.state()?; // Returns dfx-mgr package listing
36+
//! # Ok(())
37+
//! # }
38+
//! ```
39+
1340
use crate::config;
1441
use crate::error::FpgadError;
1542
use crate::platforms::platform::Fpga;
@@ -18,11 +45,46 @@ use crate::system_io::{fs_read, fs_write};
1845
use log::{error, trace};
1946
use std::path::Path;
2047

48+
/// Xilinx DFX Manager FPGA device implementation.
49+
///
50+
/// This struct represents a Xilinx FPGA device and provides methods to interact
51+
/// with it through the dfx-mgr backend. It stores only the device handle and
52+
/// uses dfx-mgr-client for most operations.
53+
///
54+
/// # Fields
55+
///
56+
/// * `device_handle` - The device identifier (e.g., "fpga0") used to locate the device in sysfs.
57+
/// Only used for sysfs backed functions e.g. flags
58+
///
59+
/// # Implementation Notes
60+
///
61+
/// While this implementation uses the dfx-mgr backend, it still reads flags directly
62+
/// from sysfs for consistency with the standard FPGA subsystem interface.
2163
pub struct XilinxDfxMgrFPGA {
2264
device_handle: String,
2365
}
2466

2567
impl XilinxDfxMgrFPGA {
68+
/// Create a new XilinxDfxMgrFPGA instance for the specified device.
69+
///
70+
/// This constructor simply stores the device handle. It does not verify that
71+
/// the device exists or that dfx-mgrd is running - validation occurs when
72+
/// methods are called.
73+
///
74+
/// # Arguments
75+
///
76+
/// * `device_handle` - The device handle (e.g., "fpga0")
77+
///
78+
/// # Returns: `Self`
79+
/// * New XilinxDfxMgrFPGA instance
80+
///
81+
/// # Examples
82+
///
83+
/// ```rust,no_run
84+
/// use daemon::softeners::xilinx_dfx_mgr_fpga::XilinxDfxMgrFPGA;
85+
///
86+
/// let fpga = XilinxDfxMgrFPGA::new("fpga0");
87+
/// ```
2688
pub(crate) fn new(device_handle: &str) -> Self {
2789
XilinxDfxMgrFPGA {
2890
device_handle: device_handle.to_owned(),

daemon/src/softeners/xilinx_dfx_mgr_helpers.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,33 @@
1010
//
1111
// You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
1212

13+
//! Helper functions for Xilinx DFX Manager operations.
14+
//!
15+
//! This module provides utility functions for working with Xilinx device tree overlay
16+
//! files and extracting information needed for dfx-mgr operations.
17+
//!
18+
//! # Key Functions
19+
//!
20+
//! - [`extract_firmware_name`] - Parses .dtbo files to extract the firmware-name property
21+
//!
22+
//! # Device Tree Parsing
23+
//!
24+
//! The module uses the `fdt` crate to parse flattened device tree binary (.dtbo) files
25+
//! and extract properties. This is essential for coordinating bitstream and overlay loading
26+
//! in the Xilinx dfx-mgr workflow.
27+
//!
28+
//! # Examples
29+
//!
30+
//! ```rust,no_run
31+
//! # use std::path::Path;
32+
//! # use daemon::softeners::xilinx_dfx_mgr_helpers::extract_firmware_name;
33+
//! # fn example() -> Result<(), daemon::error::FpgadError> {
34+
//! let firmware = extract_firmware_name(Path::new("/lib/firmware/design.dtbo"))?;
35+
//! println!("Bitstream file: {}", firmware);
36+
//! # Ok(())
37+
//! # }
38+
//! ```
39+
1340
use crate::error::FpgadError;
1441
use crate::softeners::error::FpgadSoftenerError;
1542
use log::trace;

daemon/src/softeners/xilinx_dfx_mgr_overlay_handler.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,38 @@
1010
//
1111
// You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
1212

13+
//! Xilinx DFX Manager overlay handler implementation.
14+
//!
15+
//! This module provides the [`XilinxDfxMgrOverlayHandler`] struct, which implements the
16+
//! [`OverlayHandler`] trait for managing device tree overlays on Xilinx FPGA devices
17+
//! using the dfx-mgr backend.
18+
//!
19+
//! # Key Features
20+
//!
21+
//! - **Slot-based Management**: Uses dfx-mgr's slot system for overlay tracking and removal
22+
//!
23+
//! # Overlay Loading Process
24+
//!
25+
//! 1. Parse the .dtbo file to extract the `firmware-name` property
26+
//! 2. Locate the bitstream file in the same directory as the .dtbo
27+
//! 3. Call `dfx-mgr-client -o <dtbo_path> -b <bitstream_path>` to load both
28+
//!
29+
//! This ensures the bitstream and overlay are applied together, which is required
30+
//! as a temporary workaround while `-load` is not supported due to snap confinement limitations
31+
//!
32+
//! # Examples
33+
//!
34+
//! ```rust,no_run
35+
//! # use daemon::platforms::platform::platform_for_known_platform;
36+
//! # use std::path::Path;
37+
//! # fn example() -> Result<(), daemon::error::FpgadError> {
38+
//! let platform = platform_for_known_platform("xlnx,zynqmp-pcap-fpga")?;
39+
//! let handler = platform.overlay_handler("my_overlay")?;
40+
//! handler.apply_overlay(Path::new("/lib/firmware/design.dtbo"), Path::new(""))?;
41+
//! # Ok(())
42+
//! # }
43+
//! ```
44+
1345
use crate::error::FpgadError;
1446
use crate::platforms::platform::OverlayHandler;
1547
use crate::softeners::error::FpgadSoftenerError;
@@ -19,9 +51,35 @@ use log::{debug, trace};
1951
use std::option::Option;
2052
use std::path::Path;
2153

54+
/// Xilinx DFX Manager overlay handler implementation.
55+
///
56+
/// This struct provides overlay management for Xilinx FPGA devices using the
57+
/// dfx-mgr backend. Unlike the universal overlay handler, it doesn't directly
58+
/// manage configfs overlay directories since dfx-mgr handles that internally.
59+
///
60+
/// # Implementation Notes
61+
///
62+
/// The overlay handle parameter is currently unused since dfx-mgr manages
63+
/// overlay lifecycle internally through its slot system.
2264
pub struct XilinxDfxMgrOverlayHandler {}
2365

2466
impl XilinxDfxMgrOverlayHandler {
67+
/// Create a new XilinxDfxMgrOverlayHandler instance.
68+
///
69+
/// # Arguments
70+
///
71+
/// * `_overlay_handle` - Overlay handle (currently unused, slot management WIP)
72+
///
73+
/// # Returns: `Self`
74+
/// * New XilinxDfxMgrOverlayHandler instance
75+
///
76+
/// # Examples
77+
///
78+
/// ```rust,no_run
79+
/// use daemon::softeners::xilinx_dfx_mgr_overlay_handler::XilinxDfxMgrOverlayHandler;
80+
///
81+
/// let handler = XilinxDfxMgrOverlayHandler::new("");
82+
/// ```
2583
pub(crate) fn new(_: &str) -> Self {
2684
XilinxDfxMgrOverlayHandler {}
2785
}

0 commit comments

Comments
 (0)