@@ -9,7 +9,7 @@ use std::path::PathBuf;
9
9
10
10
use anyhow:: { bail, Result } ;
11
11
12
- use serde_annotate:: { serialize, Annotate } ;
12
+ use serde_annotate:: { serialize, Annotate , Base } ;
13
13
14
14
use structopt:: StructOpt ;
15
15
@@ -24,8 +24,6 @@ use opentitanlib::otp::otp_img::{OtpImg, OtpImgItem, OtpImgPartition, OtpImgValu
24
24
pub struct AlertDigest {
25
25
#[ structopt( help = "OTP memory map file containing alert_handler config in HJSON format" ) ]
26
26
alert_cfg : PathBuf ,
27
- #[ structopt( help = r#"Life cycle state ("TEST", "DEV", "PROD", PROD_END, "RMA")"# ) ]
28
- lc_state : String ,
29
27
#[ structopt(
30
28
long,
31
29
help = "Output file to write the new OTP overlay to instead of printing"
@@ -37,8 +35,6 @@ pub struct AlertDigest {
37
35
help = "Override switch to specify a custom partition"
38
36
) ]
39
37
partition : String ,
40
- #[ structopt( long, help = "Override switch to specify a custom OTP item name" ) ]
41
- name : Option < String > ,
42
38
}
43
39
44
40
impl CommandDispatch for AlertDigest {
@@ -50,48 +46,53 @@ impl CommandDispatch for AlertDigest {
50
46
// From kErrorOk in ROM.
51
47
const ERROR_OK : u32 = 0x739 ;
52
48
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
+
53
57
// Read in the OTP img description.
54
58
let otp = OtpImg :: from_file ( & self . alert_cfg ) ?;
55
59
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 ( ) ;
65
61
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) ?;
68
65
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 ( ) ;
71
68
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 ;
74
71
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
+ }
79
77
80
78
// Construct OTP image overlay.
81
79
let img_out = OtpImg {
82
80
seed : None ,
83
81
partitions : vec ! [ OtpImgPartition {
84
82
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) ,
89
84
} ] ,
90
85
} ;
91
86
92
87
if let Some ( output) = & self . output {
93
88
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
+ ) ?;
95
96
Ok ( None )
96
97
} else {
97
98
Ok ( Some ( Box :: new ( img_out) ) )
0 commit comments