Skip to content

Commit 0c9af49

Browse files
author
Jon Flatley
committed
[opentitantool] Output OTP image overlays with hex values
Signed-off-by: Jon Flatley <[email protected]>
1 parent 39b6772 commit 0c9af49

File tree

3 files changed

+43
-37
lines changed

3 files changed

+43
-37
lines changed

sw/host/opentitanlib/src/otp/otp_img.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use anyhow::{anyhow, bail, Result};
1212
use serde::de::{self, Unexpected};
1313
use serde::{Deserialize, Serialize};
1414

15-
#[derive(Serialize, Debug, PartialEq, Eq)]
15+
use serde_annotate::Annotate;
16+
17+
#[derive(Annotate, Serialize, Debug, PartialEq, Eq)]
1618
#[serde(untagged)]
1719
pub enum OtpImgValue {
1820
Word(u64),
@@ -90,22 +92,25 @@ impl<'de> Deserialize<'de> for OtpImgValue {
9092
}
9193
}
9294

93-
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
95+
#[derive(Annotate, Serialize, Deserialize, Debug, PartialEq, Eq)]
9496
pub struct OtpImgItem {
9597
pub name: String,
9698
pub value: OtpImgValue,
9799
}
98100

99-
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
101+
#[derive(Annotate, Serialize, Deserialize, Debug, PartialEq, Eq)]
100102
pub struct OtpImgPartition {
101103
pub name: String,
102104
pub items: Option<Vec<OtpImgItem>>,
103105
}
104106

105-
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
107+
#[derive(Annotate, Serialize, Deserialize, Debug, PartialEq, Eq)]
106108
pub struct OtpImg {
107109
#[serde(skip_serializing_if = "Option::is_none")]
108110
pub seed: Option<u64>,
111+
// FIXME: Needed to get `OtpImgValue` serailization to emit hex values.
112+
// See: https://github.com/cfrantz/serde-annotate/issues/5.
113+
#[annotate(format = hex)]
109114
pub partitions: Vec<OtpImgPartition>,
110115
}
111116

sw/host/opentitanlib/src/util/num_de.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,17 +255,17 @@ mod test {
255255
fn byte_field_test() {
256256
assert_eq!(Vec::from_str("0x1"), Ok(vec![0x1]));
257257
assert_eq!(
258-
Vec::from_str("0x4b4b4b4b4b4ba5a5"),
259-
Ok(vec![0xa5, 0xa5, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b])
258+
Vec::from_str("0x0706050403020100"),
259+
Ok(vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07])
260260
);
261261
assert_eq!(
262262
u64::from_ne_bytes(
263-
Vec::from_str("0x4b4b4b4b4b4ba5a5")
263+
Vec::from_str("0x0706050403020100")
264264
.unwrap()
265265
.try_into()
266266
.unwrap()
267267
),
268-
u64::from_str("0x4b4b4b4b4b4ba5a5").unwrap()
268+
u64::from_str("0x0706050403020100").unwrap()
269269
);
270270
assert!(Vec::from_str("-1").is_err());
271271
}

sw/host/opentitantool/src/command/otp.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::path::PathBuf;
99

1010
use anyhow::{bail, Result};
1111

12-
use serde_annotate::{serialize, Annotate};
12+
use serde_annotate::{serialize, Annotate, Base};
1313

1414
use structopt::StructOpt;
1515

@@ -24,8 +24,6 @@ use opentitanlib::otp::otp_img::{OtpImg, OtpImgItem, OtpImgPartition, OtpImgValu
2424
pub struct AlertDigest {
2525
#[structopt(help = "OTP memory map file containing alert_handler config in HJSON format")]
2626
alert_cfg: PathBuf,
27-
#[structopt(help = r#"Life cycle state ("TEST", "DEV", "PROD", PROD_END, "RMA")"#)]
28-
lc_state: String,
2927
#[structopt(
3028
long,
3129
help = "Output file to write the new OTP overlay to instead of printing"
@@ -37,8 +35,6 @@ pub struct AlertDigest {
3735
help = "Override switch to specify a custom partition"
3836
)]
3937
partition: String,
40-
#[structopt(long, help = "Override switch to specify a custom OTP item name")]
41-
name: Option<String>,
4238
}
4339

4440
impl CommandDispatch for AlertDigest {
@@ -50,48 +46,53 @@ impl CommandDispatch for AlertDigest {
5046
// From kErrorOk in ROM.
5147
const ERROR_OK: u32 = 0x739;
5248

49+
// Life cycle states to generate digests for.
50+
let lc_states = [
51+
("OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD", LcStateVal::Prod),
52+
("OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_END", LcStateVal::ProdEnd),
53+
("OWNER_SW_CFG_ROM_ALERT_DIGEST_DEV", LcStateVal::Dev),
54+
("OWNER_SW_CFG_ROM_ALERT_DIGEST_RMA", LcStateVal::Rma),
55+
];
56+
5357
// Read in the OTP img description.
5458
let otp = OtpImg::from_file(&self.alert_cfg)?;
5559

56-
let lc_str = self.lc_state.to_uppercase();
57-
let lc_state = match lc_str.as_ref() {
58-
"TEST" => LcStateVal::Test,
59-
"DEV" => LcStateVal::Dev,
60-
"PROD" => LcStateVal::Prod,
61-
"PROD_END" => LcStateVal::ProdEnd,
62-
"RMA" => LcStateVal::Rma,
63-
_ => bail!("invalid life cycle state {}", self.lc_state),
64-
};
60+
let mut items = Vec::<OtpImgItem>::new();
6561

66-
// Create model for alert_handler register states.
67-
let alert = AlertRegs::try_new(lc_state, &otp)?;
62+
for lc_state in lc_states {
63+
// Create model for alert_handler register states.
64+
let alert = AlertRegs::try_new(lc_state.1, &otp)?;
6865

69-
// Use alert_handler registers states to construct CRC32 checksum.
70-
let crc32 = alert.crc32();
66+
// Use alert_handler registers states to construct CRC32 checksum.
67+
let crc32 = alert.crc32();
7168

72-
// Match digest format expected by ROM.
73-
let digest = crc32 ^ lc_state as u32 ^ ERROR_OK;
69+
// Match digest format expected by ROM.
70+
let digest = crc32 ^ lc_state.1 as u32 ^ ERROR_OK;
7471

75-
let item_name = self
76-
.name
77-
.clone()
78-
.unwrap_or(format!("OWNER_SW_CFG_ROM_ALERT_DIGEST_{}", self.lc_state).to_string());
72+
items.push(OtpImgItem {
73+
name: lc_state.0.to_owned(),
74+
value: OtpImgValue::Word(digest as u64),
75+
});
76+
}
7977

8078
// Construct OTP image overlay.
8179
let img_out = OtpImg {
8280
seed: None,
8381
partitions: vec![OtpImgPartition {
8482
name: self.partition.clone(),
85-
items: Some(vec![OtpImgItem {
86-
name: item_name,
87-
value: OtpImgValue::Word(digest as u64),
88-
}]),
83+
items: Some(items),
8984
}],
9085
};
9186

9287
if let Some(output) = &self.output {
9388
let mut file = File::create(&output)?;
94-
file.write_all(serialize(&img_out)?.to_json().to_string().as_bytes())?;
89+
file.write_all(
90+
serialize(&img_out)?
91+
.to_json()
92+
.bases(&[Base::Hex])
93+
.to_string()
94+
.as_bytes(),
95+
)?;
9596
Ok(None)
9697
} else {
9798
Ok(Some(Box::new(img_out)))

0 commit comments

Comments
 (0)