1use anyhow::{Result, bail};
6use bitflags::bitflags;
7use serde::{Deserialize, Serialize};
8
9use crate::with_unknown;
10
11with_unknown! {
12 pub enum DifLcCtrlState: u32 [default = Self::StateInvalid] {
13 Raw = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateRaw ,
14 TestUnlocked0 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked0 ,
15 TestLocked0 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked0 ,
16 TestUnlocked1 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked1 ,
17 TestLocked1 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked1 ,
18 TestUnlocked2 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked2 ,
19 TestLocked2 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked2 ,
20 TestUnlocked3 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked3 ,
21 TestLocked3 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked3 ,
22 TestUnlocked4 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked4 ,
23 TestLocked4 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked4 ,
24 TestUnlocked5 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked5 ,
25 TestLocked5 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked5 ,
26 TestUnlocked6 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked6 ,
27 TestLocked6 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked6 ,
28 TestUnlocked7 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked7 ,
29 Dev = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateDev ,
30 Prod = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateProd ,
31 ProdEnd = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateProdEnd ,
32 Rma = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateRma ,
33 Scrap = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateScrap ,
34 PostTransition = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStatePostTransition ,
35 Escalate = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateEscalate ,
36 StateInvalid = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateInvalid ,
37 }
38}
39
40pub struct DifLcCtrlTransCheck {
41 pub valid: bool,
43 pub token: bool,
45}
46
47impl DifLcCtrlState {
48 pub fn from_redundant_encoding(encoding: u32) -> Result<Self> {
49 let base_encoding = encoding & 0x1fu32;
50 if base_encoding > u32::from(DifLcCtrlState::StateInvalid) {
51 bail!("Invalid life cycle state value.");
52 }
53 Ok(DifLcCtrlState(encoding & 0x1fu32))
54 }
55
56 pub fn redundant_encoding(&self) -> u32 {
59 let value: u32 = self.0;
60 assert_eq!(value & 0b11111, value);
61 (0..6).fold(0u32, |acc, _| (acc << 5) | value)
62 }
63
64 pub fn lc_state_to_str(self) -> &'static str {
65 match self {
66 DifLcCtrlState::Raw => "raw",
67 DifLcCtrlState::TestUnlocked0 => "test_unlocked0",
68 DifLcCtrlState::TestLocked0 => "test_locked0",
69 DifLcCtrlState::TestUnlocked1 => "test_unlocked1",
70 DifLcCtrlState::TestLocked1 => "test_locked1",
71 DifLcCtrlState::TestUnlocked2 => "test_unlocked2",
72 DifLcCtrlState::TestLocked2 => "test_locked2",
73 DifLcCtrlState::TestUnlocked3 => "test_unlocked3",
74 DifLcCtrlState::TestLocked3 => "test_locked3",
75 DifLcCtrlState::TestUnlocked4 => "test_unlocked4",
76 DifLcCtrlState::TestLocked4 => "test_locked4",
77 DifLcCtrlState::TestUnlocked5 => "test_unlocked5",
78 DifLcCtrlState::TestLocked5 => "test_locked5",
79 DifLcCtrlState::TestUnlocked6 => "test_unlocked6",
80 DifLcCtrlState::TestLocked6 => "test_locked6",
81 DifLcCtrlState::TestUnlocked7 => "test_unlocked7",
82 DifLcCtrlState::Dev => "dev",
83 DifLcCtrlState::Prod => "prod",
84 DifLcCtrlState::ProdEnd => "prod_end",
85 DifLcCtrlState::Rma => "rma",
86 DifLcCtrlState::Scrap => "scrap",
87 DifLcCtrlState::PostTransition => "post_transition",
88 DifLcCtrlState::Escalate => "escalate",
89 _ => "invalid",
90 }
91 }
92
93 pub fn parse_lc_state_str(lc_state_str: &str) -> Result<Self> {
94 match lc_state_str {
95 "raw" => Ok(DifLcCtrlState::Raw),
96 "test_unlocked0" => Ok(DifLcCtrlState::TestUnlocked0),
97 "test_locked0" => Ok(DifLcCtrlState::TestLocked0),
98 "test_unlocked1" => Ok(DifLcCtrlState::TestUnlocked1),
99 "test_locked1" => Ok(DifLcCtrlState::TestLocked1),
100 "test_unlocked2" => Ok(DifLcCtrlState::TestUnlocked2),
101 "test_locked2" => Ok(DifLcCtrlState::TestLocked2),
102 "test_unlocked3" => Ok(DifLcCtrlState::TestUnlocked3),
103 "test_locked3" => Ok(DifLcCtrlState::TestLocked3),
104 "test_unlocked4" => Ok(DifLcCtrlState::TestUnlocked4),
105 "test_locked4" => Ok(DifLcCtrlState::TestLocked4),
106 "test_unlocked5" => Ok(DifLcCtrlState::TestUnlocked5),
107 "test_locked5" => Ok(DifLcCtrlState::TestLocked5),
108 "test_unlocked6" => Ok(DifLcCtrlState::TestUnlocked6),
109 "test_locked6" => Ok(DifLcCtrlState::TestLocked6),
110 "test_unlocked7" => Ok(DifLcCtrlState::TestUnlocked7),
111 "dev" => Ok(DifLcCtrlState::Dev),
112 "prod" => Ok(DifLcCtrlState::Prod),
113 "prod_end" => Ok(DifLcCtrlState::ProdEnd),
114 "rma" => Ok(DifLcCtrlState::Rma),
115 "scrap" => Ok(DifLcCtrlState::Scrap),
116 "post_transition" => Ok(DifLcCtrlState::PostTransition),
117 "escalate" => Ok(DifLcCtrlState::Escalate),
118 _ => Ok(DifLcCtrlState::StateInvalid),
119 }
120 }
121
122 pub fn check_transition(self, target: DifLcCtrlState) -> DifLcCtrlTransCheck {
125 match (self, target) {
126 (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked0)
128 | (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked1)
129 | (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked2)
130 | (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked3)
131 | (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked4)
132 | (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked5)
133 | (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked6)
134 | (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked7)
135 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::Dev)
136 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::Prod)
137 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::ProdEnd)
138 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::Dev)
139 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::Prod)
140 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::ProdEnd)
141 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::Dev)
142 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::Prod)
143 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::ProdEnd)
144 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::Dev)
145 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::Prod)
146 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::ProdEnd)
147 | (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::Dev)
148 | (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::Prod)
149 | (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::ProdEnd)
150 | (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::Dev)
151 | (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::Prod)
152 | (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::ProdEnd)
153 | (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::Dev)
154 | (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::Prod)
155 | (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::ProdEnd)
156 | (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::Dev)
157 | (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::Prod)
158 | (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::ProdEnd)
159 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked1)
160 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked2)
161 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked3)
162 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked4)
163 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked5)
164 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked6)
165 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked7)
166 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::Dev)
167 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::Prod)
168 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::ProdEnd)
169 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked2)
170 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked3)
171 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked4)
172 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked5)
173 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked6)
174 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked7)
175 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::Dev)
176 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::Prod)
177 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::ProdEnd)
178 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked3)
179 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked4)
180 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked5)
181 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked6)
182 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked7)
183 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::Dev)
184 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::Prod)
185 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::ProdEnd)
186 | (DifLcCtrlState::TestLocked3, DifLcCtrlState::TestUnlocked4)
187 | (DifLcCtrlState::TestLocked3, DifLcCtrlState::TestUnlocked5)
188 | (DifLcCtrlState::TestLocked3, DifLcCtrlState::TestUnlocked6)
189 | (DifLcCtrlState::TestLocked3, DifLcCtrlState::TestUnlocked7)
190 | (DifLcCtrlState::TestLocked3, DifLcCtrlState::Dev)
191 | (DifLcCtrlState::TestLocked3, DifLcCtrlState::Prod)
192 | (DifLcCtrlState::TestLocked3, DifLcCtrlState::ProdEnd)
193 | (DifLcCtrlState::TestLocked4, DifLcCtrlState::TestUnlocked5)
194 | (DifLcCtrlState::TestLocked4, DifLcCtrlState::TestUnlocked6)
195 | (DifLcCtrlState::TestLocked4, DifLcCtrlState::TestUnlocked7)
196 | (DifLcCtrlState::TestLocked4, DifLcCtrlState::Dev)
197 | (DifLcCtrlState::TestLocked4, DifLcCtrlState::Prod)
198 | (DifLcCtrlState::TestLocked4, DifLcCtrlState::ProdEnd)
199 | (DifLcCtrlState::TestLocked5, DifLcCtrlState::TestUnlocked6)
200 | (DifLcCtrlState::TestLocked5, DifLcCtrlState::TestUnlocked7)
201 | (DifLcCtrlState::TestLocked5, DifLcCtrlState::Dev)
202 | (DifLcCtrlState::TestLocked5, DifLcCtrlState::Prod)
203 | (DifLcCtrlState::TestLocked5, DifLcCtrlState::ProdEnd)
204 | (DifLcCtrlState::TestLocked6, DifLcCtrlState::TestUnlocked7)
205 | (DifLcCtrlState::TestLocked6, DifLcCtrlState::Dev)
206 | (DifLcCtrlState::TestLocked6, DifLcCtrlState::Prod)
207 | (DifLcCtrlState::TestLocked6, DifLcCtrlState::ProdEnd)
208 | (DifLcCtrlState::Dev, DifLcCtrlState::Rma)
209 | (DifLcCtrlState::Prod, DifLcCtrlState::Rma) => DifLcCtrlTransCheck {
210 valid: true,
211 token: true,
212 },
213 (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::Rma)
215 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::Rma)
216 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::Rma)
217 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::Rma)
218 | (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::Rma)
219 | (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::Rma)
220 | (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::Rma)
221 | (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::Rma)
222 | (DifLcCtrlState::Raw, DifLcCtrlState::Scrap)
223 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::Scrap)
224 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::Scrap)
225 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::Scrap)
226 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::Scrap)
227 | (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::Scrap)
228 | (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::Scrap)
229 | (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::Scrap)
230 | (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::Scrap)
231 | (DifLcCtrlState::TestLocked0, DifLcCtrlState::Scrap)
232 | (DifLcCtrlState::TestLocked1, DifLcCtrlState::Scrap)
233 | (DifLcCtrlState::TestLocked2, DifLcCtrlState::Scrap)
234 | (DifLcCtrlState::TestLocked3, DifLcCtrlState::Scrap)
235 | (DifLcCtrlState::TestLocked4, DifLcCtrlState::Scrap)
236 | (DifLcCtrlState::TestLocked5, DifLcCtrlState::Scrap)
237 | (DifLcCtrlState::TestLocked6, DifLcCtrlState::Scrap)
238 | (DifLcCtrlState::Dev, DifLcCtrlState::Scrap)
239 | (DifLcCtrlState::Prod, DifLcCtrlState::Scrap)
240 | (DifLcCtrlState::ProdEnd, DifLcCtrlState::Scrap)
241 | (DifLcCtrlState::Rma, DifLcCtrlState::Scrap)
242 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked0)
243 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked1)
244 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked2)
245 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked3)
246 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked4)
247 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked5)
248 | (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked6)
249 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked1)
250 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked2)
251 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked3)
252 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked4)
253 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked5)
254 | (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked6)
255 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked2)
256 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked3)
257 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked4)
258 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked5)
259 | (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked6)
260 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::TestLocked3)
261 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::TestLocked4)
262 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::TestLocked5)
263 | (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::TestLocked6)
264 | (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::TestLocked4)
265 | (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::TestLocked5)
266 | (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::TestLocked6)
267 | (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::TestLocked5)
268 | (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::TestLocked6)
269 | (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::TestLocked6) => DifLcCtrlTransCheck {
270 valid: true,
271 token: false,
272 },
273 _ => DifLcCtrlTransCheck {
275 valid: false,
276 token: false,
277 },
278 }
279 }
280}
281
282#[derive(Copy, Clone)]
283pub struct DifLcCtrlToken(bindgen::dif::dif_lc_ctrl_token);
284
285impl From<[u8; 16]> for DifLcCtrlToken {
286 fn from(bytes: [u8; 16]) -> Self {
287 DifLcCtrlToken(bindgen::dif::dif_lc_ctrl_token { data: bytes })
288 }
289}
290
291impl From<Vec<u8>> for DifLcCtrlToken {
292 fn from(vector: Vec<u8>) -> Self {
293 let bytes: [u8; 16] = vector.try_into().unwrap();
294 DifLcCtrlToken::from(bytes)
295 }
296}
297
298impl From<[u32; 4]> for DifLcCtrlToken {
299 fn from(words: [u32; 4]) -> Self {
300 let bytes: [u8; 16] = words
301 .iter()
302 .flat_map(|v| v.to_le_bytes())
303 .collect::<Vec<u8>>()
304 .try_into()
305 .unwrap();
306 DifLcCtrlToken::from(bytes)
307 }
308}
309
310impl From<Vec<u32>> for DifLcCtrlToken {
311 fn from(vector: Vec<u32>) -> Self {
312 let bytes: [u8; 16] = vector
313 .iter()
314 .flat_map(|v| v.to_le_bytes())
315 .collect::<Vec<u8>>()
316 .try_into()
317 .unwrap();
318 DifLcCtrlToken::from(bytes)
319 }
320}
321
322impl DifLcCtrlToken {
323 pub fn into_register_values(self) -> [u32; 4] {
327 let mut out_words = [0u32; 4];
328 let bytes = self.0.data;
329 bytes
330 .chunks_exact(std::mem::size_of::<u32>())
331 .map(|chunk| u32::from_le_bytes(chunk.try_into().unwrap()))
332 .zip(&mut out_words)
333 .for_each(|(word, out)| *out = word);
334 out_words
335 }
336
337 pub fn is_zero(self) -> bool {
339 self.0.data == [0; 16]
340 }
341}
342
343#[derive(clap::ValueEnum, Clone, Copy, Debug, strum::EnumString)]
344#[strum(serialize_all = "snake_case")]
345#[repr(u32)]
346pub enum LcCtrlReg {
347 AlertTest = bindgen::dif::LC_CTRL_ALERT_TEST_REG_OFFSET,
348 Status = bindgen::dif::LC_CTRL_STATUS_REG_OFFSET,
349 ClaimTransitionIf = bindgen::dif::LC_CTRL_CLAIM_TRANSITION_IF_REG_OFFSET,
350 TransitionRegwen = bindgen::dif::LC_CTRL_TRANSITION_REGWEN_REG_OFFSET,
351 TransitionCmd = bindgen::dif::LC_CTRL_TRANSITION_CMD_REG_OFFSET,
352 TransitionCtrl = bindgen::dif::LC_CTRL_TRANSITION_CTRL_REG_OFFSET,
353 TransitionToken0 = bindgen::dif::LC_CTRL_TRANSITION_TOKEN_0_REG_OFFSET,
354 TransitionToken1 = bindgen::dif::LC_CTRL_TRANSITION_TOKEN_1_REG_OFFSET,
355 TransitionToken2 = bindgen::dif::LC_CTRL_TRANSITION_TOKEN_2_REG_OFFSET,
356 TransitionToken3 = bindgen::dif::LC_CTRL_TRANSITION_TOKEN_3_REG_OFFSET,
357 TransitionTarget = bindgen::dif::LC_CTRL_TRANSITION_TARGET_REG_OFFSET,
358 OtpVendorTestCtrl = bindgen::dif::LC_CTRL_OTP_VENDOR_TEST_CTRL_REG_OFFSET,
359 OtpVendorTestStatus = bindgen::dif::LC_CTRL_OTP_VENDOR_TEST_STATUS_REG_OFFSET,
360 LcState = bindgen::dif::LC_CTRL_LC_STATE_REG_OFFSET,
361 LcTransitionCnt = bindgen::dif::LC_CTRL_LC_TRANSITION_CNT_REG_OFFSET,
362 LcIdState = bindgen::dif::LC_CTRL_LC_ID_STATE_REG_OFFSET,
363 HwRevision0 = bindgen::dif::LC_CTRL_HW_REVISION0_REG_OFFSET,
364 HwRevision1 = bindgen::dif::LC_CTRL_HW_REVISION1_REG_OFFSET,
365 DeviceId0 = bindgen::dif::LC_CTRL_DEVICE_ID_0_REG_OFFSET,
366 DeviceId1 = bindgen::dif::LC_CTRL_DEVICE_ID_1_REG_OFFSET,
367 DeviceId2 = bindgen::dif::LC_CTRL_DEVICE_ID_2_REG_OFFSET,
368 DeviceId3 = bindgen::dif::LC_CTRL_DEVICE_ID_3_REG_OFFSET,
369 DeviceId4 = bindgen::dif::LC_CTRL_DEVICE_ID_4_REG_OFFSET,
370 DeviceId5 = bindgen::dif::LC_CTRL_DEVICE_ID_5_REG_OFFSET,
371 DeviceId6 = bindgen::dif::LC_CTRL_DEVICE_ID_6_REG_OFFSET,
372 DeviceId7 = bindgen::dif::LC_CTRL_DEVICE_ID_7_REG_OFFSET,
373 ManufState0 = bindgen::dif::LC_CTRL_MANUF_STATE_0_REG_OFFSET,
374 ManufState1 = bindgen::dif::LC_CTRL_MANUF_STATE_1_REG_OFFSET,
375 ManufState2 = bindgen::dif::LC_CTRL_MANUF_STATE_2_REG_OFFSET,
376 ManufState3 = bindgen::dif::LC_CTRL_MANUF_STATE_3_REG_OFFSET,
377 ManufState4 = bindgen::dif::LC_CTRL_MANUF_STATE_4_REG_OFFSET,
378 ManufState5 = bindgen::dif::LC_CTRL_MANUF_STATE_5_REG_OFFSET,
379 ManufState6 = bindgen::dif::LC_CTRL_MANUF_STATE_6_REG_OFFSET,
380 ManufState7 = bindgen::dif::LC_CTRL_MANUF_STATE_7_REG_OFFSET,
381}
382
383impl LcCtrlReg {
384 pub fn byte_offset(&self) -> u32 {
385 *self as u32
386 }
387 pub fn word_offset(&self) -> u32 {
390 const BYTES_PER_WORD: u32 = std::mem::size_of::<u32>() as u32;
391 assert_eq!(self.byte_offset() % BYTES_PER_WORD, 0);
392 self.byte_offset() / BYTES_PER_WORD
393 }
394}
395
396bitflags! {
397 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
399 #[serde(transparent)]
400 pub struct LcCtrlStatus: u32 {
401 const INITIALIZED = 0b1 << bindgen::dif::LC_CTRL_STATUS_INITIALIZED_BIT;
402 const READY = 0b1 << bindgen::dif::LC_CTRL_STATUS_READY_BIT;
403 const EXT_CLOCK_SWITCHED = 0b1 << bindgen::dif::LC_CTRL_STATUS_EXT_CLOCK_SWITCHED_BIT;
404 const TRANSITION_SUCCESSFUL = 0b1 << bindgen::dif::LC_CTRL_STATUS_TRANSITION_SUCCESSFUL_BIT;
405 const TRANSITION_COUNT_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_TRANSITION_COUNT_ERROR_BIT;
406 const TRANSITION_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_TRANSITION_ERROR_BIT;
407 const TOKEN_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_TOKEN_ERROR_BIT;
408 const FLASH_RMA_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_FLASH_RMA_ERROR_BIT;
409 const OTP_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_OTP_ERROR_BIT;
410 const STATE_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_STATE_ERROR_BIT;
411 const BUS_INTEG_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_BUS_INTEG_ERROR_BIT;
412 const OTP_PARTITION_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_OTP_PARTITION_ERROR_BIT;
413
414 const ERRORS =
415 Self::TRANSITION_COUNT_ERROR.bits() |
416 Self::TRANSITION_ERROR.bits() |
417 Self::TOKEN_ERROR.bits() |
418 Self::FLASH_RMA_ERROR.bits() |
419 Self::OTP_ERROR.bits() |
420 Self::STATE_ERROR.bits() |
421 Self::BUS_INTEG_ERROR.bits() |
422 Self::OTP_PARTITION_ERROR.bits();
423 }
424}
425
426bitflags! {
427 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
429 pub struct LcCtrlTransitionRegwen: u32 {
430 const TRANSITION_REGWEN = 0b1 << bindgen::dif::LC_CTRL_TRANSITION_REGWEN_TRANSITION_REGWEN_BIT;
431 }
432}
433
434bitflags! {
435 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
437 pub struct LcCtrlTransitionCmd: u32 {
438 const START = 0b1 << bindgen::dif::LC_CTRL_TRANSITION_CMD_START_BIT;
439 }
440}
441
442bitflags! {
443 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
445 pub struct LcCtrlTransitionCtrl: u32 {
446 const EXT_CLOCK_EN = 0b1 << bindgen::dif::LC_CTRL_TRANSITION_CTRL_EXT_CLOCK_EN_BIT;
447 const VOLATILE_RAW_UNLOCK = 0b1 << bindgen::dif::LC_CTRL_TRANSITION_CTRL_VOLATILE_RAW_UNLOCK_BIT;
448 }
449}
450
451#[cfg(test)]
452mod tests {
453 use super::*;
454
455 #[test]
457 fn lc_ctrl_state_redundant_encoding_zero() {
458 assert_eq!(u32::from(DifLcCtrlState::Raw), 0);
459 assert_eq!(DifLcCtrlState::Raw.redundant_encoding(), 0);
460 }
461
462 #[test]
464 fn lc_ctrl_state_redundant_encoding_nonzero() {
465 assert_ne!(
466 u32::from(DifLcCtrlState::Rma),
467 DifLcCtrlState::Rma.redundant_encoding()
468 );
469 assert_eq!(DifLcCtrlState::Rma.redundant_encoding(), 0x2739ce73);
470 }
471
472 #[test]
473 fn lc_ctrl_token() {
474 let token_bytes: [u8; 16] = [
476 0x01, 0x02, 0x03, 0x04, 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, ];
481 let token = DifLcCtrlToken::from(token_bytes);
482 let words: [u32; 4] = token.into_register_values();
483 assert_eq!(words, [0x04030201, 0x14131211, 0x24232221, 0x34333231]);
484 }
485
486 #[test]
487 fn lc_ctrl_register_offsets() {
488 let offset = bindgen::dif::LC_CTRL_LC_STATE_REG_OFFSET;
489 assert_eq!(LcCtrlReg::LcState.byte_offset(), offset);
490 assert_eq!(LcCtrlReg::LcState.word_offset(), offset / 4);
491 }
492
493 #[test]
494 fn lc_status_bits() {
495 assert_eq!(LcCtrlStatus::empty(), LcCtrlStatus::from_bits_truncate(0));
496 assert_eq!(
497 LcCtrlStatus::INITIALIZED,
498 LcCtrlStatus::from_bits_truncate(1)
499 );
500 assert_eq!(
501 LcCtrlStatus::INITIALIZED | LcCtrlStatus::READY,
502 LcCtrlStatus::from_bits_truncate(3)
503 );
504
505 let ready = LcCtrlStatus::INITIALIZED | LcCtrlStatus::READY;
506 assert!(ready.contains(LcCtrlStatus::READY));
507 assert!(!ready.contains(LcCtrlStatus::TRANSITION_SUCCESSFUL));
508 }
509}