libamdgpu_top/xdna/
xdna_device_path.rs1use std::{fs, io};
5use std::sync::{Arc, Mutex};
6use std::path::PathBuf;
7use crate::{DeviceType, DevicePath, PCI};
8
9pub fn find_xdna_device() -> Option<DevicePath> {
10 let [accel, sysfs_path] = find_accel_path_and_sysfs_path()?;
11 let pci: PCI::BUS_INFO = sysfs_path.file_name()?.to_str()?.parse().ok()?;
12 let render = PathBuf::new();
13 let card = PathBuf::new();
14 let [device_id, revision_id] = [pci.get_device_id(), pci.get_revision_id()];
15 let device_name = fs::read_to_string(sysfs_path.join("vbnv"))
16 .map(|mut s| {
17 let _ = s.pop(); s
19 })
20 .unwrap_or_default();
21 let arc_proc_index = Arc::new(Mutex::new(Vec::new()));
22 let config_pm = sysfs_path.join("power").exists();
23
24 Some(DevicePath {
25 libdrm_amdgpu: None,
26 render,
27 card,
28 accel,
29 pci,
30 sysfs_path,
31 device_id,
32 revision_id,
33 device_name,
34 arc_proc_index,
35 config_pm,
36 device_type: DeviceType::AMDXDNA,
37 })
38}
39
40fn find_accel_path_and_sysfs_path() -> Option<[PathBuf; 2]> {
41 const ACCEL_MAJOR: usize = 261;
42 const MAX_MINOR: usize = 64;
43
44 for i in 0..MAX_MINOR {
45 let accel_path = PathBuf::from(format!("/dev/accel/accel{i}"));
46 if !accel_path.exists() {
49 continue;
50 }
51
52 let sysfs_path = PathBuf::from(format!("/sys/dev/char/{ACCEL_MAJOR}:{i}/device/"));
54 let sysfs_path = fs::canonicalize(sysfs_path).ok()?;
55 let device_type_path = sysfs_path.join("device_type");
56 let vbnv_path = sysfs_path.join("vbnv");
57
58 if device_type_path.exists() && vbnv_path.exists() {
60 return Some([accel_path, sysfs_path]);
61 }
62 }
63
64 None
65}
66
67impl DevicePath {
68 pub fn get_xdna_fw_version(&self) -> io::Result<String> {
69 std::fs::read_to_string(self.sysfs_path.join("fw_version"))
70 .map(|mut s| {
71 let _ = s.pop(); s
73 })
74 }
75}