• 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  * Description: Provides efuse port template \n
16  *
17  * History: \n
18  * 2023-3-4, Create file. \n
19  */
20 #include "hal_efuse_v151.h"
21 #include "chip_io.h"
22 #include "securec.h"
23 #include "soc_porting.h"
24 #include "efuse.h"
25 #include "efuse_porting.h"
26 
27 #define EFUSE0_BASE_ADDR             0x44008000
28 #define HAL_EFUSE0_WRITE_BASE_ADDR   (EFUSE0_BASE_ADDR + 0x800)
29 #define HAL_EFUSE0_READ_BASE_ADDR    (EFUSE0_BASE_ADDR + 0x800)
30 #define BIT_SIZE_OF_BYTE 8
31 
32 uint32_t g_efuse_boot_done_addr = EFUSE0_BASE_ADDR + 0x2c;
33 uint32_t g_efuse_base_addr[1] = {EFUSE0_BASE_ADDR + 0x30};
34 uint32_t g_efuse_region_read_address[1] = {HAL_EFUSE0_READ_BASE_ADDR};
35 uint32_t g_efuse_region_write_address[1] = {HAL_EFUSE0_WRITE_BASE_ADDR};
36 
37 typedef struct {
38     uint16_t id_start_bit;
39     uint16_t id_size;
40     uint8_t attr;
41 } efuse_stru;
42 
43 static efuse_stru g_efuse_cfg[EFUSE_IDX_MAX] = {
44     { 0,    8,   EFUSE_IDX_RW }, // chip id
45     { 8,    160, EFUSE_IDX_RW }, // die id
46     { 624,  32,  EFUSE_IDX_RW }, // mcu ver
47     { 656,  8,   EFUSE_IDX_RW }, // flashboot ver
48     { 664,  8,   EFUSE_IDX_RW }, // params ver
49     { 672,  256, EFUSE_IDX_RW }, // hash root public key
50     { 928,  32,  EFUSE_IDX_RW }, // msid
51     { 960,  1,   EFUSE_IDX_RW }, // sec verify enable
52     { 1000, 8,   EFUSE_IDX_RW }, // type id
53     { 1584, 48,  EFUSE_IDX_RW }, // mac_addr_01
54     { 1632, 48,  EFUSE_IDX_RW }, // mac_addr_02
55     { 1680, 48,  EFUSE_IDX_RW }, // mac_addr_03
56     { 1728, 48,  EFUSE_IDX_RW }, // mac_addr_last
57     { 1776, 128, EFUSE_IDX_RW }, // customer rsvd
58     { 672, 256,  EFUSE_IDX_RW }, // customer rsvd2
59     { 1135, 1,   EFUSE_IDX_RW }, // code to valtage s
60     { 1120, 15,  EFUSE_IDX_RW }, // code to valtage b
61     { 1136, 16,  EFUSE_IDX_RW }, // code to valtage k
62 };
63 
efuse_port_register_hal_funcs(void)64 void efuse_port_register_hal_funcs(void)
65 {
66     hal_efuse_register_funcs(hal_efuse_funcs_get());
67 }
68 
efuse_port_unregister_hal_funcs(void)69 void efuse_port_unregister_hal_funcs(void)
70 {
71     hal_efuse_unregister_funcs();
72 }
73 
hal_efuse_get_region(uint32_t byte_addr)74 hal_efuse_region_t hal_efuse_get_region(uint32_t byte_addr)
75 {
76     return (hal_efuse_region_t)(byte_addr / EFUSE_REGION_MAX_BYTES);
77 }
78 
hal_efuse_get_byte_offset(uint32_t byte_addr)79 uint16_t hal_efuse_get_byte_offset(uint32_t byte_addr)
80 {
81     return byte_addr % EFUSE_REGION_MAX_BYTES;
82 }
83 
efuse_read_item(efuse_idx efuse_id,uint8_t * data,uint16_t data_len)84 uint32_t efuse_read_item(efuse_idx efuse_id, uint8_t *data, uint16_t data_len)
85 {
86     uint16_t item_data_len;
87     uint16_t bit_index;
88     uint32_t byte_index;
89     uint8_t bit_offset;
90     uint8_t value;
91     uint16_t id_start_bit;
92     uint16_t id_size;
93     uint16_t result_index;
94     uint32_t ret;
95     if ((data == NULL) || (efuse_id >= EFUSE_IDX_MAX)) {
96         return ERRCODE_FAIL;
97     }
98     id_start_bit = g_efuse_cfg[efuse_id].id_start_bit;
99     id_size = g_efuse_cfg[efuse_id].id_size;
100     item_data_len = (id_size + BIT_SIZE_OF_BYTE - 1) / BIT_SIZE_OF_BYTE;
101     if (item_data_len > data_len) {
102         return ERRCODE_FAIL;
103     }
104     memset_s(data, data_len, 0, data_len);
105     if ((id_size % BIT_SIZE_OF_BYTE) == 0 && (id_start_bit % BIT_SIZE_OF_BYTE) == 0) {
106         return uapi_efuse_read_buffer(data, (id_start_bit / BIT_SIZE_OF_BYTE), item_data_len);
107     } else {
108         for (bit_index = id_start_bit; bit_index < (id_start_bit + id_size); bit_index++) {
109             byte_index = bit_index / BIT_SIZE_OF_BYTE;
110             bit_offset = bit_index % BIT_SIZE_OF_BYTE;
111             ret = uapi_efuse_read_bit(&value, byte_index, bit_offset);
112             if (ret != ERRCODE_SUCC) {
113                 return ret;
114             }
115             if (value != 0) {
116                 result_index = (bit_index - id_start_bit) / BIT_SIZE_OF_BYTE;
117                 data[result_index] = data[result_index] |
118                     (1 << ((uint16_t)((bit_index - id_start_bit) % BIT_SIZE_OF_BYTE)));
119             }
120         }
121     }
122     return ERRCODE_SUCC;
123 }
124 
125 #define EFUSE_24M_CLK 0x29
126 #define EFUSE_40M_CLK 0x19
set_efuse_period(void)127 void set_efuse_period(void)
128 {
129     if (get_tcxo_freq() == CLK24M_TCXO) {
130         hal_efuse_set_clock_period(EFUSE_24M_CLK);
131     } else {
132         hal_efuse_set_clock_period(EFUSE_40M_CLK);
133     }
134 }
135 
136 #define FIRST_MAC_ADDR_START_BIT 1584
137 #define SECOND_MAC_ADDR_START_BIT 1632
138 #define THIRD_MAC_ADDR_START_BIT 1680
139 #define FORTH_MAC_ADDR_START_BIT 1728
140 #define FIRST_MAC_LOCK_BIT 314
141 #define SECOND_MAC_LOCK_BIT 315
142 #define THIRD_MAC_LOCK_BIT 316
143 #define FORTH_MAC_LOCK_BIT 317
144 #define EFUSE_MAC_NUM 4
145 #define EFUSE_MAC_LEN 6
146 
147 #define BIT_TO_BYTE 8
148 #define SLE_MAC_ADDR_START_BIT 1904
149 
efuse_write_mac(uint8_t * data,uint16_t data_len)150 uint32_t efuse_write_mac(uint8_t *data, uint16_t data_len)
151 {
152     uint8_t index;
153     uint32_t lock_bit;
154     uint32_t mac_bit;
155     uint8_t lock_data = 0;
156     uint32_t ret = ERRCODE_FAIL;
157 
158     if ((data == NULL) || (data_len != EFUSE_MAC_LEN)) {
159         return ERRCODE_FAIL;
160     }
161 
162     for (index = 0; index < EFUSE_MAC_NUM; index++) {
163         lock_bit = FIRST_MAC_LOCK_BIT + index;
164         mac_bit = FIRST_MAC_ADDR_START_BIT + index * EFUSE_MAC_LEN * BIT_TO_BYTE;
165         ret = uapi_efuse_read_bit(&lock_data, (lock_bit / BIT_TO_BYTE), (lock_bit % BIT_TO_BYTE));
166         if ((ret == ERRCODE_SUCC) && (lock_data == 0)) {
167             ret = uapi_efuse_write_buffer((mac_bit / BIT_TO_BYTE), data, data_len);
168             if (ret == ERRCODE_SUCC) {
169                 ret = uapi_efuse_write_bit((lock_bit / BIT_TO_BYTE), (lock_bit % BIT_TO_BYTE));
170             }
171             return ret;
172         }
173     }
174     return ERRCODE_FAIL;
175 }
176 
efuse_read_mac(uint8_t * data,uint16_t data_len,uint8_t * left_time)177 uint32_t efuse_read_mac(uint8_t *data, uint16_t data_len, uint8_t *left_time)
178 {
179     uint8_t index;
180     uint32_t lock_bit;
181     uint32_t mac_bit;
182     uint8_t lock_data = 0;
183     uint32_t ret = ERRCODE_FAIL;
184 
185     if ((data == NULL) || (data_len != EFUSE_MAC_LEN)) {
186         return ERRCODE_FAIL;
187     }
188 
189     for (index = 0; index < EFUSE_MAC_NUM; index++) {
190         lock_bit = FIRST_MAC_LOCK_BIT + EFUSE_MAC_NUM - 1 - index;
191         mac_bit = FIRST_MAC_ADDR_START_BIT + (EFUSE_MAC_NUM - 1 - index) * EFUSE_MAC_LEN * BIT_TO_BYTE;
192         ret = uapi_efuse_read_bit(&lock_data, (lock_bit / BIT_TO_BYTE), (lock_bit % BIT_TO_BYTE));
193         if ((ret == ERRCODE_SUCC) && (lock_data != 0)) {
194             *left_time = index;
195             ret = uapi_efuse_read_buffer(data, (mac_bit / BIT_TO_BYTE), data_len);
196             return ret;
197         }
198     }
199     if (index == (EFUSE_MAC_NUM - 1)) {
200         *left_time = EFUSE_MAC_NUM;
201         ret = uapi_efuse_read_buffer(data, (mac_bit / BIT_TO_BYTE), data_len);
202         return ret;
203     }
204     return ERRCODE_FAIL;
205 }
206 
check_data(const uint8_t * data,uint16_t data_len)207 static uint32_t check_data(const uint8_t *data, uint16_t data_len)
208 {
209     uint8_t index;
210 
211     if ((data == NULL) || (data_len == 0)) {
212         return ERRCODE_FAIL;
213     }
214     for (index = 0; index < data_len; index++) {
215         if (data[index] != 0) {
216             return ERRCODE_FAIL;
217         }
218     }
219     return ERRCODE_SUCC;
220 }
221 
efuse_write_sle_mac(uint8_t * data,uint16_t data_len)222 uint32_t efuse_write_sle_mac(uint8_t *data, uint16_t data_len)
223 {
224     uint32_t ret = ERRCODE_FAIL;
225     uint8_t read_back_addr[EFUSE_MAC_LEN];
226     if ((data == NULL) || (data_len != EFUSE_MAC_LEN)) {
227         return ERRCODE_FAIL;
228     }
229     ret = uapi_efuse_read_buffer(read_back_addr, (SLE_MAC_ADDR_START_BIT / BIT_TO_BYTE), EFUSE_MAC_LEN);
230     if ((ret == ERRCODE_SUCC) && (check_data(read_back_addr, data_len) == ERRCODE_SUCC)) {
231         ret = uapi_efuse_write_buffer((SLE_MAC_ADDR_START_BIT / BIT_TO_BYTE), data, data_len);
232         return ret;
233     }
234     return ERRCODE_FAIL;
235 }
236 
efuse_read_sle_mac(uint8_t * data,uint16_t data_len)237 uint32_t efuse_read_sle_mac(uint8_t *data, uint16_t data_len)
238 {
239     if ((data == NULL) || (data_len != EFUSE_MAC_LEN)) {
240         return ERRCODE_FAIL;
241     }
242     return uapi_efuse_read_buffer(data, (SLE_MAC_ADDR_START_BIT / BIT_TO_BYTE), data_len);
243 }
244 
efuse_write_customer_rsvd_efuse(uint8_t * data,uint16_t data_len)245 uint32_t efuse_write_customer_rsvd_efuse(uint8_t *data, uint16_t data_len)
246 {
247     uint32_t ret = ERRCODE_FAIL;
248     uint8_t read_back_data[CUSTOM_RESVED_EFUSE_BYTE_LEN] = {0};
249     if ((data == NULL) || (data_len != CUSTOM_RESVED_EFUSE_BYTE_LEN)) {
250         return ERRCODE_FAIL;
251     }
252     ret = efuse_read_item(EFUSE_CUSTOM_RESVED_ID, read_back_data, CUSTOM_RESVED_EFUSE_BYTE_LEN);
253     if ((ret == ERRCODE_SUCC) && (check_data(read_back_data, CUSTOM_RESVED_EFUSE_BYTE_LEN) == ERRCODE_SUCC)) {
254         ret = uapi_efuse_write_buffer(CUSTOM_RESVED_EFUSE_LEN_START_BYTE_ADDR, data, data_len);
255         return ret;
256     }
257     return ERRCODE_FAIL;
258 }
259 
efuse_write_customer_rsvd2_efuse(uint8_t * data,uint16_t data_len)260 uint32_t efuse_write_customer_rsvd2_efuse(uint8_t *data, uint16_t data_len)
261 {
262     uint32_t ret = ERRCODE_FAIL;
263     uint8_t read_back_data[CUSTOM_RESVED2_EFUSE_BYTE_LEN] = {0};
264     if ((data == NULL) || (data_len != CUSTOM_RESVED2_EFUSE_BYTE_LEN)) {
265         return ERRCODE_FAIL;
266     }
267     ret = uapi_efuse_read_buffer(read_back_data, CUSTOM_RESVED2_EFUSE_LEN_START_BYTE_ADDR,
268         CUSTOM_RESVED2_EFUSE_BYTE_LEN);
269     if ((ret == ERRCODE_SUCC) && (check_data(read_back_data, CUSTOM_RESVED2_EFUSE_BYTE_LEN) == ERRCODE_SUCC)) {
270         ret = uapi_efuse_write_buffer(CUSTOM_RESVED2_EFUSE_LEN_START_BYTE_ADDR, data, data_len);
271         return ret;
272     } else {
273         ret = uapi_efuse_read_buffer(read_back_data, CUSTOM_RESVED3_EFUSE_LEN_START_BYTE_ADDR,
274             CUSTOM_RESVED2_EFUSE_BYTE_LEN);
275         if ((ret == ERRCODE_SUCC) && (check_data(read_back_data, CUSTOM_RESVED2_EFUSE_BYTE_LEN) == ERRCODE_SUCC)) {
276             ret = uapi_efuse_write_buffer(CUSTOM_RESVED3_EFUSE_LEN_START_BYTE_ADDR, data, data_len);
277             return ret;
278         }
279     }
280     return ERRCODE_FAIL;
281 }
282 
efuse_read_customer_rsvd2_efuse(uint8_t * data,uint16_t data_len)283 uint32_t efuse_read_customer_rsvd2_efuse(uint8_t *data, uint16_t data_len)
284 {
285     uint32_t ret = ERRCODE_FAIL;
286     if ((data == NULL) || (data_len != CUSTOM_RESVED2_EFUSE_BYTE_LEN)) {
287         return ERRCODE_FAIL;
288     }
289     ret = uapi_efuse_read_buffer(data, CUSTOM_RESVED3_EFUSE_LEN_START_BYTE_ADDR, CUSTOM_RESVED2_EFUSE_BYTE_LEN);
290     if ((ret == ERRCODE_SUCC) && (check_data(data, CUSTOM_RESVED2_EFUSE_BYTE_LEN) != ERRCODE_SUCC)) {
291         return ret;
292     } else {
293         ret = uapi_efuse_read_buffer(data, CUSTOM_RESVED2_EFUSE_LEN_START_BYTE_ADDR, CUSTOM_RESVED2_EFUSE_BYTE_LEN);
294         if ((ret == ERRCODE_SUCC) && (check_data(data, CUSTOM_RESVED2_EFUSE_BYTE_LEN) != ERRCODE_SUCC)) {
295             return ret;
296         }
297     }
298     return ERRCODE_SUCC;
299 }
300 
301 #ifdef _PRE_WLAN_FEATURE_MFG_TEST
efuse_write_jtag_ssi(void)302 uint32_t efuse_write_jtag_ssi(void)
303 {
304     uint32_t ret = ERRCODE_FAIL;
305 
306     ret = uapi_efuse_write_bit((EFUSE_SSI_MASK_START_BIT / BIT_TO_BYTE), (EFUSE_SSI_MASK_START_BIT % BIT_TO_BYTE));
307     ret |= uapi_efuse_write_bit((EFUSE_FUNC_JTAG_MASK_START_BIT / BIT_TO_BYTE),
308         (EFUSE_FUNC_JTAG_MASK_START_BIT % BIT_TO_BYTE));
309     ret |= uapi_efuse_write_bit((EFUSE_DFT_JTAG_MASK_START_BIT / BIT_TO_BYTE),
310         (EFUSE_DFT_JTAG_MASK_START_BIT % BIT_TO_BYTE));
311     return ret;
312 }
313 
efuse_read_jtag_ssi(uint8_t * data,uint16_t data_len)314 uint32_t efuse_read_jtag_ssi(uint8_t *data, uint16_t data_len)
315 {
316     uint32_t ret = ERRCODE_FAIL;
317     uint8_t ssi_jtag = 0;
318 
319     if ((data == NULL) || (data_len != EFUSE_SIZE_1_BYTS)) {
320         return ERRCODE_FAIL;
321     }
322     ret = uapi_efuse_read_buffer(&ssi_jtag, (EFUSE_SSI_MASK_START_BIT / BIT_TO_BYTE), data_len);
323     if (ret != ERRCODE_SUCC) {
324         return ret;
325     }
326     if ((ssi_jtag & 0x0E) != 0 && (ssi_jtag & 0x0E) != 0x0E) {
327         return ERRCODE_FAIL;
328     }
329     *data = (ssi_jtag == 0) ? 0 : 1;
330     return ERRCODE_SUCC;
331 }
332 
efuse_write_hash_root_public_key(uint8_t * data,uint16_t data_len)333 uint32_t efuse_write_hash_root_public_key(uint8_t *data, uint16_t data_len)
334 {
335     uint32_t ret = ERRCODE_FAIL;
336 
337     if ((data == NULL) || (data_len != HASH_ROOT_PUBLIC_KEY_LEN)) {
338         return ERRCODE_FAIL;
339     }
340     ret = uapi_efuse_write_buffer((EFUSE_HASH_ROOT_PUBLIC_KEY_START_BIT / BIT_TO_BYTE), data, data_len);
341     return ret;
342 }
343 
efuse_read_hash_root_public_key(uint8_t * data,uint16_t data_len)344 uint32_t efuse_read_hash_root_public_key(uint8_t *data, uint16_t data_len)
345 {
346     uint32_t ret = ERRCODE_FAIL;
347 
348     if ((data == NULL) || (data_len != HASH_ROOT_PUBLIC_KEY_LEN)) {
349         return ERRCODE_FAIL;
350     }
351     ret = uapi_efuse_read_buffer(data, (EFUSE_HASH_ROOT_PUBLIC_KEY_START_BIT / BIT_TO_BYTE), data_len);
352     return ret;
353 }
354 
efuse_write_sec_verify(void)355 uint32_t efuse_write_sec_verify(void)
356 {
357     uint32_t ret = ERRCODE_FAIL;
358     ret = uapi_efuse_write_bit((EFUSE_SEC_VERIFY_ENABLE_START_BIT / BIT_TO_BYTE),
359         (EFUSE_SEC_VERIFY_ENABLE_START_BIT % BIT_TO_BYTE));
360     return ret;
361 }
362 
efuse_read_sec_verify(uint8_t * data,uint16_t data_len)363 uint32_t efuse_read_sec_verify(uint8_t *data, uint16_t data_len)
364 {
365     uint32_t ret = ERRCODE_FAIL;
366 
367     if ((data == NULL) || (data_len != EFUSE_SIZE_1_BYTS)) {
368         return ERRCODE_FAIL;
369     }
370     ret = uapi_efuse_read_bit(data, (EFUSE_SEC_VERIFY_ENABLE_START_BIT / BIT_TO_BYTE),
371         (EFUSE_SEC_VERIFY_ENABLE_START_BIT % BIT_TO_BYTE));
372     return ret;
373 }
374 #endif
375