1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "stdint.h"
8 #include "stdio.h"
9 #include <string.h>
10 
11 #include "run_integration_pal_otp.h"
12 #include "run_integration_pal_log.h"
13 #include "run_integration_pal_reg.h"
14 
15 #include "board_configs.h"
16 #include "test_pal_time.h"
17 #include "test_proj_defs.h"
18 
19 #include "dx_env.h"
20 #include "dx_host.h"
21 #include "dx_nvm.h"
22 #include "dx_crys_kernel.h"
23 #include "dx_reg_base_host.h"
24 
25 #include "cc_otp_defs.h"
26 #include "cc_regs.h"
27 #include "run_integration_otp.h"
28 
29 #ifdef RUNIT_PIE_ENABLED
30 /* include sbrom data file to determine whether we are running system flows */
31 #include "bsv_integration_data_def.h"
32 #endif /* RUNIT_PIE_ENABLED */
33 
34 #ifndef RUNIT_SECURE_BOOT_SKIP_BURN_OTP
35 #define RUNIT_SECURE_BOOT_SKIP_BURN_OTP 0
36 #endif
37 /************************************************************
38  *
39  * macros
40  *
41  ************************************************************/
42 /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
43 #define RUNIT_WAIT_NVM_IDLE(regVal) \
44                 do {                                            \
45                     uint32_t regVal;                                \
46                     do {                                        \
47                         regVal = RUNIT_READ_REG(CC_REG_OFFSET(HOST_RGF, NVM_IS_IDLE));            \
48                         regVal = CC_REG_FLD_GET(0, NVM_IS_IDLE, VALUE, regVal);         \
49                     }while( !regVal );                              \
50                 }while(0)
51 
52 
53 #define RUNIT_TEST_CALC_BUFF_ZEROS(wordBuf, buffWordSize, zeros) \
54                 do {\
55                     int i = 0;\
56                     int j = 0;\
57                     int mask = 0;\
58                     zeros = 0;\
59                     for (i = 0; i< buffWordSize; i++) {\
60                         for (j = 0; j<32; j++) {\
61                             mask = 0x1;\
62                             if (!(*(wordBuf+i) & (mask << j))) {\
63                                 zeros++;\
64                             }\
65                         }\
66                     }\
67                 }
68 
69 /************************************************************
70  *
71  * public functions
72  *
73  ************************************************************/
74 
75 
runIt_getLcs(unsigned int * lcs)76 RunItError_t runIt_getLcs(unsigned int *lcs)
77 {
78     unsigned int regVal = 0;
79 
80     /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
81     RUNIT_WAIT_NVM_IDLE(regVal);
82 
83     /* Read the LCS register */
84     regVal = RUNIT_READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
85     regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
86 
87     *lcs = regVal;
88 
89     return RUNIT_ERROR__OK;
90 }
91 
runIt_checkLcs(unsigned int lcs)92 RunItError_t runIt_checkLcs(unsigned int lcs)
93 {
94     unsigned int regVal = 0;
95 
96     /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
97     RUNIT_WAIT_NVM_IDLE(regVal);
98 
99     /* Read the LCS register */
100     regVal = RUNIT_READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
101     regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
102 
103     /* Verify lcs */
104     if(regVal != lcs)
105     {
106         RUNIT_PRINT_ERROR("actual LCS %d != expected LCS %d\n", regVal, lcs);
107         return RUNIT_ERROR__FAIL;
108     }
109 
110     return RUNIT_ERROR__OK;
111 }
112 
runIt_burnOtp(unsigned int * otpBuf,unsigned int nextLcs)113 RunItError_t runIt_burnOtp(unsigned int *otpBuf, unsigned int nextLcs)
114 {
115     RunItError_t rc = RUNIT_ERROR__OK;
116 #if !RUNIT_SECURE_BOOT_SKIP_BURN_OTP
117     unsigned int i = 0;
118 
119     /*  Perform SW reset to reach CM LCS */
120     Test_ProjPerformPowerOnReset();
121 
122     RUNIT_PRINT_DBG("Restarted\n");
123     /* Copy new OTP buffer */
124     for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++)
125     {
126         RUNIT_WRITE_OTP(i, otpBuf[i]);
127         RUNIT_PRINT_DBG("0x%02x: 0x%08X\n", i, otpBuf[i]);
128 
129         Test_PalDelay(10);
130     }
131 
132     /*  Perform SW reset after writing to OTP new values */
133     Test_ProjPerformPowerOnReset();
134     RUNIT_PRINT_DBG("Restarted\n");
135 
136     /* verify LCS */
137     rc = runIt_checkLcs(nextLcs);
138     if (rc == RUNIT_ERROR__OK)
139     {
140         RUNIT_PRINT_DBG("OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
141     }
142     else
143     {
144         RUNIT_PRINT_ERROR("Error: Failed to burn OTP!!\n");
145     }
146 #endif /* !RUNIT_SECURE_BOOT_SKIP_BURN_OTP */
147     return rc;
148 }
149 
150