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 <upg_common.h>
17 #include <upg_check_file.h>
18 #include <upg_check_secure.h>
19 #include <upg_start_up.h>
20 #include <upg_check_boot_bin.h>
21 #include <upg_ver_update.h>
22 #include <flash_prv.h>
23
24 #if defined(CONFIG_FLASH_ENCRYPT_SUPPORT)
25 #include "kernel_crypto.h"
26 #endif
27
28 upg_ctx g_upg_ctx = { 0 };
29 volatile hi_u8 g_upg_updating_ver = UPG_UPDATE_VER_NONE; /* 非升级中;升级BOOT;升级kernel */
30 volatile hi_bool g_upg_update_ver_success = HI_FALSE;
31 hi_u8 g_upg_efuse_data_boot_ver[BOOT_VER_LEN] = {0};
32 hi_u8 g_upg_efuse_data_kernel_ver[KERNEL_VER_LEN] = {0};
33
34 /************************the following functions are inner functions************************************/
upg_get_ctx(hi_void)35 upg_ctx *upg_get_ctx(hi_void)
36 {
37 return &g_upg_ctx;
38 }
39
upg_is_init(hi_void)40 hi_bool upg_is_init(hi_void)
41 {
42 upg_ctx *ctx = upg_get_ctx();
43 return ctx->is_init;
44 }
45
upg_is_transmit_finish(hi_void)46 hi_bool upg_is_transmit_finish(hi_void)
47 {
48 upg_ctx *ctx = upg_get_ctx();
49 return ctx->transmit_finish_flag;
50 }
51
upg_lock(hi_void)52 hi_u32 upg_lock(hi_void)
53 {
54 upg_ctx *ctx = upg_get_ctx();
55 return hi_sem_wait(ctx->upg_sem, HI_SYS_WAIT_FOREVER);
56 }
57
upg_unlock(hi_void)58 hi_u32 upg_unlock(hi_void)
59 {
60 upg_ctx *ctx = upg_get_ctx();
61 return hi_sem_signal(ctx->upg_sem);
62 }
63
upg_is_upg_process(hi_void)64 hi_bool upg_is_upg_process(hi_void)
65 {
66 upg_ctx *ctx = upg_get_ctx();
67 hi_bool flag;
68 hi_u32 ret = HI_ERR_FAILURE;
69 if (upg_is_init()) {
70 ret = upg_lock();
71 }
72 flag = ctx->is_upg_process;
73 if (ret == HI_ERR_SUCCESS) {
74 upg_unlock();
75 }
76
77 return flag;
78 }
79
upg_set_upg_process(hi_bool is_upg_process)80 hi_void upg_set_upg_process(hi_bool is_upg_process)
81 {
82 upg_ctx *ctx = upg_get_ctx();
83 hi_u32 ret = HI_ERR_FAILURE;
84 if (upg_is_init()) {
85 ret = upg_lock();
86 }
87 ctx->is_upg_process = is_upg_process;
88 if (ret == HI_ERR_SUCCESS) {
89 upg_unlock();
90 }
91 }
92
upg_get_boot_key_addr(hi_void)93 hi_void upg_get_boot_key_addr(hi_void)
94 {
95 hi_u32 val;
96 hi_u32 rsa_key_addr = { 0 };
97 hi_u32 ecc_key_addr = { 0 };
98 upg_ctx *ctx = upg_get_ctx();
99
100 hi_reg_read16(DIAG_CTL_GP_REG0_REG, val);
101 rsa_key_addr = rsa_key_addr | val;
102 hi_reg_read16(DIAG_CTL_GP_REG1_REG, val);
103 rsa_key_addr = rsa_key_addr | (val << BIT_U16);
104 ctx->rsa_key_addr = rsa_key_addr;
105
106 hi_reg_read16(DIAG_CTL_GP_REG2_REG, val);
107 ecc_key_addr = ecc_key_addr | val;
108 hi_reg_read16(DIAG_CTL_GP_REG3_REG, val);
109 ecc_key_addr = ecc_key_addr | (val << BIT_U16);
110 ctx->ecc_key_addr = ecc_key_addr;
111 }
112
upg_tool_bit_test(const hi_u8 * data,hi_u16 pos,hi_u16 data_len)113 hi_bool upg_tool_bit_test(const hi_u8 *data, hi_u16 pos, hi_u16 data_len)
114 {
115 hi_u16 base = pos / BIT_U8;
116 hi_u16 i = pos % BIT_U8;
117 if (pos > (data_len * BIT_U8)) {
118 return HI_FALSE;
119 }
120 return (hi_bool)bit_get(data[base], i);
121 }
122
upg_tool_bit_set(hi_u8 * data,hi_u16 pos,hi_u8 val)123 hi_void upg_tool_bit_set(hi_u8 *data, hi_u16 pos, hi_u8 val)
124 {
125 hi_u16 base = pos / BIT_U8;
126 hi_u16 i = pos % BIT_U8;
127 bit_set(data[base], i, val);
128 }
129
upg_clear_contset(hi_u8 * content,hi_u32 content_len)130 hi_void upg_clear_contset(hi_u8 *content, hi_u32 content_len)
131 {
132 if ((content == HI_NULL) || (content_len == 0)) {
133 return;
134 }
135
136 (hi_void)memset_s(content, content_len, 0x0, content_len);
137 }
138
139 /*
140 Decompress NV conditions:
141 1. The decompressed NV flag exists;
142 2. nv file header error (no NV file backup area for wifi);
143 3. Upgrade and non-boot upgrade.
144 */
upg_is_refresh_nv(const hi_nv_ftm_startup_cfg * cfg)145 hi_bool upg_is_refresh_nv(const hi_nv_ftm_startup_cfg *cfg)
146 {
147 if (cfg->refresh_nv == ENV_REFRESH_NV) {
148 upg_print("[upg refresh nv]flag is true \r\n");
149 return HI_TRUE;
150 }
151
152 if ((cfg->mode == HI_UPG_MODE_UPGRADE) && (cfg->file_type != HI_UPG_FILE_BOOT)) {
153 upg_print("[upg refresh nv]mode-filetype:0x%x-0x%x \r\n", cfg->mode, cfg->file_type);
154 return HI_TRUE;
155 }
156 return HI_FALSE;
157 }
158
upg_refresh_nv(hi_void)159 hi_u32 upg_refresh_nv(hi_void)
160 {
161 hi_nv_ftm_startup_cfg cfg;
162 hi_upg_section_head section_head = { 0 };
163 hi_u32 ret = upg_get_start_up_nv(&cfg);
164 if (ret != HI_ERR_SUCCESS) {
165 return ret;
166 }
167
168 /* Not need to decompress NV during normal startup, which is a normal branch and returns successfully. */
169 if (upg_is_refresh_nv(&cfg) == HI_FALSE) {
170 return HI_ERR_SUCCESS;
171 }
172
173 /* Replace nv first and then initialize NV. */
174 ret = upg_get_section_head_from_flash(cfg.addr_start, §ion_head);
175 if (ret != HI_ERR_SUCCESS) {
176 return HI_ERR_UPG_GET_SECTION_HEAD;
177 }
178
179 hi_u32 nv_addr = cfg.addr_start + section_head.section1_offset;
180 hi_u32 nv_size = section_head.section1_len;
181 if (nv_size != HI_NV_DEFAULT_BLOCK_SIZE) {
182 return HI_ERR_UPG_NV_SIZE;
183 }
184 hi_pvoid buf = hi_malloc(HI_MOD_ID_UPG, section_head.section1_len);
185 if (buf == HI_NULL) {
186 return HI_ERR_MALLOC_FAILUE;
187 }
188 ret = hi_flash_read(nv_addr, nv_size, buf);
189 if (ret != HI_ERR_SUCCESS) {
190 upg_print("[upg refresh nv]flash read fail:nvfrom-nvsize-ret:0x%x-0x%x-0x%x \r\n", nv_addr, nv_size, ret);
191 goto fail;
192 }
193 ret = hi_nv_flush_keep_ids(buf, nv_size);
194 if (ret != HI_ERR_SUCCESS) {
195 goto fail;
196 }
197 ret = hi_nv_block_write(buf, nv_size, 0);
198 if (ret != HI_ERR_SUCCESS) {
199 goto fail;
200 }
201
202 hi_u32 normal_nv_addr = 0;
203 hi_u32 normal_nv_size = 0;
204 ret = hi_get_normal_nv_partition_table(&normal_nv_addr, &normal_nv_size);
205 if (ret == HI_ERR_SUCCESS) {
206 ret = hi_nv_init(normal_nv_addr, normal_nv_size, nv_size);
207 }
208
209 fail:
210 hi_free(HI_MOD_ID_UPG, (hi_pvoid)buf);
211 upg_print("[upg]refresh nv ret 0x%x \r\n", ret);
212 return ret;
213 }
214
upg_get_start_up_cfg(hi_nv_ftm_startup_cfg * cfg)215 hi_u32 upg_get_start_up_cfg(hi_nv_ftm_startup_cfg *cfg)
216 {
217 hi_nv_ftm_startup_cfg tmp_data = { 0 };
218 hi_u32 ret = upg_get_start_up_nv(&tmp_data);
219 if (ret == HI_ERR_SUCCESS) {
220 if (memcpy_s(cfg, sizeof(hi_nv_ftm_startup_cfg), &tmp_data, sizeof(hi_nv_ftm_startup_cfg)) != EOK) {
221 return HI_ERR_FAILURE;
222 }
223 }
224 return ret;
225 }
226
upg_set_start_up_cfg(hi_nv_ftm_startup_cfg * cfg)227 hi_u32 upg_set_start_up_cfg(hi_nv_ftm_startup_cfg *cfg)
228 {
229 hi_nv_ftm_startup_cfg current_data = { 0 };
230 hi_u32 ret = upg_get_start_up_nv(¤t_data);
231 if (ret != HI_ERR_SUCCESS) {
232 return ret;
233 }
234 if (memcmp(cfg, ¤t_data, sizeof(hi_nv_ftm_startup_cfg))) {
235 ret = upg_save_start_up_nv(cfg);
236 upg_print("[upg set env]ret:0x%x \r\n", ret);
237 }
238 return ret;
239 }
240
upg_get_code_file_ver(hi_u8 * ver)241 hi_u32 upg_get_code_file_ver(hi_u8 *ver)
242 {
243 hi_upg_common_head *head = HI_NULL;
244 hi_nv_ftm_startup_cfg cfg;
245 hi_u32 ret = upg_get_start_up_cfg(&cfg);
246 if (ret != HI_ERR_SUCCESS) {
247 upg_print("[upg get file ver]get env ret:0x%x \r\n", ret);
248 return ret;
249 }
250
251 head = hi_malloc(HI_MOD_ID_UPG, sizeof(hi_upg_common_head));
252 if (head == HI_NULL) {
253 upg_print("[upg get file ver]malloc fail \r\n");
254 return HI_ERR_UPG_MALLOC_FAIL;
255 }
256 memset_s(head, sizeof(hi_upg_common_head), 0, sizeof(hi_upg_common_head));
257 ret = upg_get_common_head_from_flash(cfg.addr_start, head);
258 if (ret != HI_ERR_SUCCESS) {
259 upg_print("[upg get file ver]get head ret:0x%x \r\n", ret);
260 hi_free(HI_MOD_ID_UPG, head);
261 return ret;
262 }
263 *ver = head->file_version;
264 hi_free(HI_MOD_ID_UPG, head);
265 upg_print("[upg get file ver]ver:%d \r\n", *ver);
266 return ret;
267 }
268
upg_set_efuse_code_ver(hi_void)269 hi_u32 upg_set_efuse_code_ver(hi_void)
270 {
271 hi_u8 pos;
272 hi_u32 ret;
273 hi_u8 upg_ver;
274 hi_u8 current_ver;
275 hi_bool flag;
276
277 ret = upg_is_secure_efuse(&flag);
278 if (ret != HI_ERR_SUCCESS) {
279 upg_print("[upg set kernel ver]get secure efuse,err:0x%x \r\n", ret);
280 return ret;
281 }
282
283 if (flag == HI_FALSE) {
284 upg_print("[upg set kernel ver]not secure boot.\r\n");
285 return HI_ERR_SUCCESS;
286 }
287
288 ret = upg_get_efuse_code_ver(¤t_ver);
289 if (ret != HI_ERR_SUCCESS) {
290 upg_print("[upg set kernel ver]get ver ret:0x%x\r\n", ret);
291 return ret;
292 }
293
294 ret = upg_get_code_file_ver(&upg_ver);
295 if (ret != HI_ERR_SUCCESS) {
296 upg_print("[upg set kernel ver]get head ret:0x%x \r\n", ret);
297 return ret;
298 }
299
300 if (upg_ver < current_ver) {
301 upg_print("[upg set kernel ver]current>file:0%d-%d \r\n", current_ver, upg_ver);
302 return HI_ERR_UPG_LOW_KERNEL_VER;
303 }
304
305 if ((current_ver == KERELN_VER_MAX) && (upg_ver > KERELN_VER_MAX)) {
306 upg_print("[upg set kernel ver]current ver:%d \r\n", upg_ver);
307 return HI_ERR_UPG_FULL_KERNEL_VER;
308 }
309
310 if (upg_ver == current_ver) {
311 upg_print("[upg set kernel ver]same ver:%d \r\n", upg_ver);
312 return HI_ERR_SUCCESS;
313 }
314
315 (hi_void) memset_s(g_upg_efuse_data_kernel_ver, KERNEL_VER_LEN, 0, KERNEL_VER_LEN);
316 for (pos = current_ver; ((pos < upg_ver) && (pos < KERELN_VER_MAX)); pos++) {
317 upg_tool_bit_set(g_upg_efuse_data_kernel_ver, pos, SRV_BIT_HIGH);
318 }
319 ret = upg_start_and_wait_update_ver(UPG_UPDATE_VER_FIRMARE);
320
321 upg_print("[upg set kernel ver]ret:0x%x \r\n", ret);
322 return ret;
323 }
324
upg_get_kernel_size(hi_void)325 hi_u32 upg_get_kernel_size(hi_void)
326 {
327 upg_ctx *ctx = upg_get_ctx();
328 return ctx->cur_kernel_size;
329 }
330
upg_set_kernel_size(hi_u32 addr_start)331 hi_u32 upg_set_kernel_size(hi_u32 addr_start)
332 {
333 upg_ctx *ctx = upg_get_ctx();
334 hi_u32 kernel_size = 0;
335 hi_u32 ret = hi_flash_read(addr_start + hi_fieldoffset(hi_upg_common_head, file_len), sizeof(hi_u32),
336 (hi_u8 *)(&kernel_size));
337 if (ret != HI_ERR_SUCCESS) {
338 upg_print("[upg set kernel size]ret:0x%x \r\n", ret);
339 return ret;
340 }
341 ctx->cur_kernel_size = upg_align_next(kernel_size, UPG_FLASH_BLOCK_SIZE);
342 return HI_ERR_SUCCESS;
343 }
344
upg_mode_init(hi_void)345 hi_u32 upg_mode_init(hi_void)
346 {
347 hi_nv_ftm_startup_cfg cfg = { 0 };
348 hi_u32 ret = upg_get_start_up_cfg(&cfg);
349 if (ret != HI_ERR_SUCCESS) {
350 upg_print("[upg mode init]get env fail:0x%x \r\n", ret);
351 return ret;
352 }
353
354 if (cfg.mode != HI_UPG_MODE_UPGRADE) {
355 if (cfg.refresh_nv == ENV_REFRESH_NV) {
356 cfg.refresh_nv = 0;
357 (hi_void) upg_set_start_up_cfg(&cfg);
358 }
359 }
360
361 if (cfg.reset_cnt > 0) {
362 upg_print("[upg mode init]resetcnt:0x%x \r\n", cfg.reset_cnt);
363 cfg.reset_cnt = 0;
364 cfg.mode = HI_UPG_MODE_NORMAL;
365 cfg.refresh_nv = 0;
366 ret = upg_set_start_up_cfg(&cfg);
367 if (cfg.file_type == HI_UPG_FILE_KERNEL) {
368 ret |= upg_set_efuse_code_ver();
369 upg_print("[upg mode init]upg set code version ret:0x%x \r\n", ret);
370 }
371 }
372 ret |= upg_set_kernel_size(cfg.addr_start);
373 if (ret != HI_ERR_SUCCESS) {
374 upg_print("[upg mode init]fail:0x%x \r\n", ret);
375 }
376 return ret;
377 }
378
upg_cache_ctrl(hi_u32 offset,hi_u8 * buf,hi_u32 buf_len,hi_bool is_write)379 hi_u32 upg_cache_ctrl(hi_u32 offset, hi_u8 *buf, hi_u32 buf_len, hi_bool is_write)
380 {
381 hi_u32 ret;
382 hi_u32 cache_addr;
383 upg_ctx *ctx = upg_get_ctx();
384
385 if (buf == HI_NULL) {
386 return HI_ERR_UPG_NULL_POINTER;
387 }
388
389 if (((offset + buf_len) > (ctx->common_head.file_len)) ||
390 ((offset + buf_len) < buf_len)) {
391 upg_print("[upg cache ctrl]error param:0x%x-0x%x-0x%x \r\n", offset, buf_len, ctx->common_head.file_len);
392 return HI_ERR_UPG_PARAMETER;
393 }
394
395 cache_addr = ctx->file_addr;
396 if (is_write == HI_FALSE) {
397 ret = hi_flash_read(offset + cache_addr, buf_len, (hi_u8 *)buf);
398 } else {
399 ret = hi_flash_write(offset + cache_addr, buf_len, (hi_u8 *)buf, HI_FALSE);
400 }
401 return ret;
402 }
403
upg_clear_ctx(hi_void)404 hi_void upg_clear_ctx(hi_void)
405 {
406 upg_ctx *ctx = upg_get_ctx();
407 hi_u32 ret = HI_ERR_FAILURE;
408 if (upg_is_init()) {
409 ret = upg_lock();
410 }
411 ctx->is_upg_process = HI_FALSE;
412 ctx->check_head_flag = HI_FALSE;
413 ctx->transmit_finish_flag = HI_FALSE;
414 ctx->cache_size = 0;
415 ctx->file_addr = 0;
416 memset_s(&ctx->common_head, sizeof(hi_upg_common_head), 0, sizeof(hi_upg_common_head));
417 if (ret == HI_ERR_SUCCESS) {
418 upg_unlock();
419 }
420 }
421
upg_clear_wait_mode(hi_nv_ftm_upg_wait_mode * mode)422 hi_u32 upg_clear_wait_mode(hi_nv_ftm_upg_wait_mode *mode)
423 {
424 hi_u32 ret = memset_s(mode, sizeof(hi_nv_ftm_upg_wait_mode), 0, sizeof(hi_nv_ftm_upg_wait_mode));
425 if (ret != HI_ERR_SUCCESS) {
426 return ret;
427 }
428
429 ret = upg_save_wait_mode_nv(mode);
430 if (ret != HI_ERR_SUCCESS) {
431 return ret;
432 }
433
434 return HI_ERR_SUCCESS;
435 }
436
upg_check_clear_wait_mode(hi_void)437 hi_void upg_check_clear_wait_mode(hi_void)
438 {
439 hi_nv_ftm_upg_wait_mode mode_cfg = {0};
440 hi_u32 ret = upg_get_wait_mode_nv(&mode_cfg);
441 if (ret != HI_ERR_SUCCESS) {
442 upg_print("[check wait mode]ret=0x%x\r\n", ret);
443 }
444
445 if ((mode_cfg.trans_finish_flag == HI_TRUE) || (mode_cfg.is_upg_process == HI_TRUE)) {
446 ret = upg_clear_wait_mode(&mode_cfg);
447 if (ret != HI_ERR_SUCCESS) {
448 upg_print("[clear wait mode]ret=0x%x\r\n", ret);
449 }
450 }
451 }
452
upg_check_clear_upg_mode(hi_void)453 hi_void upg_check_clear_upg_mode(hi_void)
454 {
455 hi_nv_ftm_startup_cfg cfg = { 0 };
456 hi_u32 ret = upg_get_start_up_cfg(&cfg);
457 if (ret != HI_ERR_SUCCESS) {
458 upg_print("[clear upg mode]get env fail,ret:0x%x.\r\n", ret);
459 }
460
461 if (cfg.mode == HI_UPG_MODE_UPGRADE_WAIT) {
462 cfg.mode = HI_UPG_MODE_NORMAL;
463 ret = upg_set_start_up_cfg(&cfg);
464 if (ret != HI_ERR_SUCCESS) {
465 upg_print("[clear upg mode]set env fail,ret=0x%x\r\n", ret);
466 }
467 }
468 }
469
470 /*
471 1. Modify to the correct boot mode and boot area;
472 2. nv file recovery;
473 3. Local global variable recovery.
474
475 */
upg_stop(hi_u32 error_no)476 hi_u32 upg_stop(hi_u32 error_no)
477 {
478 hi_nv_ftm_startup_cfg cfg = { 0 };
479 hi_u32 ret;
480
481 hi_unref_param(error_no);
482 upg_check_clear_wait_mode();
483 upg_print("[upg stop]reason:0x%x.\r\n", error_no);
484 if (upg_is_upg_process() == HI_FALSE) {
485 upg_print("[upg stop]is not upg process.\r\n");
486 return HI_ERR_UPG_NOT_START;
487 }
488
489 ret = upg_get_start_up_cfg(&cfg);
490 if (ret != HI_ERR_SUCCESS) {
491 upg_print("[upg stop]get env fail,ret:0x%x.\r\n", ret);
492 return ret;
493 }
494 if ((cfg.mode == HI_UPG_MODE_UPGRADE) && (cfg.file_type == HI_UPG_FILE_KERNEL)) {
495 #if defined(CONFIG_COMPRESSION_OTA_SUPPORT)
496 ret = hi_flash_erase(cfg.addr_write, UPG_FLASH_BLOCK_SIZE);
497 upg_print("[upg stop]erase ret-addr:0x%x-0x%x.\r\n", ret, cfg.addr_write);
498 #else
499 hi_flash_partition_table *partition = hi_get_partition_table();
500 uintptr_t kernel_a_addr = partition->table[HI_FLASH_PARTITON_KERNEL_A].addr;
501 uintptr_t kernel_b_addr = partition->table[HI_FLASH_PARTITON_KERNEL_B].addr;
502
503 ret = hi_flash_erase(cfg.addr_start, UPG_FLASH_BLOCK_SIZE);
504 upg_print("[upg stop]dual erase ret-addr:0x%x-0x%x.\r\n", ret, cfg.addr_start);
505 if (cfg.addr_start == kernel_a_addr) {
506 cfg.addr_start = kernel_b_addr;
507 } else {
508 cfg.addr_start = kernel_a_addr;
509 }
510 #endif
511 }
512 if (cfg.file_type == HI_UPG_FILE_KERNEL) {
513 cfg.addr_write = 0;
514 }
515
516 cfg.mode = HI_UPG_MODE_NORMAL;
517 cfg.file_type = 0;
518 cfg.refresh_nv = 0;
519 ret = upg_set_start_up_cfg(&cfg);
520 if (ret != HI_ERR_SUCCESS) {
521 return ret;
522 }
523 upg_clear_ctx();
524 upg_print("[upg stop]ret:0x%x \r\n", ret);
525 return ret;
526 }
527
upg_check_head(hi_void)528 hi_u32 upg_check_head(hi_void)
529 {
530 upg_ctx *ctx = upg_get_ctx();
531 hi_u32 addr = ctx->file_addr;
532 hi_u32 ret;
533 hi_upg_head *upg_head = hi_malloc(HI_MOD_ID_UPG, sizeof(hi_upg_head));
534 if (upg_head == HI_NULL) {
535 return HI_ERR_UPG_MALLOC_FAIL;
536 }
537 ret = hi_flash_read(addr, sizeof(hi_upg_head), (hi_u8 *)upg_head);
538 if (ret != HI_ERR_SUCCESS) {
539 upg_mem_free(upg_head);
540 return ret;
541 }
542
543 ret = upg_check_upg_file_head(upg_head);
544 upg_print("[upg check head]verify head,ret:0x%x. \r\n", ret);
545 upg_mem_free(upg_head);
546 return ret;
547 }
548
upg_get_cache_clear_info(hi_u8 file_type,hi_u32 file_len,hi_u32 * addr,hi_u32 * size)549 hi_u32 upg_get_cache_clear_info(hi_u8 file_type, hi_u32 file_len, hi_u32 *addr, hi_u32 *size)
550 {
551 hi_flash_partition_table *partition = hi_get_partition_table();
552
553 if (file_type == HI_UPG_FILE_BOOT) {
554 *addr = partition->table[HI_FLASH_PARTITON_BOOT_BACK].addr;
555 *size = partition->table[HI_FLASH_PARTITON_BOOT_BACK].size;
556 } else {
557 #if defined(CONFIG_COMPRESSION_OTA_SUPPORT)
558 hi_u32 erase_start_addr = partition->table[HI_FLASH_PARTITON_KERNEL_B].addr +
559 partition->table[HI_FLASH_PARTITON_KERNEL_B].size - file_len;
560 hi_u32 erase_end_addr = erase_start_addr + file_len;
561 erase_start_addr = upg_align_pre(erase_start_addr, UPG_FLASH_BLOCK_SIZE);
562 erase_end_addr = upg_align_next(erase_end_addr, UPG_FLASH_BLOCK_SIZE);
563 *addr = erase_start_addr;
564 *size = erase_end_addr - erase_start_addr;
565 #else
566 uintptr_t kernel_a_addr = partition->table[HI_FLASH_PARTITON_KERNEL_A].addr;
567 uintptr_t kernel_b_addr = partition->table[HI_FLASH_PARTITON_KERNEL_B].addr;
568 hi_nv_ftm_startup_cfg cfg;
569 hi_u32 ret = upg_get_start_up_cfg(&cfg);
570 if (ret != HI_ERR_SUCCESS) {
571 return ret;
572 }
573
574 /* Change area, read NV to get the current startup address and change to another area. */
575 if (cfg.addr_start == kernel_a_addr) {
576 *addr = kernel_b_addr;
577 *size = partition->table[HI_FLASH_PARTITON_KERNEL_B].size;
578 } else if (cfg.addr_start == kernel_b_addr) {
579 *addr = kernel_a_addr;
580 *size = partition->table[HI_FLASH_PARTITON_KERNEL_A].size;
581 } else {
582 return HI_ERR_UPG_START_ADDR;
583 }
584 #endif
585 }
586 upg_print("[upg clear info]filetype-filelen-addr-size:0x%x-0x%x-0x%x-0x%x\r\n", file_type, file_len, *addr, *size);
587 return HI_ERR_SUCCESS;
588 }
589
upg_get_backup_write_addr(hi_u8 file_type,hi_u32 file_len,hi_u32 * addr)590 hi_u32 upg_get_backup_write_addr(hi_u8 file_type, hi_u32 file_len, hi_u32 *addr)
591 {
592 hi_flash_partition_table *partition = hi_get_partition_table();
593
594 if (file_type == HI_UPG_FILE_BOOT) {
595 uintptr_t boot_bak_addr = partition->table[HI_FLASH_PARTITON_BOOT_BACK].addr +
596 partition->table[HI_FLASH_PARTITON_BOOT_BACK].size;
597 *addr = boot_bak_addr - file_len;
598 } else {
599 #if defined(CONFIG_COMPRESSION_OTA_SUPPORT)
600 hi_u32 erase_st_addr = partition->table[HI_FLASH_PARTITON_KERNEL_B].addr +
601 partition->table[HI_FLASH_PARTITON_KERNEL_B].size - file_len;
602 erase_st_addr = upg_align_pre(erase_st_addr, UPG_FLASH_BLOCK_SIZE);
603 *addr = erase_st_addr;
604 #else
605 uintptr_t kernel_a_addr = partition->table[HI_FLASH_PARTITON_KERNEL_A].addr;
606 uintptr_t kernel_b_addr = partition->table[HI_FLASH_PARTITON_KERNEL_B].addr;
607 hi_nv_ftm_startup_cfg cfg;
608 hi_u32 ret = upg_get_start_up_cfg(&cfg);
609 if (ret != HI_ERR_SUCCESS) {
610 return ret;
611 }
612
613 /* Change area, read NV to get the current startup address and change to another area. */
614 if (cfg.addr_start == kernel_a_addr) {
615 *addr = kernel_b_addr;
616 } else if (cfg.addr_start == kernel_b_addr) {
617 *addr = kernel_a_addr;
618 } else {
619 return HI_ERR_UPG_START_ADDR;
620 }
621 #endif
622 }
623 return HI_ERR_SUCCESS;
624 }
625
upg_get_max_file_len(hi_u8 file_type,hi_u32 * file_len)626 hi_u32 upg_get_max_file_len(hi_u8 file_type, hi_u32 *file_len)
627 {
628 hi_u32 ret = HI_ERR_SUCCESS;
629 hi_flash_partition_table *partition = hi_get_partition_table();
630 #if defined(CONFIG_COMPRESSION_OTA_SUPPORT)
631 if (file_type == HI_UPG_FILE_BOOT) {
632 *file_len = partition->table[HI_FLASH_PARTITON_BOOT_BACK].size;
633 } else {
634 hi_u32 end_addr = partition->table[HI_FLASH_PARTITON_KERNEL_B].addr +
635 partition->table[HI_FLASH_PARTITON_KERNEL_B].size;
636 hi_u32 start_addr = partition->table[HI_FLASH_PARTITON_KERNEL_A].addr;
637 hi_u32 current_kernel_size = upg_get_kernel_size();
638 if (current_kernel_size == 0) {
639 ret = HI_ERR_UPG_KERNEL_LEN;
640 } else {
641 *file_len = end_addr - start_addr - current_kernel_size;
642 }
643 }
644 #else
645 hi_nv_ftm_startup_cfg cfg = { 0 };
646 ret = upg_get_start_up_cfg(&cfg);
647 if (ret != HI_ERR_SUCCESS) {
648 upg_print("[upg get max len]error:0x%x \r\n", ret);
649 return ret;
650 }
651 if (file_type == HI_UPG_FILE_BOOT) {
652 *file_len = partition->table[HI_FLASH_PARTITON_BOOT_BACK].size;
653 } else if (cfg.addr_start == partition->table[HI_FLASH_PARTITON_KERNEL_A].addr) {
654 *file_len = partition->table[HI_FLASH_PARTITON_KERNEL_B].size;
655 } else if (cfg.addr_start == partition->table[HI_FLASH_PARTITON_KERNEL_B].addr) {
656 *file_len = partition->table[HI_FLASH_PARTITON_KERNEL_A].size;
657 } else {
658 ret = HI_ERR_UPG_PARAMETER;
659 }
660 #endif
661 return ret;
662 }
663
upg_cache_clear(hi_u8 file_type,hi_u32 file_len)664 hi_u32 upg_cache_clear(hi_u8 file_type, hi_u32 file_len)
665 {
666 hi_u32 backup_addr = 0;
667 hi_u8 i;
668 hi_u32 backup_size = 0;
669 hi_u32 ret = upg_get_cache_clear_info(file_type, file_len, &backup_addr, &backup_size);
670 if (ret != HI_ERR_SUCCESS) {
671 upg_print("[upg clear]get info:0x%x\r\n", ret);
672 return ret;
673 }
674 upg_print("[upg clear]start :%d \r\n", hi_get_milli_seconds());
675
676 for (i = 0; i < UPG_FLASH_RETRY_TIMES; i++) {
677 ret = hi_flash_erase(backup_addr, backup_size);
678 if (ret == HI_ERR_SUCCESS) {
679 break;
680 }
681 }
682 upg_print("[upg clear]end :%d \r\n", hi_get_milli_seconds());
683 return ret;
684 }
685
upg_set_flash_write_addr(hi_void)686 hi_u32 upg_set_flash_write_addr(hi_void)
687 {
688 hi_u32 write_addr;
689 upg_ctx *ctx = upg_get_ctx();
690 hi_u32 ret = upg_get_backup_write_addr(ctx->common_head.file_type, ctx->common_head.file_len, &write_addr);
691 if (ret == HI_ERR_SUCCESS) {
692 ctx->file_addr = write_addr;
693 }
694 upg_print("[upg write addr]ret-addr-size:0x%x-0x%x-0x%x\r\n", ret, ctx->file_addr, ctx->common_head.file_len);
695 return ret;
696 }
697
upg_start(hi_u8 * buf,hi_u32 buf_len)698 hi_u32 upg_start(hi_u8 *buf, hi_u32 buf_len)
699 {
700 hi_nv_ftm_startup_cfg cfg = { 0 };
701 hi_upg_common_head *head = HI_NULL;
702 upg_ctx *ctx = upg_get_ctx();
703 hi_u32 ret;
704
705 if (buf == HI_NULL) {
706 return HI_ERR_UPG_PARAMETER;
707 }
708
709 /* The first packet cannot be less than 96 bytes. */
710 if (buf_len < sizeof(hi_upg_common_head)) {
711 return HI_ERR_UPG_BUF_LEN;
712 }
713 head = (hi_upg_common_head *)buf;
714 ret = upg_check_common_head(head, sizeof(hi_upg_common_head));
715 if (ret != HI_ERR_SUCCESS) {
716 return ret;
717 }
718
719 ret = upg_get_start_up_cfg(&cfg);
720 if (ret != HI_ERR_SUCCESS) {
721 return ret;
722 }
723
724 cfg.file_type = 0;
725 cfg.reset_cnt = 0;
726
727 /* Record file header information. */
728 if (memcpy_s(&(ctx->common_head), sizeof(hi_upg_common_head), head, sizeof(hi_upg_common_head)) != EOK) {
729 return HI_ERR_FAILURE;
730 }
731 ctx->cache_size = 0;
732
733 /* Erase FLASH. */
734 ret = upg_cache_clear(head->file_type, head->file_len);
735 if (ret == HI_ERR_SUCCESS) {
736 ret = upg_set_flash_write_addr();
737 ctx->transmit_finish_flag = HI_FALSE;
738 upg_set_upg_process(HI_TRUE);
739 }
740
741 if (head->file_type == HI_UPG_FILE_KERNEL) {
742 cfg.addr_write = ctx->file_addr;
743 }
744
745 if (ret == HI_ERR_SUCCESS) {
746 ret = upg_set_start_up_cfg(&cfg);
747 }
748 return ret;
749 }
750
upg_cache_write(hi_u32 offset,hi_u8 * buf,hi_u32 buf_len)751 hi_u32 upg_cache_write(hi_u32 offset, hi_u8 *buf, hi_u32 buf_len)
752 {
753 return upg_cache_ctrl(offset, buf, buf_len, HI_TRUE);
754 }
755
upg_start_and_wait_update_ver(hi_u8 update_ver_type)756 hi_u32 upg_start_and_wait_update_ver(hi_u8 update_ver_type)
757 {
758 if (update_ver_type != UPG_UPDATE_VER_FIRMARE
759 && update_ver_type != UPG_UPDATE_VER_BOOT) {
760 return HI_ERR_UPG_UPDATE_VER_INVALID_PARAM;
761 }
762
763 /* init upg flag */
764 g_upg_updating_ver = update_ver_type;
765 g_upg_update_ver_success = HI_FALSE;
766
767 /* trigger upg nmi */
768 hi_reg_setbit(UPG_NMI_BASE_ADDRESS + UPG_NMI_CTRL, UPG_NMI_INT_MOD_DONE_EN_POS);
769
770 /* wait nmi handle finish */
771 hi_u32 wait_cnt = 1000; /* wait 10s */
772 hi_u32 try_cnt = 0;
773 /* 小型化和场景考虑,此处实现不采用事件通知 */
774 for (try_cnt = 0; try_cnt < wait_cnt; try_cnt++) {
775 if (g_upg_updating_ver == UPG_UPDATE_VER_NONE) {
776 break;
777 }
778 hi_sleep(10); /* sleep 10ms */
779 }
780
781 if (g_upg_update_ver_success == HI_TRUE) {
782 return HI_ERR_SUCCESS;
783 } else if (try_cnt == wait_cnt) {
784 return HI_ERR_UPG_UPDATE_VER_TIMEOUT;
785 } else {
786 return HI_ERR_UPG_UPDATE_VER_FAIL;
787 }
788 }
789
upg_get_efuse_code_ver(hi_u8 * ver)790 hi_u32 upg_get_efuse_code_ver(hi_u8 *ver)
791 {
792 hi_u8 pos;
793 hi_u8 efuse_data[KERNEL_VER_LEN];
794 hi_u32 ret;
795
796 (hi_void) memset_s(efuse_data, KERNEL_VER_LEN, 0, KERNEL_VER_LEN);
797 ret = hi_efuse_read(HI_EFUSE_TEE_KERNEL_VER_RW_ID, efuse_data, sizeof(efuse_data));
798 if (ret != HI_ERR_SUCCESS) {
799 return ret;
800 }
801
802 for (pos = 0; pos < KERELN_VER_MAX; pos++) {
803 if (upg_tool_bit_test(efuse_data, pos, KERNEL_VER_LEN) == HI_FALSE) {
804 break;
805 }
806 }
807 if (pos >= KERELN_VER_MAX) {
808 *ver = KERELN_VER_MAX;
809 } else {
810 *ver = pos;
811 }
812 return ret;
813 }
814
upg_get_efuse_boot_ver(hi_u8 * ver)815 hi_u32 upg_get_efuse_boot_ver(hi_u8 *ver)
816 {
817 hi_u8 pos;
818 hi_u8 efuse_data[BOOT_VER_LEN] = { 0 };
819 hi_u32 ret = hi_efuse_read(HI_EFUSE_TEE_BOOT_VER_RW_ID, efuse_data, sizeof(efuse_data));
820 if (ret != HI_ERR_SUCCESS) {
821 return ret;
822 }
823
824 for (pos = 0; pos < BOOT_VER_MAX; pos++) {
825 if (upg_tool_bit_test(efuse_data, pos, BOOT_VER_LEN) == HI_FALSE) {
826 break;
827 }
828 }
829 if (pos >= BOOT_VER_MAX) {
830 *ver = BOOT_VER_MAX;
831 } else {
832 *ver = pos;
833 }
834 return ret;
835 }
836
upg_get_boot_file_ver(hi_u8 * ver)837 hi_void upg_get_boot_file_ver(hi_u8 *ver)
838 {
839 upg_ctx *ctx = upg_get_ctx();
840 *ver = ctx->common_head.file_version;
841 }
842
upg_set_efuse_boot_ver(hi_void)843 hi_u32 upg_set_efuse_boot_ver(hi_void)
844 {
845 hi_u8 pos;
846 hi_u32 ret;
847 hi_u8 upg_ver;
848 hi_u8 current_ver;
849 hi_bool flag;
850
851 ret = upg_is_secure_efuse(&flag);
852 if (ret != HI_ERR_SUCCESS) {
853 upg_print("[upg set boot ver]get secure efuse,err:0x%x \r\n", ret);
854 return ret;
855 }
856
857 if (flag == HI_FALSE) {
858 upg_print("[upg set boot ver]not secure boot.\r\n");
859 return HI_ERR_SUCCESS;
860 }
861
862 ret = upg_get_efuse_boot_ver(¤t_ver);
863 if (ret != HI_ERR_SUCCESS) {
864 upg_print("[upg set boot ver]get ver ret:0x%x \r\n", ret);
865 return ret;
866 }
867 upg_get_boot_file_ver(&upg_ver);
868
869 if (upg_ver < current_ver) {
870 upg_print("[upg set boot ver]current>file:%d-%d \r\n", current_ver, upg_ver);
871 return HI_ERR_UPG_LOW_BOOT_VER;
872 }
873
874 if ((current_ver == BOOT_VER_MAX) && (upg_ver > BOOT_VER_MAX)) {
875 upg_print("[upg set boot ver]current ver:%d \r\n", upg_ver);
876 return HI_ERR_UPG_FULL_BOOT_VER;
877 }
878
879 if (upg_ver == current_ver) {
880 upg_print("[upg set boot ver]same ver:%d \r\n", upg_ver);
881 return HI_ERR_SUCCESS;
882 }
883 (hi_void) memset_s(g_upg_efuse_data_boot_ver, BOOT_VER_LEN, 0, BOOT_VER_LEN);
884 for (pos = current_ver; ((pos < upg_ver) && (pos < BOOT_VER_MAX)); pos++) {
885 upg_tool_bit_set(g_upg_efuse_data_boot_ver, pos, SRV_BIT_HIGH);
886 }
887 ret = upg_start_and_wait_update_ver(UPG_UPDATE_VER_BOOT);
888 upg_print("[upg set boot ver]ret:0x%x \r\n", ret);
889 return ret;
890 }
891
upg_refresh_boot(hi_u32 addr)892 hi_u32 upg_refresh_boot(hi_u32 addr)
893 {
894 hi_u32 offset;
895 hi_u32 total_size;
896 hi_u32 this_size;
897 hi_upg_section_head section_head = { 0 };
898
899 hi_flash_partition_table *partiton = hi_get_partition_table();
900 hi_u32 boot_addr = partiton->table[HI_FLASH_PARTITON_BOOT].addr;
901 hi_u32 boot_size = partiton->table[HI_FLASH_PARTITON_BOOT].size;
902 hi_u32 ret = upg_get_section_head_from_flash(addr, §ion_head);
903 if (ret != HI_ERR_SUCCESS) {
904 upg_print("[upg refresh boot]get section head ret:0x%x \r\n", ret);
905 return ret;
906 }
907 total_size = section_head.section0_len;
908 if ((total_size == 0) || (total_size > boot_size)) {
909 upg_print("[upg refresh boot]total size:0x%x \r\n", total_size);
910 return HI_ERR_UPG_FILE_LEN;
911 }
912
913 hi_u8 *buf = hi_malloc(HI_MOD_ID_UPG, UPG_FLASH_BLOCK_SIZE);
914 if (buf == HI_NULL) {
915 return HI_ERR_UPG_MALLOC_FAIL;
916 }
917 upg_print("[upg eraseboot]starttime:%d \r\n", hi_get_milli_seconds());
918 ret = hi_flash_erase(boot_addr, boot_size);
919 upg_print("[upg erase]ret-addr-size-end:0x%x-0x%x-0x%x-%d\r\n", ret, boot_addr, boot_size, hi_get_milli_seconds());
920 if (ret != HI_ERR_SUCCESS) {
921 hi_free(HI_MOD_ID_UPG, buf);
922 return ret;
923 }
924
925 for (offset = 0; offset < total_size;) {
926 this_size = (total_size - offset > UPG_FLASH_BLOCK_SIZE) ? UPG_FLASH_BLOCK_SIZE : (total_size - offset);
927 ret = hi_flash_read(addr + section_head.section0_offset + offset, this_size, buf);
928 if (ret != HI_ERR_SUCCESS) {
929 upg_print("[upg refresh boot]flash read ret:0x%x \r\n", ret);
930 break;
931 }
932 ret = hi_flash_write(boot_addr + offset, this_size, buf, HI_FALSE);
933 if (ret != HI_ERR_SUCCESS) {
934 upg_print("[upg refresh boot]flash write ret:0x%x \r\n", ret);
935 break;
936 }
937 offset += this_size;
938 }
939 hi_free(HI_MOD_ID_UPG, buf);
940 return ret;
941 }
942
upg_get_boot_encrypt_flag(HI_CONST boot_header * head,hi_u8 * flag)943 hi_u32 upg_get_boot_encrypt_flag(HI_CONST boot_header *head, hi_u8 *flag)
944 {
945 hi_flash_partition_table *partiton = hi_get_partition_table();
946 hi_u32 boot_addr = partiton->table[HI_FLASH_PARTITON_BOOT].addr;
947 sub_key_common *comk = HI_NULL;
948 hi_u32 ret = HI_ERR_SUCCESS;
949
950 if ((head == HI_NULL) || (flag == HI_NULL)) {
951 return HI_ERR_UPG_NULL_POINTER;
952 }
953
954 comk = hi_malloc(HI_MOD_ID_UPG, sizeof(sub_key_common));
955 if (comk == HI_NULL) {
956 ret = HI_ERR_UPG_MALLOC_FAIL;
957 goto end;
958 }
959
960 ret = hi_flash_read((boot_addr + head->sub_key_offset), sizeof(sub_key_common), (hi_u8 *)comk);
961 if (ret != HI_ERR_SUCCESS) {
962 goto end;
963 }
964
965 *flag = comk->encrypt_flag;
966 end:
967 upg_clear_contset((hi_u8 *)comk, sizeof(sub_key_common));
968 upg_mem_free(comk);
969 return ret;
970 }
971
upg_get_aes_info(HI_CONST boot_header * head,hi_u8 * key,hi_u32 key_len,hi_u8 * iv,hi_u32 iv_len)972 hi_u32 upg_get_aes_info(HI_CONST boot_header *head, hi_u8 *key, hi_u32 key_len, hi_u8 *iv, hi_u32 iv_len)
973 {
974 hi_flash_partition_table *partiton = hi_get_partition_table();
975 hi_u32 boot_addr = partiton->table[HI_FLASH_PARTITON_BOOT].addr;
976 sub_key_common *comk = HI_NULL;
977 hi_u32 ret = HI_ERR_SUCCESS;
978
979 if ((head == HI_NULL) || (key_len != IV_BYTE_LEN) || (iv_len != IV_BYTE_LEN)) {
980 return HI_ERR_UPG_PARAMETER;
981 }
982
983 comk = hi_malloc(HI_MOD_ID_UPG, sizeof(sub_key_common));
984 if (comk == HI_NULL) {
985 ret = HI_ERR_UPG_MALLOC_FAIL;
986 goto end;
987 }
988 ret = hi_flash_read((boot_addr + head->sub_key_offset), sizeof(sub_key_common), (hi_u8 *)comk);
989 if (ret != HI_ERR_SUCCESS) {
990 goto end;
991 }
992
993 if ((memcpy_s(key, key_len, comk->boot_key, key_len) != EOK) ||
994 (memcpy_s(iv, iv_len, comk->aes_iv, iv_len) != EOK)) {
995 ret = HI_ERR_FAILURE;
996 goto end;
997 }
998 end:
999 upg_clear_contset((hi_u8 *)comk, sizeof(sub_key_common));
1000 upg_mem_free(comk);
1001 return ret;
1002 }
1003
upg_set_kdf_key(const hi_u8 * boo_key,hi_u32 key_len)1004 hi_u32 upg_set_kdf_key(const hi_u8 *boo_key, hi_u32 key_len)
1005 {
1006 hi_cipher_kdf_ctrl *ctrl = HI_NULL;
1007 hi_u8 rootkey_iv[ROOTKEY_IV_BYTE_LENGTH] = { 0 };
1008 hi_u32 ret;
1009
1010 if (key_len != IV_BYTE_LEN) {
1011 return HI_ERR_UPG_PARAMETER;
1012 }
1013 ctrl = hi_malloc(HI_MOD_ID_UPG, sizeof(hi_cipher_kdf_ctrl));
1014 if (ctrl == HI_NULL) {
1015 return HI_ERR_UPG_MALLOC_FAIL;
1016 }
1017
1018 if ((memcpy_s(rootkey_iv, IV_BYTE_LEN, boo_key, IV_BYTE_LEN) != EOK) ||
1019 (memcpy_s((rootkey_iv + IV_BYTE_LEN), sizeof(rootkey_iv) - IV_BYTE_LEN, g_magic, IV_BYTE_LEN) != EOK)) {
1020 hi_free(HI_MOD_ID_UPG, ctrl);
1021 return HI_ERR_FAILURE;
1022 }
1023
1024 ctrl->salt = rootkey_iv;
1025 ctrl->salt_len = ROOTKEY_IV_BYTE_LENGTH;
1026 ctrl->kdf_cnt = KDF_ITERATION_CNT;
1027 ctrl->kdf_mode = HI_CIPHER_SSS_KDF_KEY_STORAGE;
1028
1029 ret = hi_cipher_kdf_key_derive(ctrl);
1030 hi_free(HI_MOD_ID_UPG, ctrl);
1031 return ret;
1032 }
1033
upg_boot_key_decrypt(hi_u8 * key,hi_u32 key_len,const hi_u8 * iv,hi_u32 iv_len)1034 hi_u32 upg_boot_key_decrypt(hi_u8 *key, hi_u32 key_len, const hi_u8 *iv, hi_u32 iv_len)
1035 {
1036 hi_cipher_aes_ctrl *aes_ctrl = HI_NULL;
1037 hi_u32 ret;
1038
1039 if (iv_len != IV_BYTE_LEN) {
1040 return HI_ERR_UPG_PARAMETER;
1041 }
1042 aes_ctrl = hi_malloc(HI_MOD_ID_UPG, sizeof(hi_cipher_aes_ctrl));
1043 if (aes_ctrl == HI_NULL) {
1044 return HI_ERR_UPG_MALLOC_FAIL;
1045 }
1046
1047 if (memcpy_s(aes_ctrl->iv, sizeof(aes_ctrl->iv), iv, IV_BYTE_LEN) != EOK) {
1048 hi_free(HI_MOD_ID_UPG, aes_ctrl);
1049 return HI_ERR_FAILURE;
1050 }
1051 aes_ctrl->random_en = HI_TRUE;
1052 aes_ctrl->key_from = HI_CIPHER_AES_KEY_FROM_KDF;
1053 aes_ctrl->work_mode = HI_CIPHER_AES_WORK_MODE_CBC;
1054 aes_ctrl->key_len = HI_CIPHER_AES_KEY_LENGTH_256BIT;
1055 ret = hi_cipher_aes_config(aes_ctrl);
1056 if (ret != HI_ERR_SUCCESS) {
1057 hi_free(HI_MOD_ID_UPG, aes_ctrl);
1058 return ret;
1059 }
1060 ret = hi_cipher_aes_crypto((uintptr_t)key, (uintptr_t)key, key_len, HI_FALSE);
1061 hi_cipher_aes_destroy_config();
1062 hi_free(HI_MOD_ID_UPG, aes_ctrl);
1063 return ret;
1064 }
1065
1066 /* key_n:from flash; key_e: use default value 0x10001. */
upg_get_unencrpt_rsa_key(hi_u8 * key,hi_u32 key_len)1067 hi_u32 upg_get_unencrpt_rsa_key(hi_u8 *key, hi_u32 key_len)
1068 {
1069 upg_ctx *ctx = upg_get_ctx();
1070 hi_u32 ret;
1071
1072 if (ctx->rsa_key_addr == 0) {
1073 return HI_ERR_UPG_RSA_KEY_ADDR;
1074 }
1075
1076 ret = hi_flash_read(ctx->rsa_key_addr, RSA_2048_LEN, key);
1077 if (ret != HI_ERR_SUCCESS) {
1078 upg_print("[upg get unencrpt rsa key]flash read fail:0x%x. \r\n", ret);
1079 return ret;
1080 }
1081 key[key_len - 1] = 0x01; /* 1: first byte. 0x01: part of key_e 0x10001 */
1082 key[key_len - 3] = 0x01; /* 3: last byte. 0x01: part of key_e 0x10001 */
1083 upg_print("[upg get unencrpt rsa key]success. \r\n");
1084 return HI_ERR_SUCCESS;
1085 }
1086
upg_get_unencrpt_ecc_key(hi_u8 * key,hi_u32 key_len)1087 hi_u32 upg_get_unencrpt_ecc_key(hi_u8 *key, hi_u32 key_len)
1088 {
1089 upg_ctx *ctx = upg_get_ctx();
1090 hi_u32 ret;
1091
1092 if (ctx->ecc_key_addr == 0) {
1093 return HI_ERR_UPG_ECC_KEY_ADDR;
1094 }
1095
1096 ret = hi_flash_read(ctx->ecc_key_addr, key_len, key);
1097 if (ret != HI_ERR_SUCCESS) {
1098 upg_print("[upg get unencrpt ecc key]flash read fail:0x%x. \r\n", ret);
1099 return ret;
1100 }
1101 upg_print("[upg get unencrpt ecc key]success. \r\n");
1102 return HI_ERR_SUCCESS;
1103 }
1104
upg_get_decrpt_rsa_key(HI_CONST boot_header * head,hi_u8 * key,hi_u32 key_len)1105 hi_u32 upg_get_decrpt_rsa_key(HI_CONST boot_header *head, hi_u8 *key, hi_u32 key_len)
1106 {
1107 hi_u32 ret = HI_ERR_SUCCESS;
1108 upg_ctx *ctx = upg_get_ctx();
1109 hi_flash_partition_table *partiton = hi_get_partition_table();
1110 hi_u32 boot_addr = partiton->table[HI_FLASH_PARTITON_BOOT].addr;
1111 hi_u8 *raw_data = HI_NULL;
1112 hi_u8 boot_key[IV_BYTE_LEN] = { 0 };
1113 hi_u8 aes_iv[IV_BYTE_LEN] = { 0 };
1114
1115 ret = upg_get_aes_info(head, boot_key, IV_BYTE_LEN, aes_iv, IV_BYTE_LEN);
1116 if (ret != HI_ERR_SUCCESS) {
1117 return ret;
1118 }
1119
1120 if ((ctx->rsa_key_addr == 0) || (ctx->rsa_key_addr < head->code_section_offset)) {
1121 return HI_ERR_UPG_RSA_KEY_ADDR;
1122 }
1123 hi_u32 data_len = upg_align_128bit(ctx->rsa_key_addr - head->code_section_offset + RSA_2048_LEN);
1124 upg_print("[upg get decrpt rsa key]offset-addr-len:0x%x-0x%x-0x%x \r\n", head->code_section_offset,
1125 ctx->rsa_key_addr, data_len);
1126 raw_data = hi_malloc(HI_MOD_ID_UPG, data_len);
1127 if (raw_data == HI_NULL) {
1128 return HI_ERR_UPG_MALLOC_FAIL;
1129 }
1130 ret = hi_flash_read(boot_addr + head->code_section_offset, data_len, raw_data);
1131 if (ret != HI_ERR_SUCCESS) {
1132 goto end;
1133 }
1134
1135 ret = upg_set_kdf_key(boot_key, IV_BYTE_LEN);
1136 if (ret != HI_ERR_SUCCESS) {
1137 upg_print("[upg get decrpt rsa key]kdf ret:0x%x \r\n", ret);
1138 goto end;
1139 }
1140
1141 ret = upg_boot_key_decrypt(raw_data, data_len, aes_iv, IV_BYTE_LEN);
1142 if (memcpy_s(key, RSA_2048_LEN, raw_data + (ctx->rsa_key_addr - head->code_section_offset), RSA_2048_LEN) != EOK) {
1143 ret = HI_ERR_FAILURE;
1144 goto end;
1145 }
1146 key[key_len - 1] = 0x01; /* 1: first byte. 0x01: part of key_e 0x10001 */
1147 key[key_len - 3] = 0x01; /* 3: last byte. 0x01: part of key_e 0x10001 */
1148 end:
1149 upg_clear_contset(raw_data, data_len);
1150 upg_mem_free(raw_data);
1151 return ret;
1152 }
1153
1154 /* px+py:from flash. */
upg_get_decrpt_ecc_key(HI_CONST boot_header * head,hi_u8 * key,hi_u32 key_len)1155 hi_u32 upg_get_decrpt_ecc_key(HI_CONST boot_header *head, hi_u8 *key, hi_u32 key_len)
1156 {
1157 hi_u32 ret = HI_ERR_SUCCESS;
1158 upg_ctx *ctx = upg_get_ctx();
1159 hi_flash_partition_table *partiton = hi_get_partition_table();
1160 hi_u32 boot_addr = partiton->table[HI_FLASH_PARTITON_BOOT].addr;
1161 hi_u8 *raw_data = HI_NULL;
1162 hi_u8 boot_key[IV_BYTE_LEN] = { 0 };
1163 hi_u8 aes_iv[IV_BYTE_LEN] = { 0 };
1164
1165 ret = upg_get_aes_info(head, boot_key, IV_BYTE_LEN, aes_iv, IV_BYTE_LEN);
1166 if (ret != HI_ERR_SUCCESS) {
1167 return ret;
1168 }
1169
1170 if ((ctx->ecc_key_addr == 0) || (ctx->ecc_key_addr < head->code_section_offset)) {
1171 return HI_ERR_UPG_ECC_KEY_ADDR;
1172 }
1173 hi_u32 data_len = upg_align_128bit(ctx->ecc_key_addr - head->code_section_offset + key_len);
1174 upg_print("[upg get decrpt ecc key]offset-addr-len:0x%x-0x%x-0x%x \r\n", head->code_section_offset,
1175 ctx->ecc_key_addr, data_len);
1176 raw_data = hi_malloc(HI_MOD_ID_UPG, data_len);
1177 if (raw_data == HI_NULL) {
1178 return HI_ERR_UPG_MALLOC_FAIL;
1179 }
1180 ret = hi_flash_read(boot_addr + head->code_section_offset, data_len, raw_data);
1181 if (ret != HI_ERR_SUCCESS) {
1182 goto end;
1183 }
1184
1185 ret = upg_set_kdf_key(boot_key, IV_BYTE_LEN);
1186 if (ret != HI_ERR_SUCCESS) {
1187 upg_print("[upg get decrpt ecc key]set kdf ret:0x%x \r\n", ret);
1188 goto end;
1189 }
1190
1191 ret = upg_boot_key_decrypt(raw_data, data_len, aes_iv, IV_BYTE_LEN);
1192 if (memcpy_s(key, key_len, raw_data + (ctx->ecc_key_addr - head->code_section_offset), key_len) != EOK) {
1193 ret = HI_ERR_FAILURE;
1194 }
1195 end:
1196 upg_clear_contset(raw_data, data_len);
1197 upg_mem_free(raw_data);
1198 return ret;
1199 }
1200
1201 /* key_n:from flash; key_e: use default value 0x10001. */
upg_get_rsa_key_from_boot(hi_u8 * key,hi_u32 key_len)1202 hi_u32 upg_get_rsa_key_from_boot(hi_u8 *key, hi_u32 key_len)
1203 {
1204 hi_u32 ret;
1205 hi_u8 flag;
1206 hi_u8 efuse_flag = 0xFF;
1207 boot_header *head = HI_NULL;
1208 hi_flash_partition_table *partiton = hi_get_partition_table();
1209 hi_u32 boot_addr = partiton->table[HI_FLASH_PARTITON_BOOT].addr;
1210
1211 if ((key == HI_NULL) || (key_len != RSA_KEY_LEN)) {
1212 upg_print("[upg get rsa key]param err:len:0x%x \r\n", key_len);
1213 return HI_ERR_UPG_PARAMETER;
1214 }
1215 head = hi_malloc(HI_MOD_ID_UPG, sizeof(boot_header));
1216 if (head == HI_NULL) {
1217 return HI_ERR_UPG_MALLOC_FAIL;
1218 }
1219 ret = hi_flash_read(boot_addr, sizeof(boot_header), (hi_u8 *)head);
1220 if (ret != HI_ERR_SUCCESS) {
1221 goto end;
1222 }
1223
1224 ret = upg_get_boot_encrypt_flag(head, &flag);
1225 if (ret != HI_ERR_SUCCESS) {
1226 upg_print("[upg get rsa key]get encrypt flag fail:0x%x \r\n", ret);
1227 goto end;
1228 }
1229
1230 ret = hi_efuse_read(HI_EFUSE_ENCRYPT_FLAG_RW_ID, (hi_u8 *)(&efuse_flag), sizeof(hi_u8));
1231 if (ret != HI_ERR_SUCCESS) {
1232 upg_print("[upg get rsa key]efuse read err:0x%x \r\n", ret);
1233 goto end;
1234 }
1235
1236 if ((efuse_flag == NON_ENCRYPT_FLAG) && (flag == NON_ENCRYPT_FLAG)) {
1237 ret = upg_get_unencrpt_rsa_key(key, key_len);
1238 } else {
1239 ret = upg_get_decrpt_rsa_key(head, key, key_len);
1240 }
1241
1242 end:
1243 upg_mem_free(head);
1244 return ret;
1245 }
1246
1247 /* px+py:from flash. */
upg_get_ecc_key_from_boot(hi_u8 * key,hi_u32 key_len)1248 hi_u32 upg_get_ecc_key_from_boot(hi_u8 *key, hi_u32 key_len)
1249 {
1250 hi_u32 ret;
1251 hi_u8 flag;
1252 hi_u8 efuse_flag = 0xFF;
1253 boot_header *head = HI_NULL;
1254 hi_flash_partition_table *partiton = hi_get_partition_table();
1255 hi_u32 boot_addr = partiton->table[HI_FLASH_PARTITON_BOOT].addr;
1256
1257 if ((key == HI_NULL) || (key_len != ECC_KEY_LEN)) {
1258 upg_print("[upg get ecc key]param err:len:0x%x \r\n", key_len);
1259 return HI_ERR_UPG_PARAMETER;
1260 }
1261 head = hi_malloc(HI_MOD_ID_UPG, sizeof(boot_header));
1262 if (head == HI_NULL) {
1263 return HI_ERR_UPG_MALLOC_FAIL;
1264 }
1265 ret = hi_flash_read(boot_addr, sizeof(boot_header), (hi_u8 *)head);
1266 if (ret != HI_ERR_SUCCESS) {
1267 goto end;
1268 }
1269 ret = upg_get_boot_encrypt_flag(head, &flag);
1270 if (ret != HI_ERR_SUCCESS) {
1271 upg_print("[upg get ecc key]get encrypt flag fail:0x%x \r\n", ret);
1272 goto end;
1273 }
1274
1275 ret = hi_efuse_read(HI_EFUSE_ENCRYPT_FLAG_RW_ID, (hi_u8 *)(&efuse_flag), sizeof(hi_u8));
1276 if (ret != HI_ERR_SUCCESS) {
1277 upg_print("[upg get ecc key]efuse read err:0x%x \r\n", ret);
1278 goto end;
1279 }
1280
1281 if ((efuse_flag == NON_ENCRYPT_FLAG) && (flag == NON_ENCRYPT_FLAG)) {
1282 ret = upg_get_unencrpt_ecc_key(key, key_len);
1283 } else {
1284 ret = upg_get_decrpt_ecc_key(head, key, key_len);
1285 }
1286
1287 end:
1288 upg_mem_free(head);
1289 return ret;
1290 }
1291
upg_boot_process(hi_void)1292 hi_u32 upg_boot_process(hi_void)
1293 {
1294 upg_ctx *ctx = upg_get_ctx();
1295 hi_u32 ret = hi_flash_protect_enable(HI_FALSE);
1296 if (ret != HI_ERR_SUCCESS) {
1297 upg_stop(ret);
1298 return ret;
1299 }
1300 ret = upg_refresh_boot(ctx->file_addr);
1301 upg_print("[upg transmit finish]refresh boot:0x%x\r\n", ret);
1302 if (ret != HI_ERR_SUCCESS) {
1303 upg_stop(ret);
1304 return ret;
1305 }
1306 ret = hi_flash_protect_enable(HI_TRUE);
1307 if (ret != HI_ERR_SUCCESS) {
1308 upg_print("[upg transmit finish]refresh boot:0x%x\r\n", ret);
1309 }
1310 ret = upg_set_efuse_boot_ver();
1311 if (ret != HI_ERR_SUCCESS) {
1312 upg_stop(ret);
1313 return ret;
1314 }
1315 return ret;
1316 }
1317 /************************the following functions are external interface************************************/
hi_upg_init(hi_void)1318 hi_u32 hi_upg_init(hi_void)
1319 {
1320 hi_u32 ret;
1321 upg_ctx *ctx = upg_get_ctx();
1322
1323 if (ctx->is_init == HI_TRUE) {
1324 return HI_ERR_UPG_INITILIZATION_ALREADY;
1325 }
1326
1327 ret = hi_sem_bcreate(&ctx->upg_sem, HI_SEM_ONE);
1328 if (ret != HI_ERR_SUCCESS) {
1329 upg_print("[upg init]sem create fail: 0x%x\r\n", ret);
1330 return ret;
1331 }
1332 ctx->is_init = HI_TRUE;
1333 upg_get_boot_key_addr();
1334 ret = upg_refresh_nv();
1335 ret |= upg_mode_init();
1336 if (ret != HI_ERR_SUCCESS) {
1337 upg_print("[upg init]fail:0x%x \r\n", ret);
1338 }
1339 return ret;
1340 }
1341
hi_upg_get_max_file_len(hi_u8 file_type,hi_u32 * file_len)1342 hi_u32 hi_upg_get_max_file_len(hi_u8 file_type, hi_u32 *file_len)
1343 {
1344 if (file_len == HI_NULL) {
1345 return HI_ERR_UPG_NULL_POINTER;
1346 }
1347 return upg_get_max_file_len(file_type, file_len);
1348 }
1349
hi_upg_get_content(hi_u32 offset,hi_u8 * buf,hi_u32 buf_len)1350 hi_u32 hi_upg_get_content(hi_u32 offset, hi_u8 *buf, hi_u32 buf_len)
1351 {
1352 hi_nv_ftm_startup_cfg cfg;
1353 hi_nv_ftm_upg_wait_mode mode;
1354 hi_u32 ret = upg_get_start_up_cfg(&cfg);
1355 if (ret != HI_ERR_SUCCESS) {
1356 return ret;
1357 }
1358
1359 if (cfg.mode != HI_UPG_MODE_UPGRADE_WAIT) {
1360 if (upg_is_upg_process() == HI_FALSE) {
1361 return HI_ERR_UPG_NOT_START;
1362 }
1363
1364 if (upg_is_transmit_finish() == HI_TRUE) {
1365 return HI_ERR_UPG_ALREADY_FINISH;
1366 }
1367 } else {
1368 ret = upg_get_wait_mode_nv(&mode);
1369 if (ret != HI_ERR_SUCCESS) {
1370 return ret;
1371 }
1372 if (mode.is_upg_process == HI_FALSE) {
1373 return HI_ERR_UPG_NOT_START;
1374 }
1375
1376 upg_ctx *ctx = upg_get_ctx();
1377 ctx->file_addr = mode.file_addr;
1378 hi_upg_common_head head = {0};
1379 ret = hi_flash_read(ctx->file_addr, sizeof(hi_upg_common_head), (hi_u8 *)(&head));
1380 if (ret != HI_ERR_SUCCESS) {
1381 upg_print("[upg get content]Failed to read flash,ret=%X\r\n", ret);
1382 return ret;
1383 }
1384 ctx->common_head.file_len = head.file_len;
1385 }
1386
1387 return upg_cache_ctrl(offset, buf, buf_len, HI_FALSE);
1388 }
1389
hi_upg_transmit(hi_u32 offset,hi_u8 * buf,hi_u32 buf_len)1390 hi_u32 hi_upg_transmit(hi_u32 offset, hi_u8 *buf, hi_u32 buf_len)
1391 {
1392 hi_u32 ret;
1393 upg_ctx *ctx = upg_get_ctx();
1394
1395 if (buf == HI_NULL) {
1396 return HI_ERR_UPG_NULL_POINTER;
1397 }
1398 upg_check_clear_wait_mode();
1399 upg_check_clear_upg_mode();
1400 upg_print("[upg transmit]offset-buflen-cachesize:0x%x-0x%x-0x%x\r\n", offset, buf_len, ctx->cache_size);
1401
1402 if (offset != ctx->cache_size) {
1403 upg_print("[upg transmit]offset-cachesize:0x%x-0x%x\r\n", offset, ctx->cache_size);
1404 upg_stop(HI_ERR_UPG_PARAMETER);
1405 }
1406
1407 /* The first packet. */
1408 if (upg_is_upg_process() == HI_FALSE) {
1409 if (offset != 0) {
1410 return HI_ERR_UPG_FIRST_PACKET_OFFSET;
1411 }
1412 ret = upg_start(buf, buf_len);
1413 upg_print("[upg transmit]upg start ret:0x%x\r\n", ret);
1414 if (ret != HI_ERR_SUCCESS) {
1415 upg_stop(ret);
1416 return ret;
1417 }
1418 }
1419
1420 ret = upg_cache_write(offset, buf, buf_len);
1421 if (ret != HI_ERR_SUCCESS) {
1422 upg_print("[upg transmit]cache write err: 0x%x\r\n", ret);
1423 upg_stop(ret);
1424 return ret;
1425 }
1426 ctx->cache_size += buf_len;
1427 if ((ctx->check_head_flag == HI_FALSE) && (ctx->cache_size >= sizeof(hi_upg_head))) {
1428 ret = upg_check_head();
1429 ctx->check_head_flag = HI_TRUE;
1430 }
1431
1432 if (ret != HI_ERR_SUCCESS) {
1433 upg_print("[upg transmit]check head fail:0x%x\r\n", ret);
1434 upg_stop(ret);
1435 }
1436 return ret;
1437 }
1438
upg_file_decrypt(upg_ctx * ctx)1439 hi_u32 upg_file_decrypt(upg_ctx *ctx)
1440 {
1441 hi_u32 ret = HI_ERR_SUCCESS;
1442 #if (defined(CONFIG_FLASH_ENCRYPT_SUPPORT)) && (!defined(CONFIG_COMPRESSION_OTA_SUPPORT))
1443 if (ctx->common_head.file_type == HI_UPG_FILE_KERNEL) {
1444 ret = crypto_encrypt_data_to_flash(ctx->file_addr);
1445 if (ret != HI_ERR_SUCCESS) {
1446 upg_stop(ret);
1447 return ret;
1448 }
1449 }
1450 #else
1451 hi_unref_param(ctx);
1452 #endif
1453
1454 return ret;
1455 }
1456
hi_upg_transmit_finish(hi_void)1457 hi_u32 hi_upg_transmit_finish(hi_void)
1458 {
1459 hi_nv_ftm_startup_cfg cfg;
1460 upg_ctx *ctx = upg_get_ctx();
1461 if (ctx->transmit_finish_flag == HI_TRUE) {
1462 return HI_ERR_UPG_ALREADY_FINISH;
1463 }
1464
1465 if (upg_is_upg_process() == HI_FALSE) {
1466 return HI_ERR_UPG_NOT_START;
1467 }
1468 hi_u32 ret = upg_get_start_up_cfg(&cfg);
1469 if (ret != HI_ERR_SUCCESS) {
1470 upg_stop(ret);
1471 return ret;
1472 }
1473
1474 if (upg_file_decrypt(ctx) != HI_ERR_SUCCESS) {
1475 return HI_ERR_UPG_FILE_DECRYPT_ERR;
1476 }
1477
1478 ret = upg_verify_file(ctx->file_addr);
1479 if (ret != HI_ERR_SUCCESS) {
1480 upg_stop(ret);
1481 return ret;
1482 }
1483
1484 if (ctx->common_head.file_type == HI_UPG_FILE_BOOT) {
1485 ret = upg_boot_process();
1486 if (ret != HI_ERR_SUCCESS) {
1487 return ret;
1488 }
1489 } else {
1490 /* Change kernel start address. */
1491 #if defined(CONFIG_COMPRESSION_OTA_SUPPORT)
1492 cfg.addr_write = ctx->file_addr;
1493 #else
1494 cfg.addr_start = ctx->file_addr;
1495 cfg.addr_write = ctx->file_addr;
1496 #endif
1497 cfg.refresh_nv = ENV_REFRESH_NV;
1498 cfg.reset_cnt = 0;
1499 }
1500 cfg.mode = HI_UPG_MODE_UPGRADE;
1501 cfg.file_type = ctx->common_head.file_type;
1502 ret = upg_set_start_up_cfg(&cfg);
1503 if (ret == HI_ERR_SUCCESS) {
1504 ctx->transmit_finish_flag = HI_TRUE;
1505 } else {
1506 upg_stop(ret);
1507 }
1508 upg_print("[upg transmit finish]start-type-write-ret:0x%x-0x%x-0x%x-0x%x\r\n",
1509 cfg.addr_start, cfg.file_type, cfg.addr_write, ret);
1510 return ret;
1511 }
1512
hi_upg_finish(hi_void)1513 hi_void hi_upg_finish(hi_void)
1514 {
1515 upg_ctx *ctx = upg_get_ctx();
1516
1517 upg_print("[upg finish]finish flag:0x%x \r\n", ctx->transmit_finish_flag);
1518 if (ctx->transmit_finish_flag == HI_FALSE) {
1519 hi_soft_reboot(HI_SYS_REBOOT_CAUSE_UPG_B);
1520 } else {
1521 hi_soft_reboot(HI_SYS_REBOOT_CAUSE_UPG);
1522 }
1523 }
1524
upg_check_transmit_finish_flag(hi_void)1525 hi_u32 upg_check_transmit_finish_flag(hi_void)
1526 {
1527 hi_u32 ret;
1528 hi_nv_ftm_upg_wait_mode mode_cfg = {0};
1529
1530 ret = upg_get_wait_mode_nv(&mode_cfg);
1531 if (ret != HI_ERR_SUCCESS) {
1532 upg_stop(ret);
1533 return ret;
1534 }
1535
1536 if (mode_cfg.trans_finish_flag == HI_TRUE) {
1537 return HI_ERR_UPG_ALREADY_FINISH;
1538 }
1539
1540 return HI_ERR_SUCCESS;
1541 }
1542
upg_check_download_finish(hi_void)1543 hi_u32 upg_check_download_finish(hi_void)
1544 {
1545 upg_ctx *ctx = upg_get_ctx();
1546 hi_u32 addr = ctx->file_addr;
1547 hi_u32 ret;
1548 hi_upg_common_head *comm_head = hi_malloc(HI_MOD_ID_UPG, sizeof(hi_upg_common_head));
1549 if (comm_head == HI_NULL) {
1550 return HI_ERR_UPG_MALLOC_FAIL;
1551 }
1552 ret = hi_flash_read(addr, sizeof(hi_upg_common_head), (hi_u8 *)comm_head);
1553 if (ret != HI_ERR_SUCCESS) {
1554 upg_mem_free(comm_head);
1555 return ret;
1556 }
1557
1558 if (ctx->cache_size < comm_head->file_len) {
1559 upg_mem_free(comm_head);
1560 return HI_ERR_UPG_NOT_DOWNLOAD_FINISH;
1561 }
1562
1563 upg_mem_free(comm_head);
1564 return HI_ERR_SUCCESS;
1565 }
1566
hi_upg_transmit_finish_save_cache(hi_void)1567 hi_u32 hi_upg_transmit_finish_save_cache(hi_void)
1568 {
1569 hi_nv_ftm_startup_cfg cfg;
1570 hi_nv_ftm_upg_wait_mode mode_cfg = {0};
1571 upg_ctx *ctx = upg_get_ctx();
1572 if (upg_check_transmit_finish_flag() != HI_ERR_SUCCESS) {
1573 return HI_ERR_UPG_ALREADY_FINISH;
1574 }
1575
1576 if (upg_is_upg_process() == HI_FALSE) {
1577 return HI_ERR_UPG_NOT_START;
1578 }
1579
1580 if (upg_check_download_finish() != HI_ERR_SUCCESS) {
1581 return HI_ERR_UPG_NOT_DOWNLOAD_FINISH;
1582 }
1583
1584 hi_u32 ret = upg_get_start_up_cfg(&cfg);
1585 if (ret != HI_ERR_SUCCESS) {
1586 upg_stop(ret);
1587 return ret;
1588 }
1589
1590 if (ctx->common_head.file_type == HI_UPG_FILE_BOOT) {
1591 ret = upg_verify_file(ctx->file_addr);
1592 if (ret != HI_ERR_SUCCESS) {
1593 upg_stop(ret);
1594 return ret;
1595 }
1596 mode_cfg.boot_version = ctx->common_head.file_version;
1597 } else {
1598 cfg.refresh_nv = ENV_REFRESH_NV_WAIT;
1599 cfg.reset_cnt = 0;
1600 }
1601
1602 cfg.mode = HI_UPG_MODE_UPGRADE_WAIT;
1603 cfg.file_type = ctx->common_head.file_type;
1604 ret = upg_set_start_up_cfg(&cfg);
1605 if (ret != HI_ERR_SUCCESS) {
1606 upg_stop(ret);
1607 return ret;
1608 }
1609
1610 mode_cfg.file_addr = ctx->file_addr;
1611 mode_cfg.file_type = ctx->common_head.file_type;
1612 mode_cfg.is_upg_process = ctx->is_upg_process;
1613 mode_cfg.trans_finish_flag = HI_TRUE;
1614 ret = upg_save_wait_mode_nv(&mode_cfg);
1615 if (ret != HI_ERR_SUCCESS) {
1616 upg_stop(ret);
1617 return ret;
1618 }
1619
1620 upg_print("[upg transmit finish with cache]start-type-write-ret:0x%x-0x%x-0x%x-0x%x\r\n",
1621 cfg.addr_start, cfg.file_type, cfg.addr_write, ret);
1622 return ret;
1623 }
1624
upg_kernel_decrypt_and_verify(upg_ctx * ctx)1625 hi_u32 upg_kernel_decrypt_and_verify(upg_ctx *ctx)
1626 {
1627 hi_u32 ret;
1628 if (upg_file_decrypt(ctx) != HI_ERR_SUCCESS) {
1629 upg_stop(HI_ERR_UPG_FILE_DECRYPT_ERR);
1630 return HI_ERR_UPG_FILE_DECRYPT_ERR;
1631 }
1632
1633 ret = upg_verify_file(ctx->file_addr);
1634 if (ret != HI_ERR_SUCCESS) {
1635 upg_stop(ret);
1636 return ret;
1637 }
1638
1639 return HI_ERR_SUCCESS;
1640 }
1641
hi_upg_finish_with_cache(hi_void)1642 hi_u32 hi_upg_finish_with_cache(hi_void)
1643 {
1644 hi_nv_ftm_startup_cfg cfg = {0};
1645 hi_nv_ftm_upg_wait_mode mode_cfg = {0};
1646 upg_ctx *ctx = upg_get_ctx();
1647 hi_u32 ret = upg_get_start_up_cfg(&cfg);
1648 if (ret != HI_ERR_SUCCESS) {
1649 upg_stop(ret);
1650 return ret;
1651 }
1652
1653 ret = upg_get_wait_mode_nv(&mode_cfg);
1654 if (ret != HI_ERR_SUCCESS) {
1655 upg_stop(ret);
1656 return ret;
1657 }
1658
1659 if ((cfg.mode != HI_UPG_MODE_UPGRADE_WAIT) || (mode_cfg.is_upg_process != HI_TRUE) ||
1660 (mode_cfg.trans_finish_flag != HI_TRUE)) {
1661 return HI_ERR_UPG_NOT_WITH_CACHE_MODE_ERR;
1662 }
1663
1664 upg_print("[upg finish with cache]file_addr-file_type: 0x%x-0x%x\r\n", mode_cfg.file_addr, mode_cfg.file_type);
1665 ctx->file_addr = mode_cfg.file_addr;
1666 ctx->common_head.file_type = mode_cfg.file_type;
1667
1668 ret = upg_kernel_decrypt_and_verify(ctx);
1669 if (ret != HI_ERR_SUCCESS) {
1670 return ret;
1671 }
1672
1673 if (ctx->common_head.file_type == HI_UPG_FILE_BOOT) {
1674 ctx->common_head.file_version = mode_cfg.boot_version;
1675 ret = upg_boot_process();
1676 if (ret != HI_ERR_SUCCESS) {
1677 return ret;
1678 }
1679 } else {
1680 /* Change kernel start address. */
1681 #if defined(CONFIG_COMPRESSION_OTA_SUPPORT)
1682 cfg.addr_write = ctx->file_addr;
1683 #else
1684 cfg.addr_start = ctx->file_addr;
1685 cfg.addr_write = ctx->file_addr;
1686 #endif
1687 cfg.refresh_nv = ENV_REFRESH_NV;
1688 }
1689 cfg.mode = HI_UPG_MODE_UPGRADE;
1690
1691 ret = upg_set_start_up_cfg(&cfg);
1692 if (ret != HI_ERR_SUCCESS) {
1693 upg_stop(ret);
1694 return ret;
1695 }
1696
1697 ret = upg_clear_wait_mode(&mode_cfg);
1698 if (ret != HI_ERR_SUCCESS) {
1699 upg_stop(ret);
1700 return ret;
1701 }
1702
1703 hi_soft_reboot(HI_SYS_REBOOT_CAUSE_UPG);
1704 return HI_ERR_SUCCESS;
1705 }
1706
hi_upg_get_file_index(hi_u8 * index)1707 hi_u32 hi_upg_get_file_index(hi_u8 *index)
1708 {
1709 hi_nv_ftm_startup_cfg cfg = { 0 };
1710 hi_flash_partition_table *partition = hi_get_partition_table();
1711 uintptr_t kernel_a_addr = partition->table[HI_FLASH_PARTITON_KERNEL_A].addr;
1712 hi_u32 ret = upg_get_start_up_cfg(&cfg);
1713
1714 if (index == HI_NULL) {
1715 return HI_ERR_UPG_PARAMETER;
1716 }
1717
1718 if (ret != HI_ERR_SUCCESS) {
1719 return ret;
1720 }
1721 if (cfg.addr_start == kernel_a_addr) {
1722 *index = HI_UPG_FILE_FOR_AREA_B;
1723 } else {
1724 *index = HI_UPG_FILE_FOR_AREA_A;
1725 }
1726 upg_print("[upg get file index]index:%d \r\n", *index);
1727 return ret;
1728 }
1729
hi_upg_stop(hi_void)1730 hi_u32 hi_upg_stop(hi_void)
1731 {
1732 return upg_stop(HI_ERR_UPG_STOP);
1733 }
1734
upg_update_ver(hi_void)1735 hi_bool upg_update_ver(hi_void)
1736 {
1737 if (g_upg_updating_ver == UPG_UPDATE_VER_NONE) {
1738 return HI_FALSE;
1739 }
1740
1741 hi_u32 ret = HI_ERR_FAILURE;
1742
1743 if (g_upg_updating_ver == UPG_UPDATE_VER_FIRMARE) {
1744 ret = hi_efuse_write(HI_EFUSE_TEE_KERNEL_VER_RW_ID, g_upg_efuse_data_kernel_ver);
1745 } else if (g_upg_updating_ver == UPG_UPDATE_VER_BOOT) {
1746 ret = hi_efuse_write(HI_EFUSE_TEE_BOOT_VER_RW_ID, g_upg_efuse_data_boot_ver);
1747 }
1748
1749 if (ret == HI_ERR_SUCCESS) {
1750 g_upg_update_ver_success = HI_TRUE;
1751 }
1752 g_upg_updating_ver = UPG_UPDATE_VER_NONE;
1753
1754 return HI_TRUE;
1755 }
1756