2626#include "soc_address_map.h"
2727#include "soc_ifc.h"
2828
29- volatile char * stdout = (char * )SOC_MCI_TOP_MCI_REG_DEBUG_OUT ;
29+ volatile char * stdout = (char * )SOC_MCI_TOP_MCI_REG_DEBUG_OUT ;
3030#ifdef CPT_VERBOSITY
3131enum printf_verbosity verbosity_g = CPT_VERBOSITY ;
3232#else
@@ -36,14 +36,46 @@ enum printf_verbosity verbosity_g = LOW;
3636#define LOG_ERROR (...) VPRINTF(LOW, "MCU ERROR:" #__VA_ARGS__)
3737#define LOG_INFO (...) VPRINTF(LOW, "MCU:" #__VA_ARGS__)
3838
39- const uint32_t kPartitions [] = {
40- SECRET_MANUF_PARTITION //,
41- // SECRET_PROD_PARTITION_0,
42- // SECRET_PROD_PARTITION_1,
43- // SECRET_PROD_PARTITION_2,
44- // SECRET_PROD_PARTITION_3,
39+ // This struct is used to store the partition information used in the test.
40+ typedef struct partition_info {
41+ // Partition identifier. Used to access partition in the partitions array.
42+ uint32_t id ;
43+ // Offset to the digest0 register.
44+ uint32_t digest0 ;
45+ // Offset to the digest1 register.
46+ uint32_t digest1 ;
47+ } partition_info_t ;
48+
49+ const partition_info_t kPartitionsInfo [] = {
50+ {
51+ .id = SECRET_MANUF_PARTITION ,
52+ .digest0 = SOC_OTP_CTRL_SECRET_MANUF_PARTITION_DIGEST_DIGEST_0 ,
53+ .digest1 = SOC_OTP_CTRL_SECRET_MANUF_PARTITION_DIGEST_DIGEST_1 ,
54+ },
55+ {
56+ .id = SECRET_PROD_PARTITION_0 ,
57+ .digest0 = SOC_OTP_CTRL_SECRET_PROD_PARTITION_0_DIGEST_DIGEST_0 ,
58+ .digest1 = SOC_OTP_CTRL_SECRET_PROD_PARTITION_0_DIGEST_DIGEST_1 ,
59+ },
60+ {
61+ .id = SECRET_PROD_PARTITION_1 ,
62+ .digest0 = SOC_OTP_CTRL_SECRET_PROD_PARTITION_1_DIGEST_DIGEST_0 ,
63+ .digest1 = SOC_OTP_CTRL_SECRET_PROD_PARTITION_1_DIGEST_DIGEST_1 ,
64+ },
65+ {
66+ .id = SECRET_PROD_PARTITION_2 ,
67+ .digest0 = SOC_OTP_CTRL_SECRET_PROD_PARTITION_2_DIGEST_DIGEST_0 ,
68+
69+ .digest1 = SOC_OTP_CTRL_SECRET_PROD_PARTITION_2_DIGEST_DIGEST_1 ,
70+ },
71+ {
72+ .id = SECRET_PROD_PARTITION_3 ,
73+ .digest0 = SOC_OTP_CTRL_SECRET_PROD_PARTITION_3_DIGEST_DIGEST_0 ,
74+ .digest1 = SOC_OTP_CTRL_SECRET_PROD_PARTITION_3_DIGEST_DIGEST_1 ,
75+ },
4576};
46- const uint32_t kNumPartitions = sizeof (kPartitions ) / sizeof (kPartitions [0 ]);
77+ const uint32_t kNumPartitions =
78+ sizeof (kPartitionsInfo ) / sizeof (kPartitionsInfo [0 ]);
4779
4880static bool zeroization_check_unfeasible (uint32_t partition_id ) {
4981 partition_t * p = & partitions [partition_id ];
@@ -70,7 +102,8 @@ static bool zeroization_check_unfeasible(uint32_t partition_id) {
70102
71103 // Attempt to zeroize. We check sure that the zeroize flag is still 0
72104 // to confirm that zeroization is not feasible from MCU.
73- dai_zer (p -> zer_address , & read_data [0 ], & read_data [1 ], 64 , OTP_CTRL_STATUS_DAI_ERROR_MASK );
105+ dai_zer (p -> zer_address , & read_data [0 ], & read_data [1 ], 64 ,
106+ OTP_CTRL_STATUS_DAI_ERROR_MASK );
74107 if (read_data [0 ] != 0 || read_data [1 ] != 0 ) {
75108 LOG_ERROR ("Zeroize flag was set to 0x%x%x\n" , read_data [1 ], read_data [0 ]);
76109 return false;
@@ -82,64 +115,27 @@ static bool zeroization_check_unfeasible(uint32_t partition_id) {
82115 return true;
83116}
84117
85- static bool zeroization_caliptra_request (uint32_t partition_id ) {
86- // Configure the partition ID.
87- lsu_write_32 (SOC_SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_L , partition_id );
88-
89- // Error if there is already a request in progress, otherwise request
90- // zeroization.
91- uint32_t reg = lsu_read_32 (SOC_SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ );
92- if (reg & SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_UDS_PROGRAM_REQ_MASK ) {
93- LOG_ERROR ("Zeroization request already in progress\n" );
94- return false;
95- }
96- lsu_write_32 (SOC_SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ ,
97- reg | SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_UDS_PROGRAM_REQ_MASK );
98-
99- // Poll for completion.
100- while (lsu_read_32 (SOC_SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP ) &
101- SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_UDS_PROGRAM_IN_PROGRESS_MASK );
102-
103- reg = lsu_read_32 (SOC_SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP );
104- if (reg & SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_UDS_PROGRAM_SUCCESS_MASK ) {
105- return true;
118+ // Check that the digest is zeroized or not.
119+ static bool check_digest (uint32_t partition_id , bool expected_zeroized ) {
120+ uint32_t digest [2 ];
121+ digest [0 ] = lsu_read_32 (kPartitionsInfo [partition_id ].digest0 );
122+ digest [1 ] = lsu_read_32 (kPartitionsInfo [partition_id ].digest1 );
123+ if (expected_zeroized ) {
124+ return digest [0 ] == UINT32_MAX && digest [1 ] == UINT32_MAX ;
106125 }
107- reset_fc_lcc_rtl ();
108- wait_dai_op_idle (0 );
109-
110-
111- return false;
126+ // If not zeroized, the digest should not be all ones.
127+ return digest [0 ] != UINT32_MAX && digest [1 ] != UINT32_MAX ;
112128}
113129
114- void main (void ) {
115- VPRINTF (LOW , "=================\nMCU Caliptra Boot Go\n=================\n\n" )
116-
117- // Writing to Caliptra Boot GO register of MCI for CSS BootFSM to bring
118- // Caliptra out of reset This is just to see CSSBootFSM running correctly
119- mcu_mci_boot_go ();
120-
121- // Wait for ready_for_fuses
122- while (!(lsu_read_32 (SOC_SOC_IFC_REG_CPTRA_FLOW_STATUS ) &
123- SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_FUSES_MASK ));
124-
125- mcu_cptra_init_d (.cfg_skip_set_fuse_done = true);
126- wait_dai_op_idle (0 );
127- initialize_otp_controller ();
128-
129- // Grant permission to perform writes even though we are expecting the
130- // operation to fail.
131- // grant_mcu_for_fc_writes();
132-
133- // Before releasing Caliptra core, test that we are unable to zeroize any of
134- // the partitions with or without PPD set.
130+ static bool mcu_zeroization_test (void ) {
135131 for (uint32_t i = 0 ; i < kNumPartitions ; i ++ ) {
136- uint32_t partition_id = kPartitions [i ];
132+ uint32_t partition_id = kPartitionsInfo [i ]. id ;
137133 if (!zeroization_check_unfeasible (partition_id )) {
138134 LOG_ERROR (
139135 "Unexpected zeroization success for partition_id: %d from MCU - PPD "
140136 "not set\n" ,
141137 partition_id );
142- goto epilog ;
138+ return false ;
143139 }
144140
145141 lsu_write_32 (SOC_MCI_TOP_MCI_REG_DEBUG_OUT , CMD_FC_FORCE_ZEROIZATION );
@@ -150,59 +146,48 @@ void main(void) {
150146 "Unexpected zeroization success for partition_id: %d from MCU - PPD "
151147 "set\n" ,
152148 partition_id );
153- goto epilog ;
149+ return false ;
154150 }
155151
156152 lsu_write_32 (SOC_MCI_TOP_MCI_REG_DEBUG_OUT , CMD_RELEASE_ZEROIZATION );
157153 wait_dai_op_idle (0 );
158154 }
155+ return true;
156+ }
159157
160- // revoke_grant_mcu_for_fc_writes();
161-
162- // Releases the Caliptra core by setting CPTRA_FUSE_WR_DONE.
163- lsu_write_32 (SOC_SOC_IFC_REG_CPTRA_FUSE_WR_DONE ,
164- SOC_IFC_REG_CPTRA_FUSE_WR_DONE_DONE_MASK );
165- LOG_INFO ("Set FUSE_WR_DONE\n" );
158+ void main (void ) {
159+ VPRINTF (LOW , "=====================================\n"
160+ "MCU Caliptra Boot Go\n"
161+ "=====================================\n\n" );
166162
163+ // Wait for ready_for_fuses
164+ while (!(lsu_read_32 (SOC_SOC_IFC_REG_CPTRA_FLOW_STATUS ) &
165+ SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_FUSES_MASK ))
166+ ;
167167
168- // grant_caliptra_core_for_fc_writes();
168+ mcu_cptra_init_d (.cfg_skip_set_fuse_done = true);
169+ wait_dai_op_idle (0 );
170+ initialize_otp_controller ();
169171
170- // Expect zeroization to FAIL when PPD IS NOT set.
171- for (uint32_t i = 0 ; i < kNumPartitions ; i ++ ) {
172- uint32_t partition_id = kPartitions [i ];
173- if (zeroization_caliptra_request (partition_id )) {
174- LOG_ERROR (
175- "Unexpected zeroization success for partition_id: %d from Caliptra - "
176- "PPD not set\n" ,
177- partition_id );
178- goto epilog ;
179- }
172+ // Before releasing Caliptra core, test that we are unable to zeroize any of
173+ // the partitions with or without PPD set.
174+ if (!mcu_zeroization_test ()) {
175+ LOG_ERROR ("MCU zeroization test failed\n" );
180176 }
181177
182- lsu_write_32 (SOC_MCI_TOP_MCI_REG_DEBUG_OUT , CMD_FC_FORCE_ZEROIZATION );
178+ // Reset.
179+ reset_fc_lcc_rtl ();
183180 wait_dai_op_idle (0 );
184181
185- // Expect zeroization to PASS after PPD IS set .
182+ // At this point, the partitions should not be zeroized .
186183 for (uint32_t i = 0 ; i < kNumPartitions ; i ++ ) {
187- uint32_t partition_id = kPartitions [i ];
188- if (!zeroization_caliptra_request (partition_id )) {
189- LOG_ERROR (
190- "Unexpected zeroization failure for partition_id: %d from Caliptra - "
191- "PPD set\n" ,
192- partition_id );
193- goto epilog ;
184+ uint32_t partition_id = kPartitionsInfo [i ].id ;
185+ if (!check_digest (partition_id , /*expected_zeroized=*/ false)) {
186+ LOG_ERROR ("Partition %d is not zeroized\n" , partition_id );
187+ return false;
194188 }
195189 }
196190
197- lsu_write_32 (SOC_MCI_TOP_MCI_REG_DEBUG_OUT , CMD_RELEASE_ZEROIZATION );
198- wait_dai_op_idle (0 );
199-
200- // revoke_grant_mcu_for_fc_writes();
201-
202- // TODO(moidx): Should we issue reset and verify that the partitions are
203- // zeroized?
204-
205- epilog :
206191 for (uint8_t ii = 0 ; ii < 160 ; ii ++ ) {
207192 // Sleep loop as "nop".
208193 __asm__ volatile ("nop" );
0 commit comments