• 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 <cmd_loop.h>
17 #include <crc.h>
18 #include <transfer.h>
19 
20 #define CMD_RX_DELAY_MS     100 /* 100ms */
21 #define US_PER_MS           1000
22 #define CMD_FRAME_TIMEOUT   20000 /* 20s */
23 #define CMD_ABNORMAL_MAX    100
24 #define CHECKSUM_SIZE       2
25 #define ACK_LEN             0x0C
26 
27 #define VER_CFG_BIN_LEN 8
28 #define UPDATE_VER_STATUS_NONE        0
29 #define UPDATE_VER_STATUS_BOOT        1
30 #define UPDATE_VER_STATUS_KERNEL      2
31 #define UPDATE_VER_STATUS_BOOT_KERNEL 3
32 #define KERELN_VER_MAX          48
33 #define KERNEL_VER_LEN          6
34 #define BOOT_VER_MAX            16
35 #define BOOT_VER_LEN            2
36 #define BIT_U8   8
37 #define SEC_BOOT_FLAG 0x42
38 #define WAIT_VER_UPDATE_TRY_CNT 1000
39 #define WAIT_VER_UPDATE_TRY_INTER_US 10000
40 
41 #define NMI_BASE_ADDRESS    0x40010000
42 #define NMI_CTRL            0x0258
43 #define NMI_INT_MOD_DONE_EN_POS 0
44 
45 volatile hi_u8 g_update_ver_status = UPDATE_VER_STATUS_NONE;
46 volatile hi_bool g_upg_update_ver_success = HI_FALSE;
47 hi_u8 g_upg_efuse_data_boot_ver[BOOT_VER_LEN] = {0};
48 hi_u8 g_upg_efuse_data_kernel_ver[KERNEL_VER_LEN] = {0};
49 void *g_nmi_stack_end = ((void *) &__nmi_stack_top);
50 
51 typedef enum {
52     CMD_RX_STATUS_WAIT_START_0,
53     CMD_RX_STATUS_WAIT_START_1,
54     CMD_RX_STATUS_WAIT_START_2,
55     CMD_RX_STATUS_WAIT_START_3,
56     CMD_RX_STATUS_WAIT_SIZE_0,
57     CMD_RX_STATUS_WAIT_SIZE_1,
58     CMD_RX_STATUS_WAIT_TYPE,
59     CMD_RX_STATUS_WAIT_PAD,
60     CMD_RX_STATUS_WAIT_DATA,
61     CMD_RX_STATUS_WAIT_CS_0,
62     CMD_RX_STATUS_WAIT_CS_1,
63 } cmd_rx_status;
64 
65 typedef hi_u32(*cmd_func) (const uart_ctx *cmd_ctx);
66 
67 typedef struct {
68     hi_u8 cmd_type;
69     cmd_func cmdfunc;
70 } loader_cmd;
71 
72 uart_ctx *g_cmd_ctx = HI_NULL;
73 
74 const loader_cmd g_loader_cmdtable[LOADER_CMD_MAX] = {
75     { CMD_DL_IMAGE,         loader_download_image },
76     { CMD_BURN_EFUSE,       loader_burn_efuse },
77     { CMD_UL_DATA,          loader_upload_data },
78     { CMD_READ_EFUSE,       loader_read_efuse },
79     { CMD_FLASH_PROTECT,    loader_flash_protect },
80     { CMD_RESET,            loader_reset },
81     { CMD_FACTORY_IMAGE,    loader_download_image },
82     { CMD_VERSION,          loader_burn_version},
83 };
84 
loader_read_flash_protect_state(hi_void)85 hi_void loader_read_flash_protect_state(hi_void)
86 {
87     hi_u32 reg = 0;
88     hi_reg_write(SFC_REG_BASE_ADDRESS + SFC_REG_CMD_DATABUF1, 0);
89     spif_wait_config_start();
90     hi_reg_write(SFC_REG_BASE_ADDRESS + SFC_REG_CMD_INS, 0x05);
91     hi_reg_write(SFC_REG_BASE_ADDRESS + SFC_REG_CMD_CONFIG, 0x183);
92     spif_wait_config_start();
93     hi_reg_read(SFC_REG_BASE_ADDRESS + SFC_REG_CMD_DATABUF1, reg);
94     boot_msg1("S0 ~ S7   : ", reg);
95     hi_reg_write(SFC_REG_BASE_ADDRESS + SFC_REG_CMD_DATABUF1, 0);
96     spif_wait_config_start();
97     hi_reg_write(SFC_REG_BASE_ADDRESS + SFC_REG_CMD_INS, 0x35);
98     hi_reg_write(SFC_REG_BASE_ADDRESS + SFC_REG_CMD_CONFIG, 0x183);
99     spif_wait_config_start();
100     hi_reg_read(SFC_REG_BASE_ADDRESS + SFC_REG_CMD_DATABUF1, reg);
101     boot_msg1("S8 ~ S15 : ", reg);
102 }
103 
loader_reset(const uart_ctx * cmd_ctx)104 hi_u32 loader_reset(const uart_ctx *cmd_ctx)
105 {
106     hi_unref_param(cmd_ctx);
107     boot_msg0("\nReset device...\n");
108     loader_ack(ACK_SUCCESS);
109     mdelay(5);  /* delay 5ms */
110     global_reset();
111     return HI_ERR_SUCCESS;
112 }
113 
loader_flash_protect(const uart_ctx * cmd_ctx)114 hi_u32 loader_flash_protect(const uart_ctx *cmd_ctx)
115 {
116     hi_u32 ret;
117     hi_u16 cmd_type = *(hi_u16 *)(&cmd_ctx->packet.payload[0]);
118     boot_msg0("Flash protect state");
119     loader_read_flash_protect_state();
120     if (cmd_type == 1) {
121         ret = flash_protect_set_protect(0, HI_FALSE);
122         if (ret == HI_ERR_SUCCESS) {
123             boot_msg0("\r\nUnlock Succ\r\n");
124             loader_read_flash_protect_state();
125         } else {
126             boot_msg0("\r\nUnlock Fail\r\n");
127         }
128         return ret;
129     } else if (cmd_type > 1) {
130         boot_msg0("Unknow cmd type");
131         return HI_ERR_FAILURE;
132     }
133     return HI_ERR_SUCCESS;
134 }
135 
loader_download_image(const uart_ctx * cmd_ctx)136 hi_u32 loader_download_image(const uart_ctx *cmd_ctx)
137 {
138     hi_u8 chip_id[HI_FLASH_CHIP_ID_NUM] = { 0 };
139     hi_u32 flash_size = 0;
140     hi_u32 download_addr = *(hi_u32 *)(&cmd_ctx->packet.payload[0]);
141     hi_u32 file_len = *(hi_u32 *)(&cmd_ctx->packet.payload[4]); /* offset 4 is file length */
142     hi_u32 erase_size = *(hi_u32 *)(&cmd_ctx->packet.payload[8]); /* offset 8 is erase size */
143     hi_u8 burn_efuse = cmd_ctx->packet.payload[12]; /* offset 12 is burn efuse flag */
144     hi_u32 ret = spi_flash_read_chip_id(chip_id, HI_FLASH_CHIP_ID_NUM);
145     if (ret == HI_ERR_SUCCESS) {
146         flash_size = spi_flash_get_size((const hi_u8 *)chip_id);
147     } else {
148         boot_msg0("Get flash size fail");
149         return HI_ERR_FAILURE;
150     }
151 
152     if (file_len == 0 || erase_size == 0 || erase_size < file_len || (download_addr + file_len) > flash_size) {
153         boot_msg0("Invalid params");
154         serial_puts("download_addr ");
155         serial_puthex(download_addr, 1);
156         serial_puts(" file_len ");
157         serial_puthex(file_len, 1);
158         serial_puts(" erase_size ");
159         serial_puthex(erase_size, 1);
160         serial_puts("\r\n");
161         return HI_ERR_FAILURE;
162     }
163 
164 #ifdef CONFIG_FLASH_ENCRYPT_SUPPORT
165     hi_u64 efuse_lock_status = 0;
166     ret = hi_efuse_get_lockstat(&efuse_lock_status);
167     if (ret != HI_ERR_SUCCESS) {
168         return HI_ERR_FAILURE;
169     }
170     if ((efuse_lock_status & 0x10) == 0) {
171         boot_msg0("Enable flash encryption: ");
172         boot_msg0("Please write and lock efuse root key field first!");
173         return HI_ERR_FAILURE;
174     }
175 #endif
176 
177     if (cmd_ctx->packet.head.type == CMD_FACTORY_IMAGE) {
178         return download_factory_image(download_addr, erase_size, flash_size, burn_efuse);
179     }
180 
181     return download_image(download_addr, erase_size, flash_size, burn_efuse);
182 }
183 
184 
tool_bit_test(const hi_u8 * data,hi_u16 pos,hi_u16 data_len)185 hi_bool tool_bit_test(const hi_u8 *data, hi_u16 pos, hi_u16 data_len)
186 {
187     hi_u16 base = pos / BIT_U8;
188     hi_u16 i = pos % BIT_U8;
189     if (pos > (data_len * BIT_U8)) {
190         return HI_FALSE;
191     }
192     return (hi_bool)bit_get(data[base], i);
193 }
194 
tool_bit_set(hi_u8 * data,hi_u16 pos,hi_u8 val)195 hi_void tool_bit_set(hi_u8 *data, hi_u16 pos, hi_u8 val)
196 {
197     hi_u16 base = pos / BIT_U8;
198     hi_u16 i = pos % BIT_U8;
199     bit_set(data[base], i, val);
200 }
201 
get_secure_boot_flag(hi_bool * secure_flag)202 hi_u32 get_secure_boot_flag(hi_bool *secure_flag)
203 {
204     hi_u8 data = 0;
205     hi_u32 ret = hi_efuse_read(HI_EFUSE_SEC_BOOT_RW_ID, (hi_u8 *)(&data), (hi_u8)(sizeof(hi_u8)));
206     if (ret != HI_ERR_SUCCESS) {
207         boot_msg1("secure boot efuse read err:", ret);
208         return ret;
209     }
210 
211     if (data == SEC_BOOT_FLAG) {
212         *secure_flag = HI_FALSE;
213     } else {
214         *secure_flag = HI_TRUE;
215     }
216 
217     return HI_ERR_SUCCESS;
218 }
219 
220 
get_efuse_boot_ver(hi_u8 * ver)221 hi_u32 get_efuse_boot_ver(hi_u8 *ver)
222 {
223     hi_u8 pos;
224     hi_u8 efuse_data[BOOT_VER_LEN] = { 0 };
225     hi_u32 ret = hi_efuse_read(HI_EFUSE_TEE_BOOT_VER_RW_ID, efuse_data, sizeof(efuse_data));
226     if (ret != HI_ERR_SUCCESS) {
227         return ret;
228     }
229 
230     for (pos = 0; pos < BOOT_VER_MAX; pos++) {
231         if (tool_bit_test(efuse_data, pos, BOOT_VER_LEN) == HI_FALSE) {
232             break;
233         }
234     }
235     if (pos >= BOOT_VER_MAX) {
236         *ver = BOOT_VER_MAX;
237     } else {
238         *ver = pos;
239     }
240     return ret;
241 }
242 
get_efuse_code_ver(hi_u8 * ver)243 hi_u32 get_efuse_code_ver(hi_u8 *ver)
244 {
245     hi_u8 pos;
246     hi_u8 efuse_data[KERNEL_VER_LEN];
247     hi_u32 ret;
248 
249     hi_u32 cs = (uintptr_t)efuse_data ^ KERNEL_VER_LEN ^ 0 ^ KERNEL_VER_LEN;
250     (hi_void) memset_s(efuse_data, KERNEL_VER_LEN, 0, KERNEL_VER_LEN, cs);
251     ret = hi_efuse_read(HI_EFUSE_TEE_KERNEL_VER_RW_ID, efuse_data, sizeof(efuse_data));
252     if (ret != HI_ERR_SUCCESS) {
253         return ret;
254     }
255 
256     for (pos = 0; pos < KERELN_VER_MAX; pos++) {
257         if (tool_bit_test(efuse_data, pos, KERNEL_VER_LEN) == HI_FALSE) {
258             break;
259         }
260     }
261     if (pos >= KERELN_VER_MAX) {
262         *ver = KERELN_VER_MAX;
263     } else {
264         *ver = pos;
265     }
266     return ret;
267 }
268 
start_and_wait_update_ver()269 hi_u32 start_and_wait_update_ver()
270 {
271     /* init upg flag */
272     g_upg_update_ver_success = HI_FALSE;
273 
274     /* trigger upg nmi */
275     hi_reg_setbit(NMI_BASE_ADDRESS + NMI_CTRL, NMI_INT_MOD_DONE_EN_POS);
276 
277     /* wait nmi handle finish */
278     hi_u32 try_cnt;
279     for (try_cnt = 0; try_cnt < WAIT_VER_UPDATE_TRY_CNT; try_cnt++) {
280         if (g_update_ver_status == UPDATE_VER_STATUS_NONE) {
281             break;
282         }
283         udelay(WAIT_VER_UPDATE_TRY_INTER_US);   /* sleep 10ms */
284     }
285 
286     if (g_upg_update_ver_success == HI_TRUE) {
287         return HI_ERR_SUCCESS;
288     } else if (try_cnt == WAIT_VER_UPDATE_TRY_CNT) {
289         return HI_ERR_UPG_UPDATE_VER_TIMEOUT;
290     } else {
291         return HI_ERR_UPG_UPDATE_VER_FAIL;
292     }
293 }
294 
check_boot_kernel_ver(hi_u8 boot_ver,hi_u8 kernel_ver,hi_u8 * current_boot_ver,hi_u8 * current_kernel_ver)295 hi_u32 check_boot_kernel_ver(hi_u8 boot_ver, hi_u8 kernel_ver, hi_u8 *current_boot_ver, hi_u8 *current_kernel_ver)
296 {
297     hi_u32 ret;
298 
299     ret = get_efuse_boot_ver(current_boot_ver);
300     if (ret != HI_ERR_SUCCESS) {
301         boot_msg1("get boot ver ret:", ret);
302         return ret;
303     }
304 
305     ret = get_efuse_code_ver(current_kernel_ver);
306     if (ret != HI_ERR_SUCCESS) {
307         boot_msg1("get kernel ver ret:", ret);
308         return ret;
309     }
310 
311     if (boot_ver < *current_boot_ver) {
312         boot_msg2("current boot ver >boot ver:", *current_boot_ver, boot_ver);
313         return HI_ERR_UPG_LOW_KERNEL_VER;
314     }
315 
316     if (kernel_ver < *current_kernel_ver) {
317         boot_msg2("current kernel ver > kernel ver:", *current_kernel_ver, kernel_ver);
318         return HI_ERR_UPG_LOW_KERNEL_VER;
319     }
320 
321     if (boot_ver > BOOT_VER_MAX || kernel_ver > KERELN_VER_MAX) {
322         boot_msg2("invalid boot ver, kernel ver:", boot_ver, kernel_ver);
323         return HI_ERR_UPG_FULL_KERNEL_VER;
324     }
325 
326     return HI_ERR_SUCCESS;
327 }
328 
set_efuse_boot_kernel_ver(hi_u8 boot_ver,hi_u8 kernel_ver)329 hi_u32 set_efuse_boot_kernel_ver(hi_u8 boot_ver, hi_u8 kernel_ver)
330 {
331     hi_u32 ret;
332     hi_u8 pos;
333     hi_u8 current_boot_ver = 0;
334     hi_u8 current_kernel_ver = 0;
335     hi_bool flag = HI_FALSE;
336 
337     ret = get_secure_boot_flag(&flag);
338     if (ret != HI_ERR_SUCCESS) {
339         return ret;
340     }
341 
342     if (flag == HI_FALSE) {
343         boot_msg0("not secure boot.");
344         return HI_ERR_SUCCESS;
345     }
346 
347     ret = check_boot_kernel_ver(boot_ver, kernel_ver, &current_boot_ver, &current_kernel_ver);
348     if (ret != HI_ERR_SUCCESS) {
349         return ret;
350     }
351 
352     hi_bool update_boot_ver = HI_FALSE;
353     hi_bool update_kernel_ver = HI_FALSE;
354     if (boot_ver != current_boot_ver) {
355         hi_u32 cs = (uintptr_t)g_upg_efuse_data_boot_ver ^ BOOT_VER_LEN ^ 0 ^ BOOT_VER_LEN;
356         (hi_void) memset_s(g_upg_efuse_data_boot_ver, BOOT_VER_LEN, 0, BOOT_VER_LEN, cs);
357         for (pos = current_boot_ver; pos < boot_ver; pos++) {
358             tool_bit_set(g_upg_efuse_data_boot_ver, pos, SRV_BIT_HIGH);
359         }
360         update_boot_ver = HI_TRUE;
361     }
362 
363     if (kernel_ver != current_kernel_ver) {
364         hi_u32 cs = (uintptr_t)g_upg_efuse_data_kernel_ver ^ KERNEL_VER_LEN ^ 0 ^ KERNEL_VER_LEN;
365         (hi_void) memset_s(g_upg_efuse_data_kernel_ver, KERNEL_VER_LEN, 0, KERNEL_VER_LEN, cs);
366         for (pos = current_kernel_ver; pos < kernel_ver; pos++) {
367             tool_bit_set(g_upg_efuse_data_kernel_ver, pos, SRV_BIT_HIGH);
368         }
369         update_kernel_ver = HI_TRUE;
370     }
371 
372     if (update_boot_ver == HI_FALSE && update_kernel_ver == HI_FALSE) {
373         boot_msg0("same ver with efuse");
374         return HI_ERR_SUCCESS;
375     } else if (update_boot_ver == HI_TRUE && update_kernel_ver == HI_TRUE) {
376         g_update_ver_status =  UPDATE_VER_STATUS_BOOT_KERNEL;
377     } else if (update_boot_ver == HI_TRUE) {
378         g_update_ver_status =  UPDATE_VER_STATUS_BOOT;
379     } else {
380         g_update_ver_status =  UPDATE_VER_STATUS_KERNEL;
381     }
382 
383     ret = start_and_wait_update_ver();
384 
385     return ret;
386 }
387 
nmi_update_ver(hi_void)388 hi_void nmi_update_ver(hi_void)
389 {
390     if (g_update_ver_status == UPDATE_VER_STATUS_NONE) {
391         return;
392     }
393 
394     hi_u32 ret;
395 
396     if (g_update_ver_status == UPDATE_VER_STATUS_BOOT || g_update_ver_status == UPDATE_VER_STATUS_BOOT_KERNEL) {
397         ret = hi_efuse_write(HI_EFUSE_TEE_BOOT_VER_RW_ID, g_upg_efuse_data_boot_ver);
398         if (ret != HI_ERR_SUCCESS) {
399             boot_msg1("update boot ver fail, ret:", ret);
400             g_upg_update_ver_success = HI_FALSE;
401             g_update_ver_status = UPDATE_VER_STATUS_NONE;
402             return;
403         }
404     }
405 
406     if (g_update_ver_status == UPDATE_VER_STATUS_KERNEL || g_update_ver_status == UPDATE_VER_STATUS_BOOT_KERNEL) {
407         ret = hi_efuse_write(HI_EFUSE_TEE_KERNEL_VER_RW_ID, g_upg_efuse_data_kernel_ver);
408         if (ret != HI_ERR_SUCCESS) {
409             boot_msg1("update kernel ver fail, ret:", ret);
410             g_upg_update_ver_success = HI_FALSE;
411             g_update_ver_status = UPDATE_VER_STATUS_NONE;
412             return;
413         }
414     }
415 
416     g_upg_update_ver_success = HI_TRUE;
417     g_update_ver_status = UPDATE_VER_STATUS_NONE;
418 
419     return;
420 }
421 
loader_burn_version(const uart_ctx * cmd_ctx)422 hi_u32 loader_burn_version(const uart_ctx *cmd_ctx)
423 {
424     hi_u32 ret;
425     hi_u32 file_len = *(hi_u32 *)(&cmd_ctx->packet.payload[0]);
426     if (file_len != VER_CFG_BIN_LEN) {
427         boot_msg1("Ver length error : ", file_len);
428         return HI_ERR_FAILURE;
429     }
430     hi_u8 *buf = boot_malloc(file_len);
431     if (buf == HI_NULL) {
432         boot_msg0("Malloc buffer error");
433         return HI_ERR_FAILURE;
434     }
435 
436     ret = loady_version_file((uintptr_t)buf);
437     if (ret != HI_ERR_SUCCESS) {
438         boot_msg1("Loady ver file failed:", ret);
439         return ret;
440     }
441 
442     hi_u32 boot_ver = *(hi_u32 *)buf;
443     hi_u32 kernel_ver = *(hi_u32 *)(buf + 4); /* 4: 4 byte as a word(little ending). */
444 
445     boot_msg1("boot ver:", boot_ver);
446     boot_msg1("kernel_ver:", kernel_ver);
447 
448     ret = set_efuse_boot_kernel_ver(boot_ver, kernel_ver);
449 
450     return ret;
451 }
452 
boot_nmi_handler(void)453 void boot_nmi_handler(void)
454 {
455     hi_u32 *sp_val = 0;
456 
457     /* clear NMI interrupt */
458     hi_reg_write(NMI_BASE_ADDRESS + NMI_CTRL, 0x0);
459     __asm__ __volatile__("fence":::"memory");
460 
461     nmi_update_ver();
462 
463     /* NOTICE: Start Clear NMI Stack, All User nmi service MUST BE DONE at this moment!!! */
464     __asm__ volatile ("mv %0, sp" : "=r"(sp_val));
465     while (sp_val != (hi_u32 *)(&__nmi_stack_bottom)) {
466         *sp_val = 0;
467         sp_val--;
468     }
469 }
470 
loader_burn_efuse(const uart_ctx * cmd_ctx)471 hi_u32 loader_burn_efuse(const uart_ctx *cmd_ctx)
472 {
473     hi_u32 ret;
474     hi_u32 file_len = *(hi_u32 *)(&cmd_ctx->packet.payload[0]);
475     if (file_len <= EFUSE_CFG_MIN_LEN || file_len > EFUSE_CFG_MAX_LEN) {
476         boot_msg1("File length error : ", file_len);
477         return HI_ERR_FAILURE;
478     }
479 
480     hi_u8 *buf = boot_malloc(file_len);
481     if (buf == HI_NULL) {
482         boot_msg0("Malloc buffer error");
483         return HI_ERR_FAILURE;
484     }
485 
486     ret = loady_file((uintptr_t)buf);
487     if (ret != HI_ERR_SUCCESS) {
488         boot_msg1("Loady efuse file failed:", ret);
489         return ret;
490     }
491 
492     ret = efuse_burn((uintptr_t)buf, file_len);
493     if (ret != HI_ERR_SUCCESS) {
494         return ret;
495     }
496 
497     /* 复位efuse模块,使得efuse立即生效,应用于在烧写过程中依赖huks根秘钥的场景 */
498     /* reset efuse for validate immediately */
499     hi_reg_clrbit16(CLDO_CTL_SOFT_RESET2_REG, EFUSE_RST_BIT);
500     udelay(0x3);
501     hi_reg_setbit16(CLDO_CTL_SOFT_RESET2_REG, EFUSE_RST_BIT);
502 
503     return HI_ERR_SUCCESS;
504 }
505 
loader_read_efuse(const uart_ctx * cmd_ctx)506 hi_u32 loader_read_efuse(const uart_ctx *cmd_ctx)
507 {
508     hi_u32 ret;
509     hi_u16 start_bit = *(hi_u16 *)(&cmd_ctx->packet.payload[0]);
510     hi_u16 size = *(hi_u16 *)(&cmd_ctx->packet.payload[2]); /* offset 2 is read size */
511     boot_msg0("Efuse read");
512     serial_puts("Start bit: ");
513     serial_puthex(start_bit, 1);
514     serial_puts(" len(bits)=");
515     serial_puthex(size, 1);
516     serial_puts("\r\n");
517     if ((start_bit >= EFUSE_BIT_NUM) || ((start_bit + size) > EFUSE_BIT_NUM) || size > EFUSE_READ_MAX_BITS) {
518         boot_msg0("Params err");
519         return HI_ERR_FAILURE;
520     }
521 
522     ret = efuse_read(start_bit, size);
523     if (ret != HI_ERR_SUCCESS) {
524         return HI_ERR_FAILURE;
525     }
526 
527     return HI_ERR_SUCCESS;
528 }
529 
loader_upload_data(const uart_ctx * cmd_ctx)530 hi_u32 loader_upload_data(const uart_ctx *cmd_ctx)
531 {
532     hi_u8 chip_id[HI_FLASH_CHIP_ID_NUM] = {0};
533     hi_u32 flash_size = 0;
534     hi_u32 file_len = *(hi_u32 *)(&cmd_ctx->packet.payload[0]);
535     hi_u32 upload_addr = *(hi_u32 *)(&cmd_ctx->packet.payload[4]);  /* offset 4 is read addr */
536     boot_msg2("Upload addr, length :", upload_addr, file_len);
537 
538     hi_u32 ret = spi_flash_read_chip_id(chip_id, HI_FLASH_CHIP_ID_NUM);
539     if (ret == HI_ERR_SUCCESS) {
540         flash_size = spi_flash_get_size((const hi_u8 *)chip_id);
541     } else {
542         boot_msg0("Get flash size fail");
543         return HI_ERR_FAILURE;
544     }
545 
546     if (file_len == 0 || file_len > flash_size) {
547         boot_msg0("Upload length error");
548         return HI_ERR_FAILURE;
549     }
550 
551     if ((upload_addr & 0x3) != 0) {
552         boot_msg0("Upload addr error");
553         return HI_ERR_FAILURE;
554     }
555 
556     if ((upload_addr + file_len) > flash_size) {
557         boot_msg0("Upload addr exceeds flash capacity");
558         return HI_ERR_FAILURE;
559     }
560 
561     return upload_data(upload_addr, file_len);
562 }
563 
loader_frame_head_rx(uart_ctx * ctx)564 hi_u32 loader_frame_head_rx(uart_ctx *ctx)
565 {
566     hi_u8 ch;
567     hi_bool reset_flag = HI_FALSE;
568     hi_u16 rcv = 0;
569 
570     packet_data_head *head = &ctx->packet.head;
571     hi_u8 *payload = (hi_u8 *)head;
572 
573     while (rcv <= CMD_ABNORMAL_MAX) {
574         hi_u32 ret = serial_getc_timeout(CMD_FRAME_TIMEOUT * US_PER_MS, &ch);
575         if (ret != HI_ERR_SUCCESS) {
576             continue;
577         }
578 
579         rcv++;
580         if (reset_flag == HI_TRUE) {
581             reset_flag = HI_FALSE;
582             head->start_flag = 0;
583             ctx->status = CMD_RX_STATUS_WAIT_START_0;
584         }
585         if (ctx->status <= CMD_RX_STATUS_WAIT_START_3) {
586             hi_u32 start_flag = UART_PACKET_START_FLAG;
587             hi_u8 *start_byte = (hi_u8 *)&start_flag;
588             if (ch == start_byte[ctx->status]) {
589                 payload[ctx->status] = ch;
590                 ctx->status++;
591                 continue;
592             } else if (ch == 0xEF) {
593                 payload[CMD_RX_STATUS_WAIT_START_0] = ch;
594                 ctx->status = CMD_RX_STATUS_WAIT_START_1;
595                 continue;
596             }
597             reset_flag = HI_TRUE;
598             continue;
599         } else {
600             payload[ctx->status] = ch;
601             if (ctx->status >= CMD_RX_STATUS_WAIT_START_1 && (head->packet_size > UART_PACKET_PAYLOAD_MAX)) {
602                 reset_flag = HI_TRUE;
603                 continue;
604             }
605             ctx->status++;
606             if (ctx->status >= CMD_RX_STATUS_WAIT_DATA) {
607                 return HI_ERR_SUCCESS;
608             }
609         }
610     }
611     return HI_ERR_FAILURE;
612 }
613 
loader_frame_data_rx(uart_ctx * ctx)614 hi_u32 loader_frame_data_rx(uart_ctx *ctx)
615 {
616     hi_u8 ch;
617     hi_u32 ret;
618     ctx->received = 0;
619 
620     packet_data_head *head = &ctx->packet.head;
621     hi_u8 *payload = ctx->packet.payload;
622 
623     while (ctx->received < (head->packet_size - sizeof(packet_data_head))) {
624         ret = serial_getc_timeout(CMD_RX_DELAY_MS * US_PER_MS, &ch);
625         if (ret == HI_ERR_SUCCESS) {
626             payload[ctx->received++] = ch;
627             continue;
628         }
629         return HI_ERR_FAILURE;
630     }
631     ctx->packet.check_sum = (payload[head->packet_size - 9] << 8) | payload[head->packet_size - 10]; /* 8,9,10: sub */
632     payload[head->packet_size - 9] = 0;  /* 9: sub 9 */
633     payload[head->packet_size - 10] = 0; /* 10: sub 10 */
634 
635     if (ctx->received == (head->packet_size - sizeof(packet_data_head))) {
636         return HI_ERR_SUCCESS;
637     }
638 
639     return HI_ERR_FAILURE;
640 }
641 
loader_ack(hi_u8 err_code)642 hi_void loader_ack(hi_u8 err_code)
643 {
644     uart_ctx *ctx = g_cmd_ctx;
645     packet_data_head *head = &ctx->packet.head;
646 
647     head->start_flag = UART_PACKET_START_FLAG;
648     head->type = CMD_ACK;
649     head->pad = (hi_u8)(~(CMD_ACK));
650     head->packet_size = ACK_LEN;
651     ctx->packet.payload[0] = err_code;
652     ctx->packet.payload[1] = ~err_code;
653     hi_u32 cs = 0 ^ (uintptr_t)(hi_u8 *)&(ctx->packet) ^ (head->packet_size - CHECKSUM_SIZE);
654     ctx->packet.check_sum = crc16_ccitt(0, (hi_u8 *)&(ctx->packet), head->packet_size - CHECKSUM_SIZE, cs);
655 
656     serial_put_buf ((const char *)&(ctx->packet), (int)(head->packet_size - CHECKSUM_SIZE));
657     serial_put_buf ((const char *)&(ctx->packet.check_sum), CHECKSUM_SIZE);
658 }
659 
loader_read_frame(uart_ctx * ctx)660 hi_u32 loader_read_frame(uart_ctx *ctx)
661 {
662     packet_data_info *packet = &ctx->packet;
663     packet_data_head *head = &packet->head;
664     hi_u32 ret;
665     hi_u32 cs;
666 
667     /* Reset receiving status.CNcomment:复位接收状态 */
668     ctx->status = CMD_RX_STATUS_WAIT_START_0;
669     ctx->received = 0;
670     cs = (uintptr_t)packet ^ (hi_u32)sizeof(packet_data_info) ^ 0 ^ (hi_u32)sizeof(packet_data_info);
671     if (memset_s(packet, sizeof(packet_data_info), 0, sizeof(packet_data_info), cs) != EOK) {
672         return HI_ERR_FAILURE;
673     }
674 
675     ret = loader_frame_head_rx(ctx);
676     if (ret != HI_ERR_SUCCESS) {
677         return HI_ERR_FAILURE;
678     }
679 
680     ret = loader_frame_data_rx(ctx);
681     if (ret != HI_ERR_SUCCESS) {
682         return HI_ERR_FAILURE;
683     }
684 
685     cs = 0 ^ (uintptr_t)(hi_u8 *)packet ^ (head->packet_size - CHECKSUM_SIZE);
686     cs = crc16_ccitt(0, (hi_u8 *)packet, head->packet_size - CHECKSUM_SIZE, cs);
687     if (cs == packet->check_sum) {
688         return HI_ERR_SUCCESS;
689     }
690 
691     return HI_ERR_FAILURE;
692 }
693 
loader_exe_cmd(uart_ctx * ctx)694 hi_u32 loader_exe_cmd(uart_ctx *ctx)
695 {
696     hi_u32 i;
697 
698     packet_data_info *packet = &ctx->packet;
699     packet_data_head *head = &packet->head;
700     for (i = 0; i < LOADER_CMD_MAX; i++) {
701         if (head->type == g_loader_cmdtable[i].cmd_type) {
702             if (g_loader_cmdtable[i].cmdfunc != HI_NULL) {
703                 return g_loader_cmdtable[i].cmdfunc(ctx);
704             }
705         }
706     }
707 
708     if (i == LOADER_CMD_MAX) {
709         boot_msg1("Unsupport CMD:", head->type);
710     }
711 
712     return HI_ERR_FAILURE;
713 }
714 
cmd_loop_init(hi_void)715 uart_ctx *cmd_loop_init(hi_void)
716 {
717     if (g_cmd_ctx == HI_NULL) {
718         g_cmd_ctx = (uart_ctx *)boot_malloc(sizeof(uart_ctx));
719     }
720 
721     if (g_cmd_ctx != HI_NULL) {
722         volatile hi_u32 check_sum = (uintptr_t)g_cmd_ctx ^ (hi_u32)sizeof(uart_ctx) ^ 0 ^ (hi_u32)sizeof(uart_ctx);
723         (hi_void) memset_s(g_cmd_ctx, sizeof(uart_ctx), 0, sizeof(uart_ctx), check_sum);
724         return g_cmd_ctx;
725     }
726     return HI_NULL;
727 }
728 
cmd_loop_deinit(hi_void)729 hi_u32 cmd_loop_deinit(hi_void)
730 {
731     hi_u32 ret = boot_free(g_cmd_ctx);
732     if (ret == HI_ERR_SUCCESS) {
733         g_cmd_ctx = HI_NULL;
734     }
735 
736     return ret;
737 }
738 
cmd_loop(uart_ctx * ctx)739 hi_void cmd_loop(uart_ctx *ctx)
740 {
741     hi_u32 ret;
742     for (;;) {
743         ret = loader_read_frame(ctx);
744         if (ret != HI_ERR_SUCCESS) {
745             boot_msg0("\nGet CMD fail");
746             loader_ack(ACK_FAILURE);
747             continue;
748         }
749 
750         ret = loader_exe_cmd(ctx);
751         if (ret != HI_ERR_SUCCESS) {
752             loader_ack(ACK_FAILURE);
753             boot_msg0("\nExecution Failure : ");
754             boot_msg0("============================================\n");
755             continue;
756         }
757 
758         loader_ack(ACK_SUCCESS);
759         boot_msg0("\nExecution Successful");
760         boot_msg0("============================================\n");
761     }
762 }
763 
764