1use std::path::{Path, PathBuf};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone)]
6pub struct IpHwInstance {
7 pub hw_id: HwId,
8 pub num_instance: u8,
9 pub major: u8,
10 pub minor: u8,
11 pub revision: u8,
12 pub harvest: u8,
13 pub num_base_addresses: isize,
14 pub base_address: Vec<u32>,
15}
16
17impl IpHwInstance {
18 pub fn get_from_instance_sysfs<P: Into<PathBuf>>(sysfs_path: P) -> Option<Self> {
20 let path = sysfs_path.into();
21 let hw_id = {
22 let tmp = Self::parse_file::<isize>(path.join("hw_id"))?;
23 HwId::from(tmp)
24 };
25 let num_instance = Self::parse_file::<u8>(path.join("num_instance"))?;
26 let major = Self::parse_file::<u8>(path.join("major"))?;
27 let minor = Self::parse_file::<u8>(path.join("minor"))?;
28 let revision = Self::parse_file::<u8>(path.join("revision"))?;
29 let harvest = Self::parse_harvest_file(&path)?;
30 let num_base_addresses = Self::parse_file::<isize>(path.join("num_base_addresses"))?;
31 let base_address = Self::parse_base_address_file(&path);
32
33 Some(Self {
34 hw_id,
35 num_instance,
36 major,
37 minor,
38 revision,
39 harvest,
40 num_base_addresses,
41 base_address,
42 })
43 }
44
45 pub fn parse_harvest_file<P: AsRef<Path>>(sysfs_path: P) -> Option<u8> {
46 let s = std::fs::read_to_string(sysfs_path.as_ref().join("harvest")).ok()?;
47 let len = s.len();
48
49 u8::from_str_radix(s.get(2..len-1)?, 16).ok() }
51
52 pub fn parse_base_address_file<P: AsRef<Path>>(sysfs_path: P) -> Vec<u32> {
53 let mut base_addr = Vec::with_capacity(8);
54 let Ok(s) = std::fs::read_to_string(sysfs_path.as_ref().join("base_addr")) else { return base_addr };
55 let lines = s.lines();
56
57 for l in lines {
58 let Some(addr) = l.get(2..).and_then(|s| u32::from_str_radix(s, 16).ok()) else {
60 continue
61 };
62
63 base_addr.push(addr);
64 }
65
66 base_addr
67 }
68
69 pub fn parse_file<T: std::str::FromStr>(path: PathBuf) -> Option<T> {
70 let s = std::fs::read_to_string(path).ok()?;
71
72 if s.is_empty() { return None }
73
74 let len = s.len();
75
76 s.get(..len-1)?.parse::<T>().ok()
77 }
78
79 pub fn version(&self) -> (u8, u8, u8) {
80 (self.major, self.minor, self.revision)
81 }
82}
83
84#[derive(Debug, Clone)]
85pub struct IpHwId {
86 pub hw_id: HwId,
87 pub instances: Vec<IpHwInstance>,
88}
89
90impl IpHwId {
91 pub fn get_from_die_id_sysfs<P: AsRef<Path>>(hw_id: HwId, die_id_path: P) -> Result<Self, std::io::Error> {
93 Self::get_from_ip_hw_sysfs(hw_id, die_id_path.as_ref().join(hw_id.to_string()))
94 }
95
96 pub fn get_from_ip_hw_sysfs<P: AsRef<Path>>(hw_id: HwId, ip_hw_path: P) -> Result<Self, std::io::Error> {
98 let path = ip_hw_path.as_ref();
99 let inst_count = std::fs::read_dir(path)?.count(); Ok(IpHwId {
102 hw_id,
103 instances: (0..inst_count).filter_map(|i| {
104 let path = path.join(i.to_string());
105 IpHwInstance::get_from_instance_sysfs(path)
106 }).collect(),
107 })
108 }
109}
110
111#[derive(Debug, Clone)]
112pub struct IpDieEntry {
113 pub die_id: usize,
114 pub ip_hw_ids: Vec<IpHwId>,
115}
116
117impl IpDieEntry {
118 pub fn get_all_entries_from_sysfs<P: Into<PathBuf>>(sysfs_path: P) -> Vec<Self> {
119 let path = sysfs_path.into().join("ip_discovery/die/");
120 let Ok(dies) = std::fs::read_dir(&path) else { return Vec::new() };
121 let die_count = dies.count(); (0..die_count).filter_map(|die_id| {
124 Self::get_from_sysfs_with_die_id(die_id, &path)
125 }).collect()
126 }
127
128 pub fn get_from_die_sysfs<P: AsRef<Path>>(sysfs_path: P) -> Option<Self> {
130 let path = sysfs_path.as_ref();
131 let die_id: usize = path.file_name()?.to_str()?.parse().ok()?;
132 Self::get_from_sysfs_with_die_id(die_id, path.join("../"))
133 }
134
135 pub fn get_from_sysfs_with_die_id<P: AsRef<Path>>(die_id: usize, sysfs_path: P) -> Option<Self> {
136 let die_path = sysfs_path.as_ref().join(die_id.to_string());
137 let die = std::fs::read_dir(&die_path).ok()?;
138 let mut ip_hw: Vec<isize> = die.filter_map(|ip_hw| {
139 ip_hw.ok()?.file_name().to_str()?.parse().ok()
140 }).collect();
141
142 ip_hw.sort();
143
144 let ip_hw_ids = ip_hw.iter().filter_map(|hw_id| {
145 let ip_hw_path = die_path.join(hw_id.to_string());
146 IpHwId::get_from_ip_hw_sysfs(HwId::from(*hw_id), &ip_hw_path).ok()
147 }).collect();
148
149 Some(Self{ die_id, ip_hw_ids })
150 }
151
152 pub fn vec_ip_hw_id_to_hashmap(&self) -> HashMap<HwId, IpHwId> {
153 self.ip_hw_ids.iter().map(|ip_hw_id| (ip_hw_id.hw_id, ip_hw_id.clone())).collect()
154 }
155}
156
157const MP1_HWID: isize = 1;
159const MP2_HWID: isize = 2;
160const THM_HWID: isize = 3;
161const SMUIO_HWID: isize = 4;
162const FUSE_HWID: isize = 5;
163const CLKA_HWID: isize = 6;
164const PWR_HWID: isize = 10;
165const GC_HWID: isize = 11;
166const UVD_HWID: isize = 12;
167const AUDIO_AZ_HWID: isize = 13;
169const ACP_HWID: isize = 14;
170const DCI_HWID: isize = 15;
171const DMU_HWID: isize = 271;
172const DCO_HWID: isize = 16;
173const DIO_HWID: isize = 272;
174const XDMA_HWID: isize = 17;
175const DCEAZ_HWID: isize = 18;
176const DAZ_HWID: isize = 274;
177const SDPMUX_HWID: isize = 19;
178const NTB_HWID: isize = 20;
179const VPE_HWID: isize = 21;
180const IOHC_HWID: isize = 24;
181const L2IMU_HWID: isize = 28;
182const VCE_HWID: isize = 32;
183const MMHUB_HWID: isize = 34;
184const ATHUB_HWID: isize = 35;
185const DBGU_NBIO_HWID: isize = 36;
186const DFX_HWID: isize = 37;
187const DBGU0_HWID: isize = 38;
188const DBGU1_HWID: isize = 39;
189const OSSSYS_HWID: isize = 40;
190const HDP_HWID: isize = 41;
191const SDMA0_HWID: isize = 42;
192const SDMA1_HWID: isize = 43;
193const ISP_HWID: isize = 44;
194const DBGU_IO_HWID: isize = 45;
195const DF_HWID: isize = 46;
196const CLKB_HWID: isize = 47;
197const FCH_HWID: isize = 48;
198const DFX_DAP_HWID: isize = 49;
199const L1IMU_PCIE_HWID: isize = 50;
200const L1IMU_NBIF_HWID: isize = 51;
201const L1IMU_IOAGR_HWID: isize = 52;
202const L1IMU3_HWID: isize = 53;
203const L1IMU4_HWID: isize = 54;
204const L1IMU5_HWID: isize = 55;
205const L1IMU6_HWID: isize = 56;
206const L1IMU7_HWID: isize = 57;
207const L1IMU8_HWID: isize = 58;
208const L1IMU9_HWID: isize = 59;
209const L1IMU10_HWID: isize = 60;
210const L1IMU11_HWID: isize = 61;
211const L1IMU12_HWID: isize = 62;
212const L1IMU13_HWID: isize = 63;
213const L1IMU14_HWID: isize = 64;
214const L1IMU15_HWID: isize = 65;
215const WAFLC_HWID: isize = 66;
216const FCH_USB_PD_HWID: isize = 67;
217const SDMA2_HWID: isize = 68;
218const SDMA3_HWID: isize = 69;
219const PCIE_HWID: isize = 70;
220const PCS_HWID: isize = 80;
221const DDCL_HWID: isize = 89;
222const SST_HWID: isize = 90;
223const LSDMA_HWID: isize = 91;
224const IOAGR_HWID: isize = 100;
225const NBIF_HWID: isize = 108;
226const IOAPIC_HWID: isize = 124;
227const SYSTEMHUB_HWID: isize = 128;
228const NTBCCP_HWID: isize = 144;
229const UMC_HWID: isize = 150;
230const SATA_HWID: isize = 168;
231const USB_HWID: isize = 170;
232const CCXSEC_HWID: isize = 176;
233const XGMI_HWID: isize = 200;
234const XGBE_HWID: isize = 216;
235const MP0_HWID: isize = 255;
236
237#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
238#[repr(isize)]
239pub enum HwId {
240 MP1 = self::MP1_HWID,
241 MP2 = self::MP2_HWID,
242 THM = self::THM_HWID,
243 SMUIO = self::SMUIO_HWID,
244 FUSE = self::FUSE_HWID,
245 CLKA = self::CLKA_HWID,
246 PWR = self::PWR_HWID,
247 GC = self::GC_HWID,
248 UVD = self::UVD_HWID,
249 AUDIO_AZ = self::AUDIO_AZ_HWID,
251 ACP = self::ACP_HWID,
252 DCI = self::DCI_HWID,
253 DMU = self::DMU_HWID,
254 DCO = self::DCO_HWID,
255 DIO = self::DIO_HWID,
256 XDMA = self::XDMA_HWID,
257 DCEAZ = self::DCEAZ_HWID,
258 DAZ = self::DAZ_HWID,
259 SDPMUX = self::SDPMUX_HWID,
260 NTB = self::NTB_HWID,
261 IOHC = self::IOHC_HWID,
262 VPE = self::VPE_HWID,
263 L2IMU = self::L2IMU_HWID,
264 VCE = self::VCE_HWID,
265 MMHUB = self::MMHUB_HWID,
266 ATHUB = self::ATHUB_HWID,
267 DBGU_NBIO = self::DBGU_NBIO_HWID,
268 DFX = self::DFX_HWID,
269 DBGU0 = self::DBGU0_HWID,
270 DBGU1 = self::DBGU1_HWID,
271 OSSSYS = self::OSSSYS_HWID,
272 HDP = self::HDP_HWID,
273 SDMA0 = self::SDMA0_HWID,
274 SDMA1 = self::SDMA1_HWID,
275 ISP = self::ISP_HWID,
276 DBGU_IO = self::DBGU_IO_HWID,
277 DF = self::DF_HWID,
278 CLKB = self::CLKB_HWID,
279 FCH = self::FCH_HWID,
280 DFX_DAP = self::DFX_DAP_HWID,
281 L1IMU_PCIE = self::L1IMU_PCIE_HWID,
282 L1IMU_NBIF = self::L1IMU_NBIF_HWID,
283 L1IMU_IOAGR = self::L1IMU_IOAGR_HWID,
284 L1IMU3 = self::L1IMU3_HWID,
285 L1IMU4 = self::L1IMU4_HWID,
286 L1IMU5 = self::L1IMU5_HWID,
287 L1IMU6 = self::L1IMU6_HWID,
288 L1IMU7 = self::L1IMU7_HWID,
289 L1IMU8 = self::L1IMU8_HWID,
290 L1IMU9 = self::L1IMU9_HWID,
291 L1IMU10 = self::L1IMU10_HWID,
292 L1IMU11 = self::L1IMU11_HWID,
293 L1IMU12 = self::L1IMU12_HWID,
294 L1IMU13 = self::L1IMU13_HWID,
295 L1IMU14 = self::L1IMU14_HWID,
296 L1IMU15 = self::L1IMU15_HWID,
297 WAFLC = self::WAFLC_HWID,
298 FCH_USB_PD = self::FCH_USB_PD_HWID,
299 SDMA2 = self::SDMA2_HWID,
300 SDMA3 = self::SDMA3_HWID,
301 PCIE = self::PCIE_HWID,
302 PCS = self::PCS_HWID,
303 DDCL = self::DDCL_HWID,
304 SST = self::SST_HWID,
305 LSDMA = self::LSDMA_HWID,
306 IOAGR = self::IOAGR_HWID,
307 NBIF = self::NBIF_HWID,
308 IOAPIC = self::IOAPIC_HWID,
309 SYSTEMHUB = self::SYSTEMHUB_HWID,
310 NTBCCP = self::NTBCCP_HWID,
311 UMC = self::UMC_HWID,
312 SATA = self::SATA_HWID,
313 USB = self::USB_HWID,
314 CCXSEC = self::CCXSEC_HWID,
315 XGMI = self::XGMI_HWID,
316 XGBE = self::XGBE_HWID,
317 MP0 = self::MP0_HWID,
318 Unknown(isize),
319}
320
321impl From<isize> for HwId {
322 fn from(hw_id: isize) -> Self {
323 match hw_id {
324 self::MP1_HWID => Self::MP1,
325 self::MP2_HWID => Self::MP2,
326 self::THM_HWID => Self::THM,
327 self::SMUIO_HWID => Self::SMUIO,
328 self::FUSE_HWID => Self::FUSE,
329 self::CLKA_HWID => Self::CLKA,
330 self::PWR_HWID => Self::PWR,
331 self::GC_HWID => Self::GC,
332 self::UVD_HWID => Self::UVD,
333 self::AUDIO_AZ_HWID => Self::AUDIO_AZ,
334 self::ACP_HWID => Self::ACP,
335 self::DCI_HWID => Self::DCI,
336 self::DMU_HWID => Self::DMU,
337 self::DCO_HWID => Self::DCO,
338 self::DIO_HWID => Self::DIO,
339 self::XDMA_HWID => Self::XDMA,
340 self::DCEAZ_HWID => Self::DCEAZ,
341 self::DAZ_HWID => Self::DAZ,
342 self::SDPMUX_HWID => Self::SDPMUX,
343 self::NTB_HWID => Self::NTB,
344 self::IOHC_HWID => Self::IOHC,
345 self::VPE_HWID => Self::VPE,
346 self::L2IMU_HWID => Self::L2IMU,
347 self::VCE_HWID => Self::VCE,
348 self::MMHUB_HWID => Self::MMHUB,
349 self::ATHUB_HWID => Self::ATHUB,
350 self::DBGU_NBIO_HWID => Self::DBGU_NBIO,
351 self::DFX_HWID => Self::DFX,
352 self::DBGU0_HWID => Self::DBGU0,
353 self::DBGU1_HWID => Self::DBGU1,
354 self::OSSSYS_HWID => Self::OSSSYS,
355 self::HDP_HWID => Self::HDP,
356 self::SDMA0_HWID => Self::SDMA0,
357 self::SDMA1_HWID => Self::SDMA1,
358 self::ISP_HWID => Self::ISP,
359 self::DBGU_IO_HWID => Self::DBGU_IO,
360 self::DF_HWID => Self::DF,
361 self::CLKB_HWID => Self::CLKB,
362 self::FCH_HWID => Self::FCH,
363 self::DFX_DAP_HWID => Self::DFX_DAP,
364 self::L1IMU_PCIE_HWID => Self::L1IMU_PCIE,
365 self::L1IMU_NBIF_HWID => Self::L1IMU_NBIF,
366 self::L1IMU_IOAGR_HWID => Self::L1IMU_IOAGR,
367 self::L1IMU3_HWID => Self::L1IMU3,
368 self::L1IMU4_HWID => Self::L1IMU4,
369 self::L1IMU5_HWID => Self::L1IMU5,
370 self::L1IMU6_HWID => Self::L1IMU6,
371 self::L1IMU7_HWID => Self::L1IMU7,
372 self::L1IMU8_HWID => Self::L1IMU8,
373 self::L1IMU9_HWID => Self::L1IMU9,
374 self::L1IMU10_HWID => Self::L1IMU10,
375 self::L1IMU11_HWID => Self::L1IMU11,
376 self::L1IMU12_HWID => Self::L1IMU12,
377 self::L1IMU13_HWID => Self::L1IMU13,
378 self::L1IMU14_HWID => Self::L1IMU14,
379 self::L1IMU15_HWID => Self::L1IMU15,
380 self::WAFLC_HWID => Self::WAFLC,
381 self::FCH_USB_PD_HWID => Self::FCH_USB_PD,
382 self::SDMA2_HWID => Self::SDMA2,
383 self::SDMA3_HWID => Self::SDMA3,
384 self::PCIE_HWID => Self::PCIE,
385 self::PCS_HWID => Self::PCS,
386 self::DDCL_HWID => Self::DDCL,
387 self::SST_HWID => Self::SST,
388 self::LSDMA_HWID => Self::LSDMA,
389 self::IOAGR_HWID => Self::IOAGR,
390 self::NBIF_HWID => Self::NBIF,
391 self::IOAPIC_HWID => Self::IOAPIC,
392 self::SYSTEMHUB_HWID => Self::SYSTEMHUB,
393 self::NTBCCP_HWID => Self::NTBCCP,
394 self::UMC_HWID => Self::UMC,
395 self::SATA_HWID => Self::SATA,
396 self::USB_HWID => Self::USB,
397 self::CCXSEC_HWID => Self::CCXSEC,
398 self::XGMI_HWID => Self::XGMI,
399 self::XGBE_HWID => Self::XGBE,
400 self::MP0_HWID => Self::MP0,
401 _ => Self::Unknown(hw_id),
402 }
403 }
404}
405
406use std::fmt;
407impl fmt::Display for HwId {
408 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
409 write!(f, "{:?}", self)
410 }
411}