229 lines
8.8 KiB
C
229 lines
8.8 KiB
C
/**
|
|
******************************************************************************
|
|
* @file blsp_ram_image_boot.c
|
|
* @version V1.2
|
|
* @date
|
|
* @brief This file is the peripheral case c file
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "bflb_eflash_loader_interface.h"
|
|
#include "blsp_port.h"
|
|
#include "blsp_bootinfo.h"
|
|
#include "blsp_media_boot.h"
|
|
#include "blsp_boot_decompress.h"
|
|
#include "blsp_common.h"
|
|
#include "partition.h"
|
|
#include "softcrc.h"
|
|
#include "bflb_flash.h"
|
|
#include "bflb_sec_sha.h"
|
|
|
|
#if BLSP_BOOT2_RAM_IMG_COUNT_MAX > 0
|
|
|
|
ram_img_config_t ram_img_config[BLSP_BOOT2_RAM_IMG_COUNT_MAX] = { 0 };
|
|
#define LZ4D_FLAG 0x184D2204
|
|
extern void unlz4(const void *aSource, void *aDestination, uint32_t FileLen);
|
|
|
|
/****************************************************************************/ /**
|
|
* @brief Boot2 cal image hash
|
|
*
|
|
* @param src: image address on flash
|
|
* @param total_len: total len to copy
|
|
* @param hash:hash pointer
|
|
*
|
|
* @return 0 for success ,-1 for fail
|
|
*
|
|
*******************************************************************************/
|
|
static int blsp_cal_ram_img_hash(uint32_t src, uint32_t total_len, uint8_t *hash)
|
|
{
|
|
//flash_read_via_xip(src, dest,total_len);
|
|
uint32_t cur_len = 0;
|
|
uint32_t read_len = 0;
|
|
uint32_t cal_hash[8];
|
|
|
|
bflb_sha_init(sha, SHA_MODE_SHA256);
|
|
bflb_sha256_start(sha, &ctx_sha256);
|
|
|
|
while (cur_len < total_len) {
|
|
read_len = total_len - cur_len;
|
|
if (read_len > BFLB_BOOT2_READBUF_SIZE) {
|
|
read_len = BFLB_BOOT2_READBUF_SIZE;
|
|
}
|
|
bflb_flash_read(src + cur_len, g_boot2_read_buf, read_len);
|
|
bflb_sha256_update(sha, &ctx_sha256, g_boot2_read_buf, read_len);
|
|
cur_len += read_len;
|
|
}
|
|
bflb_sha256_finish(sha, &ctx_sha256, (uint8_t *)cal_hash);
|
|
if (memcmp(hash, cal_hash, 32) != 0) {
|
|
LOG_E("Cal hash error\r\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************/ /**
|
|
* @brief Boot2 copy image from flash to ram
|
|
*
|
|
* @param src: image address on flash
|
|
* @param dest: ram address to copy to
|
|
* @param total_len: total len to copy
|
|
*
|
|
* @return 0 for success ,-1 for fail
|
|
*
|
|
*******************************************************************************/
|
|
static int blsp_do_ram_img_copy(uint32_t src, uint32_t dest, uint32_t total_len, uint8_t **hash)
|
|
{
|
|
//flash_read_via_xip(src, dest,total_len);
|
|
uint32_t cur_len = 0;
|
|
uint32_t read_len = 0;
|
|
uint32_t *p = (uint32_t *)g_boot2_read_buf;
|
|
uint32_t xip_addr = 0;
|
|
int ret = 0;
|
|
|
|
g_boot2_read_buf[0] = 0x0;
|
|
g_boot2_read_buf[1] = 0x0;
|
|
bflb_flash_read(src, g_boot2_read_buf, 4);
|
|
if (*p == LZ4D_FLAG) {
|
|
if (*hash != NULL) {
|
|
LOG_F("Cal hash\r\n");
|
|
ret = blsp_cal_ram_img_hash(src, total_len, *hash);
|
|
if (ret != 0) {
|
|
return BFLB_BOOT2_IMG_HASH_ERROR;
|
|
}
|
|
}
|
|
xip_addr = hal_boot2_get_xip_addr(src);
|
|
LOG_F("LZ4 image found, Decompress from %08x to %08x\r\n", xip_addr, dest);
|
|
if (xip_addr != 0) {
|
|
unlz4((const void *)xip_addr, (void *)dest, total_len);
|
|
LOG_F("LZ4 done\r\n");
|
|
L1C_DCache_Clean_All();
|
|
return 0;
|
|
} else {
|
|
LOG_E("Get XIP Addr fail\r\n");
|
|
return -1;
|
|
}
|
|
}
|
|
while (cur_len < total_len) {
|
|
read_len = total_len - cur_len;
|
|
if (read_len > BFLB_BOOT2_READBUF_SIZE) {
|
|
read_len = BFLB_BOOT2_READBUF_SIZE;
|
|
}
|
|
bflb_flash_read(src + cur_len, g_boot2_read_buf, read_len);
|
|
arch_memcpy((void *)(dest + cur_len), g_boot2_read_buf, read_len);
|
|
cur_len += read_len;
|
|
}
|
|
|
|
L1C_DCache_Clean_By_Addr(dest, total_len);
|
|
if (*hash != NULL) {
|
|
LOG_F("Cal hash\r\n");
|
|
ret = blsp_cal_ram_img_hash(src, total_len, *hash);
|
|
if (ret != 0) {
|
|
return BFLB_BOOT2_IMG_HASH_ERROR;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************/ /**
|
|
* @brief Boot2 do ram iamge boot,check partition to boot these images up
|
|
*
|
|
* @param activeID: Active partition table ID
|
|
* @param ptStuff: Pointer of partition table stuff
|
|
* @param ptEntry: Pointer of active entry
|
|
*
|
|
* @return None
|
|
*
|
|
*******************************************************************************/
|
|
int blsp_do_ram_image_boot(pt_table_id_type active_id, pt_table_stuff_config *pt_stuff, pt_table_entry_config *pt_entry)
|
|
{
|
|
int ret;
|
|
uint32_t img_len = 0;
|
|
uint32_t img_offset = 0;
|
|
char *img_name[BLSP_BOOT2_RAM_IMG_COUNT_MAX];
|
|
uint32_t ram_img_cnt = 0;
|
|
uint32_t i = 0;
|
|
uint8_t active_index = 0;
|
|
uint32_t hash[8];
|
|
uint8_t *phash = (uint8_t *)hash;
|
|
int try_again = 0;
|
|
int32_t blsp_boot2_rollback_ptentry(pt_table_id_type active_id,
|
|
pt_table_stuff_config * pt_stuff, pt_table_entry_config * pt_entry);
|
|
|
|
hal_boot2_get_ram_img_cnt(img_name, &ram_img_cnt);
|
|
if (ram_img_cnt == 0) {
|
|
return try_again;
|
|
}
|
|
for (i = 0; i < ram_img_cnt; i++) {
|
|
ret = pt_table_get_active_entries_by_name(pt_stuff, (uint8_t *)img_name[i], pt_entry);
|
|
if (PT_ERROR_SUCCESS == ret) {
|
|
/* we use pt_entry->len as flag for ram load, this
|
|
is very tricky but no rsvd word found */
|
|
if ((pt_entry->len & 0xF0000000) == 0) {
|
|
continue;
|
|
}
|
|
/* first, take it as invalid */
|
|
ram_img_config[i].valid = 0;
|
|
ram_img_config[i].boot_addr = pt_entry->len & 0xfffffff0;
|
|
ram_img_config[i].core = pt_entry->len & 0x0f;
|
|
active_index = pt_entry->active_index & 0x01;
|
|
LOG_F("header addr:%08x\r\n", pt_entry->start_address[active_index]);
|
|
bflb_flash_read(pt_entry->start_address[active_index],
|
|
g_boot2_read_buf, BFLB_BOOT2_READBUF_SIZE);
|
|
hal_boot2_get_img_info(g_boot2_read_buf, &img_offset, &img_len, &phash);
|
|
if (img_len) {
|
|
LOG_F("copy from %08x to %08x,len %d\r\n",
|
|
pt_entry->start_address[active_index] + img_offset,
|
|
ram_img_config[i].boot_addr,
|
|
img_len);
|
|
ret = blsp_do_ram_img_copy(pt_entry->start_address[active_index] + img_offset,
|
|
ram_img_config[i].boot_addr,
|
|
img_len, &phash);
|
|
if (BFLB_BOOT2_IMG_HASH_ERROR == ret) {
|
|
ret = blsp_boot2_rollback_ptentry(active_id, &pt_stuff[active_id], pt_entry);
|
|
if (ret == BFLB_BOOT2_SUCCESS) {
|
|
try_again = 1;
|
|
break;
|
|
} else {
|
|
LOG_F("Roll back entry fail\r\n");
|
|
}
|
|
} else if (0 == ret) {
|
|
/* all success */
|
|
ram_img_config[i].valid = 1;
|
|
}
|
|
} else {
|
|
LOG_F("Get ram image infor fail\r\n");
|
|
}
|
|
} else {
|
|
LOG_F("%s not found\r\n", img_name[i]);
|
|
}
|
|
}
|
|
return try_again;
|
|
}
|
|
#endif |