Files
SR_Switch_Hilink_14.2.0.308…/bootloader/flashboot_ws63/startup/main.c
2025-07-03 23:58:20 +08:00

781 lines
22 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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);
}