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