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.
858 lines
23 KiB
858 lines
23 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2020. All rights reserved.
|
|
* Description: reg peri
|
|
* Author:
|
|
* Create: 2012-07
|
|
*/
|
|
#include "td_type.h"
|
|
#include "common.h"
|
|
#include "drv_pmoc_ext.h"
|
|
#include "cmdline_ext.h"
|
|
|
|
#include "pdm_ext.h"
|
|
#include "soc_license.h"
|
|
#include "common_ext.h"
|
|
#include "drv_custom_ext.h"
|
|
#include "flash_ext.h"
|
|
|
|
#if defined(CHIP_TYPE_RESERVED23)
|
|
#include "drv_rpmsg_ext.h"
|
|
#endif
|
|
|
|
#if defined(SOCT_BOOT_SBL) || defined(SOCT_BOOT_ONESTAGE)
|
|
#include "drv_mailbox_ext.h"
|
|
#include "kaslr.h"
|
|
#ifdef SOCT_ANDROID_BOOT_SUPPORT
|
|
#include "recovery.h"
|
|
#include "fixmac.h"
|
|
#include "serialnum.h"
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef SOCT_BOOT_SLAVE
|
|
#include "drv_disp_ext.h"
|
|
#include "gfx_show_ext.h"
|
|
#include "uapi_i2c.h"
|
|
#include "uapi_aiao.h"
|
|
#include "drv_hdmi_ext.h"
|
|
#include "drv_pq_ext.h"
|
|
#include "drv_mailbox_ext.h"
|
|
#include "drv_vibrator_ext.h"
|
|
#endif
|
|
|
|
#ifdef SOCT_ADVCA_TYPE_AVB
|
|
#include "sec_verify.h"
|
|
#endif
|
|
#include "mbx.h"
|
|
#include "asm/io.h"
|
|
#include "huanglong/autoloader.h"
|
|
#include "loader.h"
|
|
#include "upgrade_entry.h"
|
|
|
|
#ifdef SOCT_SUPPORT_AGING
|
|
#include "aging.h"
|
|
#endif
|
|
|
|
#define SLAVE_BOOT_START_ADDR CONFIG_SLAVEBOOT_ADDR
|
|
#define SLAVE_BOOT_LEN CONFIG_SLAVEBOOT_SIZE
|
|
|
|
#ifdef CONFIG_CPU_T9
|
|
#define SLAVE_BOOT_RUN_START_ADDR CONFIG_SLAVEBOOT_SYS_SDRAM_BASE
|
|
#define SLAVE_BOOT_RUN_END_ADDR CONFIG_SLAVEBOOT_RUN_MAX_ADDR
|
|
#endif
|
|
|
|
#define RECEIVE_MSG_TIMEOUT_MS 1000
|
|
|
|
td_void set_log_level(td_void)
|
|
{
|
|
soc_log_init();
|
|
printf("set LOG level [SOC_LOG_LEVEL_NOTICE]\n");
|
|
soc_log_set_level(SOC_ID_MAX, SOC_LOG_LEVEL_NOTICE);
|
|
}
|
|
|
|
#ifdef SLAVE_BOOT_ENV
|
|
static ext_disp_param g_disp_param0 = {0};
|
|
static ext_disp_param g_disp_param1 = {0};
|
|
|
|
static td_u32 get_disp_param_data(ext_pdm_boot_partion_info *partio_info, const char *key_name,
|
|
td_u32 key_size, td_void *addr, td_u32 size)
|
|
{
|
|
errno_t rc = strncpy_s(partio_info->key_name, sizeof(partio_info->key_name), key_name, key_size);
|
|
if (rc != EOK) {
|
|
printf("strncpy_s key_name failed, rc = %d", rc);
|
|
return TD_FALSE;
|
|
}
|
|
|
|
td_s32 ret = ext_drv_pdm_db_get_data(partio_info, addr, size);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("ext_drv_pdm_db_get_data failed, key_name:%s, error:0x%x\n", key_name, ret);
|
|
return TD_FALSE;
|
|
}
|
|
return TD_TRUE;
|
|
}
|
|
static td_s32 get_disp_param_data_impl(ext_pdm_boot_partion_info *partio_info, ext_disp_param *disp_param)
|
|
{
|
|
td_u32 ret = TD_TRUE;
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_ENABLE, sizeof(PDM_BASE_KEYNAME_ENABLE),
|
|
&(disp_param->disp_enable), sizeof(disp_param->disp_enable));
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_LOGO_INDEX, sizeof(PDM_BASE_KEYNAME_LOGO_INDEX),
|
|
&(disp_param->logo_index), sizeof(disp_param->logo_index));
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_DISP_L, sizeof(PDM_BASE_KEYNAME_DISP_L),
|
|
&(disp_param->offset_info.left), sizeof(disp_param->offset_info.left));
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_DISP_R, sizeof(PDM_BASE_KEYNAME_DISP_R),
|
|
&(disp_param->offset_info.right), sizeof(disp_param->offset_info.right));
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_DISP_T, sizeof(PDM_BASE_KEYNAME_DISP_T),
|
|
&(disp_param->offset_info.top), sizeof(disp_param->offset_info.top));
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_DISP_B, sizeof(PDM_BASE_KEYNAME_DISP_B),
|
|
&(disp_param->offset_info.bottom), sizeof(disp_param->offset_info.bottom));
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_VIRSCW, sizeof(PDM_BASE_KEYNAME_VIRSCW),
|
|
&(disp_param->virt_screen_width), sizeof(disp_param->virt_screen_width));
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_VIRSCH, sizeof(PDM_BASE_KEYNAME_VIRSCH),
|
|
&(disp_param->virt_screen_height), sizeof(disp_param->virt_screen_height));
|
|
ret &= get_disp_param_data(partio_info, PDM_BASE_KEYNAME_PF, sizeof(PDM_BASE_KEYNAME_PF),
|
|
&(disp_param->pixel_format), sizeof(disp_param->pixel_format));
|
|
if (ret != TD_TRUE) {
|
|
printf("get_disp_param_data failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
printf("get_disp_param_data:[%u,%u,%u,%u,%u,%u,%u,%u,%d]\n",
|
|
disp_param->disp_enable, disp_param->logo_index, disp_param->offset_info.left,
|
|
disp_param->offset_info.right, disp_param->offset_info.top,
|
|
disp_param->offset_info.bottom, disp_param->virt_screen_width,
|
|
disp_param->virt_screen_height, disp_param->pixel_format);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 get_disp_param_impl(ext_drv_display disp)
|
|
{
|
|
errno_t rc;
|
|
ext_disp_param *disp_param = TD_NULL;
|
|
ext_pdm_boot_partion_info partio_info = {PDM_BASEPARAM_BUFNAME, PDM_BASE_TABLENAME_DISP0, PDM_BASE_KEYNAME_ENABLE};
|
|
switch (disp) {
|
|
case EXT_DRV_DISPLAY_0:
|
|
disp_param = &g_disp_param0;
|
|
rc = strncpy_s(partio_info.tbl_name, sizeof(partio_info.tbl_name),
|
|
PDM_BASE_TABLENAME_DISP0, sizeof(PDM_BASE_TABLENAME_DISP0));
|
|
if (rc != EOK) {
|
|
printf("strncpy_s tbl_name failed, rc = %d\n", rc);
|
|
return TD_FALSE;
|
|
}
|
|
break;
|
|
case EXT_DRV_DISPLAY_1:
|
|
disp_param = &g_disp_param1;
|
|
rc = strncpy_s(partio_info.tbl_name, sizeof(partio_info.tbl_name),
|
|
PDM_BASE_TABLENAME_DISP1, sizeof(PDM_BASE_TABLENAME_DISP1));
|
|
if (rc != EOK) {
|
|
printf("strncpy_s tbl_name failed, rc = %d\n", rc);
|
|
return TD_FALSE;
|
|
}
|
|
break;
|
|
default:
|
|
printf("not support %d\n", disp);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return get_disp_param_data_impl(&partio_info, disp_param);
|
|
}
|
|
|
|
static td_s32 get_disp_param(const td_bool silence_flag)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = get_disp_param_impl(EXT_DRV_DISPLAY_0);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("EXT_PDM_GetDisp0 Param err! s32Ret = %x\n", ret);
|
|
}
|
|
|
|
ret = get_disp_param_impl(EXT_DRV_DISPLAY_1);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("EXT_PDM_GetDisp1 Param err! s32Ret = %x\n", ret);
|
|
}
|
|
|
|
ret = ext_drv_disp_set_offset_info(EXT_DRV_DISPLAY_0, &(g_disp_param0.offset_info));
|
|
if (ret != TD_SUCCESS) {
|
|
printf("set disp0 is offset error\n");
|
|
}
|
|
|
|
ret = ext_drv_disp_set_offset_info(EXT_DRV_DISPLAY_1, &(g_disp_param1.offset_info));
|
|
if (ret != TD_SUCCESS) {
|
|
printf("set disp1 is offset error\n");
|
|
}
|
|
|
|
if (silence_flag == TD_FALSE) {
|
|
if (g_disp_param0.disp_enable != 0) {
|
|
ret = ext_drv_disp_open(EXT_DRV_DISPLAY_0);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("open disp0 is error\n");
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (g_disp_param1.disp_enable != 0) {
|
|
ret = ext_drv_disp_open(EXT_DRV_DISPLAY_1);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("open disp1 is error\n");
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
ret = ext_drv_pq_init();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("ext_drv_pq_init is error\n");
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_void logo_process(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 logo_data_1_len = 0;
|
|
td_u32 logo_data_2_len = 0;
|
|
td_u64 logo_data_1_addr = 0;
|
|
td_u64 logo_data_2_addr = 0;
|
|
ext_gfx_logo_info input_base_logo_info = {0};
|
|
|
|
ret = ext_drv_pdm_get_logo_data(g_disp_param0.logo_index, &logo_data_1_len, &logo_data_1_addr);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("get logo data fail:%x\n", ret);
|
|
}
|
|
|
|
ret = ext_drv_pdm_get_logo_data(g_disp_param1.logo_index, &logo_data_2_len, &logo_data_2_addr);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("get logo data fail:%x\n", ret);
|
|
}
|
|
|
|
if ((g_disp_param0.disp_enable == TD_TRUE) && (logo_data_1_len > 0) && (logo_data_1_addr > 0)) {
|
|
input_base_logo_info.data_len = logo_data_1_len;
|
|
input_base_logo_info.data_buf = (td_char*)(uintptr_t)logo_data_1_addr;
|
|
input_base_logo_info.vir_screen_width = g_disp_param0.virt_screen_width;
|
|
input_base_logo_info.vir_screen_height = g_disp_param0.virt_screen_height;
|
|
input_base_logo_info.layer_fmt = g_disp_param0.pixel_format;
|
|
input_base_logo_info.disp_channel = EXT_GFX_DISPLAY_0;
|
|
ext_gfx_show_first_frame_logo(&input_base_logo_info);
|
|
}
|
|
|
|
if ((g_disp_param1.disp_enable == TD_TRUE) && (logo_data_2_len > 0) && (logo_data_2_addr > 0)) {
|
|
input_base_logo_info.data_len = logo_data_2_len;
|
|
input_base_logo_info.data_buf = (td_char*)(uintptr_t)logo_data_2_addr;
|
|
input_base_logo_info.vir_screen_width = g_disp_param1.virt_screen_width;
|
|
input_base_logo_info.vir_screen_height = g_disp_param1.virt_screen_height;
|
|
input_base_logo_info.layer_fmt = g_disp_param1.pixel_format;
|
|
input_base_logo_info.disp_channel = EXT_GFX_DISPLAY_1;
|
|
ext_gfx_show_first_frame_logo(&input_base_logo_info);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static td_s32 slave_boot_env_config(td_void)
|
|
{
|
|
td_s32 ret;
|
|
ext_pdm_slave_boot_env_info slave_env_info = {0};
|
|
|
|
ret = ext_drv_mailbox_receive_msg(EXT_DRV_MAILBOX_SLAVE_BOOT_ENV_READY, RECEIVE_MSG_TIMEOUT_MS);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("ext_drv_mailbox_slave_receive_msg err\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = ext_drv_mailbox_receive_data(&slave_env_info, sizeof(slave_env_info));
|
|
if (ret != TD_SUCCESS) {
|
|
printf("ext_drv_mailbox_receive_data err\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = ext_drv_pdm_set_slave_boot_env(&slave_env_info);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("ext_drv_pdm_set_slave_boot_env is error \n");
|
|
return ret;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void slave_boot_app_entry_i2c_init(td_void)
|
|
{
|
|
td_u8 data;
|
|
i2c_base_para i2c_para = {0};
|
|
|
|
i2c_para.i2c_num = 0;
|
|
i2c_para.dev_address = 0x60;
|
|
i2c_para.i2c_reg_addr = 0x2;
|
|
i2c_para.reg_addr_count = 1;
|
|
data = 0xa;
|
|
uapi_i2c_write(i2c_para, &data, 1);
|
|
|
|
i2c_para.i2c_reg_addr = 0x5;
|
|
data = 0x10;
|
|
uapi_i2c_write(i2c_para, &data, 1);
|
|
|
|
i2c_para.i2c_reg_addr = 0xd;
|
|
data = 0x01;
|
|
uapi_i2c_write(i2c_para, &data, 1);
|
|
}
|
|
|
|
/*
|
|
static td_void slave_boot_i2c_amp_init(td_void)
|
|
{
|
|
td_u8 data;
|
|
i2c_base_para i2c_para = {0};
|
|
|
|
i2c_para.i2c_num = 1;
|
|
i2c_para.dev_address = 0x58;
|
|
|
|
i2c_para.i2c_reg_addr = 0x00;
|
|
i2c_para.reg_addr_count = 1;
|
|
data = 0x00;
|
|
uapi_i2c_write(i2c_para, &data, 1);
|
|
|
|
i2c_para.i2c_reg_addr = 0x7F;
|
|
data = 0x00;
|
|
uapi_i2c_write(i2c_para, &data, 1);
|
|
|
|
i2c_para.i2c_reg_addr = 0x00;
|
|
data = 0x00;
|
|
uapi_i2c_write(i2c_para, &data, 1);
|
|
|
|
|
|
i2c_para.i2c_reg_addr = 0x01;
|
|
data = 0x11;
|
|
uapi_i2c_write(i2c_para, &data, 1);
|
|
|
|
i2c_para.i2c_reg_addr = 0x03;
|
|
data = 0x03;
|
|
uapi_i2c_write(i2c_para, &data, 1);
|
|
|
|
}
|
|
*/
|
|
|
|
|
|
static td_void slave_boot_i2c_amp_init(td_void)
|
|
{
|
|
td_u32 i = 0;
|
|
i2c_base_para i2c_para = {0};
|
|
i2c_para.i2c_num = 1;
|
|
i2c_para.dev_address = 0x58;
|
|
i2c_para.reg_addr_count = 1;
|
|
|
|
td_u8 data[][2] = {
|
|
{ 0x00 , 0x00},
|
|
{ 0x7F , 0x00},
|
|
{ 0x00 , 0x00},
|
|
{ 0x01 , 0x11},
|
|
{ 0x03 , 0x03},
|
|
};
|
|
|
|
for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
|
|
{
|
|
i2c_para.i2c_reg_addr = data[i][0];
|
|
uapi_i2c_write(i2c_para, (&data[i][1]),1 ) ;
|
|
udelay(10);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static td_void ext_boot_logo_main(td_void)
|
|
{
|
|
int ret;
|
|
if (g_boot_custom.process_logo == NULL) {
|
|
logo_process();
|
|
} else {
|
|
ret = g_boot_custom.process_logo();
|
|
if (ret != 0) {
|
|
logo_process();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
static td_s32 slave_boot_app_entry(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_bool silence_flag;
|
|
|
|
ret = slave_boot_env_config();
|
|
if (ret != TD_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
ret = ext_drv_pdm_get_silence_flag(&silence_flag);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("get silence flag fail!\n");
|
|
}
|
|
ret = drv_panel_init();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("drv_panel_init is error \n");
|
|
return ret;
|
|
}
|
|
ret = ext_drv_disp_init();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("uapi_disp_init is error \n");
|
|
return ret;
|
|
}
|
|
|
|
ret = uapi_i2c_init();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("uapi_i2c_init is error \n");
|
|
return ret;
|
|
}
|
|
|
|
uapi_snd_init();
|
|
#ifndef CONFIG_SOCT_REVERSION_SLS_C
|
|
ret = drv_hdmi_init();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("drv_hdmi_init is error\n");
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
slave_boot_app_entry_i2c_init();
|
|
slave_boot_i2c_amp_init();
|
|
|
|
drv_vibrator_init();
|
|
drv_vibrator_wave_output(WT_ON);
|
|
|
|
ret = get_disp_param(silence_flag);
|
|
if (ret != TD_SUCCESS) {
|
|
return ret;
|
|
}
|
|
if (silence_flag == TD_TRUE) {
|
|
goto silence;
|
|
}
|
|
|
|
drv_vibrator_wave_output(WT_OFF);
|
|
drv_vibrator_deinit();
|
|
|
|
ext_boot_logo_main();
|
|
|
|
drv_panel_set_panel_power_on();
|
|
silence:
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
#else
|
|
#ifndef SOCT_BOOT_FBL
|
|
static td_s32 reset_slaveboot(void)
|
|
{
|
|
printf("reset Slaveboot ...\n");
|
|
|
|
if (!is_usb_selfboot()) {
|
|
#ifndef CONFIG_CPU_T9
|
|
writel(SLAVE_BOOT_START_ADDR, REG_BASE_SCTL + REG_SC_GEN16);
|
|
|
|
exec_mailbox_cmd(MBX_RESET_SLAVE_CPU, EXT_MBX_ACPU2HIL_BOOT, 0, 0, 0);
|
|
#else
|
|
td_u32 reg;
|
|
unsigned int regval;
|
|
reg = CPU_REG_SOC_CRG_REG100 + CPU1_CRG_CONTROL;
|
|
regval = readl(reg);
|
|
regval |= 1 << CPU_REG_COREPO_SRST;
|
|
writel(regval, reg);
|
|
|
|
regval = readl(reg);
|
|
regval &= ~(1 << CPU_REG_COREPO_SRST);
|
|
regval |= 1;
|
|
writel(regval, reg);
|
|
#endif
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void prepare_panel_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
if (g_boot_custom.prepare_panel_param != TD_NULL) {
|
|
ret = g_boot_custom.prepare_panel_param();
|
|
if (ret != 0) {
|
|
printf("custom prepare panel param fail!\n");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
static td_s32 load_slave_boot(void)
|
|
{
|
|
td_s32 ret;
|
|
td_char *partition_name = NULL;
|
|
|
|
#ifndef SOCT_ADVCA_TYPE_AVB
|
|
td_s32 read_len;
|
|
td_handle flash;
|
|
#endif
|
|
ext_pdm_slave_boot_env_info slave_env_info = {0};
|
|
ext_pdm_mem_info slave_run_time = {0};
|
|
|
|
ret = ext_drv_pdm_check_and_init_partion();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("ext_drv_pdm_check_and_init_partion fail \n");
|
|
}
|
|
ret = ext_drv_mailbox_init();
|
|
if (ret != TD_SUCCESS) {
|
|
printf("ext_drv_mailbox_init err\n");
|
|
return ret;
|
|
}
|
|
#ifdef CONFIG_CPU_T9
|
|
slave_run_time.addr = SLAVE_BOOT_RUN_START_ADDR;
|
|
slave_run_time.len = SLAVE_BOOT_RUN_END_ADDR - SLAVE_BOOT_RUN_START_ADDR;
|
|
#else
|
|
slave_run_time.addr = SLAVE_BOOT_START_ADDR;
|
|
slave_run_time.len = SLAVE_BOOT_LEN;
|
|
#endif
|
|
|
|
prepare_panel_param();
|
|
|
|
ret = ext_drv_pdm_prepare_slave_boot_env(&slave_run_time, &slave_env_info);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("ext_drv_pdm_prepare_slave_boot_env err\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = ext_drv_mailbox_send_data(&slave_env_info, sizeof(slave_env_info));
|
|
if (ret != TD_SUCCESS) {
|
|
printf("ext_drv_mailbox_send_data err\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = ext_drv_mailbox_send_msg(EXT_DRV_MAILBOX_SLAVE_BOOT_ENV_READY);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("ext_drv_mailbox_mater_send_msg err\n");
|
|
return ret;
|
|
}
|
|
|
|
partition_name = get_partition_fullname("slaveboot");
|
|
if (partition_name == NULL) {
|
|
printf("[%s]: %d, get_partition_fullname failed.\n", __func__, __LINE__);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
#ifndef SOCT_ADVCA_TYPE_AVB
|
|
if (is_usb_selfboot()) {
|
|
load_slaveboot_by_usb();
|
|
} else {
|
|
flash = ext_flash_open_by_name(partition_name);
|
|
if (flash == TD_INVALID_HANDLE) {
|
|
printf("load slave boot fail\n");
|
|
return ret;
|
|
}
|
|
|
|
read_len = ext_flash_read(flash, 0, (td_u8 *)SLAVE_BOOT_START_ADDR, SLAVE_BOOT_LEN, UAPI_FLASH_RW_FLAG_RAW);
|
|
if (read_len <= 0) {
|
|
ext_flash_close(flash);
|
|
return ret;
|
|
}
|
|
|
|
ext_flash_close(flash);
|
|
}
|
|
#else
|
|
ret = hvb_verify_partition(partition_name, 0);
|
|
if (ret != TD_SUCCESS) {
|
|
partition_exception();
|
|
}
|
|
#endif
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static void init_before_slave_boot(void)
|
|
{
|
|
int ret;
|
|
|
|
if (g_boot_custom.prepare_slaveboot) {
|
|
ret = g_boot_custom.prepare_slaveboot();
|
|
if (ret != 0) {
|
|
printf("custom prepare slaveboot failed, ret = %d\n", ret);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void init_prepare_os(void)
|
|
{
|
|
int ret;
|
|
if (g_boot_custom.prepare_os) {
|
|
ret = g_boot_custom.prepare_os();
|
|
if (ret != 0) {
|
|
printf("custom prepare_os failed, ret = %d\n", ret);
|
|
}
|
|
}
|
|
}
|
|
|
|
static td_s32 get_partition_info(const char* part_name, td_handle* flash_handle,
|
|
ext_flash_internal_info *flash_info_out)
|
|
{
|
|
td_s32 ret;
|
|
td_handle flash;
|
|
ext_flash_internal_info flash_info;
|
|
|
|
flash = ext_flash_open_by_name(part_name);
|
|
if (flash == TD_INVALID_HANDLE) {
|
|
soc_log_err("open %s partition failed\n", part_name);
|
|
return TD_FAILURE;
|
|
}
|
|
ret = memset_s(&flash_info, sizeof(flash_info), 0x00, sizeof(flash_info));
|
|
if (ret != EOK) {
|
|
soc_log_err("Call memset_s Failed, ret:%d\n", ret);
|
|
ext_flash_close(flash);
|
|
return ret;
|
|
}
|
|
ret = ext_flash_get_info(flash, &flash_info);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("Call ext_flash_get_info Failed, ret:%d\n", ret);
|
|
ext_flash_close(flash);
|
|
return ret;
|
|
}
|
|
|
|
ret = memcpy_s(flash_info_out, sizeof(ext_flash_internal_info), &flash_info, sizeof(flash_info));
|
|
if (ret != EOK) {
|
|
soc_log_err("Call memcpy_s Failed, ret:%d\n", ret);
|
|
ext_flash_close(flash);
|
|
return ret;
|
|
}
|
|
*flash_handle = flash;
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 repair_partition(const char* dst_part, const char* src_part)
|
|
{
|
|
td_s32 ret, read_len, write_len;
|
|
td_handle flash_handle_src, flash_handle_dst;
|
|
ext_flash_internal_info flash_info_src, flash_info_dst;
|
|
td_u8 *data_buf = NULL;
|
|
|
|
if (src_part == NULL || dst_part == NULL) {
|
|
soc_log_err("input partition is NULL, repair partition failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
/* get src partition info, flash_handle should be close after finished */
|
|
ret = get_partition_info(src_part, &flash_handle_src, &flash_info_src);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("get partition %s info failed\n", src_part);
|
|
return ret;
|
|
}
|
|
|
|
/* get dst partition info, flash_handle should be close after finished */
|
|
ret = get_partition_info(dst_part, &flash_handle_dst, &flash_info_dst);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("get partition %s info failed\n", dst_part);
|
|
goto flash_err1;
|
|
}
|
|
|
|
if (flash_info_dst.part_size < flash_info_src.part_size) {
|
|
soc_log_err("dst partition size:0x%x < src partition size:0x%x\n",
|
|
flash_info_dst.part_size, flash_info_src.part_size);
|
|
ret = TD_FAILURE;
|
|
goto flash_err2;
|
|
}
|
|
|
|
data_buf = (td_u8 *)malloc(flash_info_src.part_size);
|
|
if (data_buf == NULL) {
|
|
soc_log_err("malloc data buf failed\n");
|
|
ret = TD_FAILURE;
|
|
goto flash_err2;
|
|
}
|
|
|
|
read_len = ext_flash_read(flash_handle_src, 0, (td_u8 *)data_buf,
|
|
flash_info_src.part_size, UAPI_FLASH_RW_FLAG_RAW);
|
|
if (read_len <= 0) {
|
|
soc_log_err("ext_flash_read %s failed\n", src_part);
|
|
ret = TD_FAILURE;
|
|
goto flash_err3;
|
|
}
|
|
|
|
write_len = ext_flash_write(flash_handle_dst, 0, (td_u8 *)data_buf,
|
|
flash_info_src.part_size, UAPI_FLASH_RW_FLAG_RAW);
|
|
if (write_len <= 0) {
|
|
soc_log_err("ext_flash_write %s failed\n", dst_part);
|
|
ret = TD_FAILURE;
|
|
goto flash_err3;
|
|
}
|
|
ret = TD_SUCCESS; /* repair done */
|
|
|
|
flash_err3:
|
|
free(data_buf);
|
|
flash_err2:
|
|
ext_flash_close(flash_handle_dst);
|
|
flash_err1:
|
|
ext_flash_close(flash_handle_src);
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 verify_repair_panel(void)
|
|
{
|
|
#ifdef SOCT_ADVCA_TYPE_AVB
|
|
if (hvb_verify_partition("panel", 0) != TD_SUCCESS) {
|
|
printf("verify panel partition failed.\n");
|
|
if (hvb_verify_partition("panelbak", 0) != TD_SUCCESS) {
|
|
printf("verify panelbak partition failed.\n");
|
|
return TD_FAILURE;
|
|
} else { // repair panel partition
|
|
if (repair_partition("panel", "panelbak") != TD_SUCCESS) {
|
|
printf("repair partition panel failed\n");
|
|
return TD_FAILURE;
|
|
} else {
|
|
printf("repair partition panel with panelbak success.\n");
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
int run_slaveboot_entry(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = verify_repair_panel();
|
|
if (ret != TD_SUCCESS) {
|
|
printf("verify panel fail.\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = load_slave_boot();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("load_slave_boot fail \n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
#if defined(CHIP_TYPE_RESERVED19) || defined(CHIP_TYPE_RESERVED9) || defined(CHIP_TYPE_HI3751V811)
|
|
#if defined(SOCT_BUILD_WITH_PMOC)
|
|
if (!is_usb_selfboot()) {
|
|
ext_drv_pm_process();
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
init_before_slave_boot();
|
|
|
|
ret = reset_slaveboot();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_disp("reset_slaveboot fail \n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 main_boot_app_entry(td_void)
|
|
{
|
|
#ifdef SOCT_ADVCA_TYPE_AVB
|
|
static const char* g_requested_partitions[] = {
|
|
"boot",
|
|
"system",
|
|
"vendor",
|
|
NULL
|
|
};
|
|
#endif
|
|
#if defined(CHIP_TYPE_RESERVED23)
|
|
rpmsg_init();
|
|
#endif
|
|
|
|
#ifdef CONFIG_SOCT_LICENSE_SUPPORT
|
|
ext_license_load_img();
|
|
#endif
|
|
fdt_modify_kaslr();
|
|
ext_drv_pdm_set_tag_data();
|
|
|
|
loader_upgrade_entry();
|
|
|
|
#ifdef SOCT_ANDROID_BOOT_SUPPORT
|
|
set_serialno();
|
|
if (g_boot_custom.set_mac == NULL) {
|
|
eth_addr_process();
|
|
} else {
|
|
g_boot_custom.set_mac();
|
|
}
|
|
|
|
#ifdef SOCT_CMDLINE_SUPPORT
|
|
create_cmdline();
|
|
#endif
|
|
#endif
|
|
/* prepare resource before start kernel and enter recovery */
|
|
init_prepare_os();
|
|
|
|
#ifdef SOCT_ANDROID_BOOT_SUPPORT
|
|
load_recovery();
|
|
#ifdef SOCT_ADVCA_TYPE_AVB
|
|
if (avb_entry((const char* const*)g_requested_partitions, BOOT_KERNEL) != TD_SUCCESS) {
|
|
do_reset (NULL, 0, 0, NULL);
|
|
}
|
|
#else
|
|
get_active_slot();
|
|
#endif
|
|
#endif
|
|
#ifdef SOCT_TVOS_O_BOOT_SUPPORT
|
|
printf("tvos_o load recover\n");
|
|
load_recovery();
|
|
#endif
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
int app_aging_entry(void)
|
|
{
|
|
#ifndef SOCT_BOOT_FBL
|
|
#ifdef SOCT_SUPPORT_AGING
|
|
aging_entry();
|
|
#endif
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
#ifndef SLAVE_BOOT_ENV
|
|
static void mainboot_app_entry(void)
|
|
{
|
|
#ifndef SOCT_BOOT_FBL
|
|
td_s32 ret;
|
|
ret = main_boot_app_entry();
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call main_boot_app_entry fail\n");
|
|
}
|
|
|
|
printf("run main boot app done.\n");
|
|
#endif
|
|
}
|
|
#else
|
|
static void slaveboot_app_entry(void)
|
|
{
|
|
td_s32 ret;
|
|
ret = slave_boot_app_entry();
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call slave_boot_app_entry fail\n");
|
|
}
|
|
|
|
loader_upgrade_entry();
|
|
|
|
if (is_usb_selfboot()) {
|
|
loader_base_init(LOADER_BARE_BURN);
|
|
loader_base_deinit(loader_mandatory_upgrade());
|
|
}
|
|
|
|
ret = ext_drv_mailbox_send_msg(EXT_DRV_MAILBOX_SLAVE_BOOT_RUN_COMPLETE);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call ext_drv_mailbox_send_msg fail\n");
|
|
}
|
|
|
|
printf("run slave boot app done.\n");
|
|
}
|
|
#endif
|
|
|
|
int fastapp_entry(void)
|
|
{
|
|
#ifndef SLAVE_BOOT_ENV
|
|
mainboot_app_entry();
|
|
#else
|
|
slaveboot_app_entry();
|
|
#endif
|
|
return TD_SUCCESS;
|
|
}
|