3522 lines
109 KiB
C
Executable File
3522 lines
109 KiB
C
Executable File
/*
|
|
Main control function
|
|
|
|
This file is implement by user mode
|
|
|
|
@file bl_func.c
|
|
|
|
Copyright Novatek Microelectronics Corp. 2014. All rights reserved.
|
|
*/
|
|
|
|
#include "fuart.h"
|
|
#include "fat.h"
|
|
#include "rtc.h"
|
|
#include "timer.h"
|
|
#include "StorageDef.h"
|
|
#include "global.h"
|
|
#include "Clock.h"
|
|
#include "bl_func.h"
|
|
#include "Cache.h"
|
|
#include "string.h"
|
|
#include "lz.h"
|
|
#include "debug.h"
|
|
#include "CC.h"
|
|
#include "loader.h"
|
|
#include "nvtpack.h"
|
|
#include "dram_partition_info.h"
|
|
#include "emb_partition_info.h"
|
|
#include "modelext_parser.h"
|
|
#include "bin_info.h"
|
|
#include "shm_info.h"
|
|
#include "gic.h"
|
|
#include "libfdt.h"
|
|
#include <stdlib.h>
|
|
#include "bl_u2.h"
|
|
#include "crypto.h"
|
|
#include "nand.h"
|
|
#include "nor.h"
|
|
|
|
//#if (LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
//static uint32_t global_timer_freq = 3000000; //3MHz = 3000000 Hz
|
|
//#endif
|
|
PSTORAGE_OBJ int_strg_obj = NULL;
|
|
|
|
#define FW_PART1_SIZE_OFFSET (CODE_SECTION_OFFSET + 0x04) //ref to CodeInfo.S on rtos (addr of _section_01_size)
|
|
//#define TEE_HEADER_SIZE 0x1C // refer to: optee_header_t
|
|
|
|
#define _THUMB2 __attribute__((target("thumb2")))
|
|
|
|
#define bl_memcpy utl_memcpy
|
|
#define bl_memset utl_memset
|
|
#define ALIGN_FLOOR(value, base) ((value) & ~((base)-1))
|
|
#define ALIGN_CEIL(value, base) ALIGN_FLOOR((value) + ((base)-1), base)
|
|
#define SIZE_PRELOAD 0x400
|
|
#define SIZE_PRESERVE_USB 0x2000
|
|
|
|
#define HEADINFO_UBOOT(p_parti) ((HEADINFO *)(p_parti->uboot_addr + BIN_INFO_OFFSET_UBOOT))
|
|
#define HEADINFO_TEEOS(p_parti) ((HEADINFO *)(p_parti->teeos_addr + BIN_INFO_OFFSET_TEEOS))
|
|
#define IS_BIN_OVERLAP(addr1, size1, addr2, size2) (!(((addr1 + size1 - 1) < addr2) || (addr1 > (addr2 + size2 - 1))))
|
|
|
|
#if (STORAGE_EXT_TYPE != STORAGE_EXT_USB)
|
|
extern void set_usb_suspend(void);
|
|
#endif
|
|
|
|
#if (_ROM_PUBLIC_API_ == 1)
|
|
#define ROM_LZMA_POSITION 0x7fd0
|
|
UINT8 lzma_temp_buffer[65536];
|
|
int (*rom_lzma_inflate)(UINT8 *in_ptr, UINT32 in_size, UINT8 *out_ptr, UINT32 out_size, UINT8 *p_tmp, UINT32 tmp_size);
|
|
#endif
|
|
|
|
extern char _loader_exec_compres_start[];
|
|
//extern char _load_nand_table_start_base[];
|
|
extern char _load_LOADER_CONFIGRAM_FREQ_PARAM_end_base[];
|
|
extern void core1_reset(void);
|
|
|
|
// Function from Timer.c
|
|
//extern UINT32 timer_getLdrElapse(void);
|
|
|
|
// Define in MakeConfig.txt
|
|
static UINT8 UPDATE_FW_NAME[] = {"FW98520A.BIN"};
|
|
static UINT8 UPDATE_LOADER_NAME[] = {"LD98520A.BIN"};
|
|
static UINT8 RUN_FW_NAME[] = {"FW98520T.BIN"};
|
|
static UINT8 *LOADER_START_STR = {(UINT8 *)"\r\nLoader Start ..."};
|
|
//#if !USB_WRITELOADER
|
|
#if (STORAGE_EXT_TYPE != STORAGE_EXT_USB)
|
|
//static UINT8 *RUN_WRKEY_NAME = {(UINT8 *)"WRKEY.BIN"};
|
|
#if UPDATE_SIM_CODE
|
|
static UINT8 *RUN_WRKEY_NAME = {(UINT8 *)"SIM.BIN"};
|
|
#endif
|
|
#endif
|
|
static UINT8 RECOVERY_FW_NAME[] = {"FW98520R.BIN"};
|
|
static UINT32 g_uiPartitionID = 2;
|
|
|
|
static UINT32 g_uiVersion = 0;
|
|
|
|
// Error message
|
|
static char FWErrorMsg[] = "\r\nFW check fail\r\n";
|
|
static char RWErrorMsg[] = "\r\nR/W error\r\n";
|
|
static char LoaderErrorMsg[] = "\r\nLoader check fail\r\n";
|
|
|
|
UINT32 TopOfStack;
|
|
UINT32 BaseOfStack;
|
|
|
|
extern char _loader_heap_base[];
|
|
|
|
static BOOL g_is_flash_open = FALSE; // indicate flash is open for updating non-fully all-in-one bin.
|
|
|
|
static LDR_FASTBOOT_KEY_CB gFastbootKeyCallBack = NULL;
|
|
static LDR_SPECIAL_KEY_CB gSpecialKeyCallBack = NULL;
|
|
static LDR_CARD_DETECT_CB gCardDetectCallBack = NULL;
|
|
static STORAGEINT gStorageIntType = STORAGEINT_UNOKNOWN;
|
|
static LDR_SPECIAL_KEY_CB gsfSpecialKeyCallBack = NULL;
|
|
|
|
static LDR_RECOVERY_TRIGGER_CB gRecoveryTriggerCallBack = NULL;
|
|
//#if (!USB_WRITELOADER)
|
|
//#if (STORAGE_EXT_TYPE != STORAGE_EXT_USB)
|
|
//static BOOL g_is_recovery_triggered = FALSE; // indicate recovery flow is triggered.
|
|
//#endif
|
|
|
|
|
|
_THUMB2 static int bl_is_smp(unsigned char *p_fdt);
|
|
static UINT32 g_uiStartBlkUpdateFW = StartNandBlkUpdateFW;
|
|
static UINT32 g_uiNandBlkSize = 0;
|
|
static UINT32 g_rtos_load_addr = 0;
|
|
static UINT32 g_rtos_target_addr = 0;
|
|
static UINT32 g_rtos_size = 0;
|
|
static UINT32 g_update_from_emmc = 0;
|
|
|
|
|
|
#if (FDT_SUPPORT)
|
|
#define PATH_MEM_DRAM "/nvt_memory_cfg/dram"
|
|
#define PATH_MEM_LOADER "/nvt_memory_cfg/loader"
|
|
#define PATH_MEM_UBOOT "/nvt_memory_cfg/uboot"
|
|
#define PATH_MEM_FDT "/nvt_memory_cfg/fdt"
|
|
#define PATH_MEM_SHMEM "/nvt_memory_cfg/shmem"
|
|
#define PATH_MEM_RTOS "/nvt_memory_cfg/rtos"
|
|
#define PATH_MEM_NUTTX "/nvt_memory_cfg/nuttx"
|
|
#define PATH_MEM_TEEOS "/nvt_memory_cfg/teeos"
|
|
#define PATH_MEM_HDAL "/hdal-memory/media"
|
|
#define PATH_MEM_CORE2_ENTRY1 "/nvt_memory_cfg/core2entry1"
|
|
#define PATH_MEM_CORE2_ENTRY2 "/nvt_memory_cfg/core2entry2"
|
|
#define PATH_NVT_INFO "/nvt_info"
|
|
#define PATH_NVTPACK_INDEX "nvtpack/index"
|
|
#define PATH_PARTITION_LOADER "partition_loader"
|
|
#define PATH_PARTITION_FDT "partition_fdt"
|
|
#define PATH_PARTITION_UBOOT "partition_uboot"
|
|
#define PATH_PARTITION_NUTTX "partition_nuttx"
|
|
#define PATH_PARTITION_TEEOS "partition_teeos"
|
|
#define PATH_PARTITION_RTOS "partition_rtos"
|
|
#define PATH_PARTITION_SYS "partition_sys"
|
|
#define PROPERTY_REG "reg"
|
|
#define PROPERTY_LABEL "label"
|
|
#define PROPERTY_PARTITION_NAME "partition_name"
|
|
#define PROPERTY_NVT_LINUX_SMP "NVT_LINUX_SMP"
|
|
static DRAM_PARTITION g_dram_partition = {0};
|
|
static EMB_PARTITION g_emb_uboot = {0};
|
|
static EMB_PARTITION g_emb_teeos = {0};
|
|
static EMB_PARTITION g_emb_rtos = {0};
|
|
static EMB_PARTITION g_emb_sys = {0};
|
|
#else // NO FDT_SUPPORT
|
|
// refer to met-tbl.dtsi /nvt_memory_cfg
|
|
static DRAM_PARTITION g_dram_partition = {
|
|
.dram_addr = 0x00000000,
|
|
.dram_size = 0x20000000,
|
|
.rev_addr = 0x00007E00, ///< shmem
|
|
.rev_size = 0x00000200, ///< shmem
|
|
.loader_addr = 0x01000000,
|
|
.loader_size = 0x00800000,
|
|
.fdt_addr = 0x01800000,
|
|
.fdt_size = 0x00040000,
|
|
.uboot_addr = 0x1E000000,
|
|
.uboot_size = 0x01FC0000,
|
|
.rtos_addr = 0x01840000, ///< optional, only for fast-boot,
|
|
.rtos_size = 0x00780000, ///< optional, only for fast-boot
|
|
.core2_entry1_addr = 0x00000000, ///< optional, only for dual core IC (fixed here, and must be)
|
|
.core2_entry1_size = 0x00004000, ///< optional, only for dual core IC
|
|
.core2_entry2_addr = 0x1FFC0000, ///< optional, only for dual core IC (address better in the bottom of dram to avoid memory space overlap)
|
|
.core2_entry2_size = 0x00040000, ///< optional, only for dual core IC
|
|
};
|
|
// refer to storage-partition.dtsi
|
|
static EMB_PARTITION g_emb_uboot = {
|
|
.PartitionOffset = 0xC0000,
|
|
.PartitionSize = 0xA0000,
|
|
};
|
|
static EMB_PARTITION g_emb_rtos = { ///< optional, only for fast-boot,
|
|
.PartitionOffset = 0x2B40000,
|
|
.PartitionSize = 0xA00000,
|
|
};
|
|
static EMB_PARTITION g_emb_teeos = { ///< optional, only for optee,
|
|
.PartitionOffset = 0,
|
|
.PartitionSize = 0,
|
|
};
|
|
//following just for processing all-in-one bin (nvtpack)
|
|
//refer to nvtpack.dtsi
|
|
#define NVTPACK_IDX_UBOOT 3
|
|
#define NVTPACK_IDX_TEEOS -1
|
|
#define NVTPACK_IDX_RTOS 10
|
|
#endif
|
|
|
|
|
|
|
|
#if (UART_UPDATE_ == ENABLE)
|
|
static char g_strLength[80]; // buffer to store length string
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Static function
|
|
//---------------------------------------------------------------------------
|
|
int bl_boot_uboot(unsigned char *p_fdt);
|
|
|
|
/**
|
|
Display error message.
|
|
|
|
Display error message.
|
|
CPU loop forever and LED is red.
|
|
|
|
@param Msg: Message to display
|
|
@return void
|
|
*/
|
|
_THUMB2 static void bl_displayErrMsg(char *Msg)
|
|
{
|
|
// Display error message to UART
|
|
debug_msg(Msg);
|
|
// Loop forever
|
|
while (1) {
|
|
;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
Invert endianess of input word
|
|
|
|
|
|
@param[in] a input word
|
|
|
|
@return translated word
|
|
*/
|
|
_THUMB2 static UINT32 invertEndian(UINT32 a)
|
|
{
|
|
return __builtin_bswap32(a);
|
|
}
|
|
|
|
|
|
/**
|
|
Check FW code.
|
|
|
|
Check FW code and file length.
|
|
The FW binary file must be post-proecessd by encrypt_bin.exe.
|
|
This function must sync to encrypt_bin.exe.
|
|
If FW checking is fail, the CPU will loop forever and LED is red.
|
|
|
|
@param[in] uiAddress FW code in DRAM starting address
|
|
@param[in] uiFileLen FW code length
|
|
@return void
|
|
*/
|
|
_THUMB2 static void bl_checkFW(UINT32 uiAddress, UINT32 uiFileLen)
|
|
{
|
|
NVTPACK_MEM mem = {0};
|
|
mem.p_data = (void *)uiAddress;
|
|
mem.len = uiFileLen;
|
|
if (nvtpack_calc_nvt_sum(&mem) != 0) {
|
|
bl_displayErrMsg(FWErrorMsg);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Check boot loader code.
|
|
|
|
Check boot loader code.
|
|
|
|
@return void
|
|
*/
|
|
_THUMB2 static void bl_checkLoader(UINT32 uiAddr, UINT32 uiSize)
|
|
{
|
|
UINT16 *puiValue, uiSum;
|
|
UINT32 i;
|
|
|
|
puiValue = (UINT16 *)uiAddr;
|
|
uiSum = 0;
|
|
|
|
for (i = 0; i < (uiSize >> 1); i++) {
|
|
uiSum += (*puiValue + i);
|
|
puiValue++;
|
|
}
|
|
|
|
if ((*(UINT16 *)(uiAddr + LOADER_TAG_OFFSET) != LOADER_TAG_VALUE) ||
|
|
(uiSum != 0)) {
|
|
bl_displayErrMsg(LoaderErrorMsg);
|
|
}
|
|
}
|
|
#if (SECURE_DECRYPT_UBOOT || SECURE_DECRYPT_OPTEE_OS)
|
|
|
|
|
|
_THUMB2 static void get_bininfo_size_offset(unsigned char* bininfo,unsigned int* size,unsigned int *offset)
|
|
{
|
|
/****this headinfo is for encrypt header
|
|
BinInfo will set partition offset and size
|
|
BinInfo_1[0~3] public key offset
|
|
BinInfo_1[4~7] public key length
|
|
BinInfo_2[0~3] signature offset
|
|
BinInfo_2[4~7] signature length
|
|
BinInfo_3[0~3] encrypted offset
|
|
BinInfo_3[4~7] encrypted size
|
|
BinLength total bin size
|
|
Checksum total bin checksum
|
|
others parameters set 0
|
|
*/
|
|
*size = bininfo[4] | bininfo[5]<<8 | bininfo[6] << 16 | bininfo[7] << 24;
|
|
*offset = bininfo[0] | bininfo[1] << 8 | bininfo[2] << 16 | bininfo[3] <<24;
|
|
}
|
|
|
|
|
|
|
|
|
|
_THUMB2 static int decrypt_aes_cbc(unsigned int input, unsigned int output, unsigned int len)
|
|
{
|
|
|
|
CRYPT_OP crypt_op_param;
|
|
if(len &0x0f)
|
|
{
|
|
debug_msg_var("enc size", len);
|
|
debug_err("not align 16\r\n");
|
|
return -21;
|
|
}
|
|
if((input & 0x03) || (output & 0x03) || (len & 0x03) ){ //check word alignment
|
|
//debug_msg_var("input", input);
|
|
//debug_msg_var("output", output);
|
|
//debug_msg_var("len", len);
|
|
//debug_err("not word align\r\n");
|
|
return -22;
|
|
}
|
|
crypt_op_param.op_mode = CRYPTO_CBC;
|
|
crypt_op_param.en_de_crypt = CRYPTO_DECRYPT;
|
|
crypt_op_param.src_addr = input;
|
|
crypt_op_param.dst_addr = output;
|
|
crypt_op_param.length = len; //Need align to 16bytes align
|
|
//debug_msg_var("src",(unsigned int)crypt_op_param.src_addr);
|
|
//debug_msg_var("dst",(unsigned int)crypt_op_param.dst_addr);
|
|
|
|
#if 0
|
|
debug_msg_var("input",input);
|
|
debug_msg_var("output",output);
|
|
debug_msg_var("len",len);
|
|
unsigned char *tmp = (unsigned char *) crypt_op_param.src_addr;
|
|
int i=0;
|
|
debug_msg_var("encryped buf addr",(unsigned int)tmp);
|
|
for(i=0;i<16;i++){
|
|
debug_msg_var("encryped buf",(unsigned int)tmp[i]);
|
|
}
|
|
#endif
|
|
if(crypto_data_operation(EFUSE_OTP_1ST_KEY_SET_FIELD, crypt_op_param) != 0)
|
|
{
|
|
//debug_err("aes dec fail\r\n");
|
|
return -23;
|
|
}
|
|
#if 0
|
|
unsigned char *tmp = (unsigned char *) crypt_op_param.src_addr;
|
|
int i=0;
|
|
tmp = (unsigned char *) crypt_op_param.dst_addr;
|
|
debug_msg_var("decryped addr",(unsigned int)&tmp[0]);
|
|
for(i=0;i<16;i++){
|
|
debug_msg_var("decryped buf",(unsigned int)tmp[i]);
|
|
}
|
|
|
|
#endif
|
|
return 0;
|
|
|
|
}
|
|
#if (SECURE_SIGNATURE_BY_AES == 0)
|
|
_THUMB2 static void data_reverse(unsigned char* input_data, unsigned int size)
|
|
{
|
|
unsigned int i=0;
|
|
unsigned char tmp=0;
|
|
for(i=0;i< (size/2);i++)
|
|
{
|
|
tmp = input_data[size - 1 - i];
|
|
input_data[size - 1 - i] = input_data[i];
|
|
input_data[i] = tmp;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
_THUMB2 static int do_decrypt_aes(unsigned int input_data, unsigned int output_data, unsigned int* output_size,unsigned int partition_size)
|
|
{
|
|
|
|
unsigned int encrypt_offset =0;
|
|
unsigned int encrypt_size =0;
|
|
unsigned int data_size = 0;
|
|
HEADINFO *p_headinfo = (HEADINFO *)input_data;
|
|
int er=0;
|
|
get_bininfo_size_offset((unsigned char *)p_headinfo->BinInfo_3, &encrypt_size, &encrypt_offset);
|
|
data_size = p_headinfo->BinLength - encrypt_offset;
|
|
#if 1 //for signature check
|
|
unsigned int signature_offset =0;
|
|
unsigned int signature_size = 0;
|
|
UINT32 hash_buf[8];
|
|
unsigned int sha256_align_size =0;
|
|
UINT32 * signature_buff = NULL;
|
|
get_bininfo_size_offset((unsigned char *)p_headinfo->BinInfo_2, &signature_size, &signature_offset);
|
|
#if (SECURE_SIGNATURE_BY_AES == 0)
|
|
unsigned int key_offset =0;
|
|
unsigned int key_size =0;
|
|
unsigned int n_size=0;
|
|
unsigned int e_size=0;
|
|
UINT32 sign_rsa_output[64];
|
|
UINT32 *key_n = NULL;
|
|
UINT32 *key_e = NULL;
|
|
UINT32 *signature_addr = NULL;
|
|
get_bininfo_size_offset((unsigned char *)p_headinfo->BinInfo_1, &key_size, &key_offset);
|
|
n_size = signature_size;// if rsa 2048 , signature_size should be 256 bytes
|
|
e_size = key_size - n_size;
|
|
key_n = (UINT32 *)(input_data + key_offset);
|
|
// now only support rsa 2048
|
|
key_e = (UINT32 *)(input_data + key_offset + signature_size); // signature_size should be 256 bytes, n key should be 256
|
|
data_reverse((unsigned char *)(key_n),n_size);
|
|
data_reverse((unsigned char *)(key_e),e_size);
|
|
|
|
er = rsa_keycheck(key_n, 1);// check rsa n key in efuse 1 and 2 field, 0 field for aes key
|
|
if(er == 0)
|
|
{
|
|
debug_err("key fail\r\n");
|
|
return -20;
|
|
}
|
|
signature_addr = (UINT32 *)(input_data + signature_offset);
|
|
data_reverse((unsigned char *)signature_addr, signature_size);
|
|
|
|
//decrypt signature
|
|
rsa_decrypt(signature_addr, signature_size, key_n, n_size, key_e, e_size,sign_rsa_output);
|
|
|
|
data_reverse((unsigned char *)sign_rsa_output, signature_size);
|
|
|
|
//remove pending data 0, the last 32 bytes will be signature data
|
|
signature_buff = (UINT32 *)&sign_rsa_output[(sizeof(sign_rsa_output)/4 ) - (32/4 )];// offset need devided by 4, because of UINT32 type
|
|
#else
|
|
//UINT32 sign_aes_output[8];
|
|
|
|
er = decrypt_aes_cbc((UINT32 )(input_data + signature_offset), output_data,signature_size);
|
|
if(er != 0)
|
|
{
|
|
debug_err("decrypt_aes_cbc fail\r\n");
|
|
return -20;
|
|
}
|
|
signature_buff =(UINT32 *)output_data;
|
|
|
|
#endif
|
|
//hash encrypt data
|
|
|
|
if((data_size & 0x3f) != 0)
|
|
{
|
|
// hardware sha256 need align 64, need set pending 0
|
|
sha256_align_size = ((data_size/0x40) + 1)*0x40;
|
|
bl_memset((unsigned char *)(input_data + encrypt_offset + data_size),0, sha256_align_size - data_size);
|
|
}
|
|
else
|
|
{
|
|
sha256_align_size = data_size;
|
|
}
|
|
|
|
shahw((unsigned char *)(input_data + encrypt_offset), sha256_align_size, hash_buf);
|
|
|
|
|
|
//compare signature and current hash
|
|
if(memcmp((void *)hash_buf, (void *)signature_buff, sizeof(hash_buf)) != 0)
|
|
{
|
|
debug_err("sig fail\r\n");
|
|
return -20;
|
|
}
|
|
#endif
|
|
|
|
//decrypt data
|
|
//dma addr should 4 alignment, input_data address is 4 alignment
|
|
if((input_data + encrypt_offset) & 0x03)
|
|
{
|
|
utl_memcpy((void *)input_data,(unsigned char*)(input_data + encrypt_offset), data_size);
|
|
er = decrypt_aes_cbc(input_data, output_data, encrypt_size);
|
|
}
|
|
else
|
|
{
|
|
er = decrypt_aes_cbc(input_data + encrypt_offset, output_data, encrypt_size);
|
|
}
|
|
if(er != 0)
|
|
{
|
|
debug_err("aes fail\r\n");
|
|
return er;
|
|
}
|
|
|
|
*output_size = data_size;
|
|
|
|
//add plaintext data to output buf--> aes should 16 alignment, if data not alignment, the last bytes we will not encrypt data
|
|
int plaintext_size = data_size - encrypt_size;
|
|
unsigned char *p_output = (unsigned char *)output_data;
|
|
if( plaintext_size > 0)
|
|
{
|
|
utl_memcpy(&p_output[encrypt_size], (unsigned char*)(input_data + encrypt_offset+ encrypt_size),plaintext_size);
|
|
}
|
|
return 0;
|
|
|
|
}
|
|
#endif
|
|
|
|
//#NT#2013/04/25#Steven Wang -begin
|
|
//#NT#Show Duty calibration log
|
|
#if (_LOADER_DUTY_CALIBRATION_ == ENABLE && _LOADER_DUTY_CALIBRATION_LOG_ == ENABLE)
|
|
void BL_showROMLog(UINT32 buffer)
|
|
{
|
|
UINT32 value;
|
|
UINT32 index;
|
|
UINT32 P_duty;
|
|
UINT32 N_duty;
|
|
UINT32 diff;
|
|
|
|
index = 0;
|
|
diff = 0;
|
|
P_duty = 0;
|
|
N_duty = 0;
|
|
uart_putSystemUARTStr("\r\n");
|
|
while (1) {
|
|
value = INREG32(buffer + index);
|
|
|
|
if ((value & 0xF0000000) == 0xF0000000) {
|
|
value &= ~(0x40000000);
|
|
uart_putSystemUARTStr(Dec2HexStr(value));
|
|
uart_putSystemUARTStr(" = ");
|
|
}
|
|
|
|
else if ((value & 0xF0000000) == 0x50000000) {
|
|
uart_putSystemUARTStr(Dec2HexStr(value & 0xFFFFFFF));
|
|
uart_putSystemUARTStr("\r\n");
|
|
}
|
|
|
|
else if ((value & 0xF0000000) == 0x20000000) {
|
|
// uart_putSystemUARTStr("P_duty = ");
|
|
P_duty = value & 0xFFFFFFF;
|
|
//uart_putSystemUARTStr(Dec2HexStr(value & 0xFFFFFFF));
|
|
uart_putSystemUARTStr(Dec2HexStr(P_duty));
|
|
uart_putSystemUARTStr("\r\n");
|
|
}
|
|
|
|
else if ((value & 0xF0000000) == 0x30000000) {
|
|
// uart_putSystemUARTStr("N_duty = ");
|
|
N_duty = value & 0xFFFFFFF;
|
|
//uart_putSystemUARTStr(Dec2HexStr(value & 0xFFFFFFF));
|
|
uart_putSystemUARTStr(Dec2HexStr(N_duty));
|
|
uart_putSystemUARTStr("\r\n");
|
|
if (P_duty > N_duty) {
|
|
if (diff == 2) {
|
|
uart_putSystemUARTStr("============\r\n");
|
|
P_duty = 0;
|
|
N_duty = 0;
|
|
diff = 0;
|
|
// diff = 3;
|
|
} else {
|
|
diff = 1;
|
|
}
|
|
} else {
|
|
if (diff == 1) {
|
|
uart_putSystemUARTStr("============\r\n");
|
|
P_duty = 0;
|
|
N_duty = 0;
|
|
diff = 0;
|
|
// diff = 3;
|
|
} else {
|
|
diff = 2;
|
|
}
|
|
}
|
|
} else if ((value & 0xF0000000) == 0x60000000) {
|
|
uart_putSystemUARTStr("N+P = ");
|
|
uart_putSystemUARTStr(Dec2HexStr(value & 0xFFFFFFF));
|
|
uart_putSystemUARTStr("\r\n");
|
|
} else if ((value & 0xF0000000) == 0x70000000) {
|
|
if ((value & 0xFFFFFFF) == 0x0654321) {
|
|
break;
|
|
}
|
|
} else {
|
|
uart_putSystemUARTStr("Unknow \r\n");
|
|
}
|
|
index += 4;
|
|
}
|
|
uart_putSystemUARTStr("\r\n[0xC0001000] = 0x");
|
|
uart_putSystemUARTStr(Dec2HexStr(INREG32(0xC0001000)));
|
|
uart_putSystemUARTStr(" [0xC000101C] = 0x");
|
|
uart_putSystemUARTStr(Dec2HexStr(INREG32(0xC000101C)));
|
|
uart_putSystemUARTStr("\r\n");
|
|
}
|
|
#endif
|
|
//#NT#2013/04/25#Steven Wang -end
|
|
|
|
|
|
#if (DRAM_RANGE_SCAN_EN == ENABLE)
|
|
/**
|
|
Check Sram code.
|
|
|
|
Check is dram scan code or not
|
|
|
|
@param[in] uiAddress Scan FW code in DRAM starting address
|
|
@return void
|
|
*/
|
|
static BOOL bl_checkDramScanFW(UINT32 uiAddress)
|
|
{
|
|
if ((*(UINT32 *)uiAddress & SRAM_TAG) == SRAM_TAG) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
static BOOL bl_spiIdentify(UINT32 uiMfgID, UINT32 uiTypeID, UINT32 uiCapacityID, PSPI_IDENTIFY pIdentify)
|
|
{
|
|
// Sample to support SST25VF032
|
|
if ((uiMfgID == 0xBF) &&
|
|
(uiCapacityID == 0x4A)) {
|
|
pIdentify->bDualRead = FALSE;
|
|
pIdentify->bSupportAAI = TRUE;
|
|
pIdentify->bSupportEWSR = TRUE;
|
|
pIdentify->uiFlashSize = 4 * 1024 * 1024;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
Update multi-binary image
|
|
|
|
|
|
@param[in] uiFwBuf buffer store fw read from card
|
|
|
|
@return
|
|
-@ b TRUE: success
|
|
-@ b FALSE: fail
|
|
*/
|
|
|
|
#if !REMOVED_FLASH
|
|
#if 0
|
|
static void bl_interrupt_init(void)
|
|
{
|
|
debug_msg("arm_gic_distif_setup\r\n");
|
|
arm_gic_distif_setup();
|
|
debug_msg("arm_gic_cpuif_setup\r\n");
|
|
arm_gic_cpuif_setup();
|
|
|
|
//
|
|
//debug_dump_addr(0xF1500000+0x1000,0x500);
|
|
//debug_dump_addr(0xF1500000+0x2000,0x100);
|
|
}
|
|
#endif
|
|
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
#define OUTW(addr,value) (*(UINT32 volatile *)(addr) = (UINT32)(value))
|
|
#define INW(addr) (*(UINT32 volatile *)(addr))
|
|
|
|
|
|
static void bl_cpu_timer_init(UINT32 value)
|
|
{
|
|
UINT32 dwVal;
|
|
OUTW(configARM_TIMER_BASEADDR + ARM_TIMER_LOAD_OFFSET, value);
|
|
|
|
dwVal = INW(configARM_TIMER_BASEADDR + ARM_TIMER_CONTROL_OFFSET);
|
|
/* Enable Auto reload mode. */
|
|
dwVal |= ARM_TIMER_CONTROL_AUTO_RELOAD_MASK;
|
|
/* Clear prescaler control bits */
|
|
dwVal &= ~ARM_TIMER_CONTROL_PRESCALER_MASK;
|
|
/* Set prescaler value */
|
|
dwVal |= ((CYGHWR_HAL_RTC_PRESCALER - 1) << ARM_TIMER_CONTROL_PRESCALER_SHIFT);
|
|
/* Enable the decrementer */
|
|
//dwVal |= ARM_TIMER_CONTROL_ENABLE_MASK;
|
|
/* Enable the interrupt */
|
|
dwVal |= ARM_TIMER_CONTROL_IRQ_ENABLE_MASK;
|
|
|
|
OUTW(configARM_TIMER_BASEADDR + ARM_TIMER_CONTROL_OFFSET, dwVal);
|
|
|
|
OUTW(configARM_TIMER_BASEADDR + ARM_TIMER_ISR_OFFSET,
|
|
ARM_TIMER_ISR_EVENT_FLAG_MASK);
|
|
|
|
}
|
|
#endif
|
|
#endif
|
|
_THUMB2 int bl_flash_open(void)
|
|
{
|
|
int er = -1;
|
|
//UINT32 uiStorageVersion = (UINT32)&_load_nand_table_start_base;
|
|
|
|
if (g_is_flash_open) {
|
|
return 0;
|
|
}
|
|
//==========================================================================
|
|
//= User define SPI-NAND id table sample code =
|
|
//= You can remove // to use it =
|
|
//==========================================================================
|
|
//int_strg_obj->flash_setConfig(FLASH_CFG_ID_SPI_IDENTIFY_CB, (UINT32)nand_identify);
|
|
|
|
//==========================================================================
|
|
//= User define SPI-NOR id table sample code =
|
|
//= You can remove // to use it =
|
|
//==========================================================================
|
|
//int_strg_obj->flash_installIdentifyCB(nor_identify);
|
|
|
|
debug_msg("flash_open\r\n");
|
|
er = int_strg_obj->flash_open();
|
|
if (er < 0) {
|
|
debug_err("flash open fail\r\n");
|
|
return -1;
|
|
}
|
|
|
|
debug_msg("flash_open end\r\n");
|
|
|
|
//OUTREG32(NAND_TABLE_VERSION_ADDR, INREG32(uiStorageVersion));
|
|
|
|
//if (er == E_OK) {
|
|
// OUTREG32(NAND_TABLE_FLAG_ADDR, 0x46495053); //'S''P''I''F'
|
|
//} else { // E_OK_TABLE_FOUND(1) or E_OK_TABLE_NOT_FOUND(2)
|
|
// OUTREG32(NAND_TABLE_FLAG_ADDR, er);
|
|
//}
|
|
g_uiNandBlkSize = int_strg_obj->flash_getBlockSize();
|
|
if (g_uiNandBlkSize == 0x10000) {
|
|
debug_msg("SPI NOR\r\n");
|
|
g_uiStartBlkUpdateFW = 1;
|
|
} else if (g_uiNandBlkSize == EMMC_BLOCK_SIZE) {
|
|
debug_msg("EMMC\r\n");
|
|
g_uiStartBlkUpdateFW = FDT_OFFSET / EMMC_BLOCK_SIZE;
|
|
} else {
|
|
g_uiStartBlkUpdateFW = StartNandBlkUpdateFW;
|
|
}
|
|
g_is_flash_open = TRUE;
|
|
return 0;
|
|
}
|
|
|
|
#if 0 //[-Werror=unused-function]
|
|
static int bl_flash_close(void)
|
|
{
|
|
if (!g_is_flash_open) {
|
|
return 0;
|
|
}
|
|
|
|
flash_close();
|
|
g_is_flash_open = FALSE;
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if (FDT_SUPPORT)
|
|
_THUMB2 static const void *bl_get_fdt_property(const void *p_dtb, const char *p_path, const char *p_property, int *len)
|
|
{
|
|
int nodeoffset; /* next node offset from libfdt */
|
|
const void *nodep; /* property node pointer */
|
|
|
|
nodeoffset = fdt_path_offset(p_dtb, p_path);
|
|
if (nodeoffset < 0) {
|
|
return NULL;
|
|
}
|
|
nodep = fdt_getprop(p_dtb, nodeoffset, p_property, len);
|
|
if (len == 0) {
|
|
return NULL;
|
|
}
|
|
return nodep;
|
|
}
|
|
|
|
_THUMB2 static const void *bl_get_fdt_nvt_memory_cfg_property(const void *p_dtb, const char *p_path, const char *p_property, int *len)
|
|
{
|
|
static int nodeoffset_nvt_memory_cfg = -FDT_ERR_NOTFOUND;; /* next node offset from libfdt */
|
|
|
|
int nodeoffset;
|
|
const void *nodep; /* property node pointer */
|
|
|
|
if (strncmp(p_path, "/nvt_memory_cfg/", 3) != 0) {
|
|
debug_err("path prefix must be /nvt_memory_cfg/\r\n");
|
|
return NULL;
|
|
}
|
|
|
|
if (nodeoffset_nvt_memory_cfg == -FDT_ERR_NOTFOUND) {
|
|
nodeoffset_nvt_memory_cfg = fdt_path_offset(p_dtb, "/nvt_memory_cfg");
|
|
}
|
|
|
|
nodeoffset = fdt_subnode_offset(p_dtb, nodeoffset_nvt_memory_cfg, &p_path[16]);
|
|
//debug_msg_var("nodeoffset_nvt_memory_cfg", nodeoffset_nvt_memory_cfg);
|
|
//debug_msg_var("nodeoffset", nodeoffset);
|
|
|
|
if (nodeoffset < 0) {
|
|
return NULL;
|
|
}
|
|
nodep = fdt_getprop(p_dtb, nodeoffset, p_property, len);
|
|
//debug_msg_var("len", *len);
|
|
|
|
if (len == 0) {
|
|
return NULL;
|
|
}
|
|
return nodep;
|
|
}
|
|
#endif
|
|
|
|
|
|
_THUMB2 static unsigned char *bl_get_fdt_cfg(const void *p_dtb, MODELEXT_TYPE type)
|
|
{
|
|
#if (FDT_SUPPORT)
|
|
int len;
|
|
const int *nodep;
|
|
|
|
UINT8 *p_rt = NULL;
|
|
|
|
switch (type) {
|
|
case MODELEXT_TYPE_DRAM_PARTITION:
|
|
nodep = (const int *)bl_get_fdt_nvt_memory_cfg_property(p_dtb, PATH_MEM_DRAM, PROPERTY_REG, &len);
|
|
if (nodep == NULL) {
|
|
debug_err("dtb get dram fail\r\n");
|
|
return NULL;
|
|
}
|
|
g_dram_partition.dram_addr = be32_to_cpu(nodep[0]);
|
|
g_dram_partition.dram_size = be32_to_cpu(nodep[1]);
|
|
|
|
nodep = (const int *)bl_get_fdt_nvt_memory_cfg_property(p_dtb, PATH_MEM_LOADER, PROPERTY_REG, &len);
|
|
if (nodep == NULL) {
|
|
debug_err("dtb get loader fail\r\n");
|
|
return NULL;
|
|
}
|
|
g_dram_partition.loader_addr = be32_to_cpu(nodep[0]);
|
|
g_dram_partition.loader_size = be32_to_cpu(nodep[1]);
|
|
|
|
nodep = (const int *)bl_get_fdt_nvt_memory_cfg_property(p_dtb, PATH_MEM_UBOOT, PROPERTY_REG, &len);
|
|
if (nodep == NULL) {
|
|
debug_err("dtb get uboot fail\r\n");
|
|
return NULL;
|
|
}
|
|
g_dram_partition.uboot_addr = be32_to_cpu(nodep[0]);
|
|
g_dram_partition.uboot_size = be32_to_cpu(nodep[1]);
|
|
|
|
nodep = (const int *)bl_get_fdt_nvt_memory_cfg_property(p_dtb, PATH_MEM_FDT, PROPERTY_REG, &len);
|
|
if (nodep == NULL) {
|
|
debug_err("dtb get fdt fail\r\n");
|
|
return NULL;
|
|
}
|
|
g_dram_partition.fdt_addr = be32_to_cpu(nodep[0]);
|
|
g_dram_partition.fdt_size = be32_to_cpu(nodep[1]);
|
|
|
|
nodep = (const int *)bl_get_fdt_nvt_memory_cfg_property(p_dtb, PATH_MEM_RTOS, PROPERTY_REG, &len);
|
|
if (nodep != NULL) {
|
|
g_dram_partition.rtos_addr = be32_to_cpu(nodep[0]);
|
|
g_dram_partition.rtos_size = be32_to_cpu(nodep[1]);
|
|
}
|
|
|
|
nodep = (const int *)bl_get_fdt_nvt_memory_cfg_property(p_dtb, PATH_MEM_NUTTX, PROPERTY_REG, &len);
|
|
if (nodep != NULL) {
|
|
g_dram_partition.nuttx_addr = be32_to_cpu(nodep[0]);
|
|
g_dram_partition.nuttx_size = be32_to_cpu(nodep[1]);
|
|
}
|
|
|
|
nodep = (const int *)bl_get_fdt_nvt_memory_cfg_property(p_dtb, PATH_MEM_TEEOS, PROPERTY_REG, &len);
|
|
if (nodep != NULL) {
|
|
g_dram_partition.teeos_addr = be32_to_cpu(nodep[0]);
|
|
g_dram_partition.teeos_size = be32_to_cpu(nodep[1]);
|
|
}
|
|
|
|
p_rt = (UINT8 *)&g_dram_partition;
|
|
break;
|
|
|
|
case MODELEXT_TYPE_BIN_INFO:
|
|
nodep = (const int *)bl_get_fdt_nvt_memory_cfg_property(p_dtb, PATH_MEM_SHMEM, PROPERTY_REG, &len);
|
|
if (nodep == NULL) {
|
|
debug_err("dtb get shmem fail\r\n");
|
|
return NULL;
|
|
}
|
|
|
|
if (sizeof(SHMINFO) > be32_to_cpu(nodep[1])) {
|
|
debug_err("shmem size mismatch\r\n");
|
|
return NULL;
|
|
}
|
|
|
|
p_rt = (UINT8 *)be32_to_cpu(nodep[0]);
|
|
break;
|
|
|
|
default:
|
|
debug_err_var("not handle type\r\n", type);
|
|
return NULL;
|
|
}
|
|
return p_rt;
|
|
#else // NO FDT_SUPPORT
|
|
switch (type) {
|
|
case MODELEXT_TYPE_DRAM_PARTITION:
|
|
return (UINT8 *)&g_dram_partition;
|
|
case MODELEXT_TYPE_BIN_INFO:
|
|
return (UINT8 *)g_dram_partition.rev_addr;
|
|
default:
|
|
return NULL;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
_THUMB2 int bl_chk_valid_all_in_one(NVTPACK_MEM *p_mem_all_in_one)
|
|
{
|
|
NVTPACK_ER er;
|
|
NVTPACK_VER ver;
|
|
|
|
er = nvtpack_getver(p_mem_all_in_one, &ver);
|
|
|
|
if (er != NVTPACK_ER_SUCCESS) {
|
|
return -1;
|
|
}
|
|
|
|
if (ver == NVTPACK_VER_16072017) {
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
#if !REMOVED_FLASH
|
|
_THUMB2 int bl_chk_fdt(unsigned int addr, unsigned int size)
|
|
{
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
|
|
if (fdt_check_full((void *)addr, size) != 0) {
|
|
debug_err("invalid dtb\r\n");
|
|
return -1;
|
|
}
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)addr, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("invalid dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// check tmp memory (file load) cannot overlap with uboot and teeos
|
|
// we allow to overlap with linux, root-fs because uboot will reload bin file later
|
|
debug_msg_var("tmp_addr", SDRAM_Start_FW);
|
|
|
|
// if ((addr < p_dram_partition->uboot_addr && addr + size > p_dram_partition->uboot_addr) ||
|
|
// (addr > p_dram_partition->uboot_addr && addr + size < p_dram_partition->uboot_addr + p_dram_partition->uboot_size)) {
|
|
if (IS_BIN_OVERLAP(addr, size, p_dram_partition->uboot_addr, p_dram_partition->uboot_size)) {
|
|
debug_err_var("a", addr);
|
|
debug_err_var("s", size);
|
|
debug_err("uboot olp\r\n");
|
|
return -1;
|
|
}
|
|
#if 1
|
|
//if ((addr < p_dram_partition->teeos_addr && addr + size > p_dram_partition->teeos_addr) ||
|
|
// (addr > p_dram_partition->teeos_addr && addr + size < p_dram_partition->teeos_addr + p_dram_partition->teeos_size)) {
|
|
if (p_dram_partition->teeos_size) {
|
|
if (IS_BIN_OVERLAP(addr, size, p_dram_partition->teeos_addr, p_dram_partition->teeos_size)) {
|
|
debug_err_var("a", addr);
|
|
debug_err_var("s", size);
|
|
debug_err("teeos olp\r\n");
|
|
return -1;
|
|
}
|
|
}
|
|
#endif
|
|
// check if memory size matched real size
|
|
UINT32 ld_dram1_size = dma_get_dram_capacity(DMA_ID_1);
|
|
if (p_dram_partition->dram_size > ld_dram1_size) {
|
|
debug_err_var("fw_d1_s", p_dram_partition->dram_size);
|
|
debug_err_var("ld_d1_s", ld_dram1_size);
|
|
debug_err("d1 s not matched.\r\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if !REMOVED_FLASH
|
|
_THUMB2 int bl_chk_uboot(unsigned int addr, unsigned int size)
|
|
{
|
|
#if (_FPGA_EMULATION_ == 0)
|
|
NVTPACK_MEM mem = {0};
|
|
mem.p_data = (void *)addr;
|
|
mem.len = size;
|
|
if (nvtpack_calc_nvt_sum(&mem) != 0) {
|
|
debug_err("uboot check sum fail");
|
|
return -1;
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
static void bl_core2_reset(void)
|
|
{
|
|
UINT32 core_reg;
|
|
|
|
debug_msg("core2_reset\r\n");
|
|
|
|
core_reg = *(volatile UINT32 *)0xF0E400F0;
|
|
core_reg &= ~(1<<3);
|
|
core_reg &= ~(1<<11);
|
|
*(volatile UINT32 *)0xF0E400F0 = core_reg;
|
|
core_reg |= (1<<2)|(1<<10) | (1<<21);
|
|
core_reg |= (1<<17);
|
|
*(volatile UINT32 *)0xF0E400F0 = core_reg;
|
|
}
|
|
|
|
static void bl_core2_prepare(DRAM_PARTITION *p_dram_partition, unsigned int last_addr)
|
|
{
|
|
extern char _load_core2_jump_program_start_base[];
|
|
extern char _load_core2_jump_program_end_base[];
|
|
extern char _load_core2_entry_program_start_base[];
|
|
extern char _load_core2_entry_program_end_base[];
|
|
UINT32 code2JumpCodelen, code2EntryCodelen;
|
|
|
|
//check core2_entry1 must at addr 0
|
|
if (p_dram_partition->core2_entry1_addr != CORE2_JUMP_ADDR) {
|
|
bl_displayErrMsg("core2entry1 != 0");
|
|
}
|
|
|
|
// copy core2 jump code to dram 0x0
|
|
code2JumpCodelen = _load_core2_jump_program_end_base - _load_core2_jump_program_start_base;
|
|
utl_memcpy((void *)p_dram_partition->core2_entry1_addr, _load_core2_jump_program_start_base, code2JumpCodelen);
|
|
// CPUflushWriteCache(p_dram_partition->core2_entry1_addr, code2JumpCodelen);
|
|
|
|
debug_msg_var("core2_jump_program", (int)_load_core2_jump_program_start_base);
|
|
debug_msg_var("code2JumpCodelen", (int)code2JumpCodelen);
|
|
debug_msg_var("core2_entry2_addr", (int)p_dram_partition->core2_entry2_addr);
|
|
|
|
// copy core2 entry code to dram specified by fdt
|
|
*(volatile UINT32 *)(NVT_CORE2_START) = p_dram_partition->core2_entry2_addr;
|
|
code2EntryCodelen = _load_core2_entry_program_end_base - _load_core2_entry_program_start_base;
|
|
utl_memcpy((void *)p_dram_partition->core2_entry2_addr, _load_core2_entry_program_start_base, code2EntryCodelen);
|
|
// CPUflushWriteCache(p_dram_partition->core2_entry2_addr, code2EntryCodelen);
|
|
|
|
debug_msg_var("core2_entry_program", (int)_load_core2_entry_program_start_base);
|
|
debug_msg_var("code2EntryCodelen", (int)code2EntryCodelen);
|
|
|
|
*(volatile UINT32 *)0xF07F8000 = last_addr;
|
|
|
|
debug_msg_var("0xF07F8000=", (int)*(volatile UINT32 *)0xF07F8000);
|
|
}
|
|
|
|
static int bl_smp_start(unsigned char *p_modelext, UINT32 uboot_entry)
|
|
{
|
|
SHMINFO *p_bininfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_modelext, MODELEXT_TYPE_BIN_INFO);
|
|
if (p_bininfo == NULL) {
|
|
debug_err("null p_bininfo\r\n");
|
|
return -1;
|
|
}
|
|
|
|
DRAM_PARTITION *p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_modelext, MODELEXT_TYPE_DRAM_PARTITION);
|
|
if (p_bininfo == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
debug_msg_var("fdt", (UINT32)p_modelext);
|
|
debug_msg_var("shm", (UINT32)p_bininfo);
|
|
|
|
p_bininfo->boot.fdt_addr = (UINT32)p_modelext;
|
|
debug_msg_var("p_bininfo->boot.fdt_addr", p_bininfo->boot.fdt_addr);
|
|
utl_memset(p_bininfo->boot.LdInfo_1, 0, sizeof(p_bininfo->boot.LdInfo_1));
|
|
utl_memcpy(p_bininfo->boot.LdInfo_1, "LD_NVT", 6);
|
|
// clear cc_core1_addr, cc_core2_addr
|
|
#if USB_WRITELOADER
|
|
if(utl_get_bootsrc() == BOOT_SOURCE_UART) {
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_FROM_UART;
|
|
} else if(USB_WRITELOADER || utl_get_bootsrc() == BOOT_SOURCE_USB) {
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_FROM_USB;
|
|
} else {
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_NORMAL;
|
|
}
|
|
#else
|
|
// if (card_get_type() == EXT_STORAGE_TYPE_ETH)
|
|
// p_bininfo->comm.Resv[0] = BOOT_REASON_FROM_ETH;
|
|
// else if (g_is_recovery_triggered)
|
|
// p_bininfo->comm.Resv[0] = BOOT_REASON_RECOVERY_SYS;
|
|
// else
|
|
#if (STORAGE_EXT_TYPE == STORAGE_EXT_ETH)
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_FROM_ETH;
|
|
#else
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_NORMAL;
|
|
#endif
|
|
#endif
|
|
p_bininfo->comm.Resv[1] = 0; // COMM_CORE1_START
|
|
p_bininfo->comm.Resv[2] = 0; // COMM_CORE2_START
|
|
p_bininfo->comm.Resv[3] = 0; // COMM_UITRON_COMP_ADDR
|
|
p_bininfo->comm.Resv[4] = 0; // COMM_UITRON_COMP_LEN
|
|
|
|
debug_msg("smp(no tee)\r\n");
|
|
|
|
bl_core2_prepare(p_dram_partition, 0);
|
|
|
|
//#if USB_WRITELOADER
|
|
#if 0
|
|
USBStateMachine();
|
|
uart_putSystemUARTStr("USB update Done\n\r");
|
|
timer_delay(1000000);
|
|
USBOTGReset();
|
|
#endif
|
|
|
|
|
|
|
|
//invalid Instruciton and data cache
|
|
CPUCleanInvalidateDCacheAll();
|
|
CPUInvalidateICacheAll();
|
|
|
|
//reset core2
|
|
bl_core2_reset();
|
|
|
|
{
|
|
typedef void (*BRANCH_CB)(void);
|
|
BRANCH_CB p_func = (BRANCH_CB)uboot_entry;
|
|
debug_msg_var("jump", uboot_entry);
|
|
p_func();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
_THUMB2 static int bl_entry_boot(unsigned char *p_fdt, UINT32 uboot_entry)
|
|
{
|
|
SHMINFO *p_bininfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_BIN_INFO);
|
|
if (p_bininfo == NULL) {
|
|
debug_err("null p_bininfo\r\n");
|
|
return -1;
|
|
}
|
|
|
|
debug_msg_var("fdt", (UINT32)p_fdt);
|
|
debug_msg_var("shm", (UINT32)p_bininfo);
|
|
|
|
p_bininfo->boot.fdt_addr = (UINT32)p_fdt;
|
|
utl_memset(p_bininfo->boot.LdInfo_1, 0, sizeof(p_bininfo->boot.LdInfo_1));
|
|
utl_memcpy(p_bininfo->boot.LdInfo_1, "LD_NVT", 6);
|
|
// clear cc_core1_addr, cc_core2_addr
|
|
#if USB_WRITELOADER
|
|
CPUflushWriteCache((UINT32)p_bininfo, sizeof(BININFO));
|
|
if(utl_get_bootsrc() == BOOT_SOURCE_USB) {
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_FROM_USB;
|
|
} else {
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_FROM_UART;
|
|
}
|
|
#else
|
|
if (card_get_type() == EXT_STORAGE_TYPE_ETH)
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_FROM_ETH;
|
|
// else if (g_is_recovery_triggered)
|
|
// p_bininfo->comm.Resv[0] = BOOT_REASON_RECOVERY_SYS;
|
|
else
|
|
p_bininfo->comm.Resv[0] = BOOT_REASON_NORMAL;
|
|
#endif
|
|
p_bininfo->comm.Resv[1] = 0; // COMM_CORE1_START
|
|
p_bininfo->comm.Resv[2] = 0; // COMM_CORE2_START
|
|
p_bininfo->comm.Resv[3] = 0; // COMM_UITRON_COMP_ADDR
|
|
p_bininfo->comm.Resv[4] = 0; // COMM_UITRON_COMP_LEN
|
|
|
|
//invalid Instruciton and data cache
|
|
CPUCleanInvalidateDCacheAll();
|
|
CPUInvalidateICacheAll();
|
|
|
|
{
|
|
typedef void (*BRANCH_CB)(void);
|
|
BRANCH_CB p_func = (BRANCH_CB)uboot_entry;
|
|
debug_msg_var("jump", uboot_entry);
|
|
p_func();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
_THUMB2 int bl_copy_fdt_to_fdt_addr(unsigned char *p_fdt /*IN*/, unsigned char **pp_fdt /*OUT*/)
|
|
{
|
|
DRAM_PARTITION *p_dram_partition;
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("bl_copy_fdt_to_fdt_addr failed.\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// load fdt to fdt buffer
|
|
utl_memcpy((void *)p_dram_partition->fdt_addr, p_fdt, fdt_totalsize(p_fdt));
|
|
*pp_fdt = (unsigned char *)p_dram_partition->fdt_addr;
|
|
|
|
//reset shminfo
|
|
SHMINFO *p_bininfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_BIN_INFO);
|
|
bl_memset(p_bininfo, 0, sizeof(SHMINFO));
|
|
return 0;
|
|
}
|
|
|
|
_THUMB2 static int bl_load_fdt_from_all_in_one(unsigned char *p_all_in_one, unsigned int all_in_one_size, unsigned char **pp_fdt /*OUT*/)
|
|
{
|
|
NVTPACK_ER er;
|
|
NVTPACK_MEM emb_fdt;
|
|
NVTPACK_VERIFY_OUTPUT np_verify = {0};
|
|
NVTPACK_GET_PARTITION_INPUT np_get_input;
|
|
NVTPACK_MEM mem_in = {(void *)p_all_in_one, (unsigned int)all_in_one_size};
|
|
|
|
if (nvtpack_verify(&mem_in, &np_verify) != NVTPACK_ER_SUCCESS) {
|
|
debug_err("packbin verify failed.\r\n");
|
|
return -1;
|
|
}
|
|
|
|
np_get_input.id = 1; // fdt must always put in partition[1]
|
|
np_get_input.mem = mem_in;
|
|
er = nvtpack_get_partition(&np_get_input, &emb_fdt);
|
|
|
|
if (er == NVTPACK_ER_NOT_FOUND) {
|
|
return -2;
|
|
} else if (er == NVTPACK_ER_SUCCESS) {
|
|
debug_msg_var("fdt addr", (int)emb_fdt.p_data);
|
|
debug_msg_var("fdt size", (int)emb_fdt.len);
|
|
if (bl_chk_fdt((unsigned int)emb_fdt.p_data, emb_fdt.len) == 0) {
|
|
return bl_copy_fdt_to_fdt_addr(emb_fdt.p_data, pp_fdt);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
_THUMB2 static unsigned int bl_load_rtos_from_all_in_one(unsigned char *p_all_in_one, unsigned int all_in_one_size, unsigned char **pp_fdt /*OUT*/)
|
|
{
|
|
UINT32 uItron_fw_addr= 0;
|
|
NVTPACK_ER er;
|
|
NVTPACK_MEM emb_fdt;
|
|
NVTPACK_VERIFY_OUTPUT np_verify = {0};
|
|
NVTPACK_GET_PARTITION_INPUT np_get_input;
|
|
NVTPACK_MEM mem_in = {(void *)p_all_in_one, (unsigned int)all_in_one_size};
|
|
HEADINFO *p_headinfo;
|
|
|
|
if (nvtpack_verify(&mem_in, &np_verify) != NVTPACK_ER_SUCCESS) {
|
|
debug_err("packbin verify failed.\r\n");
|
|
return 0;
|
|
}
|
|
|
|
np_get_input.id = 5; // rtos must always put in partition[5] for now
|
|
np_get_input.mem = mem_in;
|
|
er = nvtpack_get_partition(&np_get_input, &emb_fdt);//&np_get_input, &emb_fdt);
|
|
|
|
if (er == NVTPACK_ER_NOT_FOUND) {
|
|
return 0;
|
|
} else if (er == NVTPACK_ER_SUCCESS) {
|
|
debug_msg("get rtos partition ok\r\n");
|
|
|
|
p_headinfo = (HEADINFO *)(emb_fdt.p_data + BIN_INFO_OFFSET_RTOS);
|
|
uItron_fw_addr = p_headinfo->CodeEntry - CODE_SECTION_OFFSET;
|
|
|
|
utl_memcpy((void *)uItron_fw_addr, emb_fdt.p_data, emb_fdt.len);
|
|
CPUflushWriteCache(uItron_fw_addr, emb_fdt.len);
|
|
}
|
|
debug_msg_var("uItron_fw_addr=", uItron_fw_addr);
|
|
return uItron_fw_addr;
|
|
}
|
|
|
|
_THUMB2 static int bl_load_fdt_from_flash(unsigned char *p_tmp, unsigned int tmp_size, unsigned char **pp_fdt /*OUT*/)
|
|
{
|
|
|
|
// read first block to get dtb size
|
|
int blk_size = (int)int_strg_obj->flash_getBlockSize();
|
|
int er = int_strg_obj->flash_readSectors(g_uiStartBlkUpdateFW, blk_size, p_tmp, NAND_RW_FIRMWARE);
|
|
if (er < 0) {
|
|
debug_err("bl_load_fdt_from_flash");
|
|
return -1;
|
|
}
|
|
|
|
int total_size = ALIGN_CEIL(fdt_totalsize(p_tmp), blk_size);
|
|
if ((int)tmp_size < total_size) {
|
|
debug_err_var("tmp_size too small, require:", fdt_totalsize(p_tmp));
|
|
return -1;
|
|
}
|
|
|
|
total_size -= blk_size;
|
|
if (total_size > 0) {
|
|
// read remain to get uboot starting addr on dram and offset in flash
|
|
er = int_strg_obj->flash_readSectors(g_uiStartBlkUpdateFW+1, total_size, p_tmp+blk_size, NAND_RW_FIRMWARE);
|
|
if (er < 0) {
|
|
debug_err("bl_load_fdt_from_flash");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (bl_chk_fdt((unsigned int)p_tmp, fdt_totalsize(p_tmp)) == 0) {
|
|
return bl_copy_fdt_to_fdt_addr(p_tmp, pp_fdt);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
#if (FDT_SUPPORT)
|
|
_THUMB2 static int bl_get_partition_fdt_offset(unsigned char *p_fdt)
|
|
{
|
|
static int nodeoffset= -FDT_ERR_NOTFOUND;
|
|
|
|
if (nodeoffset > 0) {
|
|
return nodeoffset;
|
|
}
|
|
|
|
const static char *p_names[3] = {
|
|
"/nand",
|
|
"/nor",
|
|
"/mmc@f0510000"
|
|
};
|
|
|
|
const char *name = NULL;
|
|
switch(gStorageIntType) {
|
|
case STORAGEINT_SPI_NAND:
|
|
name = p_names[0];
|
|
break;
|
|
case STORAGEINT_SPI_NOR:
|
|
name = p_names[1];
|
|
break;
|
|
case STORAGEINT_EMMC:
|
|
name = p_names[2];
|
|
break;
|
|
default:
|
|
debug_err("loader_setStorageIntType needs.\r\n");
|
|
return NULL;
|
|
}
|
|
|
|
nodeoffset = fdt_path_offset(p_fdt, name);
|
|
|
|
if (nodeoffset < 0) {
|
|
debug_err("E:bl_get_partition_name\r\n");
|
|
}
|
|
return nodeoffset;
|
|
}
|
|
#endif
|
|
|
|
#if (FDT_SUPPORT)
|
|
_THUMB2 static const void *bl_get_fdt_partition_property(const void *p_dtb, const char *p_path, const char *p_property, int *len)
|
|
{
|
|
int nodeoffset_partition = bl_get_partition_fdt_offset((unsigned char *)p_dtb);
|
|
|
|
int nodeoffset;
|
|
const void *nodep; /* property node pointer */
|
|
|
|
if (nodeoffset_partition < 0) {
|
|
debug_err("nodeoffset_partition invalid \r\n");
|
|
return NULL;
|
|
}
|
|
|
|
nodeoffset = fdt_subnode_offset(p_dtb, nodeoffset_partition, p_path);
|
|
if (nodeoffset < 0) {
|
|
return NULL;
|
|
}
|
|
nodep = fdt_getprop(p_dtb, nodeoffset, p_property, len);
|
|
if (len == 0) {
|
|
return NULL;
|
|
}
|
|
return nodep;
|
|
}
|
|
#endif
|
|
|
|
#if (FDT_SUPPORT)
|
|
_THUMB2 static int bl_get_partition(unsigned char *p_fdt /*IN*/, char *p_emb_name /*IN*/, EMB_PARTITION *p_emb/*OUT*/, int *p_id)
|
|
{
|
|
int len;
|
|
const unsigned long long *nodep;
|
|
|
|
// get partition offset and size
|
|
nodep = (const unsigned long long *)bl_get_fdt_partition_property(p_fdt, p_emb_name, PROPERTY_REG, &len);
|
|
if (nodep == NULL) {
|
|
debug_err("bl_get_partition-1\r\n");
|
|
return -1;
|
|
}
|
|
|
|
p_emb->PartitionOffset = be64_to_cpu(nodep[0]);
|
|
p_emb->PartitionSize = be64_to_cpu(nodep[1]);
|
|
|
|
// get partition label
|
|
char *p_label_name = (char *)bl_get_fdt_partition_property(p_fdt, p_emb_name, PROPERTY_LABEL, &len);
|
|
if (p_label_name == NULL) {
|
|
debug_err("bl_get_partition-2\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// get id
|
|
int nodeoffset_partition = bl_get_partition_fdt_offset(p_fdt);
|
|
int nodeoffset = fdt_subnode_offset(p_fdt, nodeoffset_partition, "nvtpack");
|
|
nodeoffset = fdt_subnode_offset(p_fdt, nodeoffset, "index");
|
|
|
|
for (nodeoffset = fdt_first_subnode(p_fdt, nodeoffset);
|
|
(nodeoffset >= 0);
|
|
(nodeoffset = fdt_next_subnode(p_fdt, nodeoffset))) {
|
|
const struct fdt_property *prop;
|
|
|
|
if (!(prop = fdt_get_property(p_fdt, nodeoffset, PROPERTY_PARTITION_NAME, &len))) {
|
|
break;
|
|
}
|
|
const char *p_id_name = fdt_get_name(p_fdt, nodeoffset, &len);
|
|
|
|
if (strcmp(p_label_name, (char *)prop->data) == 0) {
|
|
*p_id = atoi(p_id_name + strlen("id"));
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
_THUMB2 static void *bl_get_uboot_partition(unsigned char *p_fdt /*IN*/, int *p_id /*OUT*/)
|
|
{
|
|
#if (FDT_SUPPORT)
|
|
if (bl_get_partition(p_fdt, PATH_PARTITION_UBOOT, &g_emb_uboot, p_id) != 0) {
|
|
return NULL;
|
|
}
|
|
#else
|
|
*p_id = NVTPACK_IDX_UBOOT;
|
|
#endif
|
|
g_emb_uboot.EmbType = EMBTYPE_UBOOT;
|
|
return &g_emb_uboot;
|
|
}
|
|
|
|
_THUMB2 static void *bl_get_rtos_partition(unsigned char *p_fdt /*IN*/, int *p_id /*OUT*/)
|
|
{
|
|
#if (FDT_SUPPORT)
|
|
if (bl_get_partition(p_fdt, PATH_PARTITION_RTOS, &g_emb_rtos, p_id) != 0) {
|
|
return NULL;
|
|
}
|
|
#else
|
|
*p_id = NVTPACK_IDX_RTOS;
|
|
#endif
|
|
g_emb_rtos.EmbType = EMBTYPE_RTOS;
|
|
return &g_emb_rtos;
|
|
}
|
|
|
|
#if (NUTTX_SUPPORT)
|
|
_THUMB2 static void *bl_get_nuttx_partition(unsigned char *p_fdt /*IN*/, int *p_id /*OUT*/)
|
|
{
|
|
if (bl_get_partition(p_fdt, PATH_PARTITION_NUTTX, &g_emb_nuttx, p_id) != 0) {
|
|
return NULL;
|
|
}
|
|
g_emb_nuttx.EmbType = EMBTYPE_NUTTX;
|
|
|
|
return &g_emb_nuttx;
|
|
}
|
|
#endif
|
|
|
|
_THUMB2 static void *bl_get_teeos_partition(unsigned char *p_fdt /*IN*/, int *p_id /*OUT*/)
|
|
{
|
|
#if (FDT_SUPPORT)
|
|
if (bl_get_partition(p_fdt, PATH_PARTITION_TEEOS, &g_emb_teeos, p_id) != 0) {
|
|
return NULL;
|
|
}
|
|
#else
|
|
*p_id = NVTPACK_IDX_TEEOS;
|
|
#endif
|
|
g_emb_teeos.EmbType = EMBTYPE_TEEOS;
|
|
|
|
return &g_emb_teeos;
|
|
}
|
|
#endif
|
|
|
|
// return decompress_fw_size
|
|
_THUMB2 static unsigned int bl_decompress_rtos(UINT32 compress_addr, UINT32 compress_size, UINT32 fw_base_addr)
|
|
{
|
|
UINT32 decoded_size;
|
|
NVTPACK_BFC_HDR *pBfc = (NVTPACK_BFC_HDR *)compress_addr;
|
|
UINT32 size_comp_le = invertEndian(pBfc->uiSizeComp);
|
|
UINT32 size_uncomp_le = invertEndian(pBfc->uiSizeUnComp);
|
|
|
|
size_comp_le = (compress_size < size_comp_le) ? compress_size : size_comp_le;
|
|
decoded_size = LZ_Un_compress((UINT8 *)compress_addr + sizeof(NVTPACK_BFC_HDR), (UINT8 *)fw_base_addr, size_comp_le);
|
|
//because some padding bytes are decoded, we must return real rtos size
|
|
return (decoded_size < size_uncomp_le) ? decoded_size : size_uncomp_le;
|
|
}
|
|
|
|
#if !REMOVED_FLASH
|
|
_THUMB2 static int bl_load_uboot_from_all_in_one(unsigned char *p_fdt, unsigned char *p_all_in_one, unsigned int all_in_one_size)
|
|
{
|
|
NVTPACK_ER er;
|
|
NVTPACK_MEM mem_uboot;
|
|
int uboot_partition_id;
|
|
NVTPACK_GET_PARTITION_INPUT input;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
EMB_PARTITION *p_emb_partition_uboot = bl_get_uboot_partition(p_fdt, &uboot_partition_id);
|
|
|
|
if (p_emb_partition_uboot == NULL) {
|
|
debug_err("null p_emb_partition_uboot\r\n");
|
|
return -1;
|
|
}
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// get partition data address and size
|
|
input.id = (unsigned int)uboot_partition_id;
|
|
input.mem.p_data = (void *)p_all_in_one;
|
|
input.mem.len = all_in_one_size;
|
|
er = nvtpack_get_partition(&input, &mem_uboot);
|
|
if (er == NVTPACK_ER_NOT_FOUND) {
|
|
return -2;
|
|
}
|
|
|
|
if (er != NVTPACK_ER_SUCCESS) {
|
|
return -1;
|
|
}
|
|
|
|
debug_msg_var("uboot_addr", p_dram_partition->uboot_addr);
|
|
// debug_msg_var("uboot_size", p_dram_partition->uboot_size);
|
|
# if 0
|
|
if(0) {
|
|
#else
|
|
#if (_FPGA_EMULATION_ == 0)
|
|
if(is_secure_enable() == 0) {
|
|
#else
|
|
if (1) {
|
|
#endif
|
|
#endif
|
|
if (bl_chk_uboot((unsigned int)mem_uboot.p_data, mem_uboot.len) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
// flow to handle compressed u-boot and uncompressed one.
|
|
HEADINFO *p_headinfo = (HEADINFO *)(mem_uboot.p_data + BIN_INFO_OFFSET_UBOOT); // describe uncompressed u-boot
|
|
NVTPACK_BFC_HDR *pBfc = (NVTPACK_BFC_HDR *)mem_uboot.p_data; // describe compressed u-boot
|
|
|
|
// load uboot bin to dram partiton location
|
|
//debug_msg_var("uboot_addr", p_dram_partition->uboot_addr);
|
|
//debug_msg_var("uboot_size", p_dram_partition->uboot_size);
|
|
|
|
if (pBfc->uiFourCC == MAKEFOURCC('B', 'C', 'L', '1')) {
|
|
if((cpu_to_be32(pBfc->uiAlgorithm) & 0xFF ) == 11) {
|
|
#if (_ROM_PUBLIC_API_ == 1)
|
|
UINT32 lzma_addr = *(UINT32 *)ROM_LZMA_POSITION;
|
|
UINT32 size_comp_le = invertEndian(pBfc->uiSizeComp);
|
|
UINT32 size_uncomp_le = invertEndian(pBfc->uiSizeUnComp);
|
|
rom_lzma_inflate = (int (*)(UINT8 *, UINT32 , UINT8 * , UINT32 , UINT8 *, UINT32 ))((lzma_addr));
|
|
rom_lzma_inflate(mem_uboot.p_data + sizeof(NVTPACK_BFC_HDR), size_comp_le, (unsigned char *) p_dram_partition->uboot_addr, size_uncomp_le, (UINT8 *)lzma_temp_buffer, 65536);
|
|
debug_msg("lzma ");
|
|
|
|
#else
|
|
debug_msg("Can not support LZMA\r\n");
|
|
#endif
|
|
} else {
|
|
UINT32 size_comp_le = invertEndian(pBfc->uiSizeComp);
|
|
LZ_Un_compress(mem_uboot.p_data + sizeof(NVTPACK_BFC_HDR), (unsigned char *) p_dram_partition->uboot_addr, size_comp_le);
|
|
debug_msg("lz");
|
|
}
|
|
} else {
|
|
debug_msg("nml");
|
|
utl_memcpy((void *)p_dram_partition->uboot_addr, mem_uboot.p_data, p_headinfo->BinLength);
|
|
}
|
|
} else {
|
|
#if (SECURE_DECRYPT_UBOOT)
|
|
utl_memcpy((void *)p_dram_partition->uboot_addr, mem_uboot.p_data, mem_uboot.len);
|
|
unsigned int plaintext_size =0;
|
|
|
|
if((er = do_decrypt_aes(p_dram_partition->uboot_addr, p_dram_partition->uboot_addr, &plaintext_size, p_dram_partition->uboot_size))!= 0 )
|
|
{
|
|
//debug_err("aes fail\r\n");
|
|
return er;
|
|
}
|
|
if (bl_chk_uboot((unsigned int)p_dram_partition->uboot_addr, plaintext_size) != 0) {
|
|
return -1;
|
|
}
|
|
#else
|
|
debug_msg("please enable SECURE_DECRYPT_UBOOT\r\n");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if (NUTTX_SUPPORT)
|
|
_THUMB2 static int bl_load_nuttx_from_all_in_one(unsigned char *p_fdt, unsigned char *p_all_in_one, unsigned int all_in_one_size)
|
|
{
|
|
NVTPACK_ER er;
|
|
NVTPACK_MEM mem_nuttx;
|
|
int nuttx_partition_id;
|
|
NVTPACK_GET_PARTITION_INPUT input;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
EMB_PARTITION *p_emb_partition_nuttx = bl_get_nuttx_partition(p_fdt, &nuttx_partition_id);
|
|
|
|
if (p_emb_partition_nuttx == NULL) {
|
|
debug_err("null p_emb_partition_nuttx\r\n");
|
|
return -1;
|
|
}
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// get partition data address and size
|
|
input.id = (unsigned int)nuttx_partition_id;
|
|
input.mem.p_data = (void *)p_all_in_one;
|
|
input.mem.len = all_in_one_size;
|
|
er = nvtpack_get_partition(&input, &mem_nuttx);
|
|
if (er == NVTPACK_ER_NOT_FOUND) {
|
|
return -2;
|
|
}
|
|
|
|
if (er != NVTPACK_ER_SUCCESS) {
|
|
return -1;
|
|
}
|
|
|
|
// using check uboot's check sum is ok
|
|
if (bl_chk_uboot((unsigned int)mem_nuttx.p_data, mem_nuttx.len) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
// flow to handle compressed u-boot and uncompressed one.
|
|
HEADINFO *p_headinfo = (HEADINFO *)(mem_nuttx.p_data + BIN_INFO_OFFSET_NUTTX); // describe uncompressed u-boot
|
|
NVTPACK_BFC_HDR *pBfc = (NVTPACK_BFC_HDR *)mem_nuttx.p_data; // describe compressed u-boot
|
|
|
|
// load nuttx bin to dram partiton location
|
|
debug_msg_var("nuttx_addr", p_dram_partition->nuttx_addr);
|
|
debug_msg_var("nuttx_size", p_dram_partition->nuttx_size);
|
|
|
|
if (pBfc->uiFourCC == MAKEFOURCC('B', 'C', 'L', '1')) {
|
|
UINT32 size_comp_le = invertEndian(pBfc->uiSizeComp);
|
|
LZ_Un_compress(mem_nuttx.p_data + sizeof(NVTPACK_BFC_HDR), (unsigned char *) p_dram_partition->nuttx_addr, size_comp_le);
|
|
} else {
|
|
utl_memcpy((void *)p_dram_partition->nuttx_addr, mem_nuttx.p_data, p_headinfo->BinLength);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
_THUMB2 static int bl_load_teeos_from_all_in_one(unsigned char *p_fdt, unsigned char *p_all_in_one, unsigned int all_in_one_size)
|
|
{
|
|
NVTPACK_ER er;
|
|
NVTPACK_MEM mem_teeos;
|
|
int teeos_partition_id;
|
|
NVTPACK_GET_PARTITION_INPUT input;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
EMB_PARTITION *p_emb_partition_teeos = bl_get_teeos_partition(p_fdt, &teeos_partition_id);
|
|
HEADINFO *p_headinfo = NULL;
|
|
if (p_emb_partition_teeos == NULL) {
|
|
debug_err("null p_emb_partition_teeos\r\n");
|
|
return -1;
|
|
}
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// get partition data address and size
|
|
input.id = (unsigned int)teeos_partition_id;
|
|
input.mem.p_data = (void *)p_all_in_one;
|
|
input.mem.len = all_in_one_size;
|
|
er = nvtpack_get_partition(&input, &mem_teeos);
|
|
if (er == NVTPACK_ER_NOT_FOUND) {
|
|
return -2;
|
|
}
|
|
|
|
if (er != NVTPACK_ER_SUCCESS) {
|
|
return -1;
|
|
}
|
|
|
|
#if 0
|
|
if(1){
|
|
#else
|
|
if(is_secure_enable()) {
|
|
#endif
|
|
#if (SECURE_DECRYPT_OPTEE_OS)
|
|
unsigned int plaintext_size =0;
|
|
utl_memcpy((void *)p_dram_partition->teeos_addr, mem_teeos.p_data, mem_teeos.len);
|
|
if((er = do_decrypt_aes(p_dram_partition->teeos_addr, p_dram_partition->teeos_addr,&plaintext_size, p_dram_partition->teeos_size))!= 0)
|
|
{
|
|
//debug_err("aes fail\r\n");
|
|
return er;
|
|
}
|
|
|
|
//this is the second headinfo information , not encrpyted headinfo
|
|
p_headinfo = (HEADINFO *)(p_dram_partition->teeos_addr + BIN_INFO_OFFSET_TEEOS);
|
|
#else
|
|
debug_err("please enable SECURE_DECRYPT_OPTEE_OS");
|
|
return -1;
|
|
#endif
|
|
}
|
|
else{
|
|
p_headinfo = (HEADINFO *)(mem_teeos.p_data + BIN_INFO_OFFSET_TEEOS); // describe uncompressed u-boot
|
|
utl_memcpy((void *)p_dram_partition->teeos_addr, (unsigned char*)mem_teeos.p_data, p_headinfo->BinLength);
|
|
}
|
|
UINT32 teeos_addr = p_headinfo->Resv1[HEADINFO_TEEOS_RESV_IDX_LOAD_ADDR];
|
|
|
|
//check addr matched or not
|
|
debug_msg_var("teeos_addr", p_dram_partition->teeos_addr);
|
|
if (teeos_addr != p_dram_partition->teeos_addr) {
|
|
debug_msg_var("teeos_addr(bin)", teeos_addr);
|
|
debug_err("teeos addr not matched.\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// using check uboot's check sum is ok
|
|
if (bl_chk_uboot((unsigned int)teeos_addr, p_headinfo->BinLength) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
_THUMB2 static int bl_load_uboot_from_flash(unsigned char *p_fdt, unsigned char *p_tmp)
|
|
{
|
|
int er;
|
|
int uboot_partition_id;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
unsigned int blk_size = int_strg_obj->flash_getBlockSize();
|
|
EMB_PARTITION *p_emb_partition_uboot = bl_get_uboot_partition(p_fdt, &uboot_partition_id);
|
|
|
|
if (p_emb_partition_uboot == NULL) {
|
|
debug_err("null p_emb_partition_uboot\r\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg(p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
#if (SECURE_DECRYPT_UBOOT)
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_uboot->PartitionOffset / blk_size,
|
|
ALIGN_CEIL(BIN_INFO_OFFSET_UBOOT + sizeof(HEADINFO), blk_size), p_tmp, NAND_RW_FIRMWARE)) < 0)
|
|
{
|
|
debug_err_var("bl_load_uboot_from_flash,er=", er);
|
|
bl_displayErrMsg(RWErrorMsg); // read uboot failed
|
|
return -1;
|
|
}
|
|
#else
|
|
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_uboot->PartitionOffset / blk_size,
|
|
ALIGN_CEIL(BIN_INFO_OFFSET_UBOOT + sizeof(HEADINFO), blk_size), p_tmp, NAND_RW_FIRMWARE)) < 0)
|
|
{
|
|
debug_err_var("bl_load_uboot_from_flash,er=", er);
|
|
bl_displayErrMsg(RWErrorMsg); // read uboot failed
|
|
return -1;
|
|
}
|
|
|
|
#endif
|
|
|
|
debug_msg_var("uboot_addr", p_dram_partition->uboot_addr);
|
|
debug_msg_var("uboot_size", p_dram_partition->uboot_size);
|
|
#if 0
|
|
if(0){
|
|
#else
|
|
if(is_secure_enable() == 0) {
|
|
#endif
|
|
HEADINFO *p_headinfo = (HEADINFO *)(p_tmp + BIN_INFO_OFFSET_UBOOT); // describe uncompressed u-boot
|
|
NVTPACK_BFC_HDR *pBfc = (NVTPACK_BFC_HDR *)p_tmp; // describe compressed u-boot
|
|
|
|
if (pBfc->uiFourCC == MAKEFOURCC('B', 'C', 'L', '1'))
|
|
{
|
|
UINT32 size_comp_le = invertEndian(pBfc->uiSizeComp);
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_uboot->PartitionOffset / blk_size,
|
|
ALIGN_CEIL(size_comp_le, blk_size),p_tmp, NAND_RW_FIRMWARE)) < 0)
|
|
{
|
|
debug_err_var("bl_load_uboot_from_flash_comp,er=", er); // read bfc-uboot failed
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
if((cpu_to_be32(pBfc->uiAlgorithm) & 0xFF ) == 11) {
|
|
#if (_ROM_PUBLIC_API_ == 1)
|
|
UINT32 lzma_addr = *(UINT32 *)ROM_LZMA_POSITION;
|
|
UINT32 size_comp_le = invertEndian(pBfc->uiSizeComp);
|
|
UINT32 size_uncomp_le = invertEndian(pBfc->uiSizeUnComp);
|
|
rom_lzma_inflate = (int (*)(UINT8 *, UINT32 , UINT8 * , UINT32 , UINT8 *, UINT32 ))((lzma_addr));
|
|
rom_lzma_inflate(p_tmp + sizeof(NVTPACK_BFC_HDR), size_comp_le, (unsigned char *) p_dram_partition->uboot_addr, size_uncomp_le, (UINT8 *)lzma_temp_buffer, 65536);
|
|
debug_msg("lzma ");
|
|
#else
|
|
debug_msg("Can not support LZMA\r\n");
|
|
#endif
|
|
} else {
|
|
LZ_Un_compress(p_tmp + sizeof(NVTPACK_BFC_HDR), (unsigned char *)p_dram_partition->uboot_addr, size_comp_le);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_uboot->PartitionOffset / blk_size,
|
|
ALIGN_CEIL(p_headinfo->BinLength, blk_size),
|
|
(UINT8 *)p_dram_partition->uboot_addr, NAND_RW_FIRMWARE)) < 0)
|
|
{
|
|
debug_err_var("bl_load_uboot_from_flash,er=", er); // read bfc-uboot failed
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#if (SECURE_DECRYPT_UBOOT)
|
|
HEADINFO *p_headinfo = (HEADINFO *)(p_tmp); // describe uncompressed u-boot
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_uboot->PartitionOffset / blk_size,
|
|
ALIGN_CEIL(p_headinfo->BinLength, blk_size),
|
|
(UINT8 *)p_dram_partition->uboot_addr, NAND_RW_FIRMWARE)) < 0)
|
|
{
|
|
debug_err_var("bl_load_uboot_from_flash,er=", er); // read bfc-uboot failed
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
unsigned int plaintext_size=0;
|
|
if((er =do_decrypt_aes(p_dram_partition->uboot_addr, p_dram_partition->uboot_addr, &plaintext_size, p_dram_partition->uboot_size))!= 0)
|
|
{
|
|
//debug_err("aes fail\r\n");
|
|
return er;
|
|
}
|
|
#else
|
|
debug_msg("plase enable SECURE_DECRYPT_UBOOT config\r\n");
|
|
return -1;
|
|
#endif
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************************/
|
|
|
|
//#define VER_STR_MAX 32
|
|
//#define CHAR char
|
|
//#define FL_IndexInfoMAX 216
|
|
//#define NVT_MAX_BSS_DESC (64)
|
|
//#define NVT_WIFIIPC_MAC_ADDR_LEN (6)
|
|
//#define NVT_MESH_ID_LEN 32
|
|
//
|
|
//#define NVT_WSC_MAX_SSID_LEN (64)
|
|
//#define NVT_MAX_WEP_KEY_LEN (26)
|
|
//#define NVT_MAX_NETWORK_KEY_LEN (64)
|
|
//#define NVT_PIN_LEN (8)
|
|
//#define NVT_MAX_DEVICE_NAME_LEN (32)
|
|
//
|
|
//#define SF_TIMER_MAX_NUMBER 2
|
|
//typedef struct sf_PARA_TIME_S
|
|
//{
|
|
// UINT16 Year;
|
|
// UINT16 Mon;
|
|
// UINT16 Day;
|
|
//
|
|
// UINT16 Hour;
|
|
// UINT16 Min;
|
|
// UINT16 Sec;
|
|
//} SF_PARA_TIME_S;
|
|
//
|
|
//typedef struct sf_WORKTIME_S
|
|
//{
|
|
// SF_PARA_TIME_S StartTime;
|
|
// SF_PARA_TIME_S StopTime;
|
|
//} SF_WORKTIME_S;
|
|
//
|
|
//
|
|
// typedef struct _UIMenuUIMenuStoreInfo {
|
|
// UINT32 OtaFlag;
|
|
// //Common
|
|
// CHAR strMakerString[VER_STR_MAX];
|
|
// CHAR strModelString[VER_STR_MAX];
|
|
// CHAR strSoftwareVer[VER_STR_MAX];
|
|
// CHAR strMakeNote[VER_STR_MAX];
|
|
// CHAR strImageDescription[VER_STR_MAX];
|
|
// UINT32 uhInfoSize;
|
|
// UINT32 UIParameter[FL_IndexInfoMAX];
|
|
// UINT32 ulmodeIndex ; //Record Last Mode Index
|
|
// UINT32 cbYear;
|
|
// UINT32 cbMonth;
|
|
// UINT32 cbDay;
|
|
// UINT32 cbFileID;
|
|
// UINT32 ubLanguageIndex;
|
|
// //photo menu
|
|
// UINT32 ubAFWindowIndex;
|
|
// UINT32 ubAFBeamIndex;
|
|
// UINT32 ubContAF;
|
|
// UINT32 ubAEmode;
|
|
// UINT32 ubQviewIndex;
|
|
// UINT32 ubDzoom;
|
|
// UINT32 ubBlinkDet;
|
|
// UINT32 ubSlowShutter;
|
|
// UINT32 ubContshotIndex;
|
|
// UINT32 ubTimelapseIndex;
|
|
// UINT32 ubDatePrint;
|
|
// UINT32 ubPanModeIndex;
|
|
// UINT32 ubFlashIndex;
|
|
// UINT32 ubEVIndex;
|
|
// UINT32 ubSizeIndex;
|
|
// UINT32 ubQualityIndex;
|
|
// UINT32 ubWBIndex;
|
|
// UINT32 ubColorIndex;
|
|
// UINT32 ubISOIndex;
|
|
// UINT32 ubFDIndex ;
|
|
// UINT32 ubSharpnessIndex;
|
|
// UINT32 ubPhotoDispMode;
|
|
//
|
|
// //wifi
|
|
// CHAR strSSID[NVT_WSC_MAX_SSID_LEN];
|
|
// CHAR strPASSPHRASE[NVT_MAX_WEP_KEY_LEN];
|
|
//
|
|
// CHAR strSSID_hotspot_1[NVT_WSC_MAX_SSID_LEN];
|
|
// CHAR strPASSPHRASE_hotspot_1[NVT_MAX_WEP_KEY_LEN];
|
|
//
|
|
//
|
|
// //============Sifar==============///Payton
|
|
// SF_PARA_TIME_S TimelapseTime;
|
|
// SF_WORKTIME_S WorkTime[SF_TIMER_MAX_NUMBER];
|
|
// SF_PARA_TIME_S PirDelayTime;
|
|
// SF_PARA_TIME_S DailyReportTime;
|
|
// SF_PARA_TIME_S DailyReportTime2;
|
|
//
|
|
// SF_PARA_TIME_S TimeSend1;
|
|
// SF_PARA_TIME_S TimeSend2;
|
|
// SF_PARA_TIME_S TimeSend3;
|
|
// SF_PARA_TIME_S TimeSend4;
|
|
//
|
|
// //#2023/02/10#Payton - begin
|
|
// CHAR CamNameSwitch;/*ON/OFF ,cam name off*/
|
|
// CHAR CamMode;/* 0 Photo / 1 Video / 2 PIC+Video*/
|
|
// CHAR FlashLed;/* 0 High / 1 Low */
|
|
// CHAR ImgSize;/* 24M/12M/8M/5M */
|
|
// CHAR NightMode;/* Max.Range/Balanced/Min.Blur */
|
|
// CHAR Multishot;/*1P/2P/3P/4P/5P*/
|
|
// CHAR MultiShotIntevel;/*0s/1s/2s*/
|
|
// CHAR SendMulti;/*OFF/ON*/
|
|
// CHAR VideoSize;/*FHD-1080P/HD-720P/WVGA*/
|
|
// CHAR VideoTimeMenu;/*5/10/15/20/30/40/50/59*/
|
|
// CHAR VideoLenth;
|
|
// CHAR PirSwitch;/*OFF/ON*/
|
|
// CHAR PirSensitivity;/*High/Middle/Low*/
|
|
// CHAR PirDelaySwitch;/*OFF/ON*/
|
|
// CHAR TimelapseSwitch;/*OFF/ON*/
|
|
// CHAR WorkTime1Switch;/*OFF/ON*/
|
|
// CHAR WorkTime2Switch;/*OFF/ON*/
|
|
// CHAR SimAutoSwitch;/*Auto/Manual*/
|
|
// CHAR SendMaxNum;/*Unlimited/1~99*/
|
|
// CHAR GprsMode;/*Daily/Instant*/
|
|
// CHAR DailyReportSwitch;/*OFF/ON*/
|
|
// CHAR ReDailyReport;
|
|
// CHAR DailyReportTestSwitch;
|
|
// CHAR SimPinFlag;/*ON*/
|
|
// CHAR GpsSwitch;/*0:OFF;1:ON*/
|
|
// CHAR Language;
|
|
// CHAR DateStyle;/*YY/MM/DD-(CN) / MM/DD/YY-(US) / DD/MM/YY-(EU)*/
|
|
// CHAR StampSwitch;/*0:OFF;1:ON*///FL_DATE_STAMP
|
|
// CHAR BatteryType;/*Alkaline/NI-MH/LI*/
|
|
// CHAR SdLoopSwitch;/*0:OFF;1:ON*/
|
|
// CHAR PwdSwitch;/*0:OFF;1:ON*/
|
|
// CHAR SendPhotoSwitch;/*0:OFF;1:ON*/
|
|
// CHAR SendVideoSwitch;/*0:OFF;1:ON*/
|
|
// CHAR SendPicSize;/*Small/Bigger/Original*/
|
|
// CHAR SendMultishotIndex1;/*OFF/ON*/
|
|
// CHAR SendMultishotIndex2;/*OFF/ON*/
|
|
// CHAR SendMultishotIndex3;/*OFF/ON*/
|
|
// CHAR SendMultishotIndex4;/*OFF/ON*/
|
|
// CHAR SendMultishotIndex5;/*OFF/ON*/
|
|
// CHAR DateAuto;/*Auto/Manual*/
|
|
// CHAR NTPZoneS;
|
|
// CHAR NTPZoneH;
|
|
// CHAR NTPZoneM;
|
|
// CHAR DigitPirSensitivity;/*9\7\5*/
|
|
// CHAR DigitPirCnt;
|
|
// CHAR DigitPirWindowTime;
|
|
// CHAR CamArmDiable;
|
|
// CHAR DebugMode;/*0:OFF;1:ON*/
|
|
// CHAR AutoOffSwitch;/*0:OFF;1:ON*/
|
|
// CHAR AutoLogSwitch;/*0:OFF;1:ON*/
|
|
// CHAR RawSwitch;/*0:OFF;1:ON*/
|
|
// //ProfLogSwitch;/*0:OFF;1:ON*/
|
|
// CHAR GprsSwitch;/*0:OFF;1:ON*/
|
|
// CHAR GpsSendFlag;/*dp need send flag;*/
|
|
// CHAR FristSendDailyAndGps;
|
|
// CHAR NetGeneration;/*0:NO 1:xx 2:2G 3:3G 4:4G*/
|
|
// CHAR NeedTimeSyncStartUp;
|
|
// CHAR NetWorkNeedSearch;
|
|
// //SmsNumber;
|
|
// CHAR QLogSwitch;/*0:OFF;1:ON*/
|
|
// CHAR GpsAntiTheftSwitch;
|
|
// CHAR BatteryLogSwitch;
|
|
//
|
|
// ////////////S530////////
|
|
// CHAR GpsNumber;
|
|
// CHAR TimeSend1Switch;/*OFF/ON*/
|
|
// CHAR TimeSend2Switch;/*OFF/ON*/
|
|
// CHAR TimeSend3Switch;/*OFF/ON*/
|
|
// CHAR TimeSend4Switch;/*OFF/ON*/
|
|
// CHAR SendType;
|
|
// CHAR PicUpDailyReport;
|
|
// ///////////////////////
|
|
//
|
|
// CHAR CamNameStr[13];
|
|
// CHAR PwdStr[7];
|
|
// CHAR Latitude[16];
|
|
// CHAR Longitude[16];
|
|
// CHAR Sim4gApn[40];
|
|
// CHAR Sim4gUsr[40];
|
|
// CHAR Sim4gPwd[20];/* */
|
|
// CHAR SimPinStr[8];/* */
|
|
// CHAR MmsMmsc[50];
|
|
// CHAR MmsApn[40];
|
|
// CHAR MmsProxy[40];
|
|
// CHAR MmsPort[6];
|
|
// CHAR MmsUsr[40];
|
|
// CHAR MmsPwd[20];
|
|
// CHAR ModuleImei[20];
|
|
// CHAR ModuleVer[50];
|
|
// CHAR ModuleSubver[50];
|
|
// CHAR AcmIp[60];
|
|
// CHAR AcmPort[5];
|
|
// CHAR WebIp[70];
|
|
// CHAR OperatorCode[8];
|
|
// CHAR SimIccid[21];
|
|
// CHAR ServiceProvider[64];
|
|
// UINT8 SimSignal;
|
|
// UINT8 SimType;
|
|
// UINT8 FtpSwitch;/*FTP/OFF/FTPS*/
|
|
// UINT8 FtpIp[40];
|
|
// UINT8 FtpPort[5];
|
|
// UINT8 FtpUsr[40];
|
|
// UINT8 FtpPwd[20];
|
|
//
|
|
// UINT8 FtpsIp[40];
|
|
// UINT8 FtpsPort[5];
|
|
// UINT8 FtpsUsr[40];
|
|
// UINT8 FtpsPwd[20];
|
|
//
|
|
// UINT8 OtaFtpIp[40];
|
|
// UINT8 OtaFtpPort[5];
|
|
// UINT8 OtaFtpUserName[40];
|
|
// UINT8 OtaFtpPassWord[40];
|
|
//
|
|
// UINT8 WifiSwitch;
|
|
// UINT8 WifiMode;
|
|
// UINT8 WifiApPWD[16];
|
|
// UINT8 Zoom;
|
|
// UINT32 FileKey;
|
|
//
|
|
// UINT32 x1;
|
|
// UINT32 x2;
|
|
// UINT32 x3;
|
|
// UINT32 x4;
|
|
// UINT32 x5;
|
|
// UINT32 x6;
|
|
// //============Sifar==============///Payton
|
|
//
|
|
// } UIMenuStoreInfo;
|
|
#if 1
|
|
_THUMB2 static void *bl_get_sys_partition(unsigned char *p_fdt /*IN*/, int *p_id /*OUT*/)
|
|
{
|
|
#if (FDT_SUPPORT)
|
|
if (bl_get_partition(p_fdt, PATH_PARTITION_SYS, &g_emb_sys, p_id) != 0) {
|
|
return NULL;
|
|
}
|
|
#else
|
|
*p_id = NVTPACK_IDX_RTOS;
|
|
#endif
|
|
g_emb_sys.EmbType = 0x12;
|
|
return &g_emb_sys;
|
|
}
|
|
|
|
_THUMB2 static int bl_load_sys_from_flash(unsigned char *p_fdt, unsigned char *p_tmp)
|
|
{
|
|
int er;
|
|
int sys_partition_id;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
unsigned int blk_size = int_strg_obj->flash_getBlockSize();
|
|
EMB_PARTITION *p_emb_partition_sys = bl_get_sys_partition(p_fdt, &sys_partition_id);
|
|
|
|
if (p_emb_partition_sys == NULL) {
|
|
debug_err("null p_emb_partition_sys\r\n");
|
|
return -1;
|
|
}
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg(p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_sys->PartitionOffset / blk_size, p_emb_partition_sys->PartitionSize, p_tmp, NAND_RW_FIRMWARE)) < 0) {
|
|
debug_err_var("bl_load_sys_from_flash,er=", er);
|
|
bl_displayErrMsg(RWErrorMsg); // read sys failed
|
|
return -1;
|
|
}
|
|
|
|
// UIMenuStoreInfo* info = (UIMenuStoreInfo*)p_tmp;
|
|
|
|
// debug_err_var("FL_PHOTO_SIZE=", info->UIParameter[1]);
|
|
// debug_err_var("OtaFlag=", info->OtaFlag);
|
|
return 0;
|
|
}
|
|
/* assume ota_flag is read from partition_sys and in the first word */
|
|
_THUMB2 static UINT32 bl_check_ota_flag(UINT32 buf_fdt, UINT32 buf_size)
|
|
{
|
|
int er;
|
|
unsigned char *p_fdt = NULL;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
unsigned char *p_tmp = (unsigned char *)SDRAM_Start_FW;
|
|
|
|
// open flash
|
|
if (bl_flash_open() != 0) {
|
|
debug_msg("flash open failed\r\n");
|
|
return 0;
|
|
}
|
|
|
|
#if (FDT_SUPPORT)
|
|
// load fdt
|
|
|
|
debug_msg_var("buf_fdt=", buf_fdt);
|
|
debug_msg_var("buf_size=", buf_size);
|
|
er = bl_load_fdt_from_flash((unsigned char *)buf_fdt, buf_size, &p_fdt); // dtb size less than 32MB to be safer.
|
|
if (er != 0) {
|
|
debug_err("load fdt failed\r\n");
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg(p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return 0;
|
|
}
|
|
|
|
if(bl_load_sys_from_flash((unsigned char *)p_dram_partition->fdt_addr, p_tmp)){
|
|
debug_err("bl_load_sys_from_flash failed\r\n");
|
|
return 0;
|
|
}
|
|
|
|
UINT32* ota_flag = (UINT32*)p_tmp;
|
|
debug_msg_var("ota_flag=", *ota_flag);
|
|
|
|
return (*ota_flag);
|
|
}
|
|
#endif
|
|
/***********************************************************************************/
|
|
|
|
_THUMB2 static int bl_load_rtos_from_flash(unsigned char *p_fdt, unsigned char *p_tmp)
|
|
{
|
|
int er;
|
|
int rtos_partition_id;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
unsigned int blk_size = int_strg_obj->flash_getBlockSize();
|
|
EMB_PARTITION *p_emb_partition_rtos = bl_get_rtos_partition(p_fdt, &rtos_partition_id);
|
|
SHMINFO *p_shminfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_BIN_INFO);
|
|
|
|
if (p_emb_partition_rtos == NULL) {
|
|
debug_err("null p_emb_partition_rtos\r\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg(p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
if(bl_is_smp(p_fdt)) {
|
|
bl_core2_prepare(p_dram_partition, 0);
|
|
//invalid Instruciton and data cache
|
|
CPUCleanInvalidateDCacheAll();
|
|
bl_core2_reset();
|
|
}
|
|
#endif
|
|
|
|
// load 1st block of rtos to tmp dram (to detect compressed u-boot)
|
|
unsigned int bininfo_preload_size = ALIGN_CEIL(BIN_INFO_OFFSET_RTOS + sizeof(HEADINFO), blk_size);
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_rtos->PartitionOffset / blk_size, bininfo_preload_size, p_tmp, NAND_RW_FIRMWARE)) < 0) {
|
|
debug_err_var("bl_load_rtos_from_flash,er=", er);
|
|
bl_displayErrMsg(RWErrorMsg); // read rtos failed
|
|
}
|
|
|
|
// flow to handle compressed u-boot and uncompressed one.
|
|
NVTPACK_BFC_HDR *pBfc = (NVTPACK_BFC_HDR *)p_tmp; // describe compressed u-boot
|
|
|
|
// load rtos bin to dram partiton location
|
|
//debug_msg_var("rtos_addr", p_dram_partition->rtos_addr);
|
|
//debug_msg_var("rtos_size", p_dram_partition->rtos_size);
|
|
|
|
if (pBfc->uiFourCC == MAKEFOURCC('B', 'C', 'L', '1')) {
|
|
|
|
if((cpu_to_be32(pBfc->uiAlgorithm) & 0xFF ) == 11)
|
|
{
|
|
/* lzma compressed image*/
|
|
debug_msg("lzma, use uboot\r\n");
|
|
er = bl_load_uboot_from_flash((unsigned char *)p_dram_partition->fdt_addr, p_tmp);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load uboot failed\r\n");
|
|
}
|
|
|
|
// boot uboot
|
|
er = bl_boot_uboot((unsigned char *)p_dram_partition->fdt_addr);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("boot uboot failed\r\n");
|
|
}
|
|
} else {
|
|
UINT32 size_comp_le = invertEndian(pBfc->uiSizeComp);
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_rtos->PartitionOffset / blk_size, ALIGN_CEIL(size_comp_le, blk_size), p_tmp, NAND_RW_FIRMWARE)) < 0) {
|
|
debug_err_var("bl_load_rtos_from_flash_comp,er=", er); // read bfc-rtos failed
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
LZ_Un_compress(p_tmp + sizeof(NVTPACK_BFC_HDR), (unsigned char *)p_dram_partition->rtos_addr, size_comp_le);
|
|
}
|
|
} else {
|
|
BININFO *p_bininfo = (BININFO *)(p_tmp + BIN_INFO_OFFSET_RTOS); // describe uncompressed u-boot
|
|
if (p_bininfo->head.Resv1[HEADINFO_RESV_IDX_BOOT_FLAG] & BOOT_FLAG_PARTLOAD_EN) {
|
|
// copy bininfo_preload to rtos_addr
|
|
bl_memcpy((UINT8 *)p_dram_partition->rtos_addr, p_tmp, bininfo_preload_size);
|
|
// preload some to get part-1 size for partial load and partial compressed load
|
|
UINT32 preload_size = ALIGN_CEIL(FW_PART1_SIZE_OFFSET, blk_size) - bininfo_preload_size;
|
|
|
|
if (preload_size!= 0) {
|
|
er = int_strg_obj->flash_readSectors(
|
|
(p_emb_partition_rtos->PartitionOffset + bininfo_preload_size) / blk_size,
|
|
preload_size,
|
|
(UINT8 *)(p_dram_partition->rtos_addr + bininfo_preload_size), NAND_RW_FIRMWARE
|
|
);
|
|
|
|
if (er < 0) {
|
|
debug_err_var("bl_load_rtos_from_flash_pl1,er=", er); // read bfc-uboot failed
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
}
|
|
UINT32 part1_size = *(UINT32 *)(p_dram_partition->rtos_addr + FW_PART1_SIZE_OFFSET);
|
|
debug_msg_var("part1_size",part1_size);
|
|
part1_size = ALIGN_CEIL(part1_size, blk_size);
|
|
//debug_msg_var("part1_size_aligned",part1_size);
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_rtos->PartitionOffset / blk_size, part1_size, (UINT8 *)p_dram_partition->rtos_addr, NAND_RW_FIRMWARE)) < 0) {
|
|
debug_err_var("bl_load_rtos_from_flash_pl1,er=", er);
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
// update loaded size
|
|
p_shminfo->boot.LdLoadSize = part1_size;
|
|
} else {
|
|
// full load
|
|
debug_msg_var("rtos_size", p_bininfo->head.BinLength);
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_rtos->PartitionOffset /blk_size, ALIGN_CEIL(p_bininfo->head.BinLength, blk_size), (UINT8 *)p_dram_partition->rtos_addr, NAND_RW_FIRMWARE)) < 0) {
|
|
debug_err_var("bl_load_rtos_from_flash,er=", er); // read bfc-uboot failed
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
// update loaded size
|
|
p_shminfo->boot.LdLoadSize = p_bininfo->head.BinLength;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
_THUMB2 static int bl_load_teeos_from_flash(unsigned char *p_fdt, unsigned char *p_tmp)
|
|
{
|
|
int er;
|
|
int teeos_partition_id;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
unsigned int blk_size = int_strg_obj->flash_getBlockSize();
|
|
EMB_PARTITION *p_emb_partition_teeos = bl_get_teeos_partition(p_fdt, &teeos_partition_id);
|
|
|
|
if (p_emb_partition_teeos == NULL) {
|
|
debug_err("null p_emb_partition_teeos\r\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg(p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// load 1st block of u-boot to tmp dram (to detect compressed u-boot)
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_teeos->PartitionOffset / blk_size, ALIGN_CEIL(BIN_INFO_OFFSET_TEEOS + sizeof(HEADINFO), blk_size), p_tmp, NAND_RW_FIRMWARE)) < 0) {
|
|
debug_err_var("bl_load_teeos_from_flash,er=", er);
|
|
bl_displayErrMsg(RWErrorMsg); // read teeos failed
|
|
}
|
|
|
|
// flow to handle compressed u-boot and uncompressed one.
|
|
#if (SECURE_DECRYPT_OPTEE_OS)
|
|
HEADINFO *p_headinfo = (HEADINFO *)(p_tmp); // describe uncompressed u-boot
|
|
#else
|
|
HEADINFO *p_headinfo = (HEADINFO *)(p_tmp + BIN_INFO_OFFSET_TEEOS); // describe uncompressed u-boot
|
|
|
|
#endif
|
|
|
|
if ((er = int_strg_obj->flash_readSectors(p_emb_partition_teeos->PartitionOffset / blk_size, ALIGN_CEIL(p_headinfo->BinLength, blk_size), (UINT8 *)p_dram_partition->teeos_addr, NAND_RW_FIRMWARE)) < 0) {
|
|
debug_err_var("bl_load_teeos_from_flash,er=", er); // read bfc-teeos failed
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
#if 0
|
|
if(1){
|
|
#else
|
|
if(is_secure_enable()) {
|
|
#endif
|
|
#if (SECURE_DECRYPT_OPTEE_OS)
|
|
|
|
unsigned int plaintext_size=0;
|
|
if((er = do_decrypt_aes(p_dram_partition->teeos_addr, p_dram_partition->teeos_addr, &plaintext_size, p_dram_partition->teeos_size)) != 0)
|
|
{
|
|
//debug_err("aes fail\r\n");
|
|
return er;
|
|
}
|
|
|
|
p_headinfo = (HEADINFO *)(p_dram_partition->teeos_addr + BIN_INFO_OFFSET_TEEOS); // describe uncompressed u-boot
|
|
#else
|
|
debug_err("please ENABLE SECURE_DECRYPT_OPTEE_OS config\n");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
// load teeos bin to dram partiton location
|
|
UINT32 teeos_addr = p_headinfo->Resv1[HEADINFO_TEEOS_RESV_IDX_LOAD_ADDR];
|
|
debug_msg_var("teeos_addr", p_dram_partition->teeos_addr);
|
|
if (teeos_addr != p_dram_partition->teeos_addr) {
|
|
debug_msg_var("teeos_addr(bin)", teeos_addr);
|
|
debug_err("teeos addr not matched.\r\n");
|
|
return -1;
|
|
}
|
|
//check check sum
|
|
if (bl_chk_uboot((unsigned int)teeos_addr, p_headinfo->BinLength) != 0) {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if !(USB_WRITELOADER || UART_UPDATE)
|
|
_THUMB2 static int bl_load_rtos_from_non_nvtpack(unsigned int src_addr, unsigned int src_size, unsigned int *p_dst_addr, unsigned int *p_dst_size)
|
|
{
|
|
NVTPACK_BFC_HDR *pBFC = (NVTPACK_BFC_HDR *)src_addr;
|
|
HEADINFO *p_headinfo = (HEADINFO *)(src_addr + BIN_INFO_OFFSET_RTOS);
|
|
if (pBFC->uiFourCC == MAKEFOURCC('B', 'C', 'L', '1')) {
|
|
// to avoid rtos_addr is overlapped by src_addr, we need extract some bits to get real rtos addr.
|
|
// compressed firmware
|
|
debug_msg("compressed t.bin\r\n");
|
|
// decode some bytes to get uncompressed address
|
|
bl_decompress_rtos(src_addr, SIZE_PRELOAD, src_addr + SIZE_PRELOAD);
|
|
p_headinfo = (HEADINFO *)(src_addr + SIZE_PRELOAD + BIN_INFO_OFFSET_RTOS);
|
|
// check if valid after decode
|
|
if ((strncmp(p_headinfo->BinInfo_1, "NT", 2) == 0) ||
|
|
(strncmp(p_headinfo->BinInfo_1, "NC", 2) == 0)) {
|
|
UINT32 uncompress_addr = p_headinfo->CodeEntry - CODE_SECTION_OFFSET;
|
|
UINT32 uncompress_size = p_headinfo->BinLength;
|
|
UINT32 compress_size = invertEndian(pBFC->uiSizeComp) + sizeof(NVTPACK_BFC_HDR);
|
|
//adjust src_addr that lay compressed f.w followed by uncomppressed f.w
|
|
src_addr = uncompress_addr + uncompress_size;
|
|
src_addr = ALIGN_CEIL(src_addr, 4);
|
|
src_size = fat_read_rootfile((UINT8 *)src_addr, compress_size);
|
|
} else {
|
|
return -1;
|
|
}
|
|
} else if ((strncmp(p_headinfo->BinInfo_1, "NT", 2) == 0) ||
|
|
(strncmp(p_headinfo->BinInfo_1, "NC", 2) == 0)) {
|
|
// uncompressed firmware
|
|
UINT32 uncompress_addr = p_headinfo->CodeEntry - CODE_SECTION_OFFSET;
|
|
UINT32 uncompress_size = p_headinfo->BinLength;
|
|
|
|
src_size = fat_read_rootfile((UINT8 *)src_addr, uncompress_size);
|
|
src_addr = uncompress_addr;
|
|
src_size = uncompress_size;
|
|
debug_msg("uncompressed t.bin\r\n");
|
|
#if (DRAM_RANGE_SCAN_EN == ENABLE)
|
|
} else if (utl_is_sram_fw(src_addr) == TRUE) {
|
|
debug_msg("detected as SRAM fw\r\n");
|
|
src_size = fat_read_rootfile((UINT8 *)src_addr, FAT_READ_TOTAL_FILE_LENGTH);
|
|
#endif
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
*p_dst_addr = src_addr;
|
|
*p_dst_size = src_size;
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if 0//(STORAGE_EXT_TYPE == STORAGE_EXT_USB)
|
|
_THUMB2 static int bl_load_rtos_from_usb_raw(unsigned int src_addr, unsigned int src_size, unsigned int *p_dst_addr, unsigned int *p_dst_size)
|
|
{
|
|
NVTPACK_BFC_HDR *pBFC = (NVTPACK_BFC_HDR *)src_addr;
|
|
HEADINFO *p_headinfo = (HEADINFO *)(src_addr + BIN_INFO_OFFSET_RTOS);
|
|
if (pBFC->uiFourCC == MAKEFOURCC('B', 'C', 'L', '1')) {
|
|
// to avoid rtos_addr is overlapped by src_addr, we need extract some bits to get real rtos addr.
|
|
// compressed firmware
|
|
debug_msg("compressed t.bin\r\n");
|
|
// decode some bytes to get uncompressed address
|
|
// assume usb write loader receive full fw at 0x0200_0000, decompress it to smaller address
|
|
bl_decompress_rtos(src_addr, SIZE_PRELOAD, src_addr - SIZE_PRESERVE_USB);
|
|
p_headinfo = (HEADINFO *)(src_addr - SIZE_PRESERVE_USB + BIN_INFO_OFFSET_RTOS);
|
|
// check if valid after decode
|
|
if ((strncmp(p_headinfo->BinInfo_1, "NT", 2) == 0) ||
|
|
(strncmp(p_headinfo->BinInfo_1, "NC", 2) == 0)) {
|
|
UINT32 uncompress_addr = p_headinfo->CodeEntry - CODE_SECTION_OFFSET;
|
|
UINT32 uncompress_size = p_headinfo->BinLength;
|
|
UINT32 compress_size = invertEndian(pBFC->uiSizeComp) + sizeof(NVTPACK_BFC_HDR);
|
|
//adjust src_addr that lay compressed f.w followed by uncomppressed f.w
|
|
utl_memcpy((void *)(uncompress_addr + uncompress_size), (void *)src_addr, compress_size);
|
|
src_addr = uncompress_addr + uncompress_size;
|
|
src_addr = ALIGN_CEIL(src_addr, 4);
|
|
src_size = compress_size;
|
|
} else {
|
|
return -1;
|
|
}
|
|
} else if ((strncmp(p_headinfo->BinInfo_1, "NT", 2) == 0) ||
|
|
(strncmp(p_headinfo->BinInfo_1, "NC", 2) == 0)) {
|
|
// uncompressed firmware
|
|
UINT32 uncompress_addr = p_headinfo->CodeEntry - CODE_SECTION_OFFSET;
|
|
UINT32 uncompress_size = p_headinfo->BinLength;
|
|
debug_msg("uncompressed t.bin\r\n");
|
|
utl_memcpy((void *)uncompress_addr, (void *)src_addr, uncompress_size);
|
|
src_size = uncompress_size;
|
|
#if (DRAM_RANGE_SCAN_EN == ENABLE)
|
|
} else if (utl_is_sram_fw(src_addr) == TRUE) {
|
|
debug_msg("detected as SRAM fw. NOt Support from USB\r\n");
|
|
#endif
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
*p_dst_addr = src_addr;
|
|
*p_dst_size = src_size;
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
//#if !USB_WRITELOADER
|
|
#if !((STORAGE_EXT_TYPE == STORAGE_EXT_USB) || (STORAGE_EXT_TYPE == STORAGE_EXT_UART))
|
|
_THUMB2 static int bl_load_rtos_from_uart(unsigned int src_addr, unsigned int src_size, unsigned int *p_dst_addr, unsigned int *p_dst_size)
|
|
{
|
|
#if UART_UPDATE_
|
|
UINT32 tick_kms = 10; // timeout 1000 ms
|
|
char key;
|
|
|
|
debug_msg("UART press Enter to\r\n");
|
|
|
|
while (--tick_kms) {
|
|
uart_chkChar(&key);
|
|
|
|
if (key != 0x00) {
|
|
break;
|
|
}
|
|
timer_delay(100000); //100000
|
|
debug_msg(".");
|
|
}
|
|
|
|
if (tick_kms) {
|
|
UINT32 uiLength;
|
|
debug_msg("\r\nEnter uboot length (Decimal):\r\n"); //must \r\n at the end because of auto_test tool
|
|
uart_getStr_polling(g_strLength);
|
|
uiLength = DecStr2Int(g_strLength);
|
|
debug_msg("\r\nPlz pass uboot bin > ");
|
|
uart_getBinary((char *)src_addr, uiLength); // Temp Receive to DRAM start
|
|
debug_msg("\r\nGot it\r\n");
|
|
#if (DRAM_RANGE_SCAN_EN == ENABLE)
|
|
// First word is code entry point address, once if entry address is 0xC000XXXX
|
|
// represent code is running on sram.
|
|
if (bl_checkDramScanFW(src_addr) == TRUE) {
|
|
UINT32 i;
|
|
|
|
// Enable sram usage
|
|
SETREG32(0xF0900128, 0x00000002);
|
|
SETREG32(0xF0800128, 0x00000006);
|
|
SETREG32(0xF0020060, 0x00030002);
|
|
|
|
uiLength = ((uiLength + 3) & 0xFFFFFFFC);
|
|
|
|
for (i = 0; i < uiLength; i += 4) {
|
|
*(UINT32 *)(src_addr + i) = *(UINT32 *)(src_addr + i);
|
|
}
|
|
*(UINT32 *)(src_addr) = *(UINT32 *)(src_addr);
|
|
return 1;
|
|
}
|
|
#endif
|
|
if (*(UINT32 *)src_addr == MAKEFOURCC('B', 'C', 'L', '1')) {
|
|
HEADINFO *p_headinfo = NULL;
|
|
NVTPACK_BFC_HDR *pBFC = (NVTPACK_BFC_HDR *)src_addr;
|
|
bl_checkFW(src_addr, uiLength);
|
|
debug_msg_var("uiLength", uiLength);
|
|
debug_msg("compressed t.bin\r\n");
|
|
// decode some bytes to get uncompressed address
|
|
bl_decompress_rtos(src_addr, SIZE_PRELOAD, src_addr + uiLength);
|
|
p_headinfo = (HEADINFO *)(src_addr + uiLength + BIN_INFO_OFFSET_RTOS);
|
|
// check if valid after decode
|
|
if ((strncmp(p_headinfo->BinInfo_1, "NT", 2) == 0) ||
|
|
(strncmp(p_headinfo->BinInfo_1, "NC", 2) == 0)) {
|
|
UINT32 uncompress_addr = p_headinfo->CodeEntry - CODE_SECTION_OFFSET;
|
|
UINT32 uncompress_size = p_headinfo->BinLength;
|
|
UINT32 compress_size = invertEndian(pBFC->uiSizeComp) + sizeof(NVTPACK_BFC_HDR);
|
|
unsigned int ori_src_addr = src_addr;
|
|
//adjust src_addr that lay compressed f.w followed by uncomppressed f.w
|
|
src_addr = uncompress_addr + uncompress_size;
|
|
src_addr = ALIGN_CEIL(src_addr, 4);
|
|
src_size = uncompress_size;
|
|
utl_memcpy((void *)src_addr, (void *)ori_src_addr, uiLength);
|
|
*p_dst_addr = src_addr;
|
|
*p_dst_size = compress_size;
|
|
return 0;
|
|
} else {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
#endif
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
_THUMB2 static void bl_update_uItron_headInfo(UINT32 fw_base_addr, DRAM_PARTITION *p_dram_partition)
|
|
{
|
|
HEADINFO *pHeadInfo;
|
|
#if (UITRON_FW == ENABLE)
|
|
BININFO *pBinInfo;
|
|
#endif
|
|
pHeadInfo = (HEADINFO *)(fw_base_addr + BIN_INFO_OFFSET_RTOS);
|
|
if (p_dram_partition) {
|
|
pHeadInfo->ModelextAddr = p_dram_partition->fdt_addr;
|
|
} else {
|
|
pHeadInfo->ModelextAddr = 0;
|
|
#if (UITRON_FW == ENABLE)
|
|
pBinInfo = (BININFO *)(fw_base_addr + BIN_INFO_OFFSET_RTOS);
|
|
pBinInfo->ld.Resv[0] = LoaderInternalInfo[1];
|
|
pBinInfo->ld.LdPackage = (LoaderInternalInfo[3] & 0xFFFF);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
_THUMB2 static int bl_update_loader_bininfo(unsigned char *p_fdt, unsigned int ld_flag, unsigned int rtos_loaded_size)
|
|
{
|
|
BOOTINFO *p_ld;
|
|
SHMINFO *p_shminfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_BIN_INFO);
|
|
DRAM_PARTITION *p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
BININFO *p_bininfo = (BININFO *)(p_dram_partition->rtos_addr + BIN_INFO_OFFSET_RTOS);
|
|
|
|
p_ld = &p_shminfo->boot;
|
|
if (!(p_bininfo->head.Resv1[HEADINFO_RESV_IDX_BOOT_FLAG] & BOOT_FLAG_PARTLOAD_EN)) {
|
|
// LdLoadSize updated on uboot or bl_load_rtos_from_flash(), if BOOT_FLAG_PARTLOAD_EN
|
|
p_ld->LdLoadSize = rtos_loaded_size;
|
|
}
|
|
p_ld->LdLoadTime = timer_getLdrElapse();
|
|
p_ld->LdResvSize = 0; //unused
|
|
p_ld->FWResvSize = 0; //unused
|
|
return 0;
|
|
}
|
|
|
|
_THUMB2 static int bl_is_smp(unsigned char *p_fdt)
|
|
{
|
|
#if (FDT_SUPPORT)
|
|
int len;
|
|
const char *nodep;
|
|
nodep = (const char *)bl_get_fdt_property(p_fdt, PATH_NVT_INFO, PROPERTY_NVT_LINUX_SMP, &len);
|
|
debug_msg_var("nodep", (UINT32)nodep);
|
|
if (nodep == NULL) {
|
|
return 0;
|
|
}
|
|
debug_msg((char *)nodep);
|
|
if (strcmp(nodep, "NVT_LINUX_SMP_ON") == 0) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
#if !REMOVED_FLASH
|
|
_THUMB2 int bl_boot_uboot(unsigned char *p_fdt)
|
|
{
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
UINT32 No_CPU;
|
|
#endif
|
|
DRAM_PARTITION *p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// update shminfo
|
|
SHMINFO *p_shminfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_BIN_INFO);
|
|
unsigned int *p_param = (unsigned int *)(&_load_LOADER_CONFIGRAM_FREQ_PARAM_start_base[0]);
|
|
p_shminfo->boot.LdPackage = p_param[3] & 0xFFFF;
|
|
p_shminfo->boot.LdStorage = (p_param[3] >> 16) & 0xFF;
|
|
|
|
// update headinfo as real u-boot address
|
|
HEADINFO *p_headinfo = (HEADINFO *)(p_dram_partition->uboot_addr + BIN_INFO_OFFSET_UBOOT);
|
|
|
|
if (bl_chk_uboot(p_dram_partition->uboot_addr, p_headinfo->BinLength) != 0) {
|
|
return -1;
|
|
}
|
|
// start cpu2
|
|
if (p_dram_partition->uboot_addr != p_headinfo->CodeEntry) {
|
|
debug_err_var("drampat-uboot_addr ", (int)p_dram_partition->uboot_addr);
|
|
debug_err_var("bin-uboot_addr ", (int)p_headinfo->CodeEntry);
|
|
return -1;
|
|
}
|
|
// for uboot to indicate this boot is all-in-one fw or non-all-in-one boot from uart or usb
|
|
// if boot from uart or usb with non-all-in-one fw, the uboot's ModelextAddr will be zero
|
|
p_headinfo->ModelextAddr = p_dram_partition->fdt_addr;
|
|
|
|
CPUflushWriteCache(p_headinfo->CodeEntry, p_headinfo->BinLength);
|
|
UINT32 isSMP = bl_is_smp(p_fdt);
|
|
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
No_CPU = *(UINT32 *)0xFFD00004;
|
|
No_CPU &= 0x3;
|
|
debug_msg_var("core No.=", No_CPU+1);
|
|
#endif
|
|
// init cpu timer
|
|
// bl_cpu_timer_init(CPU_TIMER_SETTING);
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
if (!isSMP || !No_CPU)
|
|
#else
|
|
if (!isSMP)
|
|
#endif
|
|
{
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
debug_msg_var("Bin core=", isSMP+1);
|
|
#endif
|
|
bl_entry_boot(p_fdt, p_headinfo->CodeEntry);
|
|
} else {
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
// init cpu timer
|
|
bl_cpu_timer_init(global_timer_freq);
|
|
|
|
bl_smp_start(p_fdt, p_headinfo->CodeEntry);
|
|
// boot u-boot and never return back to loader
|
|
#else
|
|
//bl_smp_start(p_fdt, p_headinfo->CodeEntry);
|
|
debug_err("not support smp\r\n");
|
|
#endif
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#if (NUTTX_SUPPORT)
|
|
_THUMB2 static int bl_boot_nuttx(unsigned char *p_fdt)
|
|
{
|
|
DRAM_PARTITION *p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// update headinfo as real u-boot address
|
|
HEADINFO *p_headinfo = (HEADINFO *)(p_dram_partition->nuttx_addr + BIN_INFO_OFFSET_NUTTX);
|
|
|
|
if (bl_chk_uboot(p_dram_partition->nuttx_addr, p_headinfo->BinLength) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
// start cpu2
|
|
if (p_dram_partition->nuttx_addr != p_headinfo->CodeEntry) {
|
|
debug_err_var("drampat-nuttx_addr ", (int)p_dram_partition->nuttx_addr);
|
|
debug_err_var("bin-nuttx_addr ", (int)p_headinfo->CodeEntry);
|
|
return -1;
|
|
}
|
|
|
|
CPUflushWriteCache(p_headinfo->CodeEntry, p_headinfo->BinLength);
|
|
|
|
// init cpu timer
|
|
bl_cpu_timer_init(CPU_TIMER_SETTING);
|
|
|
|
bl_entry_boot(p_fdt, p_headinfo->CodeEntry);
|
|
// boot nuttx and never return back to loader
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
_THUMB2 static int bl_boot_teeos(unsigned char *p_fdt)
|
|
{
|
|
DRAM_PARTITION *p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition == NULL) {
|
|
debug_err("null p_dram_partition\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// update headinfo as real u-boot address
|
|
HEADINFO *p_headinfo = (HEADINFO *)(p_dram_partition->teeos_addr + BIN_INFO_OFFSET_TEEOS);
|
|
|
|
// update uboot addr for teeos
|
|
p_headinfo->Resv1[HEADINFO_TEEOS_RESV_IDX_UBOOT_ADDR] = p_dram_partition->uboot_addr;
|
|
|
|
|
|
#if 0 //do not checksum, because teeos header has removed cause checksum failed
|
|
if (bl_chk_uboot(p_dram_partition->teeos_addr, p_headinfo->BinLength) != 0) {
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
//flush uboot
|
|
CPUflushWriteCache(p_dram_partition->uboot_addr, p_dram_partition->uboot_size);
|
|
//flush teeos
|
|
CPUflushWriteCache(p_headinfo->CodeEntry, p_headinfo->BinLength);
|
|
|
|
// init cpu timer
|
|
|
|
#if 0//(LOADER_TYPE == STAND_ALONE_LOADER_528) || (LOADER_TYPE == COMBINATION_528)
|
|
bl_cpu_timer_init(CPU_TIMER_SETTING);
|
|
// boot core2 (after teeos is loaded)
|
|
if (HEADINFO_UBOOT(p_dram_partition)->BinCtrl & 0x00000002) {
|
|
//if SMP, trigger core2
|
|
debug_msg("smp(tee)\r\n");
|
|
bl_core2_prepare(p_dram_partition, p_headinfo->CodeEntry);
|
|
//invalid Instruciton and data cache
|
|
CPUCleanInvalidateDCacheAll();
|
|
bl_core2_reset();
|
|
} else {
|
|
debug_msg_var("not smp\r\n", p_headinfo->BinCtrl);
|
|
}
|
|
#endif
|
|
bl_entry_boot(p_fdt, p_headinfo->CodeEntry);
|
|
// boot teeos and never return back to loader
|
|
return 0;
|
|
}
|
|
|
|
_THUMB2 static int bl_update_loader_flag(unsigned char *p_fdt, UINT32 uiLoaderFunc)
|
|
{
|
|
SHMINFO *p_bininfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_BIN_INFO);
|
|
|
|
utl_memcpy(p_bininfo->boot.LdInfo_1, "LD_NVT", 6);
|
|
|
|
p_bininfo->boot.LdCtrl2 = 0;
|
|
if (uiLoaderFunc & FUNC_UPDATE_FW) {
|
|
p_bininfo->boot.LdCtrl2 |= LDCF_UPDATE_FW;
|
|
}
|
|
if (uiLoaderFunc & FUNC_UPDATE_LOADER) {
|
|
p_bininfo->boot.LdCtrl2 |= LDCF_UPDATE_LD;
|
|
}
|
|
if (uiLoaderFunc & FUNC_RUN_CARD) {
|
|
p_bininfo->boot.LdCtrl2 |= LDCF_BOOT_CARD;
|
|
}
|
|
if (uiLoaderFunc & FUNC_RUN_FLASH) {
|
|
p_bininfo->boot.LdCtrl2 |= LDCF_BOOT_FLASH;
|
|
}
|
|
//CPUflushWriteCache((UINT32)p_bininfo, sizeof(BININFO));
|
|
debug_msg_var("LdCtrl2", p_bininfo->boot.LdCtrl2);
|
|
|
|
unsigned int ver;
|
|
SHMINFO *p_shminfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_fdt, MODELEXT_TYPE_BIN_INFO);
|
|
BOOTINFO *p_ld = &p_shminfo->boot;
|
|
|
|
utl_memset(p_ld->LdInfo_1, 0, sizeof(p_ld->LdInfo_1));
|
|
utl_memcpy(p_ld->LdInfo_1, "LD_NVT", 6);
|
|
|
|
ver = (((LoaderInternalInfo[1] >> 28) & 0xF) << 24) |
|
|
(((LoaderInternalInfo[1] >> 24) & 0xF) << 16) |
|
|
((LoaderInternalInfo[1] >> 16) & 0xFF);
|
|
|
|
if (g_uiVersion == 0) {
|
|
g_uiVersion = ver;
|
|
}
|
|
|
|
utl_memcpy(&p_ld->LdInfo_1[8], &g_uiVersion, sizeof(g_uiVersion));
|
|
unsigned int *p_param = (unsigned int *)(&_load_LOADER_CONFIGRAM_FREQ_PARAM_start_base[0]);
|
|
p_ld->LdPackage = p_param[3] & 0xFFFF;
|
|
p_ld->LdStorage = (p_param[3] >> 16) & 0xFF;
|
|
|
|
return 0;
|
|
}
|
|
|
|
// return uItron_fw_addr
|
|
_THUMB2 unsigned int bl_process_all_in_one(UINT32 uiFwBuf, UINT32 uiFwBufSize, DRAM_PARTITION **pOut_dram_partition, UINT32 uiLoaderFunc, UINT32 *p_comp_addr, UINT32 *p_comp_size)
|
|
{
|
|
int er;
|
|
unsigned char *p_fdt = NULL;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
//p_tmp for the case of all-in-one without fdt or uboot
|
|
unsigned char *p_tmp = (unsigned char *)(uiFwBuf + ALIGN_CEIL(uiFwBufSize, 4));
|
|
|
|
// load fdt
|
|
er = bl_load_fdt_from_all_in_one((unsigned char *)uiFwBuf, uiFwBufSize, &p_fdt);
|
|
if (er == -2) { // try to load from nand
|
|
debug_msg("fdt from flash.\r\n");
|
|
// open flash
|
|
if (bl_flash_open() != 0) { // dont move flash open outside section, consider that T without flash device.
|
|
bl_displayErrMsg("flash open failed\r\n");
|
|
}
|
|
|
|
//p_tmp for the case of all-in-one without fdt or uboot
|
|
unsigned char *p_tmp = (unsigned char *)(uiFwBuf + ALIGN_CEIL(uiFwBufSize, 4));
|
|
er = bl_load_fdt_from_flash(p_tmp, 0x2000000, &p_fdt); // dtb size less than 32MB to be safer.
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load fdt failed\r\n");
|
|
}
|
|
}
|
|
else if (er == -1){
|
|
return 0;
|
|
}
|
|
// update loader flag
|
|
bl_update_loader_flag(p_fdt, uiLoaderFunc);
|
|
if (uiLoaderFunc & FUNC_UPDATE_FW) {
|
|
SHMINFO *p_bininfo = (SHMINFO *)bl_get_fdt_cfg(p_fdt, MODELEXT_TYPE_BIN_INFO);
|
|
if (p_bininfo == NULL) {
|
|
debug_err("null p_bininfo\r\n");
|
|
return -1;
|
|
}
|
|
p_bininfo->comm.Resv[5] = uiFwBuf; // COMM_FW_UPD_ADDR
|
|
p_bininfo->comm.Resv[6] = uiFwBufSize; // COMM_FW_UPD_LEN
|
|
debug_msg_var("upd_src_addr=", uiFwBuf);
|
|
debug_msg_var("upd_src_size=", uiFwBufSize);
|
|
}
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg(p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
//check loader addr is matched with loader self.
|
|
extern char _loader_exec_compres_start[];
|
|
if (p_dram_partition->loader_addr != (UINT32)_loader_exec_compres_start) {
|
|
debug_msg_var("p_dram_partition->loader_addr", p_dram_partition->loader_addr);
|
|
debug_msg_var("_loader_exec_compres_start", (UINT32)_loader_exec_compres_start);
|
|
bl_displayErrMsg("loader addr is not match.");
|
|
}
|
|
//when rtos boot from flash, the boot from loader directly,
|
|
//but when rtos need to burn image, the uboot is still required.
|
|
//so, any one need to burn image, uboot is always needed to boot.
|
|
//if ((uiLoaderFunc & FUNC_UPDATE_FW) || p_dram_partition->rtos_addr == 0) {
|
|
if (1) {
|
|
// always use uboot to handle all-in-one bin
|
|
if (p_dram_partition->nuttx_size == 0 && p_dram_partition->teeos_size == 0) {
|
|
// load uboot
|
|
er = bl_load_uboot_from_all_in_one((unsigned char *)p_dram_partition->fdt_addr, (unsigned char *)uiFwBuf, uiFwBufSize);
|
|
if (er == -2) { // try to load from nand
|
|
debug_msg("uboot from flash.\r\n");
|
|
// open flash
|
|
if (bl_flash_open() != 0) { // dont move flash open outside section, consider that T without flash device.
|
|
bl_displayErrMsg("flash open failed\r\n");
|
|
}
|
|
er = bl_load_uboot_from_flash((unsigned char *)p_dram_partition->fdt_addr, p_tmp);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load uboot failed\r\n");
|
|
}
|
|
}
|
|
|
|
er = bl_boot_uboot((unsigned char *)p_dram_partition->fdt_addr);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("boot uboot failed\r\n");
|
|
}
|
|
} else if (p_dram_partition->nuttx_size) {
|
|
#if (NUTTX_SUPPORT)
|
|
// load nuttx
|
|
er = bl_load_nuttx_from_all_in_one((unsigned char *)p_dram_partition->fdt_addr, (unsigned char *)uiFwBuf, uiFwBufSize);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load nuttx failed\r\n");
|
|
}
|
|
er = bl_boot_nuttx((unsigned char *)p_dram_partition->fdt_addr);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("boot nuttx failed\r\n");
|
|
}
|
|
#else
|
|
bl_displayErrMsg("NUTTX_SUPPORT disabled\r\n");
|
|
#endif
|
|
} else if (p_dram_partition->teeos_size) {
|
|
// load teeos
|
|
er = bl_load_teeos_from_all_in_one((unsigned char *)p_dram_partition->fdt_addr, (unsigned char *)uiFwBuf, uiFwBufSize);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load teeos failed\r\n");
|
|
}
|
|
// load uboot
|
|
er = bl_load_uboot_from_all_in_one((unsigned char *)p_dram_partition->fdt_addr, (unsigned char *)uiFwBuf, uiFwBufSize);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load uboot failed\r\n");
|
|
}
|
|
// boot teeos
|
|
er = bl_boot_teeos((unsigned char *)p_dram_partition->fdt_addr);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("boot teeos failed\r\n");
|
|
}
|
|
}
|
|
return er;
|
|
} else {
|
|
// update rtos information
|
|
// the following is for uncompressed-rtos only, others needing uboot
|
|
SHMINFO *p_bininfo = (SHMINFO *)bl_get_fdt_cfg((const void *)p_dram_partition->fdt_addr, MODELEXT_TYPE_BIN_INFO);
|
|
|
|
if (p_bininfo == NULL) {
|
|
debug_err("null p_bininfo\r\n");
|
|
return -1;
|
|
}
|
|
*p_comp_addr = p_bininfo->comm.Resv[3]; // COMM_UITRON_COMP_ADDR
|
|
*p_comp_size = p_bininfo->comm.Resv[4]; // COMM_UITRON_COMP_LEN
|
|
|
|
*pOut_dram_partition = p_dram_partition;
|
|
return bl_load_rtos_from_all_in_one((unsigned char *)uiFwBuf, uiFwBufSize, &p_fdt);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// return uItron_fw_addr, no need to fully decode
|
|
_THUMB2 static unsigned int bl_process_rtos_only(UINT32 uiFwBuf, UINT32 uiFwBufSize, UINT32 uiLoaderFunc, UINT32 *p_comp_addr, UINT32 *p_comp_size)
|
|
{
|
|
UINT32 uItron_fw_addr;
|
|
NVTPACK_BFC_HDR *pBFC;
|
|
HEADINFO *p_headinfo;
|
|
|
|
debug_msg("\r\nbl_process_rtos_only\r\n");
|
|
pBFC = (NVTPACK_BFC_HDR *)uiFwBuf;
|
|
if (pBFC->uiFourCC == MAKEFOURCC('B', 'C', 'L', '1')) {
|
|
UINT32 compressSize;
|
|
unsigned char *p_tmp = (unsigned char *)(uiFwBuf + ALIGN_CEIL(uiFwBufSize, 4));
|
|
LZ_Un_compress((UINT8 *)uiFwBuf + LDC_HEADER_SIZE, p_tmp, SIZE_PRELOAD);
|
|
p_headinfo = (HEADINFO *)(p_tmp + BIN_INFO_OFFSET_RTOS);
|
|
uItron_fw_addr = p_headinfo->CodeEntry - CODE_SECTION_OFFSET;
|
|
#if UITRON_FW
|
|
uItron_fw_addr = p_headinfo->CodeEntry - CODE_ENTRY_OFFSET; // cliff
|
|
#endif
|
|
|
|
if ((uItron_fw_addr & 0x0000FFFF) != 0) { //cc engine's limitation
|
|
debug_err_var("rtos addr must match (&0x0000FFFF)==0", uItron_fw_addr); // but 660 allow
|
|
uItron_fw_addr = uItron_fw_addr & 0xFFFF0000;
|
|
}
|
|
compressSize = invertEndian(pBFC->uiSizeComp) + sizeof(NVTPACK_BFC_HDR);
|
|
//debug_dump_addr(tmpBuf,0x200);
|
|
debug_msg_var("F compress uItron_fw_addr", uItron_fw_addr);
|
|
// uiFwBuf has adjusted on bl_load_rtos_from_non_nvtpack()
|
|
*p_comp_addr = uiFwBuf;
|
|
*p_comp_size = compressSize;
|
|
} else {
|
|
p_headinfo = (HEADINFO *)(uiFwBuf + BIN_INFO_OFFSET_RTOS);
|
|
uItron_fw_addr = p_headinfo->CodeEntry - CODE_SECTION_OFFSET;
|
|
#if UITRON_FW
|
|
uItron_fw_addr = p_headinfo->CodeEntry - CODE_ENTRY_OFFSET; // cliff
|
|
#endif
|
|
|
|
if ((uItron_fw_addr & 0x0000FFFF) != 0) { //cc engine's limitation
|
|
debug_err_var("rtos addr must match (&0x0000FFFF)==0", uItron_fw_addr); // but 660 allow
|
|
uItron_fw_addr = uItron_fw_addr & 0xFFFF0000;
|
|
}
|
|
|
|
debug_msg_var("Normal uItron_fw_addr", uItron_fw_addr);
|
|
*p_comp_addr = 0;
|
|
*p_comp_size = 0;
|
|
}
|
|
return uItron_fw_addr;
|
|
}
|
|
#if !UPDATE_EMU_CODE && !REMOVED_FLASH
|
|
_THUMB2 static unsigned int bl_process_flash_boot(unsigned char *p_tmp, DRAM_PARTITION **pOut_dram_partition, UINT32 uiLoaderFunc, UINT32 *p_comp_addr, UINT32 *p_comp_size)
|
|
{
|
|
int er;
|
|
unsigned char *p_fdt = NULL;
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
|
|
// open flash
|
|
if (bl_flash_open() != 0) {
|
|
bl_displayErrMsg("flash open failed\r\n");
|
|
}
|
|
|
|
// load fdt
|
|
er = bl_load_fdt_from_flash(p_tmp, SDRAM_Start_FW, &p_fdt); // dtb size less than 32MB to be safer.
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load fdt failed\r\n");
|
|
}
|
|
|
|
// update loader flag
|
|
bl_update_loader_flag(p_fdt, uiLoaderFunc);
|
|
|
|
p_dram_partition = (DRAM_PARTITION *)bl_get_fdt_cfg(p_fdt, MODELEXT_TYPE_DRAM_PARTITION);
|
|
|
|
if (p_dram_partition->teeos_size) {
|
|
// load teeos
|
|
er = bl_load_teeos_from_flash((unsigned char *)p_dram_partition->fdt_addr, p_tmp);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load teeos failed\r\n");
|
|
}
|
|
// load uboot
|
|
er = bl_load_uboot_from_flash((unsigned char *)p_dram_partition->fdt_addr, p_tmp);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load uboot failed\r\n");
|
|
}
|
|
// boot teeos
|
|
er = bl_boot_teeos((unsigned char *)p_dram_partition->fdt_addr);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("boot teeos failed\r\n");
|
|
}
|
|
}
|
|
#if 1
|
|
//added by greg
|
|
else if (p_dram_partition->rtos_addr == 0 || DUAL_RTOS_SUPPORT || (gFastbootKeyCallBack == NULL) || (!gFastbootKeyCallBack()|| g_update_from_emmc)) {
|
|
// load uboot
|
|
er = bl_load_uboot_from_flash((unsigned char *)p_dram_partition->fdt_addr, p_tmp);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load uboot failed\r\n");
|
|
}
|
|
|
|
// boot uboot
|
|
er = bl_boot_uboot((unsigned char *)p_dram_partition->fdt_addr);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("boot uboot failed\r\n");
|
|
}
|
|
|
|
}
|
|
#endif
|
|
else {
|
|
// load rtos
|
|
er = bl_load_rtos_from_flash((unsigned char *)p_dram_partition->fdt_addr, p_tmp);
|
|
if (er != 0) {
|
|
bl_displayErrMsg("load rtos failed\r\n");
|
|
}
|
|
debug_msg("sf load rtos\r\n");
|
|
}
|
|
|
|
// update compressed rtos information
|
|
SHMINFO *p_bininfo = (SHMINFO *)bl_get_fdt_cfg((unsigned char *)p_dram_partition->fdt_addr, MODELEXT_TYPE_BIN_INFO);
|
|
if (p_bininfo == NULL) {
|
|
debug_err("null p_bininfo\r\n");
|
|
return -1;
|
|
}
|
|
*p_comp_addr = p_bininfo->comm.Resv[3]; // COMM_UITRON_COMP_ADDR
|
|
*p_comp_size = p_bininfo->comm.Resv[4]; // COMM_UITRON_COMP_LEN
|
|
|
|
*pOut_dram_partition = p_dram_partition;
|
|
return p_dram_partition->rtos_addr;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
bl_process_update_loader.
|
|
|
|
Write loader will update loader binary file
|
|
|
|
@param[in] loader_addr loader in DRAM starting address
|
|
@param[in] loader_size loader code length (from loader header offset 0x24)
|
|
@return void
|
|
*/
|
|
_THUMB2 static int bl_process_update_loader(unsigned int loader_addr, unsigned int loader_size)
|
|
{
|
|
unsigned int reload_addr;
|
|
|
|
// Check boot loader read from SD card
|
|
if(is_data_area_encrypted() == 0) {
|
|
|
|
#if ((STORAGE_EXT_TYPE == STORAGE_EXT_ETH)|(STORAGE_EXT_TYPE == STORAGE_EXT_USB))
|
|
//UINT32 uiOffset;
|
|
//uiOffset = *((UINT32 *)(loader_addr + 0x80));
|
|
//if(uiOffset) {//Combo loader
|
|
// if(*(UINT32*)0xF00100F0 == 0x50210000) {
|
|
// debug_msg("combo loader 528\r\n");
|
|
// bl_checkLoader(loader_addr+uiOffset, COMBINATION_LOADER_SIZE - uiOffset); //check 528
|
|
// } else{
|
|
// debug_msg("combo loader 52X\r\n");
|
|
// bl_checkLoader(loader_addr, loader_size); //check 52x
|
|
// }
|
|
//}else
|
|
bl_checkLoader(loader_addr, loader_size);
|
|
#else
|
|
#if 0//(LOADER_TYPE == COMBINATION_528)
|
|
debug_msg("CB8\r\n");
|
|
bl_checkLoader(loader_addr + loader_size, (COMBINATION_LOADER_SIZE - loader_size));
|
|
#else //STAND_ALONE_LOADER or combination 52x loader
|
|
//debug_msg("STD\r\n");
|
|
bl_checkLoader(loader_addr, loader_size);
|
|
#endif
|
|
#endif
|
|
}
|
|
debug_msg("update loader\r\n");
|
|
|
|
// open flash
|
|
if (bl_flash_open() != 0) {
|
|
bl_displayErrMsg("flash open failed\r\n");
|
|
}
|
|
|
|
// Program loader
|
|
#if 0
|
|
#if ((STORAGE_EXT_TYPE == STORAGE_EXT_ETH)|(STORAGE_EXT_TYPE == STORAGE_EXT_USB))
|
|
UINT32 uiOffset;
|
|
uiOffset = *((UINT32 *)(loader_addr + 0x80));
|
|
if(uiOffset) //Combo loader
|
|
loader_size = COMBINATION_LOADER_SIZE;
|
|
//If single loader , it already got
|
|
#else
|
|
#if (LOADER_TYPE == STAND_ALONE_LOADER_560) || (LOADER_TYPE == STAND_ALONE_LOADER_528)
|
|
#else //Combination loader
|
|
loader_size = COMBINATION_LOADER_SIZE;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
if (int_strg_obj->flash_writeSectors(StartNandBlkUpdateLoader, loader_size, (UINT8 *)loader_addr, NAND_RW_LOADER) < 0) {
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
// Read back
|
|
reload_addr = loader_addr + loader_size;
|
|
if (int_strg_obj->flash_readSectors(StartNandBlkUpdateLoader, loader_size, (UINT8 *)reload_addr, NAND_RW_LOADER) < 0) {
|
|
bl_displayErrMsg("rd fail\r\n");
|
|
}
|
|
// Verify
|
|
if (memcmp((void *)loader_addr, (void *)reload_addr, loader_size) != 0) {
|
|
bl_displayErrMsg("verify fail\r\n");
|
|
}
|
|
return 0;
|
|
}
|
|
#if UPDATE_EMU_CODE
|
|
_THUMB2 static int bl_process_update_emu_firmware(unsigned int emu_addr, unsigned int emu_size)
|
|
{
|
|
unsigned int reload_addr;
|
|
|
|
// Check boot loader read from SD card
|
|
// bl_checkFW(emu_addr, emu_size);
|
|
debug_msg("update emu firmware size");
|
|
uart_putSystemUARTStr(Dec2HexStr(emu_size));
|
|
uart_putSystemUARTStr("\r\n");
|
|
|
|
// open flash
|
|
if (bl_flash_open() != 0) {
|
|
bl_displayErrMsg("flash open failed\r\n");
|
|
}
|
|
|
|
// Program firmware
|
|
if (int_strg_obj->flash_writeSectors(g_uiStartBlkUpdateFW, emu_size, (UINT8 *)emu_addr, NAND_RW_FIRMWARE) < 0) {
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
// Read back
|
|
reload_addr = emu_addr + emu_size;
|
|
if (int_strg_obj->flash_readSectors(g_uiStartBlkUpdateFW, emu_size, (UINT8 *)reload_addr, NAND_RW_FIRMWARE) < 0) {
|
|
bl_displayErrMsg("rd fail\r\n");
|
|
}
|
|
// Verify
|
|
if (memcmp((void *)emu_addr, (void *)reload_addr, emu_size) != 0) {
|
|
bl_displayErrMsg("verify fail\r\n");
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
_THUMB2 void bl_read_rtos_addr(UINT32 *pLoadAddr, UINT32 *pTargetAddr, UINT32 *pSize)
|
|
{
|
|
*pLoadAddr = g_rtos_load_addr;
|
|
*pTargetAddr = g_rtos_target_addr;
|
|
*pSize = g_rtos_size;
|
|
}
|
|
|
|
/**
|
|
main flow code
|
|
|
|
If there is Calibration Firmware code store in NAND, running flow as follow
|
|
O's work flow
|
|
|
|
@return fw base addr
|
|
*/
|
|
|
|
_THUMB2 UINT32 bl_mainFlow(void)
|
|
{
|
|
UINT32 uiUpdateFileLen = 0;
|
|
UINT32 uiLoaderFunc = 0;
|
|
UINT32 uiLoaderSize = 32 * 1024; // pre-assume 32KB, actual size is parsed from loader
|
|
//Show Duty calibration log
|
|
#if (_LOADER_DUTY_CALIBRATION_ == ENABLE && _LOADER_DUTY_CALIBRATION_LOG_ == ENABLE)
|
|
UINT32 uiLoaderAddress;
|
|
UINT32 uiLogSramAddress;
|
|
#endif
|
|
|
|
#if !(USB_WRITELOADER || UART_UPDATE)
|
|
unsigned int adjusted_addr = 0;
|
|
unsigned int adjusted_size = 0;
|
|
#endif
|
|
UINT32 uiFwBaseAddr = SDRAM_Start_FW; // FW base address
|
|
DRAM_PARTITION *p_dram_partition = NULL;
|
|
|
|
// BaseOfStack is initialized at doRemapLZ.s
|
|
UINT32 uiheapBufferAddr = (UINT32)_loader_heap_base;
|
|
// UINT32 uiheapBufferAddr = BaseOfStack + 0x40000; // reserve 16KB for tmp buffer usage
|
|
UINT32 uiTmpBufferAddr = uiheapBufferAddr + FAT_HEAP_BUFFER_SIZE;
|
|
UINT32 uiUpdateBootloaderBufAddr = uiTmpBufferAddr + 0x4000;
|
|
UINT32 uiUpdateMainBinBufAddr = SDRAM_Start_FW;
|
|
UINT32 uiOTABufferAddr = uiUpdateBootloaderBufAddr + 0xA000;
|
|
UINT32 uiOTABufferSize = 0x10000 * 2; /* 2 blks */
|
|
// UART initial sequence
|
|
//uart_openSystemUART();
|
|
// rtc reset shutdown timer
|
|
// rtc_resetShutDownTimer();
|
|
|
|
// Display Loader Version
|
|
debug_msg((char *)LOADER_START_STR);
|
|
UTL_setDrvTmpBufferAddress(uiTmpBufferAddr);
|
|
|
|
#if 0
|
|
// Sample to hook spi flash extending function
|
|
flash_installIdentifyCB(bl_spiIdentify);
|
|
#endif
|
|
prj_main();
|
|
|
|
#if !(USB_WRITELOADER)
|
|
set_usb_suspend();
|
|
#endif
|
|
|
|
if(utl_get_bootsrc() == BOOT_SOURCE_UART)
|
|
{
|
|
#if UART_UPDATE
|
|
debug_msg("Boot from UART ...\r\n");
|
|
bl_uart();//never returned.
|
|
#else
|
|
bl_displayErrMsg("UART_UPDATE must enable on loader\r\n");
|
|
#endif
|
|
}
|
|
|
|
if(USB_WRITELOADER || utl_get_bootsrc() == BOOT_SOURCE_USB)
|
|
{
|
|
#if USB_WRITELOADER
|
|
debug_msg("Boot from USB ...\r\n");
|
|
bl_usb(); //never returned.
|
|
#else
|
|
bl_displayErrMsg("USB_WRITELOADER must enable on loader\r\n");
|
|
#endif
|
|
}
|
|
|
|
UINT32 ota_flag = 0;
|
|
if(FALSE == gsfSpecialKeyCallBack(0))
|
|
{
|
|
ota_flag = bl_check_ota_flag(uiOTABufferAddr, uiOTABufferSize);
|
|
}
|
|
|
|
#if !(USB_WRITELOADER || UART_UPDATE)
|
|
if (bl_load_rtos_from_uart(uiUpdateMainBinBufAddr, FAT_READ_TOTAL_FILE_LENGTH, &adjusted_addr, &adjusted_size) == 0) {
|
|
//specail case, load small rtos from uart
|
|
uiUpdateMainBinBufAddr = adjusted_addr;
|
|
uiUpdateFileLen = adjusted_size;
|
|
uiLoaderFunc |= FUNC_RUN_CARD;
|
|
} else if ((int_strg_obj->flash_getBlockSize() == EMMC_BLOCK_SIZE) && gRecoveryTriggerCallBack && gRecoveryTriggerCallBack()) {
|
|
debug_msg("Recovery triggered not support currently.\r\n");
|
|
|
|
}
|
|
#if 1
|
|
else if ((gSpecialKeyCallBack(ota_flag)) && (gCardDetectCallBack())) {
|
|
|
|
if (card_open() == TRUE && fat_initFAT(uiheapBufferAddr, FAT_HEAP_BUFFER_SIZE) == TRUE) {
|
|
#if UPDATE_SIM_CODE
|
|
BOOL bWDTInit = UTL_canUpdateSecKey();
|
|
if (bWDTInit && fat_open_rootfile(RUN_WRKEY_NAME) == TRUE) {
|
|
debug_msg("sim.bin exist\r\n"); // the others A or T are skipped.
|
|
// Read byte count specified in file directory entry
|
|
uiUpdateFileLen = fat_read_rootfile((UINT8 *)uiUpdateMainBinBufAddr, FAT_READ_TOTAL_FILE_LENGTH);
|
|
fat_close_rootfile();
|
|
debug_msg("\r\n"); // for line end RRRRRRR....
|
|
uiLoaderFunc |= FUNC_RUN_WRBIN;
|
|
} else { // exclude others update if FUNC_RUN_WRBIN is existing.
|
|
#endif
|
|
// Update loader or not, loader is fixed to 16 KB
|
|
if (fat_open_rootfile(UPDATE_LOADER_NAME) == TRUE) {
|
|
// Read byte count specified in file directory entry
|
|
fat_read_rootfile((UINT8 *)uiUpdateBootloaderBufAddr, FAT_READ_TOTAL_FILE_LENGTH);
|
|
fat_close_rootfile();
|
|
debug_msg("\r\n"); // for line end RRRRRRR....
|
|
uiLoaderFunc |= FUNC_UPDATE_LOADER;
|
|
uiLoaderSize = *((UINT32 *)(uiUpdateBootloaderBufAddr + 0x24));
|
|
}
|
|
// "Update FW" or "Run FW" function
|
|
// Update FW has higher priority
|
|
if (fat_open_rootfile(UPDATE_FW_NAME) == TRUE) {
|
|
NVTPACK_MEM mem_in ;
|
|
fat_read_rootfile((UINT8 *)uiUpdateMainBinBufAddr, SIZE_PRELOAD);
|
|
mem_in.p_data = (void *)uiUpdateMainBinBufAddr;
|
|
mem_in.len = uiUpdateFileLen;
|
|
// all in one bin
|
|
if (bl_chk_valid_all_in_one(&mem_in) == 0) {
|
|
// Read all
|
|
uiUpdateFileLen = fat_read_rootfile((UINT8 *)uiUpdateMainBinBufAddr, FAT_READ_TOTAL_FILE_LENGTH);
|
|
uiLoaderFunc |= FUNC_UPDATE_FW;
|
|
} else {
|
|
// only rtos
|
|
debug_msg("not all-in-one, force behavior as T bin.\r\n");
|
|
adjusted_addr = 0;
|
|
adjusted_size = 0;
|
|
if (bl_load_rtos_from_non_nvtpack(uiUpdateMainBinBufAddr, uiUpdateFileLen, &adjusted_addr, &adjusted_size) == 0) {
|
|
uiFwBaseAddr = adjusted_addr; //fix compressed fit bl_checkDramScanFW() after copy its to temp area, see commit log
|
|
uiUpdateFileLen = adjusted_size;
|
|
|
|
#if UPDATE_EMU_CODE
|
|
uiLoaderFunc |= FUNC_UPDATE_FW;
|
|
#else
|
|
uiLoaderFunc |= FUNC_RUN_CARD;
|
|
#endif
|
|
|
|
} else {
|
|
debug_err("invalid firmware");
|
|
uiLoaderFunc |= FUNC_RUN_FLASH;
|
|
}
|
|
|
|
|
|
}
|
|
fat_close_rootfile();
|
|
debug_msg("\r\n"); // for line end RRRRRRR....
|
|
}
|
|
// Run FW has lower priority
|
|
else if (fat_open_rootfile(RUN_FW_NAME) == TRUE) {
|
|
|
|
NVTPACK_MEM mem_in ;
|
|
uiUpdateFileLen = fat_read_rootfile((UINT8 *)uiUpdateMainBinBufAddr, SIZE_PRELOAD);
|
|
mem_in.p_data = (void *)uiUpdateMainBinBufAddr;
|
|
mem_in.len = uiUpdateFileLen;
|
|
if (bl_chk_valid_all_in_one(&mem_in) == 0) {
|
|
// Read all
|
|
uiUpdateFileLen = fat_read_rootfile((UINT8 *)uiUpdateMainBinBufAddr, FAT_READ_TOTAL_FILE_LENGTH);
|
|
} else {
|
|
// Read rtos
|
|
unsigned int adjusted_addr = 0;
|
|
unsigned int adjusted_size = 0;
|
|
if (bl_load_rtos_from_non_nvtpack(uiUpdateMainBinBufAddr, uiUpdateFileLen, &adjusted_addr, &adjusted_size) != 0) {
|
|
bl_displayErrMsg("invalid firmware");
|
|
} else {
|
|
uiFwBaseAddr = adjusted_addr; //fix compressed fit bl_checkDramScanFW() after copy its to temp area, see commit log
|
|
uiUpdateFileLen = adjusted_size;
|
|
}
|
|
uiLoaderFunc |= FUNC_RUN_CARD;
|
|
}
|
|
fat_close_rootfile();
|
|
debug_msg("\r\n"); // for line end RRRRRRR....
|
|
uiLoaderFunc |= FUNC_RUN_CARD;
|
|
}
|
|
/* no fw found in sd card , start emmc check flow */
|
|
else{
|
|
|
|
g_update_from_emmc = 1;
|
|
uiLoaderFunc &= ~(FUNC_UPDATE_LOADER); /* loader won't be updated by emmc */
|
|
}
|
|
#if UPDATE_SIM_CODE
|
|
}
|
|
#endif
|
|
card_close();
|
|
} else {
|
|
debug_msg("card open fail\r\n");
|
|
// while (1);
|
|
}
|
|
}
|
|
#endif
|
|
else if (((gSpecialKeyCallBack == NULL) || gSpecialKeyCallBack(ota_flag)) &&
|
|
((gCardDetectCallBack != NULL) || (gCardDetectCallBack() == FALSE))) {
|
|
debug_msg("No card inserted\r\n");
|
|
g_update_from_emmc = 1;
|
|
uiLoaderFunc &= ~(FUNC_UPDATE_LOADER); /* loader won't be updated by emmc */
|
|
}
|
|
#endif
|
|
|
|
if (uiLoaderFunc & FUNC_UPDATE_LOADER) {
|
|
bl_process_update_loader(uiUpdateBootloaderBufAddr, uiLoaderSize);
|
|
}
|
|
|
|
// Run FW
|
|
UINT32 comp_addr = 0;
|
|
UINT32 comp_size = 0;
|
|
if (uiLoaderFunc & (FUNC_RUN_CARD | FUNC_UPDATE_FW)) {
|
|
debug_msg("RC\r\n");
|
|
NVTPACK_MEM mem_in ;
|
|
int chk_valid_all_in_one;
|
|
#if (DRAM_RANGE_SCAN_EN == ENABLE)
|
|
// First word is code entry point address, once if entry address is 0xC000XXXX
|
|
// represent code is running on sram.
|
|
debug_msg("Check SRAM fw\r\n");
|
|
if (bl_checkDramScanFW(uiUpdateMainBinBufAddr) == TRUE) {
|
|
|
|
debug_msg("This fw is on SRAM\r\n");
|
|
// Enable sram usage
|
|
SETREG32(0xF0900128, 0x00000002);
|
|
SETREG32(0xF0800128, 0x00000006);
|
|
SETREG32(0xF0020060, 0x00030002);
|
|
|
|
debug_msg(Dec2HexStr(*((UINT32 *)SRAM_Start_FW)));
|
|
debug_msg("before jump\r\n");
|
|
// while (b_debug_go == FALSE);
|
|
load_dram_scan(uiUpdateMainBinBufAddr, uiUpdateFileLen);
|
|
return *((UINT32 *)SRAM_Start_FW);
|
|
}
|
|
#endif
|
|
mem_in.p_data = (void *)uiUpdateMainBinBufAddr;
|
|
mem_in.len = uiUpdateFileLen;
|
|
chk_valid_all_in_one = bl_chk_valid_all_in_one(&mem_in);
|
|
if (chk_valid_all_in_one == 0) {
|
|
// all-in-one flow
|
|
// File len got from fat_read_rootfile() may exceed actual file size.
|
|
// In such condition, we should use info in NVTPACK_FW_HDR2
|
|
if (((NVTPACK_FW_HDR2 *)uiUpdateMainBinBufAddr)->TotalSize < uiUpdateFileLen) {
|
|
uiUpdateFileLen = ((NVTPACK_FW_HDR2 *)uiUpdateMainBinBufAddr)->TotalSize;
|
|
mem_in.len = uiUpdateFileLen;
|
|
}
|
|
#if (REMOVED_FLASH == ENABLE)
|
|
bl_displayErrMsg("cannot process all-in-one fw");
|
|
#else
|
|
uiFwBaseAddr = bl_process_all_in_one(uiUpdateMainBinBufAddr, uiUpdateFileLen, &p_dram_partition, uiLoaderFunc, &comp_addr, &comp_size);
|
|
if(uiFwBaseAddr == 0){
|
|
debug_err("bl_process_all_in_one failed, boot from flash\n");
|
|
uiLoaderFunc &= ~(FUNC_RUN_CARD | FUNC_UPDATE_FW);
|
|
uiLoaderFunc |= FUNC_RUN_FLASH;
|
|
goto BOOT_FROM_FLASH;
|
|
}
|
|
#endif
|
|
} else {
|
|
// non-all-in-one flow
|
|
// check valid
|
|
if (uiLoaderFunc & FUNC_UPDATE_FW) {
|
|
#if UPDATE_EMU_CODE
|
|
bl_process_update_emu_firmware(uiUpdateMainBinBufAddr, uiUpdateFileLen);
|
|
#else
|
|
bl_displayErrMsg("cannot write non-all-in-one fw");
|
|
#endif
|
|
}
|
|
uiFwBaseAddr = bl_process_rtos_only(uiUpdateMainBinBufAddr, mem_in.len, uiLoaderFunc, &comp_addr, &comp_size);
|
|
}
|
|
|
|
// here uiFwBaseAddr is ready to use.
|
|
if (comp_addr == 0) {
|
|
HEADINFO *p_headinfo = (HEADINFO *)(uiFwBaseAddr + BIN_INFO_OFFSET_RTOS);
|
|
debug_msg("Nrml\r\n");
|
|
if (chk_valid_all_in_one == 0) {
|
|
uiUpdateFileLen = p_headinfo->BinLength;
|
|
uiUpdateMainBinBufAddr = uiFwBaseAddr;
|
|
} else {
|
|
// uiUpdateFileLen is already set when file is loaded
|
|
}
|
|
} else {
|
|
debug_msg("Fcompress\r\n");
|
|
//for speed up, u-boot only copy compressed rtos and loader needs to decode it
|
|
uiUpdateFileLen = bl_decompress_rtos(comp_addr, comp_size, uiFwBaseAddr);
|
|
uiUpdateMainBinBufAddr = uiFwBaseAddr;
|
|
}
|
|
debug_msg_var("uiUpdateFileLen", uiUpdateFileLen);
|
|
//boot from flash or update fw is no need to check sanity because of ecc, turn on it just for debug
|
|
if (uiLoaderFunc & FUNC_RUN_CARD) {
|
|
bl_checkFW(uiUpdateMainBinBufAddr, uiUpdateFileLen);
|
|
}
|
|
if (chk_valid_all_in_one == 0) {
|
|
bl_update_uItron_headInfo(uiFwBaseAddr, p_dram_partition);
|
|
} else {
|
|
debug_msg_var("fw load addr", uiUpdateMainBinBufAddr);
|
|
bl_update_uItron_headInfo(uiUpdateMainBinBufAddr, p_dram_partition);
|
|
}
|
|
} else { //boot from flash
|
|
#if (REMOVED_FLASH == DISABLE)
|
|
#if UPDATE_EMU_CODE
|
|
// UINT32 uiNandBlkSize;
|
|
// open flash
|
|
if (bl_flash_open() != 0) {
|
|
bl_displayErrMsg("flash open failed\r\n");
|
|
}
|
|
debug_msg("RFlash\r\n");
|
|
if (int_strg_obj->flash_readSectors(g_uiStartBlkUpdateFW, g_uiNandBlkSize, (UINT8 *)SDRAM_Start_FW, NAND_RW_FIRMWARE) < 0) {
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
|
|
uiUpdateFileLen = *(volatile UINT32 *)(SDRAM_Start_FW + 0x168);
|
|
|
|
if (int_strg_obj->flash_readSectors(g_uiStartBlkUpdateFW + 1, uiUpdateFileLen - g_uiNandBlkSize, (UINT8 *)(SDRAM_Start_FW + g_uiNandBlkSize), NAND_RW_FIRMWARE) < 0) {
|
|
bl_displayErrMsg(RWErrorMsg);
|
|
}
|
|
|
|
uiFwBaseAddr = bl_process_rtos_only(SDRAM_Start_FW, uiUpdateFileLen, uiLoaderFunc, &comp_addr, &comp_size);
|
|
bl_checkFW(SDRAM_Start_FW, uiUpdateFileLen);
|
|
uiUpdateMainBinBufAddr = SDRAM_Start_FW;
|
|
if (comp_addr == 0) {
|
|
debug_msg("Nrml\r\n");
|
|
} else {
|
|
debug_msg("Fcompress not support\r\n");
|
|
}
|
|
|
|
#else
|
|
BOOT_FROM_FLASH:
|
|
uiFwBaseAddr = bl_process_flash_boot((UINT8 *)SDRAM_Start_FW, &p_dram_partition, uiLoaderFunc, &comp_addr, &comp_size);
|
|
if (comp_addr == 0) {
|
|
uiUpdateMainBinBufAddr = uiFwBaseAddr;
|
|
} else {
|
|
//for speed up, u-boot only copy compressed rtos and loader needs to decode it
|
|
uiUpdateFileLen = bl_decompress_rtos(comp_addr, comp_size, uiFwBaseAddr);
|
|
uiUpdateMainBinBufAddr = uiFwBaseAddr;
|
|
}
|
|
// no need to bl_checkFW, because check sanity in flash_read
|
|
bl_update_uItron_headInfo(uiFwBaseAddr, p_dram_partition);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
if (p_dram_partition) {
|
|
bl_update_loader_bininfo((unsigned char *)p_dram_partition->fdt_addr, uiLoaderFunc, uiUpdateFileLen);
|
|
}
|
|
|
|
#if UPDATE_EMU_CODE
|
|
debug_msg_var("emu fw len", uiUpdateFileLen);
|
|
#endif
|
|
g_rtos_load_addr = uiUpdateMainBinBufAddr;
|
|
g_rtos_target_addr = uiFwBaseAddr;
|
|
g_rtos_size = uiUpdateFileLen;
|
|
//invalid Instruciton and data cache
|
|
CPUCleanInvalidateDCacheAll();
|
|
CPUInvalidateICacheAll();
|
|
debug_msg_var("rtos start", uiFwBaseAddr);
|
|
return uiFwBaseAddr;
|
|
|
|
}
|
|
|
|
_THUMB2 void loader_setUpdateFwName(char *fileName)
|
|
{
|
|
strncpy((char *)UPDATE_FW_NAME, fileName, sizeof(UPDATE_FW_NAME));
|
|
}
|
|
|
|
_THUMB2 void loader_setUpdateLdrName(char *fileName)
|
|
{
|
|
strncpy((char *)UPDATE_LOADER_NAME, fileName, sizeof(UPDATE_LOADER_NAME));
|
|
}
|
|
|
|
_THUMB2 void loader_setRunFwName(char *fileName)
|
|
{
|
|
strncpy((char *)RUN_FW_NAME, fileName, sizeof(RUN_FW_NAME));
|
|
}
|
|
|
|
_THUMB2 void loader_setRecoveryFwName(char *fileName)
|
|
{
|
|
strncpy((char *)RECOVERY_FW_NAME, fileName, sizeof(RECOVERY_FW_NAME));
|
|
}
|
|
|
|
_THUMB2 void loader_setRecoveryPartitionID(UINT32 partition_id)
|
|
{
|
|
g_uiPartitionID = partition_id;
|
|
}
|
|
|
|
_THUMB2 void loader_setVersion(UINT32 version)
|
|
{
|
|
g_uiVersion = version;
|
|
}
|
|
|
|
_THUMB2 void loader_installSpecialKeyCB(LDR_SPECIAL_KEY_CB callback)
|
|
{
|
|
gSpecialKeyCallBack = callback;
|
|
}
|
|
_THUMB2 void loader_installsfSpecialKeyCB(LDR_SPECIAL_KEY_CB callback)
|
|
{
|
|
gsfSpecialKeyCallBack = callback;
|
|
}
|
|
_THUMB2 void loader_installCardDetectCB(LDR_CARD_DETECT_CB callback)
|
|
{
|
|
gCardDetectCallBack = callback;
|
|
}
|
|
|
|
_THUMB2 void loader_installRecoveryTriggerCB(LDR_RECOVERY_TRIGGER_CB callback)
|
|
{
|
|
gRecoveryTriggerCallBack = callback;
|
|
}
|
|
|
|
_THUMB2 void loader_installFastbootKeyCB(LDR_FASTBOOT_KEY_CB callback)
|
|
{
|
|
gFastbootKeyCallBack = callback;
|
|
}
|
|
|
|
_THUMB2 void loader_setStorageIntType(STORAGEINT type, PSTORAGE_OBJ strg_obj)
|
|
{
|
|
gStorageIntType = type;
|
|
int_strg_obj = strg_obj;
|
|
}
|