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 * Description: main
15 *
16 * Create: 2021-03-09
17 */
18
19 #include "boot_serial.h"
20 #include "boot_init.h"
21 #include "boot_reset.h"
22 #include "boot_verify.h"
23 #include "secure_verify_boot.h"
24 #include "efuse.h"
25 #include "efuse_porting.h"
26 #include "chip_io.h"
27 #include "pinctrl.h"
28 #include "boot_flash.h"
29 #include "sfc.h"
30 #include "boot_delay.h"
31 #include "boot_jump.h"
32 #include "tcxo.h"
33 #include "watchdog.h"
34 #include "drv_pmp.h"
35 #include "pmp_cfg.h"
36 #include "malloc_porting.h"
37 #include "upg_porting.h"
38 #include "upg_common.h"
39 #include "upg_alloc.h"
40 #include "upg_config.h"
41 #include "soc_porting.h"
42 #include "drv_flashboot_cipher.h"
43 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
44 #include "upg_ab.h"
45 #endif
46 #include "factory.h"
47 #include "sfc_protect.h"
48 #include "reset_porting.h"
49
50 #define FLASHBOOT_UART_DEFAULT_PARAM {115200, 8, 1, 0, 0, 2, 1, 4, 0}
51 #define APP_START_INSTRUCTION 0x40006f
52 #define DELAY_100MS 100
53 #define REG_CMU_CFG0 0x40003408
54 #define APP_IMAGE_HEADER_LEN ((KEY_AREA_STRUCTURE_LENGTH) + (CODE_INFO_STRUCTURE_LENGTH))
55 #define BOOT_WATCH_DOG_TIMOUT 7 // 7s
56 #define FLASH_KEY_SALT_LEN 28
57 #define FLASH_ENCRY_ADDR_ALINE 256
58 #define FLASH_NO_ENCRY_FLAG 0x3C7896E1
59 #define FLASHBOOT_RAM_ADDR 0xA28000
60
61 #define FLASH_BOOT_TYPE_REG 0x40000024
62 #define FLASH_BOOT_TYPE_REG_MAIN 0xA5A5A5A5
63 #define FLASH_BOOT_TYPE_REG_BKUP 0x5A5A5A5A
64
65 const sfc_flash_config_t sfc_cfg = {
66 .read_type = FAST_READ_QUAD_OUTPUT,
67 .write_type = PAGE_PROGRAM,
68 .mapping_addr = 0x200000,
69 .mapping_size = 0x800000,
70 };
71
sfc_flash_init(void)72 static uint32_t sfc_flash_init(void)
73 {
74 return uapi_sfc_init((sfc_flash_config_t *)&sfc_cfg);
75 }
sfc_flash_read(uint32_t flash_addr,uint32_t read_size,uint8_t * read_buffer)76 static uint32_t sfc_flash_read(uint32_t flash_addr, uint32_t read_size, uint8_t *read_buffer)
77 {
78 return uapi_sfc_reg_read(flash_addr, read_buffer, read_size);
79 }
sfc_flash_write(uint32_t flash_addr,uint32_t flash_write_size,const uint8_t * p_flash_write_data,bool do_erase)80 static uint32_t sfc_flash_write(uint32_t flash_addr, uint32_t flash_write_size, const uint8_t *p_flash_write_data,
81 bool do_erase)
82 {
83 unused(do_erase);
84 return uapi_sfc_reg_write(flash_addr, (uint8_t *)p_flash_write_data, flash_write_size);
85 }
86
sfc_flash_erase(uint32_t flash_addr,uint32_t flash_erase_size)87 static uint32_t sfc_flash_erase(uint32_t flash_addr, uint32_t flash_erase_size)
88 {
89 return uapi_sfc_reg_erase(flash_addr - sfc_cfg.mapping_addr, flash_erase_size);
90 }
91
boot_flash_init(void)92 static void boot_flash_init(void)
93 {
94 flash_cmd_func flash_funcs = {0};
95 flash_funcs.init = sfc_flash_init;
96 flash_funcs.read = sfc_flash_read;
97 flash_funcs.write = sfc_flash_write;
98 flash_funcs.erase = sfc_flash_erase;
99 boot_regist_flash_cmd(&flash_funcs);
100
101 uint32_t ret = sfc_flash_init();
102 if (ret != ERRCODE_SUCC) {
103 boot_msg1("Flash Init Fail! ret = ", ret);
104 } else {
105 boot_msg0("Flash Init Succ!");
106 }
107 switch_flash_clock_to_pll();
108 config_sfc_ctrl_ds();
109 }
110
111 #define FAMA_REMAP_SRC_BASE_ADDR 0x44007800
112 #define FAMA_REMAP_LEN_BASE_ADDR 0x44007820
113 #define FAMA_REMAP_DST_BASE_ADDR 0x44007840
114 #define FAMA_REMAP_REGION_OFFSET 0x4
115 #define FAMA_REMAP_LOW_BITS 12
dmmu_set(uint32_t src_start_addr,uint32_t src_end_addr,uint32_t dst_start_addr,uint32_t region)116 static void dmmu_set(uint32_t src_start_addr, uint32_t src_end_addr, uint32_t dst_start_addr, uint32_t region)
117 {
118 uint32_t src_reg_addr = FAMA_REMAP_SRC_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET;
119 uint32_t len_reg_addr = FAMA_REMAP_LEN_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET;
120 uint32_t dst_reg_addr = FAMA_REMAP_DST_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET;
121 uint32_t src_start_align_addr = src_start_addr >> FAMA_REMAP_LOW_BITS;
122 uint32_t src_end_align_addr = src_end_addr >> FAMA_REMAP_LOW_BITS;
123 uint32_t dst_start_align_addr = dst_start_addr >> FAMA_REMAP_LOW_BITS;
124 uint32_t dst_src_offset = 0;
125 if (region >= FAMA_REMAP_LOW_BITS) {
126 return ;
127 }
128 writel(src_reg_addr, src_start_align_addr);
129 writel(len_reg_addr, src_end_align_addr);
130 if (src_start_align_addr > dst_start_align_addr) {
131 dst_src_offset = src_start_align_addr - dst_start_align_addr;
132 dst_src_offset = ~dst_src_offset;
133 dst_src_offset = dst_src_offset + 1;
134 } else {
135 dst_src_offset = dst_start_align_addr - src_start_align_addr;
136 }
137 writel(dst_reg_addr, dst_src_offset);
138 }
139
flashboot_need_recovery(void)140 static bool flashboot_need_recovery(void)
141 {
142 uint32_t reg = readl(FLASH_BOOT_TYPE_REG);
143 writel(FLASH_BOOT_TYPE_REG, 0);
144 return (reg == FLASH_BOOT_TYPE_REG_BKUP) ? true : false;
145 }
146
ws63_flashboot_recovery(void)147 static void ws63_flashboot_recovery(void)
148 {
149 if (!flashboot_need_recovery()) {
150 return;
151 }
152 uapi_watchdog_kick();
153 boot_msg0("Flashboot backup is working!");
154 partition_information_t src_img_info = {0};
155 partition_information_t dst_img_info = {0};
156 errcode_t ret;
157 ret = uapi_partition_get_info(PARTITION_FLASH_BOOT_IMAGE_BACKUP, &src_img_info);
158 ret |= uapi_partition_get_info(PARTITION_FLASH_BOOT_IMAGE, &dst_img_info);
159 if (ret != ERRCODE_SUCC) {
160 boot_msg0("Flashboot partition info get fail!");
161 return;
162 }
163
164 ret = uapi_sfc_reg_erase(dst_img_info.part_info.addr_info.addr, dst_img_info.part_info.addr_info.size);
165 if (ret != ERRCODE_SUCC) {
166 boot_msg1("flashboot recovery erase failed!! ret = ", ret);
167 }
168 ret = uapi_sfc_reg_write(dst_img_info.part_info.addr_info.addr,
169 (uint8_t *)(src_img_info.part_info.addr_info.addr + FLASH_START), src_img_info.part_info.addr_info.size);
170 if (ret != ERRCODE_SUCC) {
171 boot_msg1("flashboot recovery write failed!! ret = ", ret);
172 }
173 boot_msg0("Flashboot fix ok!");
174 }
175
176 #define UPG_FIX_RETRY_CNT_REG RESET_COUNT_REG
177 #define VERIFY_RETRY_CNT_THRES 0x3
178 #define UPG_FIX_RETRY_CNT_THRES (VERIFY_RETRY_CNT_THRES + 0x3)
179 #define UPG_AB_RETRY_CNT_THRES (VERIFY_RETRY_CNT_THRES + 0x3)
180
ws63_get_try_fix_cnt(void)181 static uint8_t ws63_get_try_fix_cnt(void)
182 {
183 gp_reg1_union gp;
184 gp.u32 = readl(UPG_FIX_RETRY_CNT_REG);
185 return gp.bits.fota_fix_app_cnt;
186 }
187
ws63_set_try_fix_cnt(uint8_t cnt)188 static void ws63_set_try_fix_cnt(uint8_t cnt)
189 {
190 gp_reg1_union gp;
191 gp.u32 = readl(UPG_FIX_RETRY_CNT_REG);
192 gp.bits.fota_fix_app_cnt = cnt & 0xF;
193 writel(UPG_FIX_RETRY_CNT_REG, gp.u32);
194 }
195
196 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
ws63_try_fix_app(void)197 static void ws63_try_fix_app(void)
198 {
199 uint8_t try_cnt = ws63_get_try_fix_cnt() + 1;
200 ws63_set_try_fix_cnt(try_cnt);
201
202 /* 启动分区连续验签失败次数等于阈值倍数时,切换启动分区 */
203 if (try_cnt % VERIFY_RETRY_CNT_THRES) { // 1 2 4 5 7 8 a b d e
204 return;
205 } else { // 3 6 9 c f
206 boot_msg0("switch booting");
207 upg_set_run_region(upg_get_upg_region());
208 return;
209 }
210 }
211 #else // 压缩
212 /* 尝试ota修复运行区镜像 */
ws63_try_fix_app(void)213 static void ws63_try_fix_app(void)
214 {
215 uint8_t try_cnt = ws63_get_try_fix_cnt();
216 /* 连续验签失败次数小于阈值不做处理 */
217 if (try_cnt < VERIFY_RETRY_CNT_THRES) {
218 ws63_set_try_fix_cnt(try_cnt + 1);
219 return;
220 }
221
222 /* 修复app超次数阈值后不再尝试 */
223 if (try_cnt >= UPG_FIX_RETRY_CNT_THRES) {
224 return;
225 }
226 ws63_set_try_fix_cnt(try_cnt + 1);
227
228 /* 重置升级标记 */
229 errcode_t ret = uapi_upg_reset_upgrade_flag();
230 if (ret != ERRCODE_SUCC) {
231 boot_msg1("reset_upgrade_flag fail, ret = ", ret);
232 return;
233 }
234
235 /* 请求升级 */
236 ret = uapi_upg_request_upgrade(false);
237 if (ret != ERRCODE_SUCC) {
238 boot_msg0("request_upgrade fail, fota_pkt_not_exit.");
239 return;
240 }
241 boot_msg0("fota_pkt exit, try_fota_fix_app.");
242 }
243 #endif
244
ws63_upg_need_upgrade(void)245 static bool ws63_upg_need_upgrade(void)
246 {
247 uint32_t fota_address = 0;
248 partition_information_t info;
249 errcode_t ret_val = uapi_partition_get_info(PARTITION_FOTA_DATA, &info);
250 if (ret_val != ERRCODE_SUCC || info.type != PARTITION_BY_ADDRESS) {
251 boot_msg1("uapi_partition_get_info failed ", __LINE__);
252 return false;
253 }
254 upg_get_upgrade_flag_flash_start_addr(&fota_address);
255 fota_upgrade_flag_area_t upg_flag_info;
256 ret_val = upg_flash_read(fota_address, sizeof(fota_upgrade_flag_area_t), (uint8_t *)(&upg_flag_info));
257 if (ret_val != ERRCODE_SUCC) {
258 boot_msg1("upg_flash_read failed ", ret_val);
259 return false;
260 }
261 if (!(upg_flag_info.head_magic == UPG_HEAD_MAGIC &&
262 upg_flag_info.head_end_magic == UPG_END_MAGIC &&
263 upg_flag_info.complete_flag != 0)) {
264 /* 不需要升级直接返回 */
265 boot_msg0("No need to upgrade...");
266 return false;
267 }
268 return true;
269 }
270
ws63_upg_check(void)271 static void ws63_upg_check(void)
272 {
273 (void)ws63_upg_init();
274 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
275 return;
276 #endif
277 if (ws63_upg_need_upgrade()) {
278 boot_msg0("need upgrade");
279 errcode_t ret = uapi_upg_start();
280 // 1, 没有升级包、或者升级标记区结果已经设置的情况不需要重启
281 // 2, 升级模块没有初始化不需要重启
282 // 3, 升级成功需要重启
283 // 4, 升级失败的时候需要重启重新进入升级流程,尝试三次未成功,后会变为1的情况
284 if (!(ret == ERRCODE_UPG_NOT_NEED_TO_UPDATE || ret == ERRCODE_UPG_NOT_INIT || ret == ERRCODE_SUCC)) {
285 boot_msg0("--------------------------");
286 boot_msg0("upgrade failed, reset now");
287 } else {
288 // 升级后重启
289 boot_msg0("--------------------------");
290 boot_msg0("upgrade success, reset now");
291 }
292 reset();
293 }
294 }
295
ws63_flashboot_init(void)296 static uint32_t ws63_flashboot_init(void)
297 {
298 errcode_t err;
299 uart_param_stru uart_param = FLASHBOOT_UART_DEFAULT_PARAM;
300 uapi_tcxo_init();
301 hiburn_uart_init(uart_param, HIBURN_CODELOADER_UART);
302 boot_msg0("Flashboot Uart Init Succ!");
303 uapi_partition_init();
304 pmp_enable();
305 malloc_port_init();
306 boot_msg0("Flashboot Malloc Init Succ!");
307 boot_flash_init();
308 err = sfc_port_fix_sr();
309 if (err != ERRCODE_SUCC) {
310 boot_msg1("SFC fix SR ret =", err);
311 }
312 print_str("flashboot version : %s\r\n", SDK_VERSION);
313 return 0;
314 }
315
ws63_verify_app(uint32_t addr)316 static errcode_t ws63_verify_app(uint32_t addr)
317 {
318 errcode_t ret = ERRCODE_SUCC;
319 image_key_area_t *flashboot_key_area = (image_key_area_t *)(FLASHBOOT_RAM_ADDR);
320
321 ret = verify_image_head(APP_BOOT_TYPE, (uint32_t)flashboot_key_area->ext_pulic_key_area, addr);
322 if (ret != ERRCODE_SUCC) {
323 boot_msg1("flashboot verify_image_app_head failed!! ret = ", ret);
324 return ret;
325 }
326
327 ret = verify_image_body(addr, addr + APP_IMAGE_HEADER_LEN);
328 if (ret != ERRCODE_SUCC) {
329 boot_msg1("verify_image_app_body failed!! ret = ", ret);
330 return ret;
331 }
332 return ERRCODE_SUCC;
333 }
334
ws63_verify_app_handle(uint32_t addr)335 static void ws63_verify_app_handle(uint32_t addr)
336 {
337 errcode_t ret = ws63_verify_app(addr);
338 if (ret != ERRCODE_SUCC) {
339 ws63_try_fix_app();
340 reset();
341 }
342 set_reset_count(0);
343 ws63_set_try_fix_cnt(0);
344 }
345
ws63_flash_encrypt_config(uint32_t image_addr,uint32_t image_size)346 static void ws63_flash_encrypt_config(uint32_t image_addr, uint32_t image_size)
347 {
348 image_code_info_t *img_info = (image_code_info_t *)(uintptr_t)(image_addr + sizeof(image_key_area_t));
349 crypto_klad_effective_key flash_key = {0};
350 uint32_t start_addr = image_addr + APP_IMAGE_HEADER_LEN;
351 uint32_t end_addr = image_addr + image_size;
352 int32_t ret = ERRCODE_SUCC;
353
354 if (img_info->code_enc_flag == FLASH_NO_ENCRY_FLAG) {
355 boot_msg0("flash_encrypt disable.");
356 return;
357 }
358
359 if (start_addr % FLASH_ENCRY_ADDR_ALINE != 0 || end_addr % FLASH_ENCRY_ADDR_ALINE != 0) {
360 boot_msg2("app_image start or end addr err, must 256byte alignment ", image_addr, end_addr);
361 reset();
362 }
363 boot_msg0("flash_encrypt enable.");
364 flash_key.kdf_hard_alg = CRYPTO_KDF_HARD_ALG_SHA256;
365 flash_key.key_parity = TD_FALSE;
366 flash_key.key_size = CRYPTO_KLAD_KEY_SIZE_128BIT;
367 flash_key.salt = img_info->protection_key_l1;
368 flash_key.salt_length = FLASH_KEY_SALT_LEN;
369 flash_key.oneway = TD_TRUE;
370 ret = drv_rom_cipher_config_odrk1(flash_key);
371 if (ret != ERRCODE_SUCC) {
372 boot_msg1("fapc_set_config drv_rom_cipher_config_odrk1 err = ", (uint32_t)ret);
373 reset();
374 }
375 ret = drv_rom_cipher_fapc_config(0, start_addr, end_addr, img_info->iv, IV_LEN);
376 if (ret != ERRCODE_SUCC) {
377 boot_msg1("fapc_set_config drv_rom_cipher_fapc_config err = ", (uint32_t)ret);
378 reset();
379 }
380
381 ret = drv_rom_cipher_fapc_bypass_config(1, end_addr, FLASH_MAX_END, TD_TRUE);
382 if (ret != ERRCODE_SUCC) {
383 boot_msg1("fapc_set_config drv_rom_cipher_fapc_bypass_config err = ", (uint32_t)ret);
384 reset();
385 }
386 }
387
ws63_ftm_mode_init(uint32_t image_addr)388 static uint32_t ws63_ftm_mode_init(uint32_t image_addr)
389 {
390 uint32_t image_size = 0;
391 uint32_t jump_addr = 0;
392 mfg_factory_config_t mfg_factory_cfg = {0};
393 uint32_t run_region = mfg_get_ftm_run_region(&mfg_factory_cfg);
394 if (run_region == FTM_REGION_SERVICE) {
395 return 0;
396 }
397 jump_addr = mfg_factory_cfg.factory_addr_start;
398 image_size = mfg_factory_cfg.factory_size;
399 image_key_area_t *mfg_key_area = (image_key_area_t *)(jump_addr);
400
401 if (mfg_key_area->image_id == FACTORYBOOT_KEY_AREA_IMAGE_ID && mfg_factory_cfg.factory_valid == MFG_FACTORY_VALID) {
402 dmmu_set(image_addr, image_addr + image_size, jump_addr, 0);
403 }
404 return 0;
405 }
406
407 /* the entry of C. */
start_fastboot(void)408 void start_fastboot(void)
409 {
410 partition_information_t img_info = {0};
411 uint32_t image_addr = 0;
412 uint32_t image_size = 0;
413 errcode_t err;
414
415 // 关闭CMU假负载
416 uapi_reg_setbits(REG_CMU_CFG0, 3, 3, 0x7); // 0x7 -> 0x40003408 bit 5:3 (3 bits)
417
418 boot_clock_adapt();
419 dmmu_set(0, 0, 0, FAMA_REMAP_LOW_BITS);
420 uapi_watchdog_init(BOOT_WATCH_DOG_TIMOUT);
421 uapi_watchdog_enable(WDT_MODE_RESET);
422 ws63_flashboot_init();
423 set_efuse_period();
424 uapi_efuse_init();
425 ws63_upg_check(); // 升级模式判断
426 err = uapi_partition_get_info(PARTITION_APP_IMAGE, &img_info);
427 if (err != ERRCODE_SUCC) {
428 boot_msg0("Flashboot get app partition failed!, boot abort!");
429 reset();
430 }
431 image_addr = img_info.part_info.addr_info.addr + FLASH_START;
432 image_size = img_info.part_info.addr_info.size;
433 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
434 char *boot_str = "A";
435 uint32_t jump_addr = upg_get_region_addr(upg_get_run_region()) + FLASH_START;
436 *boot_str = (image_addr == jump_addr) ? 'A' : 'B';
437 boot_msg0(boot_str);
438 ws63_flash_encrypt_config(jump_addr, image_size); // flash在线加解密配置
439 ws63_verify_app_handle(jump_addr); // A/B验签
440 if (image_addr != jump_addr) {
441 dmmu_set(image_addr, image_addr + image_size, jump_addr, 0);
442 }
443 #else // 压缩
444 ws63_flash_encrypt_config(image_addr, image_size); // flash在线加解密配置
445 ws63_verify_app_handle(image_addr); // app验签
446 #endif
447 ws63_ftm_mode_init(image_addr);
448 ws63_flashboot_recovery();
449 uapi_watchdog_kick();
450 jump_to_execute_addr(image_addr + APP_IMAGE_HEADER_LEN);
451 }
452