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