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 <stdlib.h>
9 #include <stdio.h>
10 #include <stdbool.h>
11 #include <unistd.h>
12 #include <sys/mman.h>
13 #include <fcntl.h>
14 #include <string.h>
15 #include "cc_pal_types.h"
16 #include "dx_env.h"
17 #include "dx_reg_base_host.h"
18 #include "cc_regs.h"
19 #include "dx_host.h"
20 #include "tests_hw_access.h"
21 #include "tests_phys_map.h"
22 #include "test_log.h"
23 #include "dx_crys_kernel.h"
24 
25 
26 
27 /////////////////////////////////////
28 //         macro defines           //
29 /////////////////////////////////////
30 
31 
32 /*************************/
33 /*   Global variables    */
34 /*************************/
35 
36 
37 /******************************/
38 /*   function definitions     */
39 /*****************************/
testCheckLcs(unsigned int nextLcs)40 unsigned int testCheckLcs(unsigned int  nextLcs)
41 {
42     unsigned int regVal = 0;
43     unsigned int error = TEST_OK;
44 
45     /* Wait on LCS valid before reading the LCS register */
46     do {
47         regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_IS_VALID));
48         regVal = CC_REG_FLD_GET(0, LCS_IS_VALID, VALUE, regVal);
49     }while (!regVal);
50 
51     /* Read the LCS register */
52     regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
53     regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
54     TEST_PRINTF_ERROR("regVal is 0x%x", regVal);
55 
56     /* Verify lcs */
57     if(regVal != nextLcs) {
58         TEST_PRINTF_ERROR("Failed to verify new LCS !!!\n");
59         return TEST_BURN_OTP_LCS_ERR;
60     }
61 
62     /* Check HW errors */
63     switch(nextLcs){
64     case TESTS_LCS_SEC_ENABLED:
65         /* Check RKEK error bit */
66         regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
67         regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_KDR_ZERO_CNT, regVal);
68         if (regVal) {
69             error = TEST_BURN_OTP_KDR_ERR;
70             break;
71         }
72         /* FALLTHROUGH */
73 
74     case TESTS_LCS_DM:
75         /* Check Provision (Scp) error bit */
76         regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
77         regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_PROV_ZERO_CNT, regVal);
78         if (regVal) {
79             error = TEST_BURN_OTP_SCP_ERR;
80         }
81         break;
82     default:
83         break;
84     }
85 
86     return error;
87 }
88 
89 
90 /* Global Reset of CC and AO and env regs */
performPowerOnReset(void)91 void performPowerOnReset(void)
92 {
93     /* Call sw reset to reset the CC before starting to work with it */
94     WRITE_ENV(DX_ENV_CC_POR_N_ADDR_REG_OFFSET , 0x1UL);
95     usleep(1000);
96 
97     WRITE_REG(CC_REG_OFFSET(HOST_RGF, AXIM_CACHE_PARAMS), 0x277UL);
98     usleep(1000);
99 
100 #ifdef BIG__ENDIAN
101     /* Set DMA endianess to big */
102     WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
103 #else /* LITTLE__ENDIAN */
104     WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
105 #endif
106     return;
107 
108 }
109 
110 
111 /* Reset both CC and AO regs */
performColdReset(void)112 void performColdReset(void)
113 {
114     /* perform global reset */
115     WRITE_ENV(DX_ENV_CC_COLD_RST_REG_OFFSET , 0x1UL);
116     usleep(1000);
117 
118     WRITE_REG(CC_REG_OFFSET(HOST_RGF, AXIM_CACHE_PARAMS), 0x277UL);
119     usleep(1000);
120 
121 #ifdef BIG__ENDIAN
122     /* Set DMA endianess to big */
123     WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
124 #else /* LITTLE__ENDIAN */
125     WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
126 #endif
127     return;
128 }
129 
130 
131 /* Reset only CC regs */
performWarmReset(void)132 void performWarmReset(void)
133 {
134     WRITE_ENV(DX_ENV_CC_RST_N_REG_OFFSET , 0x1UL);
135     usleep(1000);
136 
137     WRITE_REG(CC_REG_OFFSET(HOST_RGF, AXIM_CACHE_PARAMS), 0x277UL);
138     usleep(1000);
139 
140 #ifdef BIG__ENDIAN
141     /* Set DMA endianess to big */
142     WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
143 #else /* LITTLE__ENDIAN */
144     WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
145 #endif
146     return;
147 
148 }
149 
testBurnOtp(unsigned int * otp,unsigned int nextLcs)150 unsigned int testBurnOtp(unsigned int  *otp, unsigned int  nextLcs)
151 {
152 
153     CCError_t error = TEST_OK;
154     unsigned int i = 0;
155 
156 #if 0
157     /* Clear OTP is not needed any more since we call to powerOnReset to clear env regs */
158     error = testClearOtp();
159     if (error) {
160         TEST_PRINTF_ERROR("Failed to clear OTP!!!\n");
161         return error;
162     }
163 #endif
164 
165     /*  Perform SW reset to reach CM LCS */
166     performPowerOnReset();
167 
168     for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
169                 TEST_PRINTF("writing Otp [%d] 0x%X", i, otp[i]);
170         WRITE_OTP(i, otp[i]);
171         usleep(1000);
172 
173     }
174 #ifdef DEBUG
175     uint32_t tempOtp;
176     for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
177         tempOtp = READ_OTP(i);
178         TEST_PRINTF_ERROR("tempOtp [%d] 0x%X", i, tempOtp);
179 
180         }
181 #endif
182 
183     /*  Perform SW reset after writing to OTP new values */
184     performPowerOnReset();
185 
186     /* verify LCS */
187     error = testCheckLcs(nextLcs);
188     if (error == TEST_OK) {
189         TEST_PRINTF(" OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
190     } else {
191         TEST_PRINTF_ERROR("Error: Failed to burn OTP lcs is %d!!!\n", nextLcs);
192     }
193 
194     return error;
195 }
196 
197 
testClearOtp(void)198 unsigned int testClearOtp(void)
199 {
200     CCError_t error = TEST_OK;
201     unsigned int i = 0;
202 
203     /*  Perform SW reset to reach CM LCS */
204     performPowerOnReset();
205 
206     for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
207         WRITE_OTP(i, 0);
208         usleep(1000);
209 
210     }
211 #ifdef DEBUG
212     uint32_t tempOtp;
213     for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
214         tempOtp = READ_OTP(i);
215         TEST_PRINTF_ERROR("tempOtp [%d] 0x%X", i, tempOtp);
216 
217         }
218 #endif
219 
220     /*  Perform SW reset after writing to OTP new values */
221     performPowerOnReset();
222 
223     /* verify LCS */
224     error = testCheckLcs(0);
225     if (error == TEST_OK) {
226         TEST_PRINTF(" OTP burn succeeded with new LCS = CM \n");
227     } else {
228         TEST_PRINTF_ERROR("Error: Failed to burn OTP \n");
229     }
230 
231     return error;
232 }
233 
234 
235 
testSetScpInOtpBuff(unsigned int * otp,unsigned char * scpBuff)236 unsigned int testSetScpInOtpBuff(unsigned int *otp, unsigned char *scpBuff)
237 {
238     int  i = 0;
239     int  zeroCount = 0;
240     int scpZeroSize = ((0x1 << OTP_MANUFACTOR_FLAG_SCP_ZEROS_NUM_BITS)-1);
241     int scpZeroMask = (scpZeroSize << OTP_MANUFACTOR_FLAG_SCP_ZEROS_BIT_OFFSET);
242 
243     if ((NULL == otp) ||
244         (NULL == scpBuff)) {
245         TEST_PRINTF_ERROR("testSetScpInOtpBuff ilegal params\n");
246         return TEST_INVALID_PARAM_ERR;
247     }
248     for (i=0; i< OTP_SCP_SIZE_IN_WORDS; i++) {
249         TEST_CONVERT_BYTE_ARR_TO_WORD(&scpBuff[i*sizeof(uint32_t)], otp[OTP_SCP_START_WORD_OFFSET+i])
250     }
251 
252     TEST_CALC_BUFF_ZEROS(&otp[OTP_SCP_START_WORD_OFFSET], OTP_SCP_SIZE_IN_WORDS, zeroCount);
253     otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] &= ~(scpZeroMask);
254     otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] |= (zeroCount)<<OTP_MANUFACTOR_FLAG_SCP_ZEROS_BIT_OFFSET;
255     return TEST_OK;
256 
257 }
258 
259 
260 /*
261  * @brief This function
262  *
263  * @param[in]
264  *
265  * @param[out]
266  *
267  * @return void -
268 
269  */
testSetKdrInOtpBuff(unsigned int * otp,unsigned char * kdrBuff)270 unsigned int testSetKdrInOtpBuff(unsigned int *otp, unsigned char *kdrBuff)
271 {
272     int  i = 0;
273     int  zeroCount = 0;
274     int kdrZeroSize = ((0x1 << OTP_MANUFACTOR_FLAG_KDR_ZEROS_NUM_BITS)-1);
275     int kdrZeroMask = (kdrZeroSize << OTP_MANUFACTOR_FLAG_KDR_ZEROS_BIT_OFFSET);
276 
277     if ((NULL == otp) ||
278         (NULL == kdrBuff)) {
279         TEST_PRINTF_ERROR(" ilegal params\n");
280         return TEST_INVALID_PARAM_ERR;
281     }
282     for (i=0; i< OTP_KRD_SIZE_IN_WORDS; i++) {
283         TEST_CONVERT_BYTE_ARR_TO_WORD(&kdrBuff[i*sizeof(uint32_t)], otp[OTP_KRD_START_WORD_OFFSET+i])
284     }
285 
286     TEST_CALC_BUFF_ZEROS(&otp[OTP_KRD_START_WORD_OFFSET], OTP_KRD_SIZE_IN_WORDS, zeroCount);
287     otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] &= ~(kdrZeroMask);
288     otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] |= (zeroCount)<<OTP_MANUFACTOR_FLAG_KDR_ZEROS_BIT_OFFSET;
289     return TEST_OK;
290 
291 }
292 
293 
294 /*
295  * @brief This function
296  *
297  * @param[in]
298  *
299  * @param[out]
300  *
301  * @return void -
302 
303  */
testSetHbkInOtpBuff(unsigned int * otp,unsigned char * hbkBuff,OtpHbkTypes_t type)304 unsigned int testSetHbkInOtpBuff(unsigned int *otp, unsigned char *hbkBuff, OtpHbkTypes_t type)
305 {
306     int  i = 0;
307     int  zeroCount = 0;
308     int otpStartOffset = (type == TEST_OTP_HBK1_TYPE)?OTP_HBK1_START_WORD_OFFSET:OTP_HBK0_START_WORD_OFFSET;
309     int hbkStartOffset = (type == TEST_OTP_HBK1_TYPE)?OTP_HBK0_SIZE_IN_WORDS:0;
310     int hbkWordSize;
311     int hbkZeroSizeBits = 0;
312     int hbkZeroMaskBits = 0;
313 
314 
315     if ((NULL == otp) ||
316         (NULL == hbkBuff)) {
317         TEST_PRINTF_ERROR("testSetHbkInOtpBuff ilegal params\n");
318         return TEST_INVALID_PARAM_ERR;
319     }
320     TEST_PRINTF_ERROR("type %d\n", type);
321     if ((type == TEST_OTP_HBK0_TYPE) ||
322         (type == TEST_OTP_HBK1_TYPE)) {
323         hbkWordSize = OTP_HBK0_SIZE_IN_WORDS;
324     } else if ((type == TEST_OTP_HBK_256_TYPE) ||
325            (type == (TEST_OTP_HBK0_TYPE | TEST_OTP_HBK1_TYPE))) {
326         hbkWordSize = OTP_HBK0_SIZE_IN_WORDS+OTP_HBK1_SIZE_IN_WORDS;
327     } else {
328         TEST_PRINTF_ERROR("ilegal type %d\n", type);
329         return TEST_INVALID_PARAM_ERR;
330     }
331     TEST_PRINTF_ERROR("writing hbk otpStartOffset %d, hbkWordSize %d\n", otpStartOffset, hbkWordSize);
332     for (i=0; i< hbkWordSize; i++) {
333         TEST_CONVERT_BYTE_ARR_TO_WORD(&hbkBuff[(hbkStartOffset+i)*sizeof(uint32_t)], otp[otpStartOffset+i]);
334     }
335 
336     /* calculate HBK's zeros and save in OTP */
337     if (type == TEST_OTP_HBK0_TYPE) {
338         memset(&otp[OTP_HBK1_START_WORD_OFFSET], 0, OTP_HBK1_SIZE_IN_WORDS);
339     }
340     if (type == TEST_OTP_HBK1_TYPE) {
341         memset(&otp[OTP_HBK0_START_WORD_OFFSET], 0, OTP_HBK0_SIZE_IN_WORDS);
342     }
343     otp[OTP_DM_DEF_START_WORD_OFFSET] &= ~(0xFFFF);
344     if (type == TEST_OTP_HBK_256_TYPE) {
345         otp[OTP_DM_DEF_START_WORD_OFFSET] |= 0xFF00;
346     }
347     if (type & TEST_OTP_HBK1_TYPE) {
348         hbkZeroSizeBits = ((0x1 << OTP_DM_DEF_HBK1_ZEROS_NUM_BITS)-1);
349         hbkZeroMaskBits = (hbkZeroSizeBits << OTP_DM_DEF_HBK1_ZEROS_BIT_OFFSET);
350         TEST_CALC_BUFF_ZEROS(&otp[OTP_HBK1_START_WORD_OFFSET], OTP_HBK1_SIZE_IN_WORDS, zeroCount);
351         otp[OTP_DM_DEF_START_WORD_OFFSET] &= ~(hbkZeroMaskBits);
352         otp[OTP_DM_DEF_START_WORD_OFFSET] |= (zeroCount)<<OTP_DM_DEF_HBK1_ZEROS_BIT_OFFSET;
353         TEST_PRINTF_ERROR("zeros for HBK1 %d\n", zeroCount);
354     }
355     if (type == (TEST_OTP_HBK0_TYPE | TEST_OTP_HBK1_TYPE)) {
356         hbkWordSize = OTP_HBK0_SIZE_IN_WORDS; // OTP_HBK1_SIZE_IN_WORDS  was already writen
357     }
358     if ((type & TEST_OTP_HBK0_TYPE) ||
359         (type == TEST_OTP_HBK_256_TYPE)) {
360         hbkZeroSizeBits = ((0x1 << OTP_DM_DEF_HBK0_ZEROS_NUM_BITS)-1);
361         hbkZeroMaskBits = (hbkZeroSizeBits << OTP_DM_DEF_HBK0_ZEROS_BIT_OFFSET);
362         TEST_CALC_BUFF_ZEROS(&otp[OTP_HBK0_START_WORD_OFFSET], hbkWordSize, zeroCount);
363         otp[OTP_DM_DEF_START_WORD_OFFSET] &= ~(hbkZeroMaskBits);
364         otp[OTP_DM_DEF_START_WORD_OFFSET] |= (zeroCount)<<OTP_DM_DEF_HBK0_ZEROS_BIT_OFFSET;
365         TEST_PRINTF_ERROR("zeros for HBK0 %d\n", zeroCount);
366     }
367     TEST_PRINTF_ERROR("otp[OTP_DM_DEF_START_WORD_OFFSET] 0x%x\n", otp[OTP_DM_DEF_START_WORD_OFFSET]);
368 
369     return TEST_OK;
370 
371 }
372 
373 
374 /*
375  * @brief This function
376  *
377  * @param[in]
378  *
379  * @param[out]
380  *
381  * @return void -
382 
383  */
testSetSecureInOtpBuff(unsigned int * otp,unsigned char enFlag)384 unsigned int testSetSecureInOtpBuff(unsigned int *otp, unsigned char enFlag)
385 {
386     int   secEnSizeBits = ((0x1 << OTP_MANUFACTOR_FLAG_SEC_EN_NUM_BITS)-1);
387     int   secEnMaskBits = (secEnSizeBits << OTP_MANUFACTOR_FLAG_SEC_EN_BIT_OFFSET);
388     if (NULL == otp) {
389         TEST_PRINTF_ERROR("testSetSecureInOtpBuff ilegal params\n");
390         return TEST_INVALID_PARAM_ERR;
391     }
392     otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] &= ~(secEnMaskBits);
393     otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] |= (enFlag)<<OTP_MANUFACTOR_FLAG_SEC_EN_BIT_OFFSET;
394     return TEST_OK;
395 }
396 
397 
398 
399 /*
400  * @brief This function
401  *
402  * @param[in]
403  *
404  * @param[out]
405  *
406  * @return void -
407 
408  */
409 
410 
testReadKdrZeros()411 int testReadKdrZeros()
412 {
413     int otpVal = 0;
414     int ZeroSize = 0;
415     int ZeroMask = 0;
416 
417     ZeroSize = ((0x1 << OTP_MANUFACTOR_FLAG_KDR_ZEROS_NUM_BITS)-1);
418     ZeroMask = (ZeroSize << OTP_MANUFACTOR_FLAG_KDR_ZEROS_BIT_OFFSET);
419 
420     /* NOTE! manufacturer word bits[15:0] acn be read only if LCS is CM or DM */
421     READ_AIB(OTP_MANUFACTOR_FLAG_START_WORD_OFFSET*sizeof(uint32_t), otpVal);
422 
423     return (otpVal&ZeroMask);
424 }
425 
testReadOtp(unsigned int offset,unsigned int size,uint32_t * buff)426 unsigned int testReadOtp(unsigned int offset, unsigned int size, uint32_t *buff)
427 {
428         unsigned int i = 0;
429 
430         if ((size == 0) || (buff == NULL)) {
431         return TEST_INVALID_PARAM_ERR;
432     }
433 
434         for (i = 0; i < size; i++) {
435                 buff[i] = READ_OTP(offset+i);
436                 TEST_PRINTF("buff[%d] 0x%X", i, buff[i]);
437         }
438 
439     return TEST_OK;
440 }
441 
442