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 "boot_upg_kernel.h"
17 #include "boot_upg_tool.h"
18
19 #if defined(CONFIG_FLASH_ENCRYPT_SUPPORT)
20 #include <crypto.h>
21 #endif
22
boot_upg_lzma_detect(hi_u32 addr_write,hi_u32 * uncompress_size,const hi_upg_section_head * section_head)23 hi_u32 boot_upg_lzma_detect(hi_u32 addr_write, hi_u32 *uncompress_size, const hi_upg_section_head *section_head)
24 {
25 hi_u8 lzma_head[13] = { 0 }; /* head 13B */
26 hi_u32 dic_size = 0;
27
28 /* get LZMA head. get uncompressed size */
29 hi_u32 ret = hi_flash_read(addr_write + section_head->section0_offset, 13, lzma_head); /* 13 Bytes:head length */
30 if (ret != HI_ERR_SUCCESS) {
31 return ret;
32 }
33 ret = hi_lzma_get_uncompress_len(lzma_head, sizeof(lzma_head), uncompress_size, &dic_size);
34 if (ret != HI_ERR_SUCCESS) {
35 boot_msg1("get uncompress len:", ret);
36 return ret;
37 }
38
39 /* RAM usage detect for LAMA uncompressing.
40 * Avoid can't uncompress after erasing file, it'll cause unable to start */
41 ret = hi_lzma_mem_detect(lzma_head, sizeof(lzma_head));
42 if (ret != HI_ERR_SUCCESS) {
43 boot_msg1("mem detect:", ret);
44 } else {
45 if ((*uncompress_size) == 0) {
46 ret = HI_ERR_UPG_FILE_LEN_ZERO;
47 boot_msg0("uncompress size.");
48 }
49 }
50 return ret;
51 }
52
boot_upg_lzma_verify(hi_u32 addr_write,hi_u32 * uncompress_size,const hi_upg_section_head * section_head,const hi_upg_file_head * file_head)53 hi_u32 boot_upg_lzma_verify(hi_u32 addr_write, hi_u32 *uncompress_size, const hi_upg_section_head *section_head,
54 const hi_upg_file_head *file_head)
55 {
56 hi_u32 ret = boot_upg_lzma_detect(addr_write, uncompress_size, section_head);
57 if (ret != HI_ERR_SUCCESS) {
58 boot_msg2("detect1 writeaddr-uncompress_size:", addr_write, *uncompress_size);
59 return ret;
60 }
61
62 ret = hi_cipher_init();
63 if (ret != HI_ERR_SUCCESS) {
64 return ret;
65 }
66 ret = boot_upg_check_before_decompress(addr_write, section_head, file_head);
67 if (ret != HI_ERR_SUCCESS) {
68 boot_msg1("check before decompress:", ret);
69 }
70 (hi_void)hi_cipher_deinit();
71 return ret;
72 }
73
boot_upg_kernel_process(hi_u32 addr_start,hi_u32 addr_write)74 hi_u32 boot_upg_kernel_process(hi_u32 addr_start, hi_u32 addr_write)
75 {
76 hi_u32 uncompress_size;
77 hi_upg_section_head section_head = { 0 };
78 hi_u32 ret = hi_flash_read(addr_write + sizeof(hi_upg_head), sizeof(hi_upg_section_head), (hi_u8 *)(§ion_head));
79 if (ret != HI_ERR_SUCCESS) {
80 return ret;
81 }
82 if (section_head.section0_compress == HI_FALSE) {
83 boot_msg0("Not support uncompressed file.");
84 return HI_ERR_UPG_PARAMETER;
85 }
86 hi_upg_file_head *file_head = boot_malloc(sizeof(hi_upg_file_head));
87 if (file_head == HI_NULL) {
88 return HI_ERR_UPG_MALLOC_FAIL;
89 }
90
91 #if defined(CONFIG_FLASH_ENCRYPT_SUPPORT)
92 ret = boot_decrypt_upg_file(addr_write, §ion_head);
93 if (ret != HI_ERR_SUCCESS) {
94 boot_msg1("decrypt upg file fail:", ret);
95 goto end;
96 }
97 #endif
98
99 ret = boot_upg_lzma_verify(addr_write, &uncompress_size, §ion_head, file_head);
100 if (ret != HI_ERR_SUCCESS) {
101 boot_msg1("lzma verify fail:", ret);
102 goto end;
103 }
104
105 ret = boot_upg_lzma_detect(addr_write, &uncompress_size, §ion_head);
106 if (ret != HI_ERR_SUCCESS) {
107 boot_msg1("detect2:", ret);
108 goto end;
109 }
110
111 /* make 4K allignment for kernal and NV before compression. Erasing target space */
112 hi_u32 erase_size = uncompress_size;
113 erase_size = align_length(erase_size, ALIGNTYPE_4K);
114 ret = hi_flash_erase(addr_start, erase_size);
115 boot_msg4("info start-erasesize-write-uncompresssize:", addr_start, erase_size, addr_write, uncompress_size);
116 /* uncompress kernel and nv file to target space */
117 ret = boot_upg_copy_flash_2_flash(addr_write + section_head.section0_offset, section_head.section0_len,
118 addr_start, uncompress_size, section_head.section0_compress);
119 if (ret == HI_ERR_SUCCESS) {
120 boot_msg0("[bootupg kernel process]decompress success.");
121 }
122 end:
123 boot_upg_mem_free(file_head);
124 #if defined(CONFIG_FLASH_ENCRYPT_SUPPORT)
125 boot_decrypt_free_memory();
126 #endif
127 return ret;
128 }