amebazii/conf/
pt.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{
4    expect_length,
5    types::{
6        enums::{KeyExportOp, PartitionType},
7        image::pt::{PartTab, Record, TrapConfig},
8        key_from_hex,
9    },
10};
11
12use super::DataArray;
13
14/// Represents a single item in the partition table configuration.
15///
16#[derive(Serialize, Deserialize, Debug)]
17pub struct PartitionItemCfg {
18    pub start_addr: u32,
19    pub length: u32,
20    pub part_type: PartitionType,
21
22    #[serde(default)]
23    pub debug_skip: bool,
24    pub hash_key: String,
25}
26
27impl TryInto<Record> for PartitionItemCfg {
28    type Error = crate::error::Error;
29
30    /// Converts a `PartitionItemCfg` instance into a `Record` instance.
31    ///
32    /// This conversion checks if the `hash_key` is a valid 64-character hexadecimal string.
33    /// If valid, it maps the `PartitionItemCfg` attributes into the `Record` struct.
34    ///
35    /// # Returns:
36    /// - `Ok(Record)`: A `Record` instance with values copied from `PartitionItemCfg`.
37    /// - `Err(Error)`: An error if the `hash_key` is invalid.
38    fn try_into(self) -> Result<Record, Self::Error> {
39        expect_length!(&self.hash_key, 64); // Ensure that the hash key is 64 characters.
40
41        let mut record = Record::default();
42        record.start_addr = self.start_addr;
43        record.length = self.length;
44        record.part_type = self.part_type;
45        record.dbg_skip = self.debug_skip;
46        record.set_hash_key(key_from_hex(&self.hash_key)); // Convert the hash key from hexadecimal string to bytes.
47
48        Ok(record)
49    }
50}
51
52impl Default for PartitionItemCfg {
53    /// Returns the default configuration for a `PartitionItemCfg` instance.
54    ///
55    /// The default values are:
56    /// - `start_addr`: `0`
57    /// - `length`: `0`
58    /// - `part_type`: `PartitionType::PartTab` (the default partition type).
59    /// - `debug_skip`: `false`
60    /// - `hash_key`: An empty string.
61    fn default() -> Self {
62        Self {
63            start_addr: 0,
64            length: 0,
65            part_type: PartitionType::PartTab,
66            debug_skip: false,
67            hash_key: String::new(),
68        }
69    }
70}
71
72/// Represents the partition table configuration.
73///
74/// This struct holds the configuration settings for a partition table.
75#[allow(non_snake_case)]
76#[derive(Serialize, Deserialize, Debug)]
77pub struct PartitionTableCfg {
78    #[serde(default)]
79    pub rma_w_state: u8,
80
81    #[serde(default)]
82    pub rma_ov_state: u8,
83
84    #[serde(default)]
85    pub eFWV: u8,
86
87    pub fw1_idx: u8,
88    pub fw2_idx: u8,
89
90    pub ota_trap: Option<TrapConfig>,
91    pub mp_trap: Option<TrapConfig>,
92
93    #[serde(default)]
94    pub key_exp_op: KeyExportOp,
95
96    pub user_ext: Option<DataArray<12>>,
97    pub user_bin: Option<DataArray<256>>,
98
99    pub items: Vec<PartitionItemCfg>,
100}
101
102impl TryInto<PartTab> for PartitionTableCfg {
103    type Error = crate::error::Error;
104
105    /// Converts a `PartitionTableCfg` instance into a `PartTab` instance.
106    ///
107    /// # Returns:
108    /// - `Ok(PartTab)`: A `PartTab` instance with the appropriate values set.
109    /// - `Err(Error)`: An error if something goes wrong, such as if the user extension file
110    ///   does not exist or cannot be read.
111    fn try_into(self) -> Result<PartTab, Self::Error> {
112        let mut pt = PartTab::default();
113        pt.eFWV = self.eFWV;
114        pt.fw1_idx = self.fw1_idx;
115        pt.fw2_idx = self.fw2_idx;
116        pt.key_exp_op = self.key_exp_op;
117        pt.rma_ov_state = self.rma_ov_state;
118        pt.rma_w_state = self.rma_w_state;
119
120        if let Some(ota_trap) = self.ota_trap {
121            pt.ota_trap = ota_trap;
122        }
123        if let Some(mp_trap) = self.mp_trap {
124            pt.mp_trap = mp_trap;
125        }
126
127        if let Some(user_ext) = &self.user_ext {
128            expect_length!(&user_ext.data, 24);
129            pt.set_user_ext(&user_ext.data);
130        }
131
132        if let Some(user_bin) = &self.user_bin {
133            pt.set_user_bin(&user_bin.data);
134        }
135
136        for item in self.items {
137            pt.add_record(item.try_into()?)
138        }
139        Ok(pt)
140    }
141}
142
143impl Default for PartitionTableCfg {
144    /// Returns the default configuration for a `PartitionTableCfg` instance.
145    ///
146    /// The default values are:
147    /// - `rma_w_state`: `0xFF`
148    /// - `rma_ov_state`: `0xFF`
149    /// - `eFWV`: `0`
150    /// - `fw1_idx`: `0`
151    /// - `fw2_idx`: `0`
152    /// - `ota_trap`: `None`
153    /// - `mp_trap`: `None`
154    /// - `key_exp_op`: `KeyExportOp::None`
155    /// - `user_ext`: `None`
156    /// - `user_bin`: `None`
157    /// - `items`: An empty vector of `PartitionItemCfg` items.
158    fn default() -> Self {
159        Self {
160            rma_w_state: 0xFF,
161            rma_ov_state: 0xFF,
162            eFWV: 0,
163            fw1_idx: 0,
164            fw2_idx: 0,
165            ota_trap: None,
166            mp_trap: None,
167            key_exp_op: KeyExportOp::None,
168            user_ext: None,
169            user_bin: None,
170            items: Vec::new(),
171        }
172    }
173}