first commit
This commit is contained in:
780
bootloader/flashboot_ws63/startup/main.c
Executable file
780
bootloader/flashboot_ws63/startup/main.c
Executable file
@ -0,0 +1,780 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
93
bootloader/flashboot_ws63/startup/riscv_init.S
Executable file
93
bootloader/flashboot_ws63/startup/riscv_init.S
Executable file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
* Description: main
|
||||
*
|
||||
* Create: 2021-03-09
|
||||
*/
|
||||
|
||||
.section .text.entry
|
||||
.global _start
|
||||
.option norvc
|
||||
_start:
|
||||
j Reset_Handler
|
||||
|
||||
Reset_Handler:
|
||||
li t0,0x0
|
||||
csrw pmpcfg0,t0
|
||||
li t0,0x0
|
||||
csrw pmpcfg1,t0
|
||||
li t0,0x0
|
||||
csrw pmpcfg2,t0
|
||||
li t0,0x0
|
||||
csrw pmpcfg3,t0
|
||||
li t0,0x0
|
||||
csrw 0x7d9,t0
|
||||
la t0, __flash_boot_flag_begin__
|
||||
mv t1, a0
|
||||
lw t3, (t1)
|
||||
sw t3, (t0)
|
||||
la t0, trap_vector
|
||||
addi t0, t0, 1
|
||||
csrw mtvec, t0
|
||||
csrwi mstatus, 0
|
||||
csrwi mie, 0
|
||||
|
||||
# initialize global pointer
|
||||
la gp, _gp_
|
||||
|
||||
# initialize stack pointer
|
||||
la sp, __stack_top__
|
||||
|
||||
/* init stack */
|
||||
la t0, g_system_stack_begin
|
||||
la t1, g_system_stack_end
|
||||
beq t0, t1, end_set_stack_loop
|
||||
li t2, 0xefbeadde
|
||||
|
||||
set_stack_loop:
|
||||
sw t2, (t0)
|
||||
addi t0, t0, 4
|
||||
blt t0, t1, set_stack_loop
|
||||
end_set_stack_loop:
|
||||
|
||||
/* clear reg */
|
||||
li ra, 0
|
||||
li tp, 0
|
||||
li s0, 0
|
||||
li s1, 0
|
||||
li a0, 0
|
||||
li a1, 0
|
||||
li a2, 0
|
||||
li a3, 0
|
||||
li a4, 0
|
||||
li a5, 0
|
||||
li a6, 0
|
||||
li a7, 0
|
||||
li s2, 0
|
||||
li s3, 0
|
||||
li s4, 0
|
||||
li s5, 0
|
||||
li s6, 0
|
||||
li s7, 0
|
||||
li s8, 0
|
||||
li s9, 0
|
||||
li s10, 0
|
||||
li s11, 0
|
||||
li t3, 0
|
||||
li t4, 0
|
||||
li t5, 0
|
||||
li t6, 0
|
||||
|
||||
/* clear bss section */
|
||||
la t0, __bss_begin__
|
||||
la t1, __bss_end__
|
||||
beq t0, t1, end_clear_bss_loop
|
||||
li t2, 0x00000000
|
||||
|
||||
clear_bss_loop:
|
||||
sw t2, (t0)
|
||||
addi t0, t0, 4
|
||||
blt t0, t1, clear_bss_loop
|
||||
end_clear_bss_loop:
|
||||
|
||||
j start_fastboot
|
Reference in New Issue
Block a user