/* * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2021-2021. All rights reserved. * Description: main * * Create: 2021-03-09 */ #include "boot_serial.h" #include "boot_init.h" #include "boot_reset.h" #include "boot_verify.h" #include "secure_verify_boot.h" #include "efuse.h" #include "efuse_porting.h" #include "chip_io.h" #include "pinctrl.h" #include "boot_flash.h" #include "sfc.h" #include "boot_delay.h" #include "boot_jump.h" #include "tcxo.h" #include "watchdog.h" #include "drv_pmp.h" #include "pmp_cfg.h" #include "malloc_porting.h" #include "upg_porting.h" #include "upg_common.h" #include "upg_alloc.h" #include "soc_porting.h" #include "drv_flashboot_cipher.h" #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB #include "upg_ab.h" #endif #include "factory.h" #include "sfc_protect.h" #include "reset_porting.h" #define FLASHBOOT_UART_DEFAULT_PARAM {115200, 8, 1, 0, 0, 2, 1, 4, 0} #define APP_START_INSTRUCTION 0x40006f #define DELAY_100MS 100 #define REG_CMU_CFG0 0x40003408 #define APP_IMAGE_HEADER_LEN ((KEY_AREA_STRUCTURE_LENGTH) + (CODE_INFO_STRUCTURE_LENGTH)) #define BOOT_WATCH_DOG_TIMOUT 7 // 7s #define FLASH_KEY_SALT_LEN 28 #define FLASH_ENCRY_ADDR_ALINE 256 #define FLASH_NO_ENCRY_FLAG 0x3C7896E1 #define FLASHBOOT_RAM_ADDR 0xA28000 #define FLASH_BOOT_TYPE_REG 0x40000024 #define FLASH_BOOT_TYPE_REG_MAIN 0xA5A5A5A5 #define FLASH_BOOT_TYPE_REG_BKUP 0x5A5A5A5A const sfc_flash_config_t sfc_cfg = { .read_type = FAST_READ_QUAD_OUTPUT, .write_type = PAGE_PROGRAM, .mapping_addr = 0x200000, .mapping_size = 0x800000, }; #if 1 //ADD LYL 2024 1122 -------- #define USERPAGE 0x003F2000 //AT参数存储区 #define BLE_CONKEYLEN 16 #pragma pack(push) #pragma pack(1) typedef struct { int8_t updateflag; //update flag int8_t validflag; //valid flag int8_t tmode_mode; int8_t wmode_mode; //STA, 140 bytes uint8_t sta_ssid[33]; uint8_t sta_key[65]; int8_t wsauth; int8_t wsencry; uint8_t wslko; uint8_t pmk_av; uint8_t sta_padding[6]; uint8_t pmk[32]; //AP, 144 bytes int8_t wap_mode; int8_t wap_channel; int8_t waauth; int8_t waencry; uint8_t walk_led; uint8_t max_sta_num; uint8_t ap_enable_hide; uint8_t ap_ssid[33]; uint8_t ap_key[65]; uint8_t ap_pmk_av; uint8_t ap_pmk[32]; uint8_t ap_padding[6]; //UART, 20 bytes int8_t baudrate; int8_t data_bits; int8_t stop_bits; int8_t parity; int8_t ctsrts; int8_t uart1_baudrate; int8_t uart1_data_bits; int8_t uart1_stop_bits; int8_t uart1_parity; int8_t uart1_debug; int8_t uartfable; int8_t fuartte_mode; uint16_t uarttm; uint16_t uartbuf; uint8_t uart_padding[4]; //NETP, 108 bytes int8_t protocol; int8_t app_mode; uint8_t maxsocket; char cipadd[101]; uint16_t pro_port; uint16_t tcpto; //SOCKB, 112 bytes uint16_t sockb_port; uint16_t sockb_tcpto; int8_t sockb_pro; char sockb_cipadd[101]; int8_t tcpdis; int8_t tcpdisb; uint16_t udp_localporta; uint16_t udp_localportb; //NETWORK, 108 bytes char wann_ipaddr[16]; char wann_mask[16]; char wann_gateway[16]; char lann_ipaddr[16]; char lann_mask[16]; uint8_t wann_mode; uint8_t network_padding[2]; uint8_t domain_name[21]; uint32_t dns_addr; //UTILS, 124 bytes int8_t echo; int8_t rlden; uint8_t debug_level; char wel_msg[11]; uint8_t event_onoff; uint8_t noise_filter; uint8_t wifi_switch; uint8_t sta_dtim; uint8_t utils_padding[40]; uint8_t dis_power_saving; int8_t modechange; uint8_t ps_interval; uint8_t mid[21]; uint8_t aswd[21]; uint8_t cmdpw[21]; //HTTPD, 36 bytes char user_name[16]; char user_password[16]; int8_t web_switch; uint8_t web_language; uint8_t web_encode_format; uint8_t httpd_padding; //DHCPD, 4 bytes int8_t dhcpsw; uint8_t dhcpd_addr_start; uint8_t dhcpd_addr_end; uint8_t dhcpd_padding; //UPDATE, 124 bytes char update_url[101]; char update_file[21]; uint8_t update_padding[2]; //NTP, 8 bytes uint8_t ntp_time; uint8_t ntp_enable; uint8_t ntp_padding; int8_t time_zone; uint32_t ntpserver; //SMTLK, 16 bytes uint32_t smtlk_sign; uint8_t smtlk_mode; uint8_t smtlk_protocol; uint8_t smtlk_rtype; uint8_t smtlk_ak_random; uint8_t connect_flag; uint8_t sta_channel; uint8_t sta_bssid[6]; //SMARTAPLINK, 44 bytes uint8_t smartaplink_enable; uint8_t smartaplink_padding; uint8_t smartaplink_prefix[21]; uint8_t smartaplink_key[21]; //NETPID, 24 bytes uint8_t netpa_iden; char netpa_id[11]; uint8_t netpb_iden; char netpb_id[11]; //NETPREG, 264 bytes uint8_t netpa_regen; uint8_t netpa_regtype; uint8_t netpa_reg_padding; char netpa_regdata[129]; uint8_t netpb_regen; uint8_t netpb_regtype; uint8_t netpb_reg_padding; char netpb_regdata[129]; //HEART, 124 bytes uint16_t heart_netp_time; uint16_t heart_sockb_time; uint16_t heart_uart_time; char heart_netp_data[39]; char heart_sockb_data[39]; char heart_uart_data[39]; uint8_t heart_padding; //HTTP, 236 bytes uint8_t http_type; uint8_t http_version; uint8_t http_connect_type; uint8_t http_recv_time; char http_url[51]; char http_header[181]; //MQTT, 224 bytes char mqtt_username[33]; char mqtt_password[33]; char mqtt_clientid[33]; char mqtt_pub_topic[61]; char mqtt_sub_topic[61]; uint8_t mqtt_qos; uint16_t mqtt_heart_time; //BLE, 188 bytes uint16_t conn_min; uint16_t conn_max; uint16_t conn_latency; uint16_t supervisionTO; uint16_t adver_min; uint16_t adver_max; uint8_t ble_name[27]; //BLE广播名 uint8_t ble_dms_name[27]; //BLE配网名 uint8_t ble_adver_data[27]; uint8_t ble_adver_data_len; uint8_t ble_switch; uint8_t ble_uuid_server; uint8_t dms_type; uint8_t ble_padding; uint8_t uuid_ntf_server[17]; uint8_t uuid_ntf_read[17]; uint8_t uuid_ntf_write[17]; uint8_t uuid_ind_server[17]; uint8_t uuid_ind_read[17]; uint8_t uuid_ind_write[17]; uint8_t adver_type; uint8_t adver_channel; uint8_t ble_ind; uint8_t smartconfiglink; uint8_t ble_conenable; uint8_t ble_conkey[BLE_CONKEYLEN]; uint8_t ble_contimeout; uint8_t netpc_iden; char netpc_id[11]; uint8_t netpc_idflag; uint8_t ble_padding2[17]; uint8_t mqtt_tls; uint8_t mqtt_padding[3]; char iot_productkey[12]; char iot_devicename[48]; char iot_devicesecret[48]; char iot_pubtopic[96]; char iot_subtopic[96]; char iot_mode; char iot_padding[3]; uint8_t product_mode; int8_t ctsrts_pin; char instance_flag; char instance_id[32]; char ntp_domain_server[33]; int8_t smk_find; uint32_t mcu_ota_size; uint8_t scan_ch14; uint32_t module_reset_reason; uint8_t reserved1[60+512-4]; uint8_t validflag_magic; int8_t validflag_end; //valid flag }HF_CONFIG_FILE; #pragma pack(pop) HF_CONFIG_FILE g_hf_config_file_boot = {0}; int hfdbg_get_sw(void) { if(g_hf_config_file_boot.debug_level > 0 && g_hf_config_file_boot.debug_level<=20) //1~20允许打印 return 0; if(g_hf_config_file_boot.uart1_debug == 1) //1允许打印 return 1; return 0; } #endif static uint32_t sfc_flash_init(void) { return uapi_sfc_init((sfc_flash_config_t *)&sfc_cfg); } static uint32_t sfc_flash_read(uint32_t flash_addr, uint32_t read_size, uint8_t *read_buffer) { return uapi_sfc_reg_read(flash_addr, read_buffer, read_size); } static uint32_t sfc_flash_write(uint32_t flash_addr, uint32_t flash_write_size, const uint8_t *p_flash_write_data, bool do_erase) { unused(do_erase); return uapi_sfc_reg_write(flash_addr, (uint8_t *)p_flash_write_data, flash_write_size); } static uint32_t sfc_flash_erase(uint32_t flash_addr, uint32_t flash_erase_size) { return uapi_sfc_reg_erase(flash_addr - sfc_cfg.mapping_addr, flash_erase_size); } static void boot_flash_init(void) { flash_cmd_func flash_funcs = {0}; flash_funcs.init = sfc_flash_init; flash_funcs.read = sfc_flash_read; flash_funcs.write = sfc_flash_write; flash_funcs.erase = sfc_flash_erase; boot_regist_flash_cmd(&flash_funcs); uint32_t ret = sfc_flash_init(); if (ret != ERRCODE_SUCC) { boot_msg1("Flash Init Fail! ret = ", ret); } else { uapi_sfc_reg_read(USERPAGE, (unsigned char *)&g_hf_config_file_boot, sizeof(HF_CONFIG_FILE)); boot_msg0("Flash Init Succ!"); } hf_boot_msg1("BootLoader debug_level = ", g_hf_config_file_boot.debug_level); switch_flash_clock_to_pll(); config_sfc_ctrl_ds(); } #define FAMA_REMAP_SRC_BASE_ADDR 0x44007800 #define FAMA_REMAP_LEN_BASE_ADDR 0x44007820 #define FAMA_REMAP_DST_BASE_ADDR 0x44007840 #define FAMA_REMAP_REGION_OFFSET 0x4 #define FAMA_REMAP_LOW_BITS 12 static void dmmu_set(uint32_t src_start_addr, uint32_t src_end_addr, uint32_t dst_start_addr, uint32_t region) { uint32_t src_reg_addr = FAMA_REMAP_SRC_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET; uint32_t len_reg_addr = FAMA_REMAP_LEN_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET; uint32_t dst_reg_addr = FAMA_REMAP_DST_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET; uint32_t src_start_align_addr = src_start_addr >> FAMA_REMAP_LOW_BITS; uint32_t src_end_align_addr = src_end_addr >> FAMA_REMAP_LOW_BITS; uint32_t dst_start_align_addr = dst_start_addr >> FAMA_REMAP_LOW_BITS; uint32_t dst_src_offset = 0; if (region >= FAMA_REMAP_LOW_BITS) { return ; } writel(src_reg_addr, src_start_align_addr); writel(len_reg_addr, src_end_align_addr); if (src_start_align_addr > dst_start_align_addr) { dst_src_offset = src_start_align_addr - dst_start_align_addr; dst_src_offset = ~dst_src_offset; dst_src_offset = dst_src_offset + 1; } else { dst_src_offset = dst_start_align_addr - src_start_align_addr; } writel(dst_reg_addr, dst_src_offset); } static bool flashboot_need_recovery(void) { uint32_t reg = readl(FLASH_BOOT_TYPE_REG); writel(FLASH_BOOT_TYPE_REG, 0); return (reg == FLASH_BOOT_TYPE_REG_BKUP) ? true : false; } static void ws63_flashboot_recovery(void) { if (!flashboot_need_recovery()) { return; } uapi_watchdog_kick(); boot_msg0("Flashboot backup is working!"); partition_information_t src_img_info = {0}; partition_information_t dst_img_info = {0}; errcode_t ret; ret = uapi_partition_get_info(PARTITION_FLASH_BOOT_IMAGE_BACKUP, &src_img_info); ret |= uapi_partition_get_info(PARTITION_FLASH_BOOT_IMAGE, &dst_img_info); if (ret != ERRCODE_SUCC) { boot_msg0("Flashboot partition info get fail!"); return; } ret = uapi_sfc_reg_erase(dst_img_info.part_info.addr_info.addr, dst_img_info.part_info.addr_info.size); if (ret != ERRCODE_SUCC) { boot_msg1("flashboot recovery erase failed!! ret = ", ret); } ret = uapi_sfc_reg_write(dst_img_info.part_info.addr_info.addr, (uint8_t *)(uintptr_t)(src_img_info.part_info.addr_info.addr + FLASH_START), src_img_info.part_info.addr_info.size); if (ret != ERRCODE_SUCC) { boot_msg1("flashboot recovery write failed!! ret = ", ret); } boot_msg0("Flashboot fix ok!"); } #define UPG_FIX_RETRY_CNT_REG RESET_COUNT_REG #define VERIFY_RETRY_CNT_THRES 0x3 #define UPG_FIX_RETRY_CNT_THRES (VERIFY_RETRY_CNT_THRES + 0x3) #define UPG_AB_RETRY_CNT_THRES (VERIFY_RETRY_CNT_THRES + 0x3) static uint8_t ws63_get_try_fix_cnt(void) { gp_reg1_union gp; gp.u32 = readl(UPG_FIX_RETRY_CNT_REG); return gp.bits.fota_fix_app_cnt; } static void ws63_set_try_fix_cnt(uint8_t cnt) { gp_reg1_union gp; gp.u32 = readl(UPG_FIX_RETRY_CNT_REG); gp.bits.fota_fix_app_cnt = cnt & 0xF; writel(UPG_FIX_RETRY_CNT_REG, gp.u32); } #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB static void ws63_try_fix_app(void) { uint8_t try_cnt = ws63_get_try_fix_cnt() + 1; ws63_set_try_fix_cnt(try_cnt); /* 启动分区连续验签失败次数等于阈值倍数时,切换启动分区 */ if (try_cnt % VERIFY_RETRY_CNT_THRES) { // 1 2 4 5 7 8 a b d e return; } else { // 3 6 9 c f boot_msg0("switch booting"); upg_set_run_region(upg_get_upg_region()); return; } } #else // 压缩 /* 尝试ota修复运行区镜像 */ static void ws63_try_fix_app(void) { uint8_t try_cnt = ws63_get_try_fix_cnt(); /* 连续验签失败次数小于阈值不做处理 */ if (try_cnt < VERIFY_RETRY_CNT_THRES) { ws63_set_try_fix_cnt(try_cnt + 1); return; } /* 修复app超次数阈值后不再尝试 */ if (try_cnt >= UPG_FIX_RETRY_CNT_THRES) { return; } ws63_set_try_fix_cnt(try_cnt + 1); /* 重置升级标记 */ errcode_t ret = uapi_upg_reset_upgrade_flag(); if (ret != ERRCODE_SUCC) { boot_msg1("reset_upgrade_flag fail, ret = ", ret); return; } /* 请求升级 */ ret = uapi_upg_request_upgrade(false); if (ret != ERRCODE_SUCC) { boot_msg0("request_upgrade fail, fota_pkt_not_exit."); return; } boot_msg0("fota_pkt exit, try_fota_fix_app."); } #endif static bool ws63_upg_need_upgrade(void) { uint32_t fota_address = 0; partition_information_t info; errcode_t ret_val = uapi_partition_get_info(PARTITION_FOTA_DATA, &info); if (ret_val != ERRCODE_SUCC || info.type != PARTITION_BY_ADDRESS) { boot_msg1("uapi_partition_get_info failed ", __LINE__); return false; } upg_get_upgrade_flag_flash_start_addr(&fota_address); fota_upgrade_flag_area_t upg_flag_info; ret_val = upg_flash_read(fota_address, sizeof(fota_upgrade_flag_area_t), (uint8_t *)(&upg_flag_info)); if (ret_val != ERRCODE_SUCC) { boot_msg1("upg_flash_read failed ", ret_val); return false; } if (!(upg_flag_info.head_magic == UPG_HEAD_MAGIC && upg_flag_info.head_end_magic == UPG_END_MAGIC && upg_flag_info.complete_flag != 0)) { /* 不需要升级直接返回 */ boot_msg0("No need to upgrade..."); return false; } return true; } static void ws63_upg_check(void) { (void)ws63_upg_init(); #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB return; #endif if (ws63_upg_need_upgrade()) { boot_msg0("need upgrade"); errcode_t ret = uapi_upg_start(); // 1, 没有升级包、或者升级标记区结果已经设置的情况不需要重启 // 2, 升级模块没有初始化不需要重启 // 3, 升级成功需要重启 // 4, 升级失败的时候需要重启重新进入升级流程,尝试三次未成功,后会变为1的情况 if (!(ret == ERRCODE_UPG_NOT_NEED_TO_UPDATE || ret == ERRCODE_UPG_NOT_INIT || ret == ERRCODE_SUCC)) { boot_msg0("--------------------------"); boot_msg0("upgrade failed, reset now"); } else { // 升级后重启 boot_msg0("--------------------------"); boot_msg0("upgrade success, reset now"); } reset(); } } #define PMU_CMU_CTL_POC_COEX 0x40003238 #define RG_POC_SEL_SW_MODE 0x2 #define PMU_VDD_FLAG_3V3 0 #define POC_SEL_SW_MODE 1 #define POC_VALUE_3V3 0 #define LEVEL_3V3 0x33 #define LEVEL_1V8 0x18 typedef union { struct { uint32_t rg_poc_value : 1; /* [0] */ uint32_t rg_poc_sel : 1; /* [1] */ uint32_t pmu_vdd3318_flag : 1; /* [2] */ uint32_t ms1c : 1; /* [3] */ uint32_t rsv : 28; /* [31:4] */ } bits; uint32_t u32; } u_poc_coex; static void fix_io_level(void) { u_poc_coex poc_coex = {0}; poc_coex.u32 = readl(PMU_CMU_CTL_POC_COEX); if (poc_coex.bits.ms1c == poc_coex.bits.pmu_vdd3318_flag) { return; } if (poc_coex.bits.pmu_vdd3318_flag != PMU_VDD_FLAG_3V3) { return; } poc_coex.bits.rg_poc_value = POC_VALUE_3V3; poc_coex.bits.rg_poc_sel = POC_SEL_SW_MODE; writel(PMU_CMU_CTL_POC_COEX, poc_coex.u32); } static void dump_io_level(void) { u_poc_coex poc_coex = {0}; uint32_t chip_level = LEVEL_3V3; uint32_t sw_level = LEVEL_3V3; poc_coex.u32 = readl(PMU_CMU_CTL_POC_COEX); if (poc_coex.bits.rg_poc_sel == POC_SEL_SW_MODE) { sw_level = (poc_coex.bits.rg_poc_value == POC_VALUE_3V3) ? LEVEL_3V3 : LEVEL_1V8; chip_level = (poc_coex.bits.ms1c == POC_VALUE_3V3) ? LEVEL_3V3 : LEVEL_1V8; boot_msg2("io level work in sw mode, level[sw:chip]:", sw_level, chip_level); } else { chip_level = (poc_coex.bits.ms1c == POC_VALUE_3V3) ? LEVEL_3V3 : LEVEL_1V8; boot_msg1("io level work in hw mode, level[chip]:", chip_level); } } static uint32_t ws63_flashboot_init(void) { errcode_t err; uart_param_stru uart_param = FLASHBOOT_UART_DEFAULT_PARAM; uapi_tcxo_init(); hiburn_uart_init(uart_param, HIBURN_CODELOADER_UART); boot_msg0("Flashboot Uart Init Succ!"); uapi_partition_init(); pmp_enable(); malloc_port_init(); boot_flash_init(); boot_msg0("Flashboot Uart Init Succ!"); boot_msg0("Flashboot Malloc Init Succ!"); err = sfc_port_fix_sr(); if (err != ERRCODE_SUCC) { boot_msg1("SFC fix SR ret =", err); } dump_io_level(); print_str("flashboot version : %s\r\n", SDK_VERSION); return 0; } static errcode_t ws63_verify_app(uint32_t addr) { errcode_t ret = ERRCODE_SUCC; image_key_area_t *flashboot_key_area = (image_key_area_t *)(FLASHBOOT_RAM_ADDR); ret = verify_image_head(APP_BOOT_TYPE, (uint32_t)(uintptr_t)flashboot_key_area->ext_pulic_key_area, addr); if (ret != ERRCODE_SUCC) { boot_msg1("flashboot verify_image_app_head failed!! ret = ", ret); return ret; } ret = verify_image_body(addr, addr + APP_IMAGE_HEADER_LEN); if (ret != ERRCODE_SUCC) { boot_msg1("verify_image_app_body failed!! ret = ", ret); return ret; } return ERRCODE_SUCC; } static void ws63_verify_app_handle(uint32_t addr) { errcode_t ret = ws63_verify_app(addr); if (ret != ERRCODE_SUCC) { ws63_try_fix_app(); reset(); } set_reset_count(0); ws63_set_try_fix_cnt(0); } static void ws63_flash_encrypt_config(uint32_t image_addr, uint32_t image_size) { image_code_info_t *img_info = (image_code_info_t *)(uintptr_t)(image_addr + sizeof(image_key_area_t)); crypto_klad_effective_key flash_key = {0}; uint32_t start_addr = image_addr + APP_IMAGE_HEADER_LEN; uint32_t end_addr = image_addr + image_size; int32_t ret = ERRCODE_SUCC; if (img_info->code_enc_flag == FLASH_NO_ENCRY_FLAG) { boot_msg0("flash_encrypt disable."); return; } if (start_addr % FLASH_ENCRY_ADDR_ALINE != 0 || end_addr % FLASH_ENCRY_ADDR_ALINE != 0) { boot_msg2("app_image start or end addr err, must 256byte alignment ", image_addr, end_addr); reset(); } boot_msg0("flash_encrypt enable."); flash_key.kdf_hard_alg = CRYPTO_KDF_HARD_ALG_SHA256; flash_key.key_parity = TD_FALSE; flash_key.key_size = CRYPTO_KLAD_KEY_SIZE_128BIT; flash_key.salt = img_info->protection_key_l1; flash_key.salt_length = FLASH_KEY_SALT_LEN; flash_key.oneway = TD_TRUE; ret = drv_rom_cipher_config_odrk1(flash_key); if (ret != ERRCODE_SUCC) { boot_msg1("fapc_set_config drv_rom_cipher_config_odrk1 err = ", (uint32_t)ret); reset(); } ret = drv_rom_cipher_fapc_config(0, start_addr, end_addr, img_info->iv, IV_LEN); if (ret != ERRCODE_SUCC) { boot_msg1("fapc_set_config drv_rom_cipher_fapc_config err = ", (uint32_t)ret); reset(); } ret = drv_rom_cipher_fapc_bypass_config(1, end_addr, FLASH_MAX_END, TD_TRUE); if (ret != ERRCODE_SUCC) { boot_msg1("fapc_set_config drv_rom_cipher_fapc_bypass_config err = ", (uint32_t)ret); reset(); } } static uint32_t ws63_ftm_mode_init(uint32_t image_addr) { uint32_t image_size = 0; uint32_t jump_addr = 0; mfg_factory_config_t mfg_factory_cfg = {0}; uint32_t run_region = mfg_get_ftm_run_region(&mfg_factory_cfg); if (run_region == FTM_REGION_SERVICE) { return 0; } jump_addr = mfg_factory_cfg.factory_addr_start; image_size = mfg_factory_cfg.factory_size; image_key_area_t *mfg_key_area = (image_key_area_t *)(uintptr_t)(jump_addr); if (mfg_key_area->image_id == FACTORYBOOT_KEY_AREA_IMAGE_ID && mfg_factory_cfg.factory_valid == MFG_FACTORY_VALID) { dmmu_set(image_addr, image_addr + image_size, jump_addr, 0); } return 0; } /* the entry of C. */ void start_fastboot(void) { partition_information_t img_info = {0}; uint32_t image_addr = 0; uint32_t image_size = 0; errcode_t err; fix_io_level(); // 关闭CMU假负载 uapi_reg_setbits(REG_CMU_CFG0, 3, 3, 0x7); // 0x7 -> 0x40003408 bit 5:3 (3 bits) boot_clock_adapt(); dmmu_set(0, 0, 0, FAMA_REMAP_LOW_BITS); uapi_watchdog_init(BOOT_WATCH_DOG_TIMOUT); uapi_watchdog_enable(WDT_MODE_RESET); ws63_flashboot_init(); set_efuse_period(); uapi_efuse_init(); ws63_upg_check(); // 升级模式判断 err = uapi_partition_get_info(PARTITION_APP_IMAGE, &img_info); if (err != ERRCODE_SUCC) { boot_msg0("Flashboot get app partition failed!, boot abort!"); reset(); } image_addr = img_info.part_info.addr_info.addr + FLASH_START; image_size = img_info.part_info.addr_info.size; #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB char *boot_str = "A"; uint32_t jump_addr = upg_get_region_addr(upg_get_run_region()) + FLASH_START; *boot_str = (image_addr == jump_addr) ? 'A' : 'B'; boot_msg0(boot_str); ws63_flash_encrypt_config(jump_addr, image_size); // flash在线加解密配置 ws63_verify_app_handle(jump_addr); // A/B验签 if (image_addr != jump_addr) { // 0x1000: dmmu配置都是闭区间,且需要是4K对齐的地址, 0: 第0组dmmu配置 dmmu_set(image_addr, image_addr + image_size - 0x1000, jump_addr, 0); // 0x1000: dmmu配置都是闭区间,且需要是4K对齐的地址, 1: 第1组dmmu配置 dmmu_set(jump_addr, jump_addr + image_size - 0x1000, image_addr, 1); } #else // 压缩 ws63_flash_encrypt_config(image_addr, image_size); // flash在线加解密配置 ws63_verify_app_handle(image_addr); // app验签 #endif ws63_ftm_mode_init(image_addr); ws63_flashboot_recovery(); uapi_watchdog_kick(); jump_to_execute_addr(image_addr + APP_IMAGE_HEADER_LEN); }