Skip to main content

intel_crashlog/collateral/
target_info.rs

1// Copyright (C) 2025 Intel Corporation
2// SPDX-License-Identifier: MIT
3
4use super::{CollateralManager, CollateralTree, ItemPath};
5use crate::Error;
6use crate::utils::Map;
7#[cfg(not(feature = "std"))]
8use alloc::string::String;
9use serde::{Deserialize, Deserializer};
10
11/// Stores various product information
12#[derive(Debug, Deserialize)]
13pub struct TargetInfo {
14    /// Product TLA
15    pub product: String,
16    /// Product ID used in the Crash Log headers
17    pub product_id: String,
18    /// Product variant
19    #[serde(default = "default_variant")]
20    pub variant: String,
21    /// Die IDs/names
22    #[serde(default, deserialize_with = "deserialize_die_ids")]
23    pub die_id: Map<u8, String>,
24}
25
26fn default_variant() -> String {
27    String::from("all")
28}
29
30fn deserialize_die_ids<'de, D>(deserializer: D) -> Result<Map<u8, String>, D::Error>
31where
32    D: Deserializer<'de>,
33{
34    let map: Map<String, String> = Deserialize::deserialize(deserializer)?;
35    Ok(map
36        .into_iter()
37        .filter_map(|(key, value)| {
38            key.parse::<u8>()
39                .inspect_err(|_| log::warn!("Invalid die ID value: {key}"))
40                .ok()
41                .map(|k| (k, value))
42        })
43        .collect())
44}
45
46impl<T: CollateralTree> CollateralManager<T> {
47    pub(super) fn update_target_info(&mut self) -> Result<(), Error> {
48        self.target_info.clear();
49        let path = ItemPath::new(["target_info.json"]);
50        for pvss in self.tree.search(&path)? {
51            let res = serde_json::from_slice::<TargetInfo>(&self.tree.get(&pvss, &path)?)
52                .inspect_err(|err| log::warn!("Invalid target info ({pvss}): {err}"));
53
54            let Ok(target_info) = res else {
55                continue;
56            };
57
58            let product_id = if target_info.product_id.starts_with("0x") {
59                u32::from_str_radix(&target_info.product_id[2..], 16)
60            } else {
61                target_info.product_id.parse()
62            };
63
64            if let Ok(product_id) = product_id {
65                log::trace!("Loading target info: {target_info:?}");
66                self.target_info.insert(product_id, target_info);
67            }
68        }
69        Ok(())
70    }
71}