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, ¤t_boot_ver, ¤t_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