You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
5.9 KiB
227 lines
5.9 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2021. All rights reserved.
|
|
* Description: API implementation of loader.
|
|
* Author: Hisilicon
|
|
* Created: 2020-04-01
|
|
*/
|
|
|
|
#include <command.h>
|
|
#include "uapi_otp.h"
|
|
#include "soc_log.h"
|
|
#include "loader_debug.h"
|
|
#include "loader.h"
|
|
#include "loader_errno.h"
|
|
#include "loader_internal.h"
|
|
#include "loader_config.h"
|
|
#include "common.h"
|
|
#include "download.h"
|
|
#include "burn.h"
|
|
#include "protocol.h"
|
|
#include "ui.h"
|
|
#include "verify.h"
|
|
#include "usb_if.h"
|
|
|
|
#define TMP_BUF_SIZE_1 (64 * 1024) /* 64k */
|
|
#define TMP_BUF_SIZE_2 (8 * 1024 *1024) /* 8M */
|
|
|
|
#define MAX_PROGRESS_BYTE (MAX_U32 / 100)
|
|
#define CONFIG_LOADER_WITHOUT_REBOOT
|
|
|
|
loader_chip_related g_chip_info = {
|
|
.name_id = 0,
|
|
.revision = CHIP_REVISION_MAX,
|
|
.fill_size = 0xffffffff,
|
|
.fmt = EXT_GFX_COLOR_FORMAT_MAX,
|
|
.burn_flag = LOADER_USB_BURN_MAX,
|
|
.mem_type = CHIP_MEM_MAX
|
|
};
|
|
|
|
static td_s32 loader_reboot(td_void)
|
|
{
|
|
#ifdef CONFIG_LOADER_WITHOUT_REBOOT
|
|
while (1) {}; /* wait for power off */
|
|
#else
|
|
do_reset(NULL, 0, 0, NULL);
|
|
#endif
|
|
/* never run the fallowing */
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void progress(loader_progress_type type, td_u64 offset, td_u64 total)
|
|
{
|
|
static td_u32 last_percent[PROGRESS_MAX] = {0};
|
|
td_u32 percent;
|
|
|
|
if (type >= PROGRESS_MAX || type < 0) {
|
|
soc_log_fatal("type %d error!\n", type);
|
|
return;
|
|
}
|
|
if (total == 0 || offset > total) {
|
|
soc_log_fatal("progress bad parameter! offset:%lld, total:%lld error!\n\n", offset, total);
|
|
return;
|
|
}
|
|
|
|
/* Avoid 64-bit division */
|
|
while (total > MAX_PROGRESS_BYTE || offset > MAX_PROGRESS_BYTE) {
|
|
offset >>= 1;
|
|
total >>= 1;
|
|
}
|
|
|
|
percent = (td_u32)offset * 100 / (td_u32)total; /* 100 : 100% */
|
|
if (percent != last_percent[type]) {
|
|
last_percent[type] = percent;
|
|
check_func(loader_ui_progress(last_percent[PROGRESS_DOWNLOAD], last_percent[PROGRESS_BURN]));
|
|
soc_log_alert("download: %d%%, burn: %d%%\n", last_percent[PROGRESS_DOWNLOAD], last_percent[PROGRESS_BURN]);
|
|
}
|
|
return;
|
|
}
|
|
|
|
static td_void exit_tip(td_s32 err_code)
|
|
{
|
|
ui_string title;
|
|
ui_string content;
|
|
|
|
if (err_code == TD_SUCCESS) {
|
|
title = UI_STR_INFO;
|
|
} else {
|
|
title = UI_STR_WARNING;
|
|
}
|
|
|
|
if (err_code == TD_SUCCESS) {
|
|
content = UI_STR_PT_SUCC;
|
|
} else if (err_code == SOC_ERR_LOADER_NOT_FOUND_USB_FILE) {
|
|
content = UI_STR_NOT_FIND_USB_FILE;
|
|
} else if (err_code == SOC_ERR_LOADER_INVALID_DATA) {
|
|
content = UI_STR_FAIL_DATA;
|
|
} else {
|
|
content = UI_STR_FAIL_DATA;
|
|
}
|
|
|
|
check_func(loader_ui_end_tip(title, content));
|
|
loader_delay(3000); /* delay 3000 */
|
|
}
|
|
|
|
static td_s32 verify_upgrade_file(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_bool lock = TD_FALSE;
|
|
|
|
if_err(uapi_otp_init(), return TD_FAILURE);
|
|
|
|
if_err(ret = uapi_otp_get_scs_stat(&lock), goto out);
|
|
|
|
soc_log_alert("success. get scs stat is %d\n", lock);
|
|
if (lock == TD_TRUE) {
|
|
if_err(ret = loader_verify_upgrade_file(), goto out);
|
|
}
|
|
|
|
out:
|
|
(td_void)uapi_otp_deinit();
|
|
return ret;
|
|
}
|
|
|
|
static td_void loader_chip_related_init(loader_burn_type type)
|
|
{
|
|
ext_chip_name_id name_id = 0;
|
|
ext_chip_revision chip_revision = CHIP_REVISION_MAX;
|
|
|
|
if (ext_drv_sys_get_chip_name_id(&name_id) != TD_SUCCESS) {
|
|
soc_log_err("Failed to ext_drv_sys_get_chip_name_id func.\n");
|
|
return;
|
|
}
|
|
if (ext_drv_sys_get_chip_revision(&chip_revision) != TD_SUCCESS) {
|
|
soc_log_err("Failed to ext_drv_sys_get_chip_revision func.\n");
|
|
return;
|
|
}
|
|
|
|
g_chip_info.name_id = name_id;
|
|
g_chip_info.revision = chip_revision;
|
|
|
|
if (type == LOADER_BARE_BURN) {
|
|
g_chip_info.burn_flag = LOADER_USB_BARE_BURN;
|
|
g_chip_info.fmt = EXT_GFX_COLOR_FORMAT_YUV42221;
|
|
g_chip_info.mem_type = CHIP_MEM_LARGE;
|
|
g_chip_info.fill_size = TMP_BUF_SIZE_2;
|
|
} else if (type == LOADER_EMPTY_BURN) {
|
|
g_chip_info.burn_flag = LOADER_USB_EMPTY_BURN;
|
|
g_chip_info.fmt = EXT_GFX_COLOR_FORMAT_8888; /* the default support reserved5 */
|
|
g_chip_info.mem_type = CHIP_MEM_SMALL;
|
|
g_chip_info.fill_size = TMP_BUF_SIZE_1;
|
|
} else {
|
|
g_chip_info.burn_flag = LOADER_USB_BURN_MAX;
|
|
}
|
|
|
|
soc_log_dbg("chip_info.fmt = %d\n", g_chip_info.fmt);
|
|
soc_log_dbg("chip_info.burn_flag = %d\n", g_chip_info.burn_flag);
|
|
soc_log_dbg("chip_info.mem_type = %d\n", g_chip_info.mem_type);
|
|
soc_log_dbg("chip_info.fill_size = 0x%x\n", g_chip_info.fill_size);
|
|
soc_log_dbg("chip_info.name_id = 0x%x\n", g_chip_info.name_id);
|
|
soc_log_dbg("chip_info.revision = 0x%x\n", g_chip_info.revision);
|
|
return;
|
|
}
|
|
|
|
loader_chip_related *loader_get_chip_related(td_void)
|
|
{
|
|
return &g_chip_info;
|
|
}
|
|
|
|
td_s32 loader_base_init(loader_burn_type type)
|
|
{
|
|
td_s32 ret;
|
|
|
|
soc_log_alert("upgrade start!\n");
|
|
loader_chip_related_init(type);
|
|
check_func(loader_ui_init());
|
|
if_err(ret = loader_dl_init(LOADER_CFG_USB_UPGRADE_FILE), goto out_ui);
|
|
|
|
return TD_SUCCESS;
|
|
out_ui:
|
|
check_func(loader_base_deinit(ret));
|
|
return ret;
|
|
}
|
|
|
|
td_s32 loader_mandatory_upgrade(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
#ifdef SOCT_BOOT_LOG_SUPPORT
|
|
soc_log_init();
|
|
#endif
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
if_err(ret = loader_burn_init(), goto out_dl);
|
|
|
|
if_err(ret = loader_prot_init(progress), goto out_burn);
|
|
|
|
if_err(ret = verify_upgrade_file(), goto out_burn);
|
|
|
|
if_err(ret = loader_prot_upgrade(), goto out_burn);
|
|
|
|
ret = TD_SUCCESS;
|
|
check_func(loader_prot_deinit());
|
|
|
|
out_burn:
|
|
check_func(loader_burn_deinit());
|
|
|
|
out_dl:
|
|
check_func(loader_dl_deinit());
|
|
|
|
soc_dbg_func_exit();
|
|
return ret;
|
|
}
|
|
|
|
td_s32 loader_base_deinit(td_s32 upgrade_status)
|
|
{
|
|
if (upgrade_status == TD_SUCCESS) {
|
|
soc_log_alert("\nupgrade success ! please reboot the machine!\n\n");
|
|
} else {
|
|
soc_log_alert("\nupgrade failed!\n\n");
|
|
}
|
|
exit_tip(upgrade_status);
|
|
check_func(loader_ui_deinit());
|
|
check_func(loader_reboot());
|
|
return TD_SUCCESS;
|
|
}
|
|
|