• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <efuse_opt.h>
17 #include <efuse.h>
18 #include <hi_cipher.h>
19 
efuse_read(hi_u16 start_bit,hi_u16 size)20 hi_u32 efuse_read(hi_u16 start_bit, hi_u16 size)
21 {
22     hi_u8 count;
23     hi_u32 print_val;
24     hi_u8 line_cnt = U32_PER_LINE;
25     hi_u8 data[EFUSE_MAX_INDEX_SIZE] = { 0 };
26     hi_void *tmp_data = HI_NULL;
27     hi_u32 ret = efuse_bits_read(start_bit, size, data, EFUSE_MAX_INDEX_SIZE);
28     if (ret != HI_ERR_SUCCESS) {
29         return ret;
30     }
31 
32     if (size < SIZE_32_BITS) {
33         *(volatile hi_u32 *)data &= ((1 << size) - 1);
34         size = SIZE_32_BITS;
35     } else if (size > SIZE_32_BITS && size < SIZE_64_BITS) {
36         *(volatile hi_u32 *)(data + WORD_WIDTH) &= ((1 << (size - SIZE_32_BITS)) - 1);
37         size = SIZE_64_BITS;
38     }
39 
40     count = size >> SHIFT_5_BITS;
41     if (count < U32_PER_LINE) {
42         line_cnt = count;
43     }
44 
45     tmp_data = (hi_void *)data;
46     while (count) {
47         boot_puthex(start_bit, 1);
48         serial_putc(':');
49         if (count < line_cnt) {
50             line_cnt = count;
51         }
52         /* Copy from memory into linebuf and print hex values */
53         for (hi_u8 i = 0; i < line_cnt; i++) {
54             print_val = *(volatile unsigned int *)tmp_data;
55             boot_puthex(print_val, 1);
56             tmp_data = (unsigned char *)tmp_data + WORD_WIDTH;
57         }
58         serial_putc('\n');
59 
60         /* update references */
61         start_bit += line_cnt * WORD_WIDTH * BITS_PER_BYTE;
62         count -= line_cnt;
63     }
64     return HI_ERR_SUCCESS;
65 }
66 
efuse_cfg_verify(uintptr_t file_addr,hi_u32 file_len)67 hi_u32 efuse_cfg_verify(uintptr_t file_addr, hi_u32 file_len)
68 {
69     hi_u32 ret;
70     hi_u8 hash[SHA_256_LENGTH] = {0};
71     efuse_config_header *header = (efuse_config_header *)file_addr;
72 
73     if (header->file_size != file_len) {
74         return HI_ERR_FAILURE;
75     }
76 
77     ret = hi_cipher_init();
78     if (ret != HI_ERR_SUCCESS) {
79         return ret;
80     }
81 
82     ret = hi_cipher_hash_sha256((uintptr_t)&(header->stru_ver), header->file_size - SHA_256_LENGTH, hash,
83         SHA_256_LENGTH);
84     if (ret != HI_ERR_SUCCESS) {
85         return ret;
86     }
87 
88     ret = hi_cipher_deinit();
89     if (ret != HI_ERR_SUCCESS) {
90         return ret;
91     }
92 
93     if (memcmp(header->hash, hash, SHA_256_LENGTH) != EOK) {
94         return HI_ERR_FAILURE;
95     }
96 
97     if (header->number > (HI_EFUSE_IDX_MAX + HI_EFUSE_LOCK_MAX)) {
98         return HI_ERR_FAILURE;
99     }
100 
101     return HI_ERR_SUCCESS;
102 }
103 
efuse_burn(uintptr_t file_addr,hi_u32 file_len)104 hi_u32 efuse_burn(uintptr_t file_addr, hi_u32 file_len)
105 {
106     hi_u32 ret = efuse_cfg_verify(file_addr, file_len);
107     if (ret != HI_ERR_SUCCESS) {
108         boot_msg0("Efuse config file invalid");
109         return HI_ERR_FAILURE;
110     }
111 
112     efuse_config_header *header = (efuse_config_header *)file_addr;
113     efuse_config_item *item = (efuse_config_item *)(file_addr + header->stru_size);
114     for (hi_u8 i = 0; i < header->number; i++) {
115         if (item == HI_NULL) {
116             return HI_ERR_FAILURE;
117         }
118         ret = efuse_bits_write(item->start_bit, item->bit_width, item->value);
119         if (ret != HI_ERR_SUCCESS) {
120             boot_msg1("efuse write error, index:", i);
121             serial_puts("Start bit: ");
122             serial_puthex(item->start_bit, 1);
123             serial_puts(" len(bits)=");
124             serial_puthex(item->bit_width, 1);
125             serial_puts("\n");
126         }
127 
128         item = (efuse_config_item *)((uintptr_t)item + item->stru_size + item->value_len);
129     }
130     return HI_ERR_SUCCESS;
131 }
132 
133