[feat][boot2] add bl616 boot2 iap demo

This commit is contained in:
jzlv 2022-11-25 20:16:20 +08:00
parent 1b35880999
commit 8d6352419a
34 changed files with 7421 additions and 0 deletions

View file

@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.15)
include(proj.conf)
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
target_sources(app PRIVATE
bflb_eflash_loader_interface.c
bflb_eflash_loader_cmds.c
bflb_eflash_loader_uart.c
blsp_boot_decompress.c
blsp_boot_parser.c
blsp_common.c
blsp_media_boot.c
blsp_port.c
blsp_ram_image_boot.c
partition.c
softcrc.c
rv32i_xtheade_lz4.S
${CMAKE_SOURCE_DIR}/port/${CHIP}/bflb_port_boot2.c
)
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/port/${CHIP})
include_directories(${CMAKE_SOURCE_DIR}/port/${CHIP})
else()
message(FATAL_ERROR "${CMAKE_SOURCE_DIR}/port/${CHIP} is not exist")
endif()
include_directories(${CMAKE_SOURCE_DIR})
sdk_set_main_file(main.c)
sdk_set_linker_script(port/${CHIP}/blsp_boot2_iap_flash.ld)
if(CONFIG_DEBUG)
sdk_add_compile_definitions(-DCONFIG_DEBUG)
endif()
project(boot2_isp)

View file

@ -0,0 +1,13 @@
SDK_DEMO_PATH ?= .
BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../..
export BL_SDK_BASE
CHIP ?= bl616
BOARD ?= bl616dk
CROSS_COMPILE ?= riscv64-unknown-elf-
# add custom cmake definition
#cmake_definition+=-Dxxx=sss
include $(BL_SDK_BASE)/project.build

View file

@ -0,0 +1,142 @@
/**
******************************************************************************
* @file blsp_eflash_loader.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BFLB_EFLASH_LOADER_H__
#define __BFLB_EFLASH_LOADER_H__
#include "bflb_eflash_loader_interface.h"
#include "bflb_eflash_loader_cmds.h"
#include "bflb_eflash_loader_uart.h"
#include "bflb_eflash_loader_usb.h"
/*error code definition*/
typedef enum tag_eflash_loader_error_code_t {
BFLB_EFLASH_LOADER_SUCCESS = 0x00,
/*flash*/
BFLB_EFLASH_LOADER_FLASH_INIT_ERROR = 0x0001,
BFLB_EFLASH_LOADER_FLASH_ERASE_PARA_ERROR = 0x0002,
BFLB_EFLASH_LOADER_FLASH_ERASE_ERROR = 0x0003,
BFLB_EFLASH_LOADER_FLASH_WRITE_PARA_ERROR = 0x0004,
BFLB_EFLASH_LOADER_FLASH_WRITE_ADDR_ERROR = 0x0005,
BFLB_EFLASH_LOADER_FLASH_WRITE_ERROR = 0x0006,
BFLB_EFLASH_LOADER_FLASH_BOOT_PARA_ERROR = 0x0007,
BFLB_EFLASH_LOADER_FLASH_SET_PARA_ERROR = 0x0008,
BFLB_EFLASH_LOADER_FLASH_READ_STATUS_REG_ERROR = 0x0009,
BFLB_EFLASH_LOADER_FLASH_WRITE_STATUS_REG_ERROR = 0x000A,
BFLB_EFLASH_LOADER_FLASH_DECOMPRESS_WRITE_ERROR = 0x000B,
BFLB_EFLASH_LOADER_FLASH_WRITE_XZ_ERROR = 0x000C,
/*cmd*/
BFLB_EFLASH_LOADER_CMD_ID_ERROR = 0x0101,
BFLB_EFLASH_LOADER_CMD_LEN_ERROR = 0x0102,
BFLB_EFLASH_LOADER_CMD_CRC_ERROR = 0x0103,
BFLB_EFLASH_LOADER_CMD_SEQ_ERROR = 0x0104,
/*image*/
BFLB_EFLASH_LOADER_IMG_BOOTHEADER_LEN_ERROR = 0x0201,
BFLB_EFLASH_LOADER_IMG_BOOTHEADER_NOT_LOAD_ERROR = 0x0202,
BFLB_EFLASH_LOADER_IMG_BOOTHEADER_MAGIC_ERROR = 0x0203,
BFLB_EFLASH_LOADER_IMG_BOOTHEADER_CRC_ERROR = 0x0204,
BFLB_EFLASH_LOADER_IMG_BOOTHEADER_ENCRYPT_NOTFIT = 0x0205,
BFLB_EFLASH_LOADER_IMG_BOOTHEADER_SIGN_NOTFIT = 0x0206,
BFLB_EFLASH_LOADER_IMG_SEGMENT_CNT_ERROR = 0x0207,
BFLB_EFLASH_LOADER_IMG_AES_IV_LEN_ERROR = 0x0208,
BFLB_EFLASH_LOADER_IMG_AES_IV_CRC_ERROR = 0x0209,
BFLB_EFLASH_LOADER_IMG_PK_LEN_ERROR = 0x020a,
BFLB_EFLASH_LOADER_IMG_PK_CRC_ERROR = 0x020b,
BFLB_EFLASH_LOADER_IMG_PK_HASH_ERROR = 0x020c,
BFLB_EFLASH_LOADER_IMG_SIGNATURE_LEN_ERROR = 0x020d,
BFLB_EFLASH_LOADER_IMG_SIGNATURE_CRC_ERROR = 0x020e,
BFLB_EFLASH_LOADER_IMG_SECTIONHEADER_LEN_ERROR = 0x020f,
BFLB_EFLASH_LOADER_IMG_SECTIONHEADER_CRC_ERROR = 0x0210,
BFLB_EFLASH_LOADER_IMG_SECTIONHEADER_DST_ERROR = 0x0211,
BFLB_EFLASH_LOADER_IMG_SECTIONDATA_LEN_ERROR = 0x0212,
BFLB_EFLASH_LOADER_IMG_SECTIONDATA_DEC_ERROR = 0x0213,
BFLB_EFLASH_LOADER_IMG_SECTIONDATA_TLEN_ERROR = 0x0214,
BFLB_EFLASH_LOADER_IMG_SECTIONDATA_CRC_ERROR = 0x0215,
BFLB_EFLASH_LOADER_IMG_HALFBAKED_ERROR = 0x0216,
BFLB_EFLASH_LOADER_IMG_HASH_ERROR = 0x0217,
BFLB_EFLASH_LOADER_IMG_SIGN_PARSE_ERROR = 0x0218,
BFLB_EFLASH_LOADER_IMG_SIGN_ERROR = 0x0219,
BFLB_EFLASH_LOADER_IMG_DEC_ERROR = 0x021a,
BFLB_EFLASH_LOADER_IMG_ALL_INVALID_ERROR = 0x021b,
/*IF*/
BFLB_EFLASH_LOADER_IF_RATE_LEN_ERROR = 0x0301,
BFLB_EFLASH_LOADER_IF_RATE_PARA_ERROR = 0x0302,
BFLB_EFLASH_LOADER_IF_PASSWORDERROR = 0x0303,
BFLB_EFLASH_LOADER_IF_PASSWORDCLOSE = 0x0304,
/*efuse*/
BFLB_EFLASH_LOADER_EFUSE_WRITE_PARA_ERROR = 0x0401,
BFLB_EFLASH_LOADER_EFUSE_WRITE_ADDR_ERROR = 0x0402,
BFLB_EFLASH_LOADER_EFUSE_WRITE_ERROR = 0x0403,
BFLB_EFLASH_LOADER_EFUSE_READ_PARA_ERROR = 0x0404,
BFLB_EFLASH_LOADER_EFUSE_READ_ADDR_ERROR = 0x0405,
BFLB_EFLASH_LOADER_EFUSE_READ_ERROR = 0x0406,
BFLB_EFLASH_LOADER_EFUSE_READ_MAC_ERROR = 0x0407,
/*MISC*/
BFLB_EFLASH_LOADER_PLL_ERROR = 0xfffc,
BFLB_EFLASH_LOADER_INVASION_ERROR = 0xfffd,
BFLB_EFLASH_LOADER_POLLING = 0xfffe,
BFLB_EFLASH_LOADER_FAIL = 0xffff,
} eflash_loader_error_code_t;
/** private definition**/
#define EFLASH_LOADER_CMD_DISABLE 0x000
#define EFLASH_LOADER_CMD_ENABLE 0x001
#define BFLB_EFLASH_LOADER_CMD_ACK 0x00004B4F
#define BFLB_EFLASH_LOADER_CMD_NACK 0x00004C46
#define BFLB_EFLASH_LOADER_EFUSE0_SIZE 128
/*max data payload in command*/
#define BFLB_EFLASH_LOADER_READBUF_SIZE (1024 * 16 + 8)
#define BFLB_EFLASH_LOADER_WRITEBUF_SIZE BFLB_EFLASH_LOADER_READBUF_SIZE
#define BFLB_EFLASH_LOADER_CMD_DATA_MAX_LEN (BFLB_EFLASH_LOADER_READBUF_SIZE - 0x04) //cmd+rsvd+len(2bytes)
#define MAXOF(a, b) ((a) > (b) ? (a) : (b))
#define OFFSET(TYPE, MEMBER) ((uint32_t)(&(((TYPE *)0)->MEMBER)))
uint8_t bootrom_read_boot_mode(void);
void bflb_eflash_loader_init_uart_gpio(uint8_t eflash_loader_uart_pin_select);
void bflb_eflash_loader_deinit_uart_gpio_do(uint8_t eflash_loader_uart_pin_select);
void bflb_eflash_loader_deinit_uart_gpio(uint8_t eflash_loader_uart_pin_select);
void bflb_eflash_loader_init_flash_gpio(uint8_t flash_cfg);
#endif

View file

@ -0,0 +1,734 @@
/**
******************************************************************************
* @file blsp_eflash_loader_cmds.c
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "softcrc.h"
#include "partition.h"
#include "bflb_flash.h"
#include "bflb_sec_sha.h"
#include "blsp_media_boot.h"
#include "blsp_common.h"
#define BFLB_EFLASH_LOADER_CHECK_LEN 2048
#define BFLB_EFLASH_MAX_SIZE 2 * 1024 * 1024
extern struct device *download_uart;
#if BLSP_BOOT2_SUPPORT_EFLASH_LOADER_RAM
static struct image_cfg_t image_cfg;
static struct bootrom_img_ctrl_t img_ctrl;
static struct segment_header_t segment_hdr;
uint32_t eflash_loader_cmd_ack_buf[16];
/*for bl602*/
static int32_t bflb_bootrom_cmd_get_bootinfo(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_bootrom_cmd_load_bootheader(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_bootrom_cmd_load_segheader(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_bootrom_cmd_load_segdata(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_bootrom_cmd_check_img(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_bootrom_cmd_run(uint16_t cmd, uint8_t *data, uint16_t len);
static void bflb_bootrom_cmd_ack(uint32_t result);
#endif
#if BLSP_BOOT2_SUPPORT_EFLASH_LOADER_FLASH
static uint32_t g_eflash_loader_error = 0;
/* for bl702 */
static int32_t bflb_eflash_loader_cmd_read_jedec_id(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_reset(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_erase_flash(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_write_flash(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_read_flash(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_readSha_flash(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_xip_readSha_flash(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_write_flash_check(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_set_flash_para(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_xip_read_flash_start(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_xip_read_flash_finish(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_clock_set(uint16_t cmd, uint8_t *data, uint16_t len);
static int32_t bflb_eflash_loader_cmd_read_mac_addr(uint16_t cmd, uint8_t *data, uint16_t len);
#endif
#if BLSP_BOOT2_SUPPORT_EFLASH_LOADER_FLASH || BLSP_BOOT2_SUPPORT_EFLASH_LOADER_RAM
static const struct eflash_loader_cmd_cfg_t eflash_loader_cmds[] = {
#if BLSP_BOOT2_SUPPORT_EFLASH_LOADER_RAM
/*for bl602*/
{ BFLB_EFLASH_LOADER_CMD_GET_BOOTINFO, EFLASH_LOADER_CMD_ENABLE, bflb_bootrom_cmd_get_bootinfo },
{ BFLB_EFLASH_LOADER_CMD_LOAD_BOOTHEADER, EFLASH_LOADER_CMD_ENABLE, bflb_bootrom_cmd_load_bootheader },
{ BFLB_EFLASH_LOADER_CMD_LOAD_SEGHEADER, EFLASH_LOADER_CMD_ENABLE, bflb_bootrom_cmd_load_segheader },
{ BFLB_EFLASH_LOADER_CMD_LOAD_SEGDATA, EFLASH_LOADER_CMD_ENABLE, bflb_bootrom_cmd_load_segdata },
{ BFLB_EFLASH_LOADER_CMD_CHECK_IMG, EFLASH_LOADER_CMD_ENABLE, bflb_bootrom_cmd_check_img },
{ BFLB_EFLASH_LOADER_CMD_RUN, EFLASH_LOADER_CMD_ENABLE, bflb_bootrom_cmd_run },
#endif
#if BLSP_BOOT2_SUPPORT_EFLASH_LOADER_FLASH
/* for bl702,bl808,bl606p,bl618,wb03 */
{ BFLB_EFLASH_LOADER_CMD_RESET, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_reset },
{ BFLB_EFLASH_LOADER_CMD_FLASH_ERASE, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_erase_flash },
{ BFLB_EFLASH_LOADER_CMD_FLASH_WRITE, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_write_flash },
{ BFLB_EFLASH_LOADER_CMD_FLASH_READ, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_read_flash },
{ BFLB_EFLASH_LOADER_CMD_FLASH_WRITE_CHECK, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_write_flash_check },
{ BFLB_EFLASH_LOADER_CMD_FLASH_SET_PARA, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_set_flash_para },
{ BFLB_EFLASH_LOADER_CMD_FLASH_READSHA, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_readSha_flash },
{ BFLB_EFLASH_LOADER_CMD_FLASH_XIP_READSHA, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_xip_readSha_flash },
{ BFLB_EFLASH_LOADER_CMD_XIP_READ_START, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_xip_read_flash_start },
{ BFLB_EFLASH_LOADER_CMD_XIP_READ_FINISH, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_xip_read_flash_finish },
{ BFLB_EFLASH_LOADER_CMD_FLASH_READ_JEDECID, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_read_jedec_id },
{ BFLB_EFLASH_LOADER_CMD_CLK_SET, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_clock_set },
{ BFLB_EFLASH_LOADER_CMD_EFUSE_READ_MAC_ADDR, EFLASH_LOADER_CMD_ENABLE, bflb_eflash_loader_cmd_read_mac_addr },
#endif
};
#endif
#if BLSP_BOOT2_SUPPORT_EFLASH_LOADER_RAM
/* ack host with command process result */
static void bflb_bootrom_cmd_ack(uint32_t result)
{
if (result == 0) {
/*OK*/
eflash_loader_cmd_ack_buf[0] = BFLB_BOOTROM_CMD_ACK;
bflb_eflash_loader_if_write((uint32_t *)eflash_loader_cmd_ack_buf, 2);
return;
} else {
/* FL+Error code(2bytes) */
eflash_loader_cmd_ack_buf[0] = BFLB_BOOTROM_CMD_NACK | ((result << 16) & 0xffff0000);
bflb_eflash_loader_if_write(eflash_loader_cmd_ack_buf, 4);
}
}
/* for bl602 eflash loader */
static int32_t bflb_bootrom_cmd_get_bootinfo(uint16_t cmd, uint8_t *data, uint16_t len)
{
/*OK(2)+len(2)+bootrom version(4)+OTP(16)*/
uint8_t *bootinfo = (uint8_t *)eflash_loader_cmd_ack_buf;
uint8_t otp_cfg[20] = { 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0xc1, 0x02, 0x0d, 0xd2, 0x1d, 0xcf, 0x0e, 0xb4, 0x18, 0x00, 0x2f, 0xf4, 0xfb, 0x08 };
//LOG_F("get bootinfo\r\n");
eflash_loader_cmd_ack_buf[0] = BFLB_BOOTROM_CMD_ACK;
bootinfo[2] = 0x18;
bootinfo[3] = 00;
*((uint32_t *)(bootinfo + 4)) = BFLB_BOOTROM_VERSION;
memcpy(bootinfo + 8, &otp_cfg, 20);
bflb_eflash_loader_if_write(eflash_loader_cmd_ack_buf, bootinfo[2] + 4);
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_bootrom_parse_bootheader(uint8_t *data)
{
struct bootheader_t *header = (struct bootheader_t *)data;
uint32_t crc;
uint32_t crcpass = 0;
if (header->bootcfg.bval.crc_ignore == 1 && header->crc32 == BOOTROM_DEADBEEF_VAL) {
crcpass = 1;
} else {
crc = BFLB_Soft_CRC32((uint8_t *)header, sizeof(struct bootheader_t) - sizeof(header->crc32));
if (header->crc32 == crc) {
crcpass = 1;
}
}
if (crcpass) {
if (header->bootcfg.bval.notload_in_bootrom) {
return BFLB_EFLASH_LOADER_IMG_BOOTHEADER_NOT_LOAD_ERROR;
}
/* for boot2, one CPU only */
/*get which CPU's img it is*/
if (0 == memcmp((void *)&header->magiccode, "BFNP", sizeof(header->magiccode))) {
//current_cpu=i;
img_ctrl.pkhash_src = 0; //boot_cpu_cfg[i].pkhash_src;
} else {
return BFLB_EFLASH_LOADER_IMG_BOOTHEADER_MAGIC_ERROR;
}
image_cfg.entrypoint = 0;
/* set image valid 0 as default */
image_cfg.img_valid = 0;
/* deal with pll config */
//bflb_bootrom_clk_set_from_user(&header->clkCfg,1);
/* encrypt and sign */
image_cfg.encrypt_type = header->bootcfg.bval.encrypt_type;
image_cfg.sign_type = header->bootcfg.bval.sign;
image_cfg.key_sel = header->bootcfg.bval.key_sel;
/* xip relative */
image_cfg.no_segment = header->bootcfg.bval.no_segment;
image_cfg.cache_select = header->bootcfg.bval.cache_select;
image_cfg.aes_region_lock = header->bootcfg.bval.aes_region_lock;
image_cfg.halt_ap = header->bootcfg.bval.halt_ap;
image_cfg.cache_way_disable = header->bootcfg.bval.cache_way_disable;
image_cfg.hash_ignore = header->bootcfg.bval.hash_ignore;
/* firmware len*/
image_cfg.img_segment_info.segment_cnt = header->img_segment_info.segment_cnt;
/*boot entry and flash offset */
image_cfg.entrypoint = header->bootentry;
image_cfg.img_start.flashoffset = header->img_start.flashoffset;
if (image_cfg.img_segment_info.segment_cnt == 0) {
return BFLB_EFLASH_LOADER_IMG_SEGMENT_CNT_ERROR;
}
/*clear segment_cnt*/
img_ctrl.segment_cnt = 0;
} else {
return BFLB_EFLASH_LOADER_IMG_BOOTHEADER_CRC_ERROR;
}
return BFLB_EFLASH_LOADER_SUCCESS;
}
static int32_t bflb_bootrom_cmd_load_bootheader(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
//LOG_F("load bootheader\r\n");
if (len != sizeof(struct bootheader_t)) {
ret = BFLB_EFLASH_LOADER_IMG_BOOTHEADER_LEN_ERROR;
} else {
ret = bflb_bootrom_parse_bootheader(data);
if (BFLB_EFLASH_LOADER_SUCCESS == ret) {
if (image_cfg.sign_type) {
img_ctrl.state = BOOTROM_IMG_PK;
} else if (image_cfg.encrypt_type) {
img_ctrl.state = BOOTROM_IMG_AESIV;
} else {
img_ctrl.state = BOOTROM_IMG_SEGHEADER;
}
}
}
bflb_bootrom_cmd_ack(ret);
return ret;
}
static int32_t bflb_bootrom_is_boot_dst_valid(uint32_t addr, uint32_t len)
{
return 1;
}
int32_t bflb_bootrom_parse_seg_header(uint8_t *data)
{
struct segment_header_t *hdr;
hdr = (struct segment_header_t *)data;
if (hdr->crc32 == BFLB_Soft_CRC32(hdr, sizeof(struct segment_header_t) - 4)) {
memcpy(&segment_hdr, hdr, sizeof(struct segment_header_t));
if (bflb_bootrom_is_boot_dst_valid(segment_hdr.destaddr, segment_hdr.len) == 1) {
return BFLB_EFLASH_LOADER_SUCCESS;
} else {
return BFLB_EFLASH_LOADER_IMG_SECTIONHEADER_DST_ERROR;
}
} else {
return BFLB_EFLASH_LOADER_IMG_SECTIONHEADER_CRC_ERROR;
}
}
static int32_t bflb_bootrom_cmd_load_segheader(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
uint8_t *segdatainfo = (uint8_t *)eflash_loader_cmd_ack_buf;
//LOG_F("load SegHdr\r\n");
if (img_ctrl.state != BOOTROM_IMG_SEGHEADER) {
ret = BFLB_EFLASH_LOADER_CMD_SEQ_ERROR;
} else {
if (len != sizeof(struct segment_header_t)) {
ret = BFLB_EFLASH_LOADER_IMG_SECTIONHEADER_LEN_ERROR;
} else {
memset(&segment_hdr, 0, sizeof(struct segment_header_t));
img_ctrl.segdata_recv_len = 0;
ret = bflb_bootrom_parse_seg_header(data);
if (ret == BFLB_EFLASH_LOADER_SUCCESS) {
//bflb_bootrom_printe("dest=%08x,len=%d\r\n",segment_hdr.destaddr,segment_hdr.len);
img_ctrl.state = BOOTROM_IMG_SEGDATA;
}
}
}
/* if segheader is encrypted, then ack segment len*/
if (ret == BFLB_EFLASH_LOADER_SUCCESS) {
/*ack segdata len*/
eflash_loader_cmd_ack_buf[0] = BFLB_BOOTROM_CMD_ACK;
segdatainfo[2] = sizeof(segment_hdr);
segdatainfo[3] = 0x00;
memcpy(&segdatainfo[4], (void *)&segment_hdr, sizeof(segment_hdr));
bflb_eflash_loader_if_write(eflash_loader_cmd_ack_buf, segdatainfo[2] + 4);
} else {
bflb_bootrom_cmd_ack(ret);
}
return ret;
}
static int32_t bflb_bootrom_cmd_load_segdata(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
//LOG_F("load SegData\r\n");
if (img_ctrl.state != BOOTROM_IMG_SEGDATA) {
ret = BFLB_EFLASH_LOADER_CMD_SEQ_ERROR;
goto finished;
}
if (image_cfg.encrypt_type && len % 16 != 0) {
ret = BFLB_EFLASH_LOADER_IMG_SECTIONDATA_LEN_ERROR;
//bflb_bootrom_printe("len error,len=%d\r\n",len);
goto finished;
}
if (img_ctrl.segdata_recv_len + len > segment_hdr.len) {
ret = BFLB_EFLASH_LOADER_IMG_SECTIONDATA_TLEN_ERROR;
//bflb_bootrom_printe("tlen error,receive=%d,indicator=%d\r\n",
//img_ctrl.segdata_recv_len+len,segment_hdr.len);
goto finished;
}
/*no encryption,copy directlly */
ARCH_MemCpy_Fast((void *)segment_hdr.destaddr, data, len);
//LOG_F("segment_hdr.destaddr 0x%08x, len %d,data %02x %02x %02x %02x \r\n", segment_hdr.destaddr, len, data[0], data[1], data[2], data[3]);
img_ctrl.segdata_recv_len += len;
segment_hdr.destaddr += len;
if (img_ctrl.segdata_recv_len >= segment_hdr.len) {
/*finish loading one segment*/
img_ctrl.segment_cnt++;
if (img_ctrl.segment_cnt == image_cfg.img_segment_info.segment_cnt) {
img_ctrl.state = BOOTROM_IMG_CHECK;
} else {
img_ctrl.state = BOOTROM_IMG_SEGHEADER;
}
}
finished:
bflb_bootrom_cmd_ack(ret);
return ret;
}
static int32_t bflb_bootrom_cmd_check_img(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
//LOG_F("check img\r\n");
if (img_ctrl.state != BOOTROM_IMG_CHECK) {
ret = BFLB_EFLASH_LOADER_IMG_HALFBAKED_ERROR;
bflb_bootrom_cmd_ack(ret);
return ret;
}
/*default,set state to BOOTROM_IMG_BOOTHEADER*/
img_ctrl.state = BOOTROM_IMG_BOOTHEADER;
/*finally, check hash and signature*/
ret = BFLB_EFLASH_LOADER_SUCCESS; //bflb_bootrom_check_hash();
if (ret == BFLB_EFLASH_LOADER_SUCCESS) {
ret = BFLB_EFLASH_LOADER_SUCCESS; //bflb_bootrom_check_signature();
bflb_bootrom_cmd_ack(ret);
if (ret == BFLB_EFLASH_LOADER_SUCCESS) {
img_ctrl.state = BOOTROM_IMG_RUN;
image_cfg.img_valid = 1;
}
} else {
bflb_bootrom_cmd_ack(ret);
}
return ret;
}
static void bflb_eflash_loader_exit_delay_us(uint32_t cnt)
{
volatile uint32_t i = (32 / 5) * cnt;
while (i--)
;
}
static void bflb_eflash_loader_jump_entry(void)
{
pentry_t pentry = 0;
/* deal NP's entry point */
if (image_cfg.img_valid) {
pentry = (pentry_t)image_cfg.entrypoint;
//LOG_F("image_cfg.entrypoint 0x%08x\r\n", image_cfg.entrypoint);
if (pentry != NULL) {
pentry();
}
}
/*if cann't jump(open jtag only?),stay here */
while (1) {
/*use soft delay only */
bflb_eflash_loader_exit_delay_us(100);
}
}
static int32_t bflb_bootrom_cmd_run(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
//LOG_F("run\r\n");
if (img_ctrl.state != BOOTROM_IMG_RUN) {
ret = BFLB_EFLASH_LOADER_CMD_SEQ_ERROR;
bflb_bootrom_cmd_ack(ret);
return ret;
}
bflb_bootrom_cmd_ack(ret);
//bflb_eflash_loader_usart_if_wait_tx_idle(BFLB_BOOTROM_IF_TX_IDLE_TIMEOUT);
bflb_mtimer_delay_ms(BFLB_BOOTROM_IF_TX_IDLE_TIMEOUT);
/* get msp and pc value */
//LOG_F("image_cfg.img_valid %d\r\n", image_cfg.img_valid);
if (image_cfg.img_valid) {
if (image_cfg.entrypoint == 0) {
if (image_cfg.img_start.ramaddr != 0) {
image_cfg.entrypoint = image_cfg.img_start.ramaddr;
} else {
image_cfg.entrypoint = BLSP_BOOT2_TCM_BASE;
}
}
}
//LOG_F("jump\r\n");
/*jump to entry */
bflb_eflash_loader_jump_entry();
return ret;
}
#endif
#if BLSP_BOOT2_SUPPORT_EFLASH_LOADER_FLASH
/* ack host with command process result */
ATTR_TCM_SECTION static void bflb_eflash_loader_cmd_ack(uint32_t result)
{
if (result == 0) {
/*OK*/
g_eflash_loader_cmd_ack_buf[0] = BFLB_EFLASH_LOADER_CMD_ACK;
bflb_eflash_loader_if_write((uint32_t *)g_eflash_loader_cmd_ack_buf, 2);
return;
} else {
/* FL+Error code(2bytes) */
g_eflash_loader_cmd_ack_buf[0] = BFLB_EFLASH_LOADER_CMD_NACK | ((result << 16) & 0xffff0000);
bflb_eflash_loader_if_write(g_eflash_loader_cmd_ack_buf, 4);
}
}
static void bflb_eflash_loader_cmd_response(uint32_t *data, uint32_t len)
{
bflb_eflash_loader_if_write(data, len);
}
static int32_t bflb_eflash_loader_cmd_read_jedec_id(uint16_t cmd, uint8_t *data, uint16_t len)
{
uint32_t ackdata[2];
uint8_t *tmp_buf;
//LOG_F("JID\n");
ackdata[0] = BFLB_EFLASH_LOADER_CMD_ACK;
tmp_buf = (uint8_t *)ackdata;
/*ack read jedec ID */
tmp_buf[2] = 4;
tmp_buf[3] = 0;
flash_read_jedec_id((uint8_t *)&ackdata[1]);
ackdata[1] &= 0x00ffffff;
ackdata[1] |= 0x80000000;
bflb_eflash_loader_if_write((uint32_t *)ackdata, 4 + 4);
return BFLB_EFLASH_LOADER_SUCCESS;
}
static int32_t bflb_eflash_loader_cmd_reset(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
//pt_table_dump();
//LOG_F("RST\n");
bflb_eflash_loader_cmd_ack(ret);
bflb_eflash_loader_if_wait_tx_idle(BFLB_EFLASH_LOADER_IF_TX_IDLE_TIMEOUT);
/* add for bl702, will impact on boot pin read */
hal_boot2_set_psmode_status(0x594c440B);
/* FPGA POR RST NOT work,so add system reset */
bflb_platform_delay_us(10);
hal_boot2_sw_system_reset();
return ret;
}
static int32_t bflb_eflash_loader_cmd_erase_flash(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
uint32_t startaddr, endaddr;
//LOG_F("E\n");
if (len != 8) {
ret = BFLB_EFLASH_LOADER_FLASH_ERASE_PARA_ERROR;
} else {
/*clean write error, since write usually behand erase*/
g_eflash_loader_error = BFLB_EFLASH_LOADER_SUCCESS;
memcpy(&startaddr, data, 4);
memcpy(&endaddr, data + 4, 4);
//LOG_F("from%08xto%08x\n", startaddr, endaddr);
if (SUCCESS != flash_erase(startaddr, endaddr - startaddr + 1)) {
//LOG_F("fail\n");
ret = BFLB_EFLASH_LOADER_FLASH_ERASE_ERROR;
}
}
bflb_eflash_loader_cmd_ack(ret);
return ret;
}
static int32_t ATTR_TCM_SECTION bflb_eflash_loader_cmd_write_flash(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
uint32_t startaddr, write_len;
//LOG_F("W\n");
if (len <= 4) {
ret = BFLB_EFLASH_LOADER_FLASH_WRITE_PARA_ERROR;
} else {
memcpy(&startaddr, data, 4);
write_len = len - 4;
//LOG_F("to%08x,%d\n", startaddr, write_len);
if (startaddr < 0xffffffff) {
if (SUCCESS != flash_write(startaddr, data + 4, write_len)) {
/*error , response again with error */
//LOG_F("fail\r\n");
ret = BFLB_EFLASH_LOADER_FLASH_WRITE_ERROR;
g_eflash_loader_error = ret;
} else {
bflb_eflash_loader_cmd_ack(ret);
return BFLB_EFLASH_LOADER_SUCCESS;
}
} else {
ret = BFLB_EFLASH_LOADER_FLASH_WRITE_ADDR_ERROR;
}
//LOG_F("%d\n", bflb_platform_get_time_us());
}
bflb_eflash_loader_cmd_ack(ret);
return ret;
}
static int32_t bflb_eflash_loader_cmd_read_flash(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
uint32_t startaddr, read_len;
uint8_t *ackdata = (uint8_t *)g_boot2_read_buf;
if (len != 8) {
ret = BFLB_EFLASH_LOADER_FLASH_WRITE_PARA_ERROR;
bflb_eflash_loader_cmd_ack(ret);
} else {
memcpy(&startaddr, data, 4);
memcpy(&read_len, data + 4, 4);
ackdata[0] = 'O';
ackdata[1] = 'K';
ackdata[2] = read_len & 0xff;
ackdata[3] = (read_len >> 8) & 0xff;
flash_read(startaddr, &ackdata[4], read_len);
bflb_eflash_loader_cmd_response((uint32_t *)ackdata, read_len + 4);
}
return BFLB_EFLASH_LOADER_SUCCESS;
}
static int32_t bflb_eflash_loader_cmd_xip_read_flash_start(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
bflb_eflash_loader_cmd_ack(ret);
return ret;
}
static int32_t bflb_eflash_loader_cmd_xip_read_flash_finish(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
//LOG_F("exit\n");
bflb_eflash_loader_cmd_ack(ret);
return ret;
}
static int32_t bflb_eflash_loader_cmd_readSha_flash(uint16_t cmd, uint8_t *data, uint16_t len)
{
return BFLB_EFLASH_LOADER_SUCCESS;
}
static int32_t bflb_eflash_loader_cmd_xip_readSha_flash(uint16_t cmd, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
uint32_t startaddr, read_len;
//SEC_Eng_SHA256_Ctx sha_ctx;
//SEC_ENG_SHA_ID_Type shaId = SEC_ENG_SHA_ID0;
uint16_t sha_len = 32;
uint8_t ackdata[32 + 4];
//LOG_F("XRSha\n");
simple_malloc_init(g_malloc_buf, sizeof(g_malloc_buf));
uint8_t *g_sha_in_buf = vmalloc(BFLB_EFLASH_LOADER_READBUF_SIZE);
if (len != 8) {
ret = BFLB_EFLASH_LOADER_FLASH_WRITE_PARA_ERROR;
bflb_eflash_loader_cmd_ack(ret);
} else {
memcpy(&startaddr, data, 4);
memcpy(&read_len, data + 4, 4);
//LOG_F("from%08x,%d\n", startaddr, read_len);
//LOG_F("!!!Be careful that SHA input data should locate at OCRAM \n");
bflb_sha_init(sha, SHA_MODE_SHA256);
bflb_sha256_start(sha, &ctx_sha256);
while (read_len > 0) {
if (read_len > BFLB_EFLASH_LOADER_READBUF_SIZE) {
blsp_mediaboot_read(startaddr, g_sha_in_buf, BFLB_EFLASH_LOADER_READBUF_SIZE);
/*cal sha here*/
bflb_sha256_update(sha, &ctx_sha256, g_sha_in_buf, BFLB_EFLASH_LOADER_READBUF_SIZE);
read_len -= BFLB_EFLASH_LOADER_READBUF_SIZE;
startaddr += BFLB_EFLASH_LOADER_READBUF_SIZE;
} else {
blsp_mediaboot_read(startaddr, g_sha_in_buf, read_len);
/*cal sha here*/
bflb_sha256_update(sha, &ctx_sha256, g_sha_in_buf, read_len);
read_len -= read_len;
startaddr += read_len;
}
}
bflb_sha256_finish(sha, &ctx_sha256, (uint8_t *)&ackdata[4]);
for (sha_len = 0; sha_len < 32; sha_len++) {
//LOG_F("\r\n");
//LOG_F("%02x ", ackdata[4 + sha_len]);
}
sha_len = 32;
/*ack read data */
ackdata[0] = BFLB_EFLASH_LOADER_CMD_ACK & 0xff;
ackdata[1] = (BFLB_EFLASH_LOADER_CMD_ACK >> 8) & 0xff;
ackdata[2] = sha_len & 0xff;
ackdata[3] = (sha_len >> 8) & 0xff;
bflb_eflash_loader_if_write((uint32_t *)ackdata, sha_len + 4);
}
return ret;
}
ATTR_TCM_SECTION static int32_t bflb_eflash_loader_cmd_write_flash_check(uint16_t cmd, uint8_t *data, uint16_t len)
{
//LOG_F("WC\n");
bflb_eflash_loader_cmd_ack(g_eflash_loader_error);
return BFLB_EFLASH_LOADER_SUCCESS;
}
static int32_t bflb_eflash_loader_cmd_set_flash_para(uint16_t cmd, uint8_t *data, uint16_t len)
{
bflb_eflash_loader_cmd_ack(BFLB_EFLASH_LOADER_SUCCESS);
return BFLB_EFLASH_LOADER_SUCCESS;
}
static int32_t bflb_eflash_loader_cmd_read_mac_addr(uint16_t cmd, uint8_t *data, uint16_t len)
{
uint32_t crc = 0;
uint8_t ackdata[14];
ackdata[0] = BFLB_EFLASH_LOADER_CMD_ACK & 0xff;
ackdata[1] = (BFLB_EFLASH_LOADER_CMD_ACK >> 8) & 0xff;
ackdata[2] = 10;
ackdata[3] = 0;
ackdata[4] = ackdata[5] = ackdata[6] = ackdata[7] = ackdata[8] = ackdata[9] = 0x22; /* fake for download */
crc = BFLB_Soft_CRC32((uint8_t *)ackdata + 4, 6);
memcpy(ackdata + 10, (uint8_t *)&crc, 4);
bflb_eflash_loader_if_write((uint32_t *)ackdata, 14);
return BFLB_EFLASH_LOADER_SUCCESS;
}
static int32_t bflb_eflash_loader_cmd_clock_set(uint16_t cmd, uint8_t *data, uint16_t len)
{
bflb_eflash_loader_cmd_ack(BFLB_EFLASH_LOADER_SUCCESS);
return BFLB_EFLASH_LOADER_SUCCESS;
}
#endif
int32_t bflb_eflash_loader_cmd_process(uint8_t cmdid, uint8_t *data, uint16_t len)
{
int32_t ret = BFLB_EFLASH_LOADER_SUCCESS;
#if BLSP_BOOT2_SUPPORT_EFLASH_LOADER_FLASH || BLSP_BOOT2_SUPPORT_EFLASH_LOADER_RAM
int i = 0;
for (i = 0; i < sizeof(eflash_loader_cmds) / sizeof(eflash_loader_cmds[0]); i++) {
if (eflash_loader_cmds[i].cmd == cmdid) {
if (EFLASH_LOADER_CMD_ENABLE == eflash_loader_cmds[i].enabled && NULL != eflash_loader_cmds[i].cmd_process) {
ret = eflash_loader_cmds[i].cmd_process(cmdid, data, len);
} else {
return BFLB_EFLASH_LOADER_CMD_ID_ERROR;
}
break;
}
}
#endif
return ret;
}

View file

@ -0,0 +1,267 @@
/**
******************************************************************************
* @file blsp_eflash_loader_cmds.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BFLB_EFLASH_LOADER_CMDS_H__
#define __BFLB_EFLASH_LOADER_CMDS_H__
#include "stdint.h"
#include "bflb_core.h"
#include "bl616_sflash.h"
#define BFLB_EFLASH_LOADER_CMD_GET_BOOTINFO 0x0010
#define BFLB_EFLASH_LOADER_CMD_LOAD_BOOTHEADER 0x0011
#define BFLB_EFLASH_LOADER_CMD_LOAD_PUBLICKEY 0x0012
#define BFLB_EFLASH_LOADER_CMD_LOAD_PUBLICKEY2 0x0013
#define BFLB_EFLASH_LOADER_CMD_LOAD_SIGNATURE 0x0014
#define BFLB_EFLASH_LOADER_CMD_LOAD_SIGNATURE2 0x0015
#define BFLB_EFLASH_LOADER_CMD_LOAD_AESIV 0x0016
#define BFLB_EFLASH_LOADER_CMD_LOAD_SEGHEADER 0x0017
#define BFLB_EFLASH_LOADER_CMD_LOAD_SEGDATA 0x0018
#define BFLB_EFLASH_LOADER_CMD_CHECK_IMG 0x0019
#define BFLB_EFLASH_LOADER_CMD_RUN 0x001A
#define BFLB_EFLASH_LOADER_CMD_CHANGE_RATE 0x0020
#define BFLB_EFLASH_LOADER_CMD_RESET 0x0021
#define BFLB_EFLASH_LOADER_CMD_CLK_SET 0x0022
#define BFLB_EFLASH_LOADER_CMD_FLASH_ERASE 0x0030
#define BFLB_EFLASH_LOADER_CMD_FLASH_WRITE 0x0031
#define BFLB_EFLASH_LOADER_CMD_FLASH_READ 0x0032
#define BFLB_EFLASH_LOADER_CMD_FLASH_BOOT 0x0033
#define BFLB_EFLASH_LOADER_CMD_FLASH_WRITE_CHECK 0x003A
#define BFLB_EFLASH_LOADER_CMD_FLASH_SET_PARA 0x003B
#define BFLB_EFLASH_LOADER_CMD_FLASH_CHIPERASE 0x003C
#define BFLB_EFLASH_LOADER_CMD_FLASH_READSHA 0x003D
#define BFLB_EFLASH_LOADER_CMD_FLASH_XIP_READSHA 0x003E
#define BFLB_EFLASH_LOADER_CMD_FLASH_XIP_READ 0x0034
#define BFLB_EFLASH_LOADER_CMD_FLASH_SBUS_XIP_READ 0x0035
#define BFLB_EFLASH_LOADER_CMD_FLASH_READ_JEDECID 0x0036
#define BFLB_EFLASH_LOADER_CMD_FLASH_READ_STATUS_REG 0x0037
#define BFLB_EFLASH_LOADER_CMD_FLASH_WRITE_STATUS_REG 0x0038
#define BFLB_EFLASH_LOADER_CMD_EFUSE_WRITE 0x0040
#define BFLB_EFLASH_LOADER_CMD_EFUSE_READ 0x0041
#define BFLB_EFLASH_LOADER_CMD_EFUSE_READ_MAC_ADDR 0x0042
#define BFLB_EFLASH_LOADER_CMD_MEM_WRITE 0x0050
#define BFLB_EFLASH_LOADER_CMD_MEM_READ 0x0051
#define BFLB_EFLASH_LOADER_CMD_LOG_READ 0x0071
#define BFLB_EFLASH_LOADER_CMD_XIP_READ_START 0x0060
#define BFLB_EFLASH_LOADER_CMD_XIP_READ_FINISH 0x0061
#define BFLB_EFLASH_LOADER_CMD_ISP_MODE 0x00a0
#define BFLB_EFLASH_LOADER_CMD_IAP_MODE 0x00a1
#define BFLB_EFLASH_LOADER_CMD_GET_ECDH_PK 0x0090
#define BFLB_EFLASH_LOADER_CMD_ECDH_CHANLLENGE 0x0091
/* public key hash type and length */
#define BFLB_EFLASH_LOADER_PK_HASH_TYPE BFLB_HASH_TYPE_SHA256
#define BFLB_EFLASH_LOADER_PK_HASH_SIZE 256 / 8
#define BFLB_EFLASH_LOADER_HASH_TYPE BFLB_HASH_TYPE_SHA256
#define BFLB_EFLASH_LOADER_AES_TYPE BFLB_CRYPT_TYPE_AES_CBC
#define BFLB_EFLASH_LOADER_HASH_SIZE 256 / 8
#define BFLB_BOOTROM_CMD_ACK 0x00004B4F
#define BFLB_BOOTROM_CMD_NACK 0x00004C46
#define BFLB_BOOTROM_VERSION 0x08080001
#define BOOTROM_DEADBEEF_VAL 0xdeadbeef
#define BFLB_BOOTROM_IF_TX_IDLE_TIMEOUT 40 /*ms*/
void bflb_eflash_loader_cmd_disable(uint8_t cmdid);
void bflb_eflash_loader_cmd_enable(uint8_t cmdid);
int32_t bflb_eflash_loader_cmd_process(uint8_t cmdid, uint8_t *data, uint16_t len);
typedef int32_t (*pfun_cmd_process)(uint16_t cmd, uint8_t *data, uint16_t len);
struct eflash_loader_cmd_cfg_t {
uint8_t cmd;
uint8_t enabled;
pfun_cmd_process cmd_process;
};
__PACKED_STRUCT boot_flash_cfg_t
{
uint32_t magiccode; /*'FCFG'*/
SPI_Flash_Cfg_Type cfg;
uint32_t crc32;
};
__PACKED_STRUCT sys_clk_cfg_t
{
uint8_t xtal_type;
uint8_t pll_clk;
uint8_t hclk_div;
uint8_t bclk_div;
uint8_t flash_clk_type;
uint8_t flash_clk_div;
uint8_t rsvd[2];
};
__PACKED_STRUCT boot_clk_cfg_t
{
uint32_t magiccode; /*'PCFG'*/
struct sys_clk_cfg_t cfg;
uint32_t crc32;
};
__PACKED_STRUCT bootheader_t
{
uint32_t magiccode; /*'BFXP'*/
uint32_t rivison;
struct boot_flash_cfg_t flashCfg;
struct boot_clk_cfg_t clkCfg;
__PACKED_UNION
{
__PACKED_STRUCT
{
uint32_t sign : 2; /* [1: 0] for sign*/
uint32_t encrypt_type : 2; /* [3: 2] for encrypt */
uint32_t key_sel : 2; /* [5: 4] for key sel in boot interface*/
uint32_t rsvd6_7 : 2; /* [7: 6] for encrypt*/
uint32_t no_segment : 1; /* [8] no segment info */
uint32_t cache_select : 1; /* [9] for cache */
uint32_t notload_in_bootrom : 1; /* [10] not load this img in bootrom */
uint32_t aes_region_lock : 1; /* [11] aes region lock */
uint32_t cache_way_disable : 4; /* [15: 12] cache way disable info*/
uint32_t crc_ignore : 1; /* [16] ignore crc */
uint32_t hash_ignore : 1; /* [17] hash crc */
uint32_t halt_ap : 1; /* [18] halt ap */
uint32_t rsvd19_31 : 13; /* [31:19] rsvd */
}
bval;
uint32_t wval;
}
bootcfg;
__PACKED_UNION
{
uint32_t segment_cnt;
uint32_t img_len;
}
img_segment_info;
uint32_t bootentry; /* entry point of the image*/
__PACKED_UNION
{
uint32_t ramaddr;
uint32_t flashoffset;
}
img_start;
uint8_t hash[256 / 8];
uint32_t rsv1;
uint32_t rsv2;
uint32_t crc32;
};
__PACKED_STRUCT image_cfg_t
{
uint8_t encrypt_type;
uint8_t sign_type;
uint8_t key_sel;
uint8_t img_valid;
uint8_t no_segment;
uint8_t cache_select;
uint8_t cache_way_disable;
uint8_t hash_ignore;
uint8_t aes_region_lock;
uint8_t halt_ap;
uint8_t r[2];
__PACKED_UNION
{
uint32_t segment_cnt;
uint32_t img_len;
}
img_segment_info;
uint32_t mspval;
uint32_t entrypoint;
__PACKED_UNION
{
uint32_t ramaddr;
uint32_t flashoffset;
}
img_start;
uint32_t sig_len;
uint32_t sig_len2;
uint32_t deallen;
uint32_t maxinputlen;
};
__PACKED_STRUCT bootrom_img_ctrl_t
{
uint8_t segment_cnt;
uint8_t state;
uint8_t pkhash_src;
uint8_t rvsd;
uint32_t segdata_recv_len;
};
__PACKED_STRUCT segment_header_t
{
uint32_t destaddr;
uint32_t len;
uint32_t rsv;
uint32_t crc32;
};
typedef enum tag_bootrom_img_state_t {
BOOTROM_IMG_BOOTHEADER = 0,
BOOTROM_IMG_PK,
BOOTROM_IMG_SIGNATURE,
BOOTROM_IMG_AESIV,
BOOTROM_IMG_SEGHEADER,
BOOTROM_IMG_SEGDATA,
BOOTROM_IMG_CHECK,
BOOTROM_IMG_RUN,
} bootrom_img_state_t;
typedef enum {
EFLASH_LOADER_DOWNLOAD_MODE_IAP = 0,
EFLASH_LOADER_DOWNLOAD_MODE_ISP,
} eflash_loader_download_mode_t;
#endif

View file

@ -0,0 +1,199 @@
/**
* *****************************************************************************
* @file bflb_eflash_loader_interface.c
* @version 0.1
* @date 2022-11-23
* @brief
* *****************************************************************************
* @attention
*
* <h2><center>&copy; 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.h"
#include "partition.h"
#include "blsp_common.h"
#include "xz_config.h"
#include "blsp_port.h"
#include "bflb_port_boot2.h"
uint8_t *g_eflash_loader_readbuf[2];
volatile uint32_t g_rx_buf_index = 0;
volatile uint32_t g_rx_buf_len = 0;
uint32_t g_eflash_loader_cmd_ack_buf[16];
static eflash_loader_if_cfg_t eflash_loader_if_cfg;
eflash_loader_if_cfg_t *bflb_eflash_loader_if_set(eflash_loader_if_type_t type)
{
switch (type) {
case BFLB_EFLASH_LOADER_IF_UART:
eflash_loader_if_cfg.if_type = (uint8_t)BFLB_EFLASH_LOADER_IF_UART;
eflash_loader_if_cfg.if_type_onfail = (uint8_t)BFLB_EFLASH_LOADER_IF_JLINK;
eflash_loader_if_cfg.disabled = 0;
eflash_loader_if_cfg.maxlen = BFLB_EFLASH_LOADER_READBUF_SIZE;
eflash_loader_if_cfg.timeout = BFLB_EFLASH_LOADER_IF_UART_RX_TIMEOUT;
eflash_loader_if_cfg.boot_if_init = bflb_eflash_loader_uart_init;
eflash_loader_if_cfg.boot_if_handshake_poll = bflb_eflash_loader_uart_handshake_poll;
eflash_loader_if_cfg.boot_if_recv = bflb_eflash_loader_uart_recv;
eflash_loader_if_cfg.boot_if_send = bflb_eflash_loader_uart_send;
eflash_loader_if_cfg.boot_if_wait_tx_idle = bflb_eflash_loader_usart_wait_tx_idle;
eflash_loader_if_cfg.boot_if_deinit = bflb_eflash_loader_uart_deinit;
//eflash_loader_if_cfg.boot_if_changerate=bflb_eflash_loader_uart_change_rate;
return &eflash_loader_if_cfg;
#if BLSP_BOOT2_SUPPORT_USB_IAP
case BFLB_EFLASH_LOADER_IF_USB:
eflash_loader_if_cfg.if_type = (uint8_t)BFLB_EFLASH_LOADER_IF_USB;
eflash_loader_if_cfg.if_type_onfail = (uint8_t)BFLB_EFLASH_LOADER_IF_UART;
eflash_loader_if_cfg.disabled = 0;
eflash_loader_if_cfg.maxlen = BFLB_EFLASH_LOADER_READBUF_SIZE;
eflash_loader_if_cfg.timeout = BFLB_EFLASH_LOADER_IF_USB_RX_TIMEOUT;
eflash_loader_if_cfg.boot_if_init = bflb_eflash_loader_usb_init;
eflash_loader_if_cfg.boot_if_handshake_poll = bflb_eflash_loader_usb_handshake_poll;
eflash_loader_if_cfg.boot_if_recv = bflb_eflash_loader_uart_recv;
eflash_loader_if_cfg.boot_if_send = bflb_eflash_loader_usb_send;
eflash_loader_if_cfg.boot_if_wait_tx_idle = bflb_eflash_loader_usb_wait_tx_idle;
eflash_loader_if_cfg.boot_if_deinit = bflb_eflash_loader_usb_deinit;
//eflash_loader_if_cfg.boot_if_changerate=bflb_eflash_loader_uart_change_rate;
return &eflash_loader_if_cfg;
#endif
default:
break;
}
return NULL;
}
int32_t bflb_eflash_loader_if_init()
{
return eflash_loader_if_cfg.boot_if_init();
}
int32_t bflb_eflash_loader_if_handshake_poll(uint32_t timeout)
{
return eflash_loader_if_cfg.boot_if_handshake_poll(timeout);
}
uint32_t *bflb_eflash_loader_if_read(uint32_t *read_len)
{
return eflash_loader_if_cfg.boot_if_recv(read_len, eflash_loader_if_cfg.maxlen, eflash_loader_if_cfg.timeout);
}
ATTR_TCM_SECTION int32_t bflb_eflash_loader_if_write(uint32_t *data, uint32_t len)
{
return eflash_loader_if_cfg.boot_if_send(data, len);
}
int32_t bflb_eflash_loader_if_wait_tx_idle(uint32_t timeout)
{
return eflash_loader_if_cfg.boot_if_wait_tx_idle(timeout);
}
int32_t bflb_eflash_loader_if_deinit()
{
return eflash_loader_if_cfg.boot_if_deinit();
}
int32_t bflb_eflash_loader_main()
{
#if defined(CHIP_BL602) || defined(CHIP_BL702)
int32_t ret;
uint32_t total_len;
uint32_t i, tmp, cmd_len;
uint8_t *recv_buf = NULL;
uint8_t err_cnt = 0;
uint8_t to_cnt = 0;
LOG_F("bflb_eflash_loader_main\r\n");
//pt_table_dump();
//ret = pt_table_get_iap_para(&p_iap_param);
//if(0 != ret){
//LOG_F("no valid partition table\r\n");
//return -1;
//}
while (1) {
to_cnt = 0;
total_len = 0;
do {
total_len = 0;
recv_buf = (uint8_t *)bflb_eflash_loader_if_read(&total_len);
if (total_len <= 0) {
to_cnt++;
}
} while (to_cnt < 2 && total_len <= 0);
if (to_cnt >= 2 || total_len <= 0) {
LOG_F("rcv err break\r\n");
break;
}
LOG_F("Recv\r\n");
//eflash_loader_dump_data(recv_buf,total_len);
cmd_len = recv_buf[2] + (recv_buf[3] << 8);
LOG_F("cmd_len %d\r\n", cmd_len);
/* Check checksum*/
if (recv_buf[1] != 0) {
tmp = 0;
for (i = 2; i < cmd_len + 4; i++) {
tmp += recv_buf[i];
}
if ((tmp & 0xff) != recv_buf[1]) {
/* FL+Error code(2bytes) */
LOG_F("Checksum error %02x\r\n", tmp & 0xff);
g_eflash_loader_cmd_ack_buf[0] = BFLB_EFLASH_LOADER_CMD_NACK | ((BFLB_EFLASH_LOADER_CMD_CRC_ERROR << 16) & 0xffff0000);
bflb_eflash_loader_if_write(g_eflash_loader_cmd_ack_buf, 4);
continue;
}
}
if (recv_buf[0] == BFLB_EFLASH_LOADER_CMD_ISP_MODE) {
eflash_loader_if_cfg.timeout = 8000;
}
ret = bflb_eflash_loader_cmd_process(recv_buf[0], recv_buf + 4, cmd_len);
if (ret != BFLB_EFLASH_LOADER_SUCCESS) {
LOG_F(" CMD Pro Ret %d\r\n", ret);
err_cnt++;
if (err_cnt > 2) {
break;
}
}
}
/* read data finished,deinit and go on*/
bflb_eflash_loader_if_deinit();
#endif
return 0;
}

View file

@ -0,0 +1,102 @@
/**
* *****************************************************************************
* @file bflb_eflash_loader_interface.h
* @version 0.1
* @date 2022-11-23
* @brief
* *****************************************************************************
* @attention
*
* <h2><center>&copy; 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.
*
* *****************************************************************************
*/
#ifndef __BFLB_EFLASH_LOADER_INTERFACE_H__
#define __BFLB_EFLASH_LOADER_INTERFACE_H__
#include "bflb_eflash_loader.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#define BFLB_EFLASH_LOADER_IF_TX_IDLE_TIMEOUT 4 /*ms*/
#define BFLB_EFLASH_LOADER_HAND_SHAKE_RCV_COUNT 32
#define BFLB_EFLASH_LOADER_HAND_SHAKE_BYTE 0x55
#define BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT 16
typedef enum tag_eflash_loader_if_type_t {
//BFLB_EFLASH_LOADER_IF_FLASH=0x01,
BFLB_EFLASH_LOADER_IF_UART = 0x0,
BFLB_EFLASH_LOADER_IF_JLINK,
BFLB_EFLASH_LOADER_IF_SDIO,
BFLB_EFLASH_LOADER_IF_USB,
BFLB_EFLASH_LOADER_IF_ALL,
} eflash_loader_if_type_t;
typedef int32_t (*boot_if_init_p)(void);
typedef int32_t (*boot_if_handshake_poll_p)(uint32_t timeout);
typedef uint32_t *(*boot_if_read_p)(uint32_t *len, uint32_t maxlen, uint32_t timeout);
typedef int32_t (*boot_if_write_p)(uint32_t *data, uint32_t len);
typedef int32_t (*boot_if_wait_tx_idle_p)(uint32_t timeout);
typedef int32_t (*boot_if_deinit_p)(void);
typedef int32_t (*boot_if_change_rate_p)(uint32_t oldval, uint32_t newval);
typedef struct tag_eflash_loader_if_cfg_t {
uint8_t if_type; //interface type
uint8_t if_type_onfail; //if fail move to this interface
uint8_t disabled; //enable this if
uint8_t rsvd;
//pentry_t boot_entry[2];
uint16_t maxlen; //max len for one buffer
uint16_t timeout; //ms
boot_if_init_p boot_if_init; //init function pointer
boot_if_handshake_poll_p boot_if_handshake_poll; //shake hand poll function pointer
boot_if_read_p boot_if_recv; //read function pointer
boot_if_write_p boot_if_send; //write function pointer
boot_if_wait_tx_idle_p boot_if_wait_tx_idle; //wait tx idle function pointer
boot_if_deinit_p boot_if_deinit; //deinit function pointer
boot_if_change_rate_p boot_if_changerate; //change rate function pointer
} eflash_loader_if_cfg_t;
eflash_loader_if_cfg_t *bflb_eflash_loader_if_set(eflash_loader_if_type_t type);
int32_t bflb_eflash_loader_if_init();
int32_t bflb_eflash_loader_if_handshake_poll(uint32_t timeout);
uint32_t *bflb_eflash_loader_if_read(uint32_t *read_len);
int32_t bflb_eflash_loader_if_write(uint32_t *data, uint32_t len);
int32_t bflb_eflash_loader_if_wait_tx_idle(uint32_t timeout);
int32_t bflb_eflash_loader_if_deinit();
int32_t bflb_eflash_loader_main(void);
extern uint8_t *g_eflash_loader_readbuf[2];
/*read data buffer from flash or boot interface*/
extern volatile uint32_t g_rx_buf_index;
extern volatile uint32_t g_rx_buf_len;
extern uint32_t g_eflash_loader_cmd_ack_buf[16];
#endif

View file

@ -0,0 +1,244 @@
/**
******************************************************************************
* @file blsp_eflash_loader_uart.c
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.h"
#include "blsp_port.h"
#include "blsp_common.h"
#include "partition.h"
#include "bflb_uart.h"
static uint32_t g_detected_baudrate;
struct bflb_device_s *uartx;
static void bflb_eflash_loader_usart_if_deinit();
#define UART_FIFO_LEN 32
void bflb_dump_data(uint8_t *buf, uint32_t size)
{
for (int i = 0; i < size; i++) {
if (i % 16 == 0)
LOG_F("\r\n");
LOG_F("%02x ", buf[i]);
}
LOG_F("\r\n");
}
void ATTR_TCM_SECTION uart0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
}
static void bflb_eflash_loader_usart_if_init(uint32_t bdrate)
{
struct bflb_uart_config_s cfg;
hal_boot2_uart_gpio_init();
uartx = bflb_device_get_by_name("uart0");
cfg.baudrate = 2000000;
cfg.data_bits = UART_DATA_BITS_8;
cfg.stop_bits = UART_STOP_BITS_1;
cfg.parity = UART_PARITY_NONE;
cfg.flow_ctrl = 0;
cfg.tx_fifo_threshold = 7;
cfg.rx_fifo_threshold = 7;
bflb_uart_init(uartx, &cfg);
}
void bflb_eflash_loader_usart_if_enable_int(void)
{
}
void bflb_eflash_loader_usart_if_send(uint8_t *data, uint32_t len)
{
uartx = bflb_device_get_by_name("uart0");
bflb_uart_put(uartx, data, len);
}
int32_t bflb_eflash_loader_usart_if_wait_tx_idle(uint32_t timeout)
{
/*UART now can't judge tx idle now*/
bflb_mtimer_delay_ms(timeout);
return 0;
}
static uint32_t *bflb_eflash_loader_usart_if_receive(uint32_t *recv_len, uint16_t maxlen, uint16_t timeout)
{
return NULL;
}
static void bflb_eflash_loader_usart_if_deinit()
{
uartx = bflb_device_get_by_name("uart0");
bflb_uart_deinit(uartx);
}
int32_t bflb_eflash_loader_uart_init()
{
bflb_eflash_loader_usart_if_deinit();
bflb_eflash_loader_usart_if_init(0);
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_eflash_loader_uart_handshake_poll(uint32_t timeout)
{
uint8_t buf[UART_FIFO_LEN] = { 0 };
uint32_t i;
uint32_t handshake_count = 0;
uint32_t rcv_buf_len = 0;
//rcv_buf_len = UART_ReceiveData(g_uart_if_id,buf,128);
//struct device *download_uart = device_find("download_uart");
uartx = bflb_device_get_by_name("uart0");
rcv_buf_len = bflb_uart_get(uartx, buf, UART_FIFO_LEN);
//while(1)
{
if (rcv_buf_len >= BFLB_EFLASH_LOADER_HAND_SHAKE_RCV_COUNT) {
for (i = 0; i < BFLB_EFLASH_LOADER_HAND_SHAKE_RCV_COUNT; i++) {
if (buf[i] == BFLB_EFLASH_LOADER_HAND_SHAKE_BYTE) {
handshake_count++;
if (handshake_count > BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
break;
}
}
}
}
}
if (handshake_count < BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
return -1;
}
#if 1 //defined(CHIP_BL606P) || defined(CHIP_BL808) || defined(CHIP_BL616) || defined(CHIP_WB03)
/*receive shake hanad signal*/
bflb_eflash_loader_usart_if_send((uint8_t *)"Boot2 ISP Ready", strlen("Boot2 ISP Ready"));
bflb_mtimer_delay_ms(2);
hal_reboot_config(HAL_REBOOT_FROM_INTERFACE);
GLB_SW_System_Reset();
while (1)
;
#endif
#if defined(CHIP_BL602) || defined(CHIP_BL702)
#define BFLB_EFLASH_LAODER_COMSUME_55_TIMEOUT 20
uint64_t nowtime;
/*receive shake hanad signal*/
bflb_eflash_loader_usart_if_send((uint8_t *)"Boot2 ISP Shakehand Suss", strlen("Boot2 ISP Shakehand Suss"));
/* consume the remaining bytes when shake hand(0x55) if needed */
nowtime = bflb_mtimer_get_time_ms();
do {
rcv_buf_len = device_read(download_uart, 0, buf, UART_FIFO_LEN);
if (rcv_buf_len > 0) {
nowtime = bflb_platform_get_time_ms();
}
} while (bflb_platform_get_time_ms() - nowtime < BFLB_EFLASH_LAODER_COMSUME_55_TIMEOUT);
bflb_eflash_loader_usart_if_send((uint8_t *)"Boot2 ISP Ready", strlen("Boot2 ISP Ready"));
/*init rx info */
g_rx_buf_index = 0;
g_rx_buf_len = 0;
#if (BLSP_BOOT2_MODE == BOOT2_MODE_DEBUG)
arch_delay_ms(2);
bflb_platform_print_set(1);
device_unregister("debug_log");
uart_register(0, "iap_download");
download_uart = device_find("iap_download");
if (download_uart) {
UART_DEV(download_uart)->fifo_threshold = 16;
device_open(download_uart, DEVICE_OFLAG_STREAM_TX);
}
#endif
simple_malloc_init(g_malloc_buf, sizeof(g_malloc_buf));
g_eflash_loader_readbuf[0] = vmalloc(BFLB_EFLASH_LOADER_READBUF_SIZE);
g_eflash_loader_readbuf[1] = vmalloc(BFLB_EFLASH_LOADER_READBUF_SIZE);
arch_memset(g_eflash_loader_readbuf[0], 0, BFLB_EFLASH_LOADER_READBUF_SIZE);
arch_memset(g_eflash_loader_readbuf[1], 0, BFLB_EFLASH_LOADER_READBUF_SIZE);
bflb_eflash_loader_usart_if_enable_int();
#endif
return 0;
}
uint32_t *bflb_eflash_loader_uart_recv(uint32_t *recv_len, uint32_t maxlen, uint32_t timeout)
{
return bflb_eflash_loader_usart_if_receive(recv_len, maxlen, timeout);
}
int32_t bflb_eflash_loader_uart_send(uint32_t *data, uint32_t len)
{
bflb_eflash_loader_usart_if_send((uint8_t *)data, len);
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_eflash_loader_usart_wait_tx_idle(uint32_t timeout)
{
return bflb_eflash_loader_usart_if_wait_tx_idle(timeout);
}
int32_t bflb_eflash_loader_uart_change_rate(uint32_t oldval, uint32_t newval)
{
uint32_t b = (uint32_t)((g_detected_baudrate * 1.0 * newval) / oldval);
//LOG_F("BDR:");
//LOG_F(oldval);
//LOG_F(newval);
//LOG_F(g_detected_baudrate);
//LOG_F(b);
bflb_eflash_loader_usart_if_wait_tx_idle(BFLB_EFLASH_LOADER_IF_TX_IDLE_TIMEOUT);
bflb_eflash_loader_usart_if_init(b);
bflb_eflash_loader_usart_if_send((uint8_t *)"OK", 2);
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_eflash_loader_uart_deinit()
{
/* delete uart deinit, when uart tx(gpio16) set input function, uart send 0xFF to uart tx fifo
bflb_eflash_loader_deinit_uart_gpio(g_abr_gpio_sel);
bflb_eflash_loader_usart_if_deinit();
*/
return BFLB_EFLASH_LOADER_SUCCESS;
}

View file

@ -0,0 +1,62 @@
/**
******************************************************************************
* @file blsp_eflash_loader_uart.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BFLB_EFLASH_LOADER_UART_H__
#define __BFLB_EFLASH_LOADER_UART_H__
#include "stdint.h"
int32_t bflb_eflash_loader_uart_init();
int32_t bflb_eflash_loader_uart_handshake_poll(uint32_t timeout);
uint32_t *bflb_eflash_loader_uart_recv(uint32_t *recv_len, uint32_t maxlen, uint32_t timeout);
int32_t bflb_eflash_loader_uart_send(uint32_t *data, uint32_t len);
int32_t bflb_eflash_loader_usart_wait_tx_idle(uint32_t timeout);
int32_t bflb_eflash_loader_uart_change_rate(uint32_t oldval, uint32_t newval);
int32_t bflb_eflash_loader_uart_deinit(void);
#define AUTO_BAUDRATE_CHECK_TIME_MAX_MS 2
#if defined(CHIP_BL602)
#define BFLB_EFLASH_LOADER_IF_UART_RX_TIMEOUT 90 /*ms*/
#else
#define BFLB_EFLASH_LOADER_IF_UART_RX_TIMEOUT 8000 /*ms*/
#endif
#endif

View file

@ -0,0 +1,316 @@
/**
******************************************************************************
* @file blsp_eflash_loader_usb.c
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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 "blsp_port.h"
#if BLSP_BOOT2_SUPPORT_USB_IAP
#include "bflb_eflash_loader.h"
#include "hal_usb.h"
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "blsp_common.h"
#include "xz_config.h"
#define CDC_IN_EP 0x82
#define CDC_OUT_EP 0x01
#define CDC_INT_EP 0x83
#define USBD_VID 0xFFFF
#define USBD_PID 0xFFFF
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
USB_DESC_SECTION const uint8_t cdc_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x02, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
USB_LANGID_INIT(USBD_LANGID_STRING),
///////////////////////////////////////
/// string1 descriptor
///////////////////////////////////////
0x12, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'B', 0x00, /* wcChar0 */
'o', 0x00, /* wcChar1 */
'u', 0x00, /* wcChar2 */
'f', 0x00, /* wcChar3 */
'f', 0x00, /* wcChar4 */
'a', 0x00, /* wcChar5 */
'l', 0x00, /* wcChar6 */
'o', 0x00, /* wcChar7 */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x24, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'B', 0x00, /* wcChar0 */
'o', 0x00, /* wcChar1 */
'u', 0x00, /* wcChar2 */
'f', 0x00, /* wcChar3 */
'f', 0x00, /* wcChar4 */
'a', 0x00, /* wcChar5 */
'l', 0x00, /* wcChar6 */
'o', 0x00, /* wcChar7 */
' ', 0x00, /* wcChar8 */
'C', 0x00, /* wcChar9 */
'D', 0x00, /* wcChar10 */
'C', 0x00, /* wcChar11 */
' ', 0x00, /* wcChar13 */
'D', 0x00, /* wcChar14 */
'E', 0x00, /* wcChar15 */
'M', 0x00, /* wcChar16 */
'O', 0x00, /* wcChar17 */
///////////////////////////////////////
/// string3 descriptor
///////////////////////////////////////
0x16, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'1', 0x00, /* wcChar3 */
'0', 0x00, /* wcChar4 */
'3', 0x00, /* wcChar5 */
'1', 0x00, /* wcChar6 */
'0', 0x00, /* wcChar7 */
'0', 0x00, /* wcChar8 */
'0', 0x00, /* wcChar9 */
///////////////////////////////////////
/// device qualifier descriptor
///////////////////////////////////////
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x40,
0x01,
0x00,
0x00
};
void usb_send(uint8_t *buf, uint32_t len)
{
// while (len >= 64) {
// usbd_ep_write(0x82, buf, 64, NULL);
// buf += 64;
// len -= 64;
// }
usbd_ep_write(0x82, buf, len, NULL);
if (len == 64) {
usbd_ep_write(0x82, NULL, 0, NULL);
}
// if (len > 0) {
// usbd_ep_write(0x82, buf, len, NULL);
// } else {
// usbd_ep_write(0x82, NULL, 0, NULL);
// }
}
void usbd_cdc_acm_bulk_out(uint8_t ep)
{
uint32_t actual_read_length = 0;
uint8_t out_buffer[64];
uint8_t *buf = g_eflash_loader_readbuf[g_rx_buf_index];
if (usbd_ep_read(ep, out_buffer, 64, &actual_read_length) < 0) {
//USBD_LOG_DBG("Read DATA Packet failed\r\n");
usbd_ep_set_stall(ep);
return;
}
// bflb_dump_data(out_buffer,actual_read_length);
// usb_send(out_buffer,actual_read_length);
if (g_rx_buf_len + actual_read_length < BFLB_EFLASH_LOADER_READBUF_SIZE) {
arch_memcpy(buf + g_rx_buf_len, out_buffer, actual_read_length);
g_rx_buf_len += actual_read_length;
} else {
g_rx_buf_len = 0;
}
//LOG_D("%d\r\n",g_rx_buf_len);
usbd_ep_read(ep, NULL, 0, NULL);
}
usbd_class_t cdc_class;
usbd_interface_t cdc_cmd_intf;
usbd_interface_t cdc_data_intf;
usbd_endpoint_t cdc_out_ep = {
.ep_addr = CDC_OUT_EP,
.ep_cb = usbd_cdc_acm_bulk_out
};
usbd_endpoint_t cdc_in_ep = {
.ep_addr = CDC_IN_EP,
.ep_cb = NULL
};
void bflb_eflash_loader_usb_if_init(void)
{
hal_boot2_debug_usb_port_init();
simple_malloc_init(g_malloc_buf, sizeof(g_malloc_buf));
g_eflash_loader_readbuf[0] = vmalloc(BFLB_EFLASH_LOADER_READBUF_SIZE);
g_eflash_loader_readbuf[1] = vmalloc(BFLB_EFLASH_LOADER_READBUF_SIZE);
arch_memset(g_eflash_loader_readbuf[0], 0, BFLB_EFLASH_LOADER_READBUF_SIZE);
arch_memset(g_eflash_loader_readbuf[1], 0, BFLB_EFLASH_LOADER_READBUF_SIZE);
usbd_desc_register(cdc_descriptor);
usbd_cdc_add_acm_interface(&cdc_class, &cdc_cmd_intf);
usbd_cdc_add_acm_interface(&cdc_class, &cdc_data_intf);
usbd_interface_add_endpoint(&cdc_data_intf, &cdc_out_ep);
usbd_interface_add_endpoint(&cdc_data_intf, &cdc_in_ep);
usbd_initialize();
while (!usb_device_is_configured()) {
}
}
int32_t bflb_eflash_loader_usb_send(uint32_t *data, uint32_t len)
{
usb_send((uint8_t *)data, len);
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_eflash_loader_usb_wait_tx_idle(uint32_t timeout)
{
/*UART now can't judge tx idle now*/
bflb_mtimer_delay_ms(timeout);
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_eflash_loader_usb_init()
{
bflb_eflash_loader_usb_deinit();
bflb_eflash_loader_usb_if_init();
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_eflash_loader_check_handshake_buf(uint8_t *buf, uint32_t len)
{
if (len == 0)
return -1;
for (int i = 0; i < len; i++) {
if (buf[i] != BFLB_EFLASH_LOADER_HAND_SHAKE_BYTE)
return -1;
}
return 0;
}
int32_t bflb_eflash_loader_usb_handshake_poll(uint32_t timeout)
{
uint64_t time_now;
uint32_t handshake_count = 0;
uint8_t *buf = g_eflash_loader_readbuf[g_rx_buf_index];
time_now = bflb_platform_get_time_ms();
LOG_D("usb iap handshake poll\r\n");
do {
if (g_rx_buf_len >= 16) {
for (int i = 0; i < 16; i++) {
if (buf[i] == BFLB_EFLASH_LOADER_HAND_SHAKE_BYTE) {
handshake_count++;
if (handshake_count > BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
break;
}
}
}
if (handshake_count > BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
break;
}
}
} while ((timeout == 0) ? 1 : (bflb_platform_get_time_ms() - time_now < timeout * 1000));
if (handshake_count >= BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
LOG_D("iap handshake %d 0x55 rcv\r\n", handshake_count);
} else {
LOG_D("iap handshake err\r\n");
return -1;
}
/*receive shake hanad signal*/
usb_send((uint8_t *)"OK", 2);
//arch_delay_ms(400);
bflb_mtimer_delay_ms(400);
/*init rx info */
g_rx_buf_index = 0;
g_rx_buf_len = 0;
time_now = bflb_platform_get_time_ms();
do {
if (g_rx_buf_len > 0) {
if (0 == bflb_eflash_loader_check_handshake_buf(buf, g_rx_buf_len)) {
g_rx_buf_len = 0;
time_now = bflb_platform_get_time_ms();
} else {
break;
}
}
} while (bflb_platform_get_time_ms() - time_now < 50);
return BFLB_EFLASH_LOADER_SUCCESS;
}
uint32_t *bflb_eflash_loader_usb_recv(uint32_t *recv_len, uint32_t maxlen, uint32_t timeout)
{
return NULL;
}
int32_t bflb_eflash_loader_usb_change_rate(uint32_t oldval, uint32_t newval)
{
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_eflash_loader_usb_deinit()
{
return BFLB_EFLASH_LOADER_SUCCESS;
}
#endif

View file

@ -0,0 +1,57 @@
/**
******************************************************************************
* @file blsp_eflash_loader_usb.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BFLB_EFLASH_LOADER_USB_H__
#define __BFLB_EFLASH_LOADER_USB_H__
#include "stdint.h"
int32_t bflb_eflash_loader_usb_init();
int32_t bflb_eflash_loader_usb_handshake_poll();
uint32_t *bflb_eflash_loader_usb_recv(uint32_t *recv_len, uint32_t maxlen, uint32_t timeout);
int32_t bflb_eflash_loader_usb_send(uint32_t *data, uint32_t len);
int32_t bflb_eflash_loader_usb_wait_tx_idle(uint32_t timeout);
int32_t bflb_eflash_loader_usb_change_rate(uint32_t oldval, uint32_t newval);
int32_t bflb_eflash_loader_usb_deinit(void);
#define BFLB_EFLASH_LOADER_IF_USB_RX_TIMEOUT 8000 /*ms*/
#endif

View file

@ -0,0 +1,277 @@
/**
******************************************************************************
* @file blsp_boot_decompress.c
* @version V1.2
* @date
* @brief This file is the peripheral case c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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 "xz.h"
#include "blsp_bootinfo.h"
#include "blsp_common.h"
#include "blsp_media_boot.h"
#include "softcrc.h"
#include "partition.h"
#include "bflb_flash.h"
#define BFLB_BOOT2_XZ_WRITE_BUF_SIZE 4 * 1024
#define BFLB_BOOT2_XZ_READ_BUF_SIZE 4 * 1024
/****************************************************************************/ /**
* @brief Decompress XZ Firmware
*
* @param srcAddress: Source address on flash
* @param destAddress: Destination address on flash
* @param destMaxSize: Destination flash region size for erase
* @param pDestSize: Pointer for output destination firmware size
*
* @return Decompress result status
*
*******************************************************************************/
static int32_t blsp_boot2_fw_decompress(uint32_t src_address, uint32_t dest_address, uint32_t dest_max_size, uint32_t *p_dest_size)
{
struct xz_buf b;
struct xz_dec *s;
enum xz_ret ret;
*p_dest_size = 0;
if (dest_max_size > 0) {
bflb_flash_erase(dest_address, dest_max_size);
}
xz_crc32_init();
simple_malloc_init(g_malloc_buf, sizeof(g_malloc_buf));
/*
* Support up to 32k dictionary. The actually needed memory
* is allocated once the headers have been parsed.
*/
s = xz_dec_init(XZ_PREALLOC, 1 << 15);
if (s == NULL) {
//LOG_E("Memory allocation failed\n");
return BFLB_BOOT2_MEM_ERROR;
}
b.in = vmalloc(BFLB_BOOT2_XZ_READ_BUF_SIZE);
b.in_pos = 0;
b.in_size = 0;
b.out = vmalloc(BFLB_BOOT2_XZ_WRITE_BUF_SIZE);
b.out_pos = 0;
b.out_size = BFLB_BOOT2_XZ_WRITE_BUF_SIZE;
while (1) {
if (b.in_pos == b.in_size) {
LOG_F("XZ Feeding\r\n");
if (BFLB_BOOT2_SUCCESS != blsp_mediaboot_read(src_address, (uint8_t *)b.in, BFLB_BOOT2_XZ_READ_BUF_SIZE)) {
//LOG_E("Read XZFW fail\r\n");
return BFLB_BOOT2_FLASH_READ_ERROR;
}
b.in_size = BFLB_BOOT2_XZ_READ_BUF_SIZE;
b.in_pos = 0;
src_address += BFLB_BOOT2_XZ_READ_BUF_SIZE;
}
ret = xz_dec_run(s, &b);
if (b.out_pos == BFLB_BOOT2_XZ_WRITE_BUF_SIZE) {
//if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
// msg = "Write error\n";
// goto error;
//}'
LOG_F("XZ outputing\r\n");
if (dest_max_size > 0) {
bflb_flash_write(dest_address, b.out, BFLB_BOOT2_XZ_WRITE_BUF_SIZE);
}
dest_address += BFLB_BOOT2_XZ_WRITE_BUF_SIZE;
*p_dest_size += BFLB_BOOT2_XZ_WRITE_BUF_SIZE;
b.out_pos = 0;
}
if (ret == XZ_OK) {
continue;
}
//if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos
// || fclose(stdout)) {
// msg = "Write error\n";
// goto error;
//}
if (b.out_pos > 0) {
if (dest_max_size > 0) {
bflb_flash_write(dest_address, b.out, b.out_pos);
}
dest_address += b.out_pos;
*p_dest_size += b.out_pos;
}
switch (ret) {
case XZ_STREAM_END:
xz_dec_end(s);
return 0;
case XZ_MEM_ERROR:
//LOG_E("Memory allocation failed\n");
goto error;
case XZ_MEMLIMIT_ERROR:
//LOG_E("Memory usage limit reached\n");
goto error;
case XZ_FORMAT_ERROR:
LOG_E("Not a .xz file\n");
goto error;
case XZ_OPTIONS_ERROR:
//LOG_E("Unsupported options in the .xz headers\n");
goto error;
case XZ_DATA_ERROR:
case XZ_BUF_ERROR:
LOG_E("File is corrupt\n");
goto error;
default:
LOG_E("XZ Bug!\n");
goto error;
}
}
error:
xz_dec_end(s);
return BFLB_BOOT2_FAIL;
}
/****************************************************************************/ /**
* @brief Update decompressed firmware to flash according to XZ firmware
*
* @param activeID: Active partition table ID
* @param ptStuff: Pointer of partition table stuff
* @param ptEntry: Pointer of active entry
*
* @return XZ firmware update result status
*
*******************************************************************************/
int32_t blsp_boot2_update_fw(pt_table_id_type active_id, pt_table_stuff_config *pt_stuff, pt_table_entry_config *pt_entry)
{
uint8_t active_index = pt_entry->active_index;
uint32_t new_fw_len;
int32_t ret;
LOG_F("try to decomp,xz s addr %08x,d addr %08x\r\n",
pt_entry->start_address[active_index],
pt_entry->start_address[!(active_index & 0x01)]);
/* Try to check Image integrity: try to decompress */
if (BFLB_BOOT2_SUCCESS != blsp_boot2_fw_decompress(pt_entry->start_address[active_index],
pt_entry->start_address[!(active_index & 0x01)],
0, &new_fw_len)) {
#ifdef BLSP_BOOT2_ROLLBACK
/* Decompress fail, try to rollback to old one */
pt_entry->active_index = !(active_index & 0x01);
pt_entry->age++;
ret = pt_table_update_entry((pt_table_id_type)(!active_id), pt_stuff, pt_entry);
if (ret != PT_ERROR_SUCCESS) {
//LOG_E("Rollback Update Partition table entry fail\r\n");
return BFLB_BOOT2_FAIL;
}
#endif
return BFLB_BOOT2_SUCCESS;
}
LOG_F("get new fw len %d\r\n", new_fw_len);
if (new_fw_len > pt_entry->max_len[!(active_index & 0x01)]) {
LOG_F("decomped img too large!\r\n");
#ifdef BLSP_BOOT2_ROLLBACK
/* Decompress fail, try to rollback to old one */
pt_entry->active_index = !(active_index & 0x01);
pt_entry->age++;
ret = pt_table_update_entry((pt_table_id_type)(!active_id), pt_stuff, pt_entry);
if (ret != PT_ERROR_SUCCESS) {
//LOG_E("Rollback Update Partition table entry fail\r\n");
return BFLB_BOOT2_FAIL;
}
#endif
return BFLB_BOOT2_SUCCESS;
}
/* Do decompress */
if (BFLB_BOOT2_SUCCESS == blsp_boot2_fw_decompress(pt_entry->start_address[active_index],
pt_entry->start_address[!(active_index & 0x01)],
pt_entry->max_len[!(active_index & 0x01)], &new_fw_len)) {
pt_entry->active_index = !(active_index & 0x01);
pt_entry->len = new_fw_len;
pt_entry->age++;
ret = pt_table_update_entry((pt_table_id_type)(!active_id), pt_stuff, pt_entry);
if (ret != PT_ERROR_SUCCESS) {
//LOG_E("Update Partition table entry fail\r\n");
return BFLB_BOOT2_FAIL;
}
} else {
LOG_E("XZ Decomp fail\r\n");
return BFLB_BOOT2_FAIL;
}
LOG_F("get new fw len %d\r\n", new_fw_len);
return BFLB_BOOT2_SUCCESS;
}
/****************************************************************************/ /**
* @brief Check if buffer is XZ header
*
* @param buffer: Buffer of firmware
*
* @return 1 for XZ firmware and 0 for not
*
*******************************************************************************/
int blsp_boot2_verify_xz_header(uint8_t *buffer)
{
const uint8_t xz_header[6] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
//const uint8_t xz_header[6] = { 0x42, 0x46, 0x4e, 0x50, 0x01, 0x00 };
if (buffer) {
if (!memcmp(buffer, xz_header, 6)) {
return 1;
}
}
return 0;
}

View file

@ -0,0 +1,45 @@
/**
******************************************************************************
* @file blsp_boot_decompress.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BLSP_BOOT_DECOMPRESS_H__
#define __BLSP_BOOT_DECOMPRESS_H__
#include "stdint.h"
#include "partition.h"
int32_t blsp_boot2_update_fw(pt_table_id_type activeID, pt_table_stuff_config *ptStuff, pt_table_entry_config *ptEntry);
int blsp_boot2_verify_xz_header(uint8_t *buffer);
#endif /* __BLSP_BOOT_DECOMPRESS_H__ */

View file

@ -0,0 +1,250 @@
/**
******************************************************************************
* @file blsp_boot_parser.c
* @version V1.2
* @date
* @brief This file is the peripheral case c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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 "blsp_common.h"
#include "blsp_bootinfo.h"
#include "blsp_boot_parser.h"
#include "softcrc.h"
#include "blsp_port.h"
#include "bflb_sec_sha.h"
#include "bflb_sec_ecdsa.h"
extern uint32_t g_user_hash_ignored;
/****************************************************************************/ /**
* @brief Check if the input public key is the same as burned in the efuse
*
* @param cpu_type: CPU Type
* @param pkhash: Public key hash pointer
*
* @return 1 for valid and 0 for invalid
*
*******************************************************************************/
static uint32_t blsp_boot_parse_is_pkhash_valid(uint8_t pk_src, uint8_t *pkhash)
{
if (pk_src == BFLB_BOOT2_CPU_0) {
if (0 == memcmp(g_efuse_cfg.pk_hash_cpu0, pkhash, BFLB_BOOT2_PK_HASH_SIZE)) {
return 1;
}
} else if (pk_src == BFLB_BOOT2_CPU_1) {
if (0 == memcmp(g_efuse_cfg.pk_hash_cpu1, pkhash, BFLB_BOOT2_PK_HASH_SIZE)) {
return 1;
}
}
return 0;
}
/****************************************************************************/ /**
* @brief Parse public key
*
* @param g_boot_img_cfg: Boot image config pointer
* @param data: Public key data pointer
* @param own: 1 for current CPU, 0 for other(s)
*
* @return boot_error_code type
*
*******************************************************************************/
int32_t blsp_boot_parse_pkey(boot2_image_config *g_boot_img_cfg, uint8_t *data, uint8_t own)
{
boot_pk_config *cfg = (boot_pk_config *)data;
uint32_t pk_hash[BFLB_BOOT2_PK_HASH_SIZE / 4];
if (cfg->crc32 == BFLB_Soft_CRC32((uint8_t *)cfg, sizeof(boot_pk_config) - 4)) {
/* Check public key with data info in OTP*/
bflb_sha256_update(sha, &ctx_sha256, data, HAL_BOOT2_ECC_KEYXSIZE + HAL_BOOT2_ECC_KEYYSIZE);
bflb_sha256_finish(sha, &ctx_sha256, (uint8_t *)pk_hash);
//bflb_sha_deinit(&hash_handle);//ToDo
bflb_sha_init(sha, SHA_MODE_SHA256);
bflb_sha256_start(sha, &ctx_sha256);
/* Check pk is valid */
if (own == 1) {
if (1 != blsp_boot_parse_is_pkhash_valid(g_boot_img_cfg->pk_src,
(uint8_t *)pk_hash)) {
LOG_E("PK sha error\r\n");
return BFLB_BOOT2_IMG_PK_HASH_ERROR;
}
}
if (own == 1) {
ARCH_MemCpy_Fast(g_boot_img_cfg->eckye_x, cfg->eckye_x, sizeof(cfg->eckye_x));
ARCH_MemCpy_Fast(g_boot_img_cfg->eckey_y, cfg->eckey_y, sizeof(cfg->eckey_y));
}
} else {
LOG_E("PK crc error\r\n");
return BFLB_BOOT2_IMG_PK_CRC_ERROR;
}
return BFLB_BOOT2_SUCCESS;
}
/****************************************************************************/ /**
* @brief Parse signature
*
* @param g_boot_img_cfg: Boot image config pointer
* @param data: Signature data pointer
* @param own: 1 for current CPU, 0 for other(s)
*
* @return boot_error_code type
*
*******************************************************************************/
int32_t blsp_boot_parse_signature(boot2_image_config *g_boot_img_cfg, uint8_t *data, uint8_t own)
{
boot_sign_config *cfg = (boot_sign_config *)data;
uint32_t crc;
if (cfg->sig_len > sizeof(g_boot_img_cfg->signature)) {
return BFLB_BOOT2_IMG_SIGNATURE_LEN_ERROR;
}
/* CRC include sig_len*/
crc = BFLB_Soft_CRC32((uint8_t *)&cfg->sig_len, cfg->sig_len + sizeof(cfg->sig_len));
if (memcmp(&crc, &cfg->signature[cfg->sig_len], 4) == 0) {
if (own == 1) {
ARCH_MemCpy_Fast(g_boot_img_cfg->signature, cfg->signature, cfg->sig_len);
//g_boot_img_cfg->sig_len = cfg->sig_len;
} else {
ARCH_MemCpy_Fast(g_boot_img_cfg->signature2, cfg->signature, cfg->sig_len);
//g_boot_img_cfg->sig_len2 = cfg->sig_len;
}
} else {
LOG_E("SIG crc error\r\n");
return BFLB_BOOT2_IMG_SIGNATURE_CRC_ERROR;
}
return BFLB_BOOT2_SUCCESS;
}
/****************************************************************************/ /**
* @brief Parse ASE IV
*
* @param g_boot_img_cfg: Boot image config pointer
* @param data: AES IV data pointer
*
* @return boot_error_code type
*
*******************************************************************************/
int32_t blsp_boot_parse_aesiv(boot2_image_config *g_boot_img_cfg, uint8_t *data)
{
boot_aes_config *cfg = (boot_aes_config *)data;
if (cfg->crc32 == BFLB_Soft_CRC32(cfg->aes_iv, sizeof(cfg->aes_iv))) {
memcpy(g_boot_img_cfg->aes_iv, cfg->aes_iv, sizeof(boot_aes_config));
/* Update image hash */
if (!g_boot_img_cfg->basic_cfg.hash_ignore) {
//Sec_Eng_SHA256_Update(&g_sha_ctx, SEC_ENG_SHA_ID0, data, sizeof(boot_aes_config));
#ifndef CHIP_WB03
bflb_sha256_update(sha, &ctx_sha256, data, sizeof(boot_aes_config));
#endif
}
} else {
LOG_E("AES IV crc error\r\n");
return BFLB_BOOT2_IMG_AES_IV_CRC_ERROR;
}
return BFLB_BOOT2_SUCCESS;
}
/****************************************************************************/ /**
* @brief Check signature is valid
*
* @param g_boot_img_cfg: Boot image config pointer
*
* @return boot_error_code type
*
*******************************************************************************/
int32_t blsp_boot_parser_check_signature(boot2_image_config *g_boot_img_cfg)
{
int32_t ret = 0;
uint64_t startTime = 0;
struct bflb_ecdsa_s ecdsa_handle;
LOG_F("ps_mode %d,efuse hbn_check_sign %d\r\n", g_ps_mode, g_efuse_cfg.hbn_check_sign);
if (g_ps_mode == BFLB_PSM_HBN && (!g_efuse_cfg.hbn_check_sign)) {
return BFLB_BOOT2_SUCCESS;
}
if (g_boot_img_cfg->basic_cfg.sign_type) {
LOG_F("Check sig1\r\n");
startTime = bflb_mtimer_get_time_ms();
bflb_sec_ecdsa_init(&ecdsa_handle, ECP_SECP256R1);
ecdsa_handle.publicKeyx = (uint32_t *)g_boot_img_cfg->eckye_x;
ecdsa_handle.publicKeyy = (uint32_t *)g_boot_img_cfg->eckey_y;
ret = bflb_sec_ecdsa_verify(&ecdsa_handle, (uint32_t *)g_boot_img_cfg->basic_cfg.hash, 8,
(uint32_t *)g_boot_img_cfg->signature, (uint32_t *)&g_boot_img_cfg->signature[32]);
if (ret != 0) {
LOG_E("verify failed\n");
return BFLB_BOOT2_IMG_SIGN_ERROR;
}
LOG_F("Sign suss,Time=%d ms\r\n", (unsigned int)(bflb_mtimer_get_time_ms() - startTime));
}
return BFLB_BOOT2_SUCCESS;
}
/****************************************************************************/ /**
* @brief Check hash is valid
*
* @param g_boot_img_cfg: Boot image config pointer
*
* @return boot_error_code type
*
*******************************************************************************/
int32_t blsp_boot_parser_check_hash(boot2_image_config *g_boot_img_cfg)
{
uint32_t img_hash_cal[HAL_BOOT2_IMG_HASH_SIZE / 4];
if (!g_boot_img_cfg->basic_cfg.hash_ignore) {
//Sec_Eng_SHA256_Finish(&g_sha_ctx, SEC_ENG_SHA_ID0, (uint8_t *)img_hash_cal);
bflb_sha256_finish(sha, &ctx_sha256, (uint8_t *)img_hash_cal);
//sec_hash_deinit(&hash_handle);//ToDo
if (memcmp(img_hash_cal, g_boot_img_cfg->basic_cfg.hash, 32) != 0) {
LOG_E("Hash error\r\n");
return BFLB_BOOT2_IMG_HASH_ERROR;
} else {
LOG_F("Hash Success\r\n");
}
}
return BFLB_BOOT2_SUCCESS;
}

View file

@ -0,0 +1,47 @@
/**
******************************************************************************
* @file blsp_boot_parser.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BLSP_BOOT_PARSER_H__
#define __BLSP_BOOT_PARSER_H__
#include "stdint.h"
int32_t blsp_boot_parse_pkey(boot2_image_config *g_boot_img_cfg, uint8_t *data, uint8_t own);
int32_t blsp_boot_parse_signature(boot2_image_config *g_boot_img_cfg, uint8_t *data, uint8_t own);
int32_t blsp_boot_parse_aesiv(boot2_image_config *g_boot_img_cfg, uint8_t *data);
int32_t blsp_boot_parser_check_signature(boot2_image_config *g_boot_img_cfg);
int32_t blsp_boot_parser_check_hash(boot2_image_config *g_boot_img_cfg);
#endif /* __BLSP_BOOT_PARSER_H__ */

View file

@ -0,0 +1,158 @@
/**
******************************************************************************
* @file blsp_bootinfo.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BLSP_BOOTINFO_H__
#define __BLSP_BOOTINFO_H__
#include "stdint.h"
#include "blsp_port.h"
#define BFLB_BOOT2_FLASH_CFG_MAGIC "FCFG"
#define BFLB_BOOT2_PLL_CFG_MAGICCODE "PCFG"
#define BFLB_BOOT2_FLASH_TZC_MAGIC "TCFG"
#define BFLB_BOOT2_READBUF_SIZE 5 * 1024
#define BFLB_FW_IMG_OFFSET_AFTER_HEADER HAL_BOOT2_FW_IMG_OFFSET_AFTER_HEADER
/* Image owner type */
#define BFLB_BOOT2_CPU_0 0
#define BFLB_BOOT2_CPU_1 1
/* Public key hash size */
#define BFLB_BOOT2_PK_HASH_SIZE HAL_BOOT2_PK_HASH_SIZE
/* Power save define */
#define BFLB_PSM_ACTIVE 0
#define BFLB_PSM_HBN 1
typedef enum {
BFLB_BOOT2_SUCCESS = 0x00,
/* Flash*/
BFLB_BOOT2_FLASH_INIT_ERROR = 0x0001,
BFLB_BOOT2_FLASH_ERASE_PARA_ERROR = 0x0002,
BFLB_BOOT2_FLASH_ERASE_ERROR = 0x0003,
BFLB_BOOT2_FLASH_WRITE_PARA_ERROR = 0x0004,
BFLB_BOOT2_FLASH_WRITE_ADDR_ERROR = 0x0005,
BFLB_BOOT2_FLASH_WRITE_ERROR = 0x0006,
BFLB_BOOT2_FLASH_BOOT_PARA = 0x0007,
BFLB_BOOT2_FLASH_READ_ERROR = 0x0008,
/* Image*/
BFLB_BOOT2_IMG_BOOTHEADER_LEN_ERROR = 0x0201,
BFLB_BOOT2_IMG_BOOTHEADER_NOT_LOAD_ERROR = 0x0202,
BFLB_BOOT2_IMG_BOOTHEADER_MAGIC_ERROR = 0x0203,
BFLB_BOOT2_IMG_BOOTHEADER_CRC_ERROR = 0x0204,
BFLB_BOOT2_IMG_BOOTHEADER_ENCRYPT_NOTFIT = 0x0205,
BFLB_BOOT2_IMG_BOOTHEADER_SIGN_NOTFIT = 0x0206,
BFLB_BOOT2_IMG_SEGMENT_CNT_ERROR = 0x0207,
BFLB_BOOT2_IMG_AES_IV_LEN_ERROR = 0x0208,
BFLB_BOOT2_IMG_AES_IV_CRC_ERROR = 0x0209,
BFLB_BOOT2_IMG_PK_LEN_ERROR = 0x020a,
BFLB_BOOT2_IMG_PK_CRC_ERROR = 0x020b,
BFLB_BOOT2_IMG_PK_HASH_ERROR = 0x020c,
BFLB_BOOT2_IMG_SIGNATURE_LEN_ERROR = 0x020d,
BFLB_BOOT2_IMG_SIGNATURE_CRC_ERROR = 0x020e,
BFLB_BOOT2_IMG_SECTIONHEADER_LEN_ERROR = 0x020f,
BFLB_BOOT2_IMG_SECTIONHEADER_CRC_ERROR = 0x0210,
BFLB_BOOT2_IMG_SECTIONHEADER_DST_ERROR = 0x0211,
BFLB_BOOT2_IMG_SECTIONDATA_LEN_ERROR = 0x0212,
BFLB_BOOT2_IMG_SECTIONDATA_DEC_ERROR = 0x0213,
BFLB_BOOT2_IMG_SECTIONDATA_TLEN_ERROR = 0x0214,
BFLB_BOOT2_IMG_SECTIONDATA_CRC_ERROR = 0x0215,
BFLB_BOOT2_IMG_HALFBAKED_ERROR = 0x0216,
BFLB_BOOT2_IMG_HASH_ERROR = 0x0217,
BFLB_BOOT2_IMG_SIGN_PARSE_ERROR = 0x0218,
BFLB_BOOT2_IMG_SIGN_ERROR = 0x0219,
BFLB_BOOT2_IMG_DEC_ERROR = 0x021a,
BFLB_BOOT2_IMG_ALL_INVALID_ERROR = 0x021b,
BFLB_BOOT2_IMG_Roll_Back = 0x021c,
/* MISC*/
BFLB_BOOT2_MEM_ERROR = 0xfffb,
BFLB_BOOT2_PLL_ERROR = 0xfffc,
BFLB_BOOT2_INVASION_ERROR = 0xfffd,
BFLB_BOOT2_POLLING = 0xfffe,
BFLB_BOOT2_FAIL = 0xffff,
} boot_error_code;
typedef struct
{
uint8_t aes_iv[16];
uint32_t crc32;
} boot_aes_config;
typedef struct
{
uint8_t eckye_x[HAL_BOOT2_ECC_KEYXSIZE]; //ec key in boot header
uint8_t eckey_y[HAL_BOOT2_ECC_KEYYSIZE]; //ec key in boot header
uint32_t crc32;
} boot_pk_config;
typedef struct
{
uint32_t sig_len;
uint8_t signature[HAL_BOOT2_SIGN_MAXSIZE];
uint32_t crc32;
} boot_sign_config;
typedef struct
{
uint32_t msp_store_addr;
uint32_t pc_store_addr;
uint32_t default_xip_addr;
} boot_cpu_config;
/**
* @brief ram image config type
*/
typedef struct
{
uint8_t valid; /*!< valid or not */
uint8_t core; /*!< which core to run */
uint32_t boot_addr; /*!< boot addr */
} ram_img_config_t;
typedef void (*pentry_t)(void);
extern ram_img_config_t ram_img_config[BLSP_BOOT2_RAM_IMG_COUNT_MAX];
extern boot2_image_config g_boot_img_cfg[BLSP_BOOT2_CPU_GROUP_MAX];
extern boot2_efuse_hw_config g_efuse_cfg;
extern uint8_t g_ps_mode;
//extern uint8_t g_cpu_count;
extern uint8_t *g_boot2_read_buf;
#endif /* __BLSP_BOOTINFO_H__ */

View file

@ -0,0 +1,197 @@
/**
******************************************************************************
* @file blsp_common.c
* @version V1.2
* @date
* @brief This file is the peripheral case c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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 "stdio.h"
#include "stdint.h"
#include "string.h"
#include "blsp_port.h"
#include "blsp_bootinfo.h"
#include "blsp_common.h"
#include "blsp_media_boot.h"
#include "bflb_flash.h"
#include "bflb_eflash_loader.h"
ATTR_NOCACHE_NOINIT_RAM_SECTION uint8_t g_malloc_buf[BFLB_BOOT2_XZ_MALLOC_BUF_SIZE];
int32_t blsp_boot2_set_encrypt(uint8_t index, boot2_image_config *g_boot_img_cfg);
/****************************************************************************/ /**
* @brief Dump data
*
* @param datain: Data pointer to dump
* @param len: Data length to dump
*
* @return None
*
*******************************************************************************/
void blsp_dump_data(void *datain, int len)
{
int i = 0;
uint8_t *data = (uint8_t *)datain;
data = data;
for (i = 0; i < len; i++) {
if (i % 16 == 0 && i != 0) {
LOG_F("\r\n");
}
LOG_F("%02x ", data[i]);
}
LOG_F("\r\n");
}
/****************************************************************************/ /**
* @brief Media boot pre-jump
*
* @param None
*
* @return BL_Err_Type
*
*******************************************************************************/
int32_t blsp_mediaboot_pre_jump(void)
{
extern void system_mtimer_clock_reinit(void);
/* reinit mtimer clock */
//system_mtimer_clock_reinit();
/* deinit uart */
hal_boot2_debug_uart_gpio_deinit();
/* Sec eng deinit*/
hal_boot2_reset_sec_eng();
/* Platform deinit */
//bflb_platform_deinit();
/* Jump to entry */
__disable_irq();
blsp_boot2_jump_entry();
return BFLB_BOOT2_SUCCESS;
}
/****************************************************************************/ /**
* @brief Boot2 exit with error and will stay forever
*
* @param None
*
* @return None
*
*******************************************************************************/
void blsp_boot2_exit(void)
{
hal_boot2_sboot_finish();
/* Release other CPUs*/
blsp_boot2_releae_other_cpu();
/* Stay here */
while (1) {
/* Use soft delay only */
arch_delay_ms(100);
}
}
/****************************************************************************/ /**
* @brief Boot2 jump to entry_point
*
* @param None
*
* @return None
*
*******************************************************************************/
void ATTR_TCM_SECTION blsp_boot2_jump_entry(void)
{
pentry_t pentry;
int32_t ret;
hal_boot2_clean_cache();
hal_boot2_sboot_finish();
/*Note:enable cache with flash offset, after this, should be no flash directl read,
If need read, should take flash offset into consideration */
if (0 != g_efuse_cfg.encrypted[0]) {
/*for encrypted img, use none-continuos read*/
ret = hal_boot2_set_cache(0, &g_boot_img_cfg[0]);
} else {
/*for unencrypted img, use continuos read*/
ret = hal_boot2_set_cache(1, &g_boot_img_cfg[0]);
}
if (ret != BFLB_BOOT2_SUCCESS) {
return;
}
#if BLSP_BOOT2_SUPPORT_SIGN_ENCRYPT
/* Set decryption before read MSP and PC*/
if (0 != g_efuse_cfg.encrypted[0]) {
blsp_boot2_set_encrypt(0, &g_boot_img_cfg[0]);
blsp_boot2_set_encrypt(1, &g_boot_img_cfg[1]);
#if BLSP_BOOT2_CPU_MAX > 1
if (hal_boot2_get_feature_flag() == HAL_BOOT2_CP_FLAG) {
/*co-processor*/
g_boot_img_cfg[0].cpu_cfg[1].msp_val = g_boot_img_cfg[0].cpu_cfg[0].msp_val;
g_boot_img_cfg[0].cpu_cfg[1].boot_entry = g_boot_img_cfg[0].cpu_cfg[0].boot_entry;
g_boot_img_cfg[0].cpu_cfg[1].cache_enable = g_boot_img_cfg[0].cpu_cfg[0].cache_enable;
g_boot_img_cfg[0].img_valid = 1;
g_boot_img_cfg[0].cpu_cfg[1].cache_way_dis = 0xf;
}
#endif
}
#endif
blsp_boot2_releae_other_cpu();
/* Deal CPU0's entry point */
for (uint32_t group = 0; group < BLSP_BOOT2_CPU_GROUP_MAX; group++) {
if (g_boot_img_cfg[group].img_valid && g_boot_img_cfg[group].cpu_cfg[0].config_enable) {
if (g_boot_img_cfg[group].cpu_cfg[0].halt_cpu == 0) {
pentry = (pentry_t)g_boot_img_cfg[group].cpu_cfg[0].boot_entry;
if (pentry) {
pentry();
}
}
}
}
/* If cann't jump stay here */
while (1) {
/*use soft delay only */
arch_delay_ms(100);
}
}

View file

@ -0,0 +1,50 @@
/**
******************************************************************************
* @file blsp_common.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BLSP_COMMON_H__
#define __BLSP_COMMON_H__
#include "stdint.h"
#define BFLB_BOOT2_XZ_MALLOC_BUF_SIZE 80 * 1024
void blsp_dump_data(void *datain, int len);
void blsp_boot2_jump_entry(void);
int32_t blsp_mediaboot_pre_jump(void);
uint8_t blsp_boot2_get_feature_flag(void);
extern uint8_t g_malloc_buf[BFLB_BOOT2_XZ_MALLOC_BUF_SIZE];
#endif /* __BLSP_COMMON_H__ */

View file

@ -0,0 +1,404 @@
/**
******************************************************************************
* @file blsp_media_boot.c
* @version V1.2
* @date
* @brief This file is the peripheral case c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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 "stdint.h"
#include "string.h"
#include "blsp_port.h"
#include "blsp_bootinfo.h"
#include "blsp_common.h"
#include "blsp_boot_parser.h"
#include "blsp_media_boot.h"
#include "softcrc.h"
#include "bflb_eflash_loader_interface.h"
extern int main(void);
/****************************************************************************/ /**
* @brief Media boot calculate hash
*
* @param startAddr: Start address to calculate
* @param totalLen: Data length to calculate
*
* @return BL_Err_Type
*
*******************************************************************************/
static int32_t blsp_mediaboot_cal_hash(uint32_t start_addr, uint32_t total_len)
{
int32_t deal_len = 0;
int32_t read_len = 0;
uint32_t addr = start_addr;
int32_t ret;
while (deal_len < total_len) {
read_len = total_len - deal_len;
if (read_len > BFLB_BOOT2_READBUF_SIZE) {
read_len = BFLB_BOOT2_READBUF_SIZE;
}
ret = blsp_mediaboot_read(addr, g_boot2_read_buf, read_len);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
/* Update hash*/
bflb_sha256_update(sha, &ctx_sha256, g_boot2_read_buf, read_len);
addr += read_len;
deal_len += read_len;
}
return BFLB_BOOT2_SUCCESS;
}
#if BLSP_BOOT2_SUPPORT_SIGN_ENCRYPT
/****************************************************************************/ /**
* @brief Media boot read signature
*
* @param addr: Start address to read signature
* @param len: Signature length pointer
*
* @return BL_Err_Type
*
*******************************************************************************/
static int32_t blsp_mediaboot_read_signaure(uint32_t addr, uint32_t *len)
{
int32_t ret = BFLB_BOOT2_SUCCESS;
uint32_t sig_len = 0;
uint8_t *ptmp;
/* Read signature*/
ret = blsp_mediaboot_read(addr, (uint8_t *)&sig_len, sizeof(sig_len));
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
addr += sizeof(sig_len);
if (sig_len > HAL_BOOT2_SIGN_MAXSIZE) {
return BFLB_BOOT2_IMG_SIGNATURE_LEN_ERROR;
}
/* Tail 4 bytes for crc */
ptmp = ((uint8_t *)g_boot2_read_buf);
ret = blsp_mediaboot_read(addr, (uint8_t *)(ptmp + sizeof(sig_len)), sig_len + 4);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
ARCH_MemCpy_Fast(g_boot2_read_buf, &sig_len, sizeof(sig_len));
addr += (sig_len + 4);
*len = sig_len;
return ret;
}
#endif
/****************************************************************************/ /**
* @brief Media boot parse one firmware
*
* @param g_boot_img_cfg: Boot image config pointer to hold parsed information
* @param bootheaderAddr: Bootheader start address
* @param imgAddr: Image start address
*
* @return BL_Err_Type
*
*******************************************************************************/
static int32_t blsp_mediaboot_parse_one_group(boot2_image_config *boot_img_cfg, uint32_t boot_header_addr, uint32_t img_addr)
{
uint32_t addr;
int32_t ret;
addr = boot_header_addr + hal_boot2_get_bootheader_offset();
/* Read boot header*/
LOG_F("R header from %08x\r\n", addr);
ret = blsp_mediaboot_read(addr, g_boot2_read_buf, sizeof(struct hal_bootheader_t));
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
addr += sizeof(struct hal_bootheader_t);
ret = hal_boot_parse_bootheader(boot_img_cfg, (uint8_t *)g_boot2_read_buf);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
/* we init hash here since aes iv need to be caled as image hash */
bflb_sha_init(sha, SHA_MODE_SHA256);
bflb_sha256_start(sha, &ctx_sha256);
/* Due to OTA, the flash_offset is changed, so copy from partition info */
boot_img_cfg->basic_cfg.group_image_offset = img_addr;
#if BLSP_BOOT2_SUPPORT_SIGN_ENCRYPT
uint32_t sig_len = 0;
/* If sign enable,get pk key and signature*/
if (boot_img_cfg->basic_cfg.sign_type) {
/* Read public key */
LOG_F("R PK\r\n");
ret = blsp_mediaboot_read(addr, g_boot2_read_buf, sizeof(boot_pk_config));
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
ret = blsp_boot_parse_pkey(boot_img_cfg, (uint8_t *)g_boot2_read_buf, 1);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
#if defined(CHIP_BL606P) || defined(CHIP_BL808)
addr += sizeof(boot_pk_config);
if (hal_boot2_get_grp_count() > 1) {
/* Read public key 2*/
LOG_F("R PK2\r\n");
ret = blsp_mediaboot_read(addr, g_boot2_read_buf, sizeof(boot_pk_config));
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
ret = blsp_boot_parse_pkey(boot_img_cfg, (uint8_t *)g_boot2_read_buf, 0);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
}
#endif
addr += sizeof(boot_pk_config);
/* Read signature*/
LOG_F("R SIG1\r\n");
blsp_mediaboot_read_signaure(addr, &sig_len);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
ret = blsp_boot_parse_signature(boot_img_cfg, (uint8_t *)g_boot2_read_buf, 1);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
#if defined(CHIP_BL606P) || defined(CHIP_BL808)
/*len+data+crc*/
addr += sizeof(sig_len);
addr += (sig_len + 4);
if (hal_boot2_get_grp_count() > 1) {
/* Read signature2*/
LOG_F("R SIG2\r\n");
blsp_mediaboot_read_signaure(addr, &sig_len);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
ret = blsp_boot_parse_signature(boot_img_cfg, (uint8_t *)g_boot2_read_buf, 0);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
}
#endif
/*len+data+crc*/
addr += sizeof(sig_len);
addr += (sig_len + 4);
}
/* If encrypt enable,get AES key*/
if (boot_img_cfg->basic_cfg.encrypt_type) {
/* Read aes iv*/
LOG_F("R IV\r\n");
ret = blsp_mediaboot_read(addr, g_boot2_read_buf, sizeof(boot_aes_config));
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
addr += sizeof(boot_aes_config);
ret = blsp_boot_parse_aesiv(boot_img_cfg, (uint8_t *)g_boot2_read_buf);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
}
#endif
if (boot_img_cfg->basic_cfg.no_segment) {
/* Flash image */
if (!boot_img_cfg->basic_cfg.hash_ignore) {
LOG_F("Cal hash addr 0x%08x,len %d\r\n", img_addr, boot_img_cfg->basic_cfg.img_len_cnt);
ret = blsp_mediaboot_cal_hash(img_addr,
boot_img_cfg->basic_cfg.img_len_cnt);
if (ret != BFLB_BOOT2_SUCCESS) {
LOG_E("Cal hash err\r\n");
return ret;
}
ret = blsp_boot_parser_check_hash(boot_img_cfg);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
}
#if BLSP_BOOT2_SUPPORT_SIGN_ENCRYPT
ret = blsp_boot_parser_check_signature(boot_img_cfg);
if (ret != BFLB_BOOT2_SUCCESS) {
return ret;
}
#endif
boot_img_cfg->img_valid = 1;
} else {
boot_img_cfg->img_valid = 0;
}
return ret;
}
/****************************************************************************/ /**
* @brief Media boot read data
*
* @param addr: Start address to read
* @param data: Data buffer to hold read data
* @param len: Data length to read
*
* @return BL_Err_Type
*
*******************************************************************************/
int32_t ATTR_TCM_SECTION blsp_mediaboot_read(uint32_t addr, uint8_t *data, uint32_t len)
{
bflb_flash_read(addr, data, len);
return BFLB_BOOT2_SUCCESS;
}
/****************************************************************************/ /**
* @brief Media boot main process
*
* @param cpuBootheaderAddr[BLSP_BOOT2_CPU_GROUP_MAX]: CPU bootheader address list
* @param cpuRollBack[BLSP_BOOT2_CPU_GROUP_MAX]: CPU need roll back flag hold list
* @param rollBack: 1 for rollback when imge error occurs, 0 for not rollback when imge error occurs
*
* @return int32_t
*
*******************************************************************************/
int32_t blsp_mediaboot_main(uint32_t group_boot_header_addr[BLSP_BOOT2_CPU_GROUP_MAX], uint8_t group_roll_back[BLSP_BOOT2_CPU_GROUP_MAX], uint8_t roll_back)
{
int32_t ret;
uint32_t i = 0, core;
uint32_t valid_group_found = 0;
uint32_t boot_header_addr[BLSP_BOOT2_CPU_GROUP_MAX];
LOG_F("Media boot main\r\n");
/* Reset some parameters*/
for (i = 0; i < BLSP_BOOT2_CPU_GROUP_MAX; i++) {
memset(&g_boot_img_cfg[i], 0, sizeof(g_boot_img_cfg[i]));
boot_header_addr[i] = group_boot_header_addr[i];
group_roll_back[i] = 0;
}
/* Try to boot from flash */
for (i = 0; i < BLSP_BOOT2_CPU_GROUP_MAX; i++) {
if (boot_header_addr[i] == 0) {
LOG_E("Group %d not boot\r\n", i);
continue;
}
ret = blsp_mediaboot_parse_one_group(&g_boot_img_cfg[i], boot_header_addr[i],
boot_header_addr[i] + BFLB_FW_IMG_OFFSET_AFTER_HEADER);
if (ret != BFLB_BOOT2_SUCCESS) {
LOG_E("Group %d parse fail\r\n", i);
group_roll_back[i] = 1;
} else {
valid_group_found++;
}
}
/* roll_back == 1 means need to check rock back, and can not jump away */
if ((valid_group_found != hal_boot2_get_grp_count()) && (1 == roll_back)) {
#if BLSP_BOOT2_CPU_GROUP_MAX > 1
if (boot_header_addr[1] == 0 && (valid_group_found == 1)) {
LOG_F("One group Only\r\n");
} else
#endif
{
LOG_E("Group roll back\r\n");
return BFLB_BOOT2_IMG_Roll_Back;
}
}
if (valid_group_found == 0) {
LOG_E("no valid group found\r\n");
return BFLB_BOOT2_IMG_ALL_INVALID_ERROR;
}
/* Get msp and pc value */
for (i = 0; i < BLSP_BOOT2_CPU_GROUP_MAX; i++) {
if (!g_boot_img_cfg[i].img_valid) {
continue;
}
for (core = 0; core < BLSP_BOOT2_CPU_MAX; core++) {
if (g_boot_img_cfg[i].cpu_cfg[core].boot_entry == 0) {
#ifdef ARCH_RISCV
g_boot_img_cfg[i].cpu_cfg[core].boot_entry = ((uint32_t)main) & 0xff000000;
#endif
}
}
}
for (i = 0; i < BLSP_BOOT2_CPU_GROUP_MAX; i++) {
if (!g_boot_img_cfg[i].img_valid) {
continue;
}
for (core = 0; core < BLSP_BOOT2_CPU_MAX; core++) {
if (g_boot_img_cfg[i].cpu_cfg[core].config_enable) {
if (g_boot_img_cfg[i].cpu_cfg[core].halt_cpu == 0) {
LOG_F("group[%d] offset %08x ,core[%d] offset %08x ", i,
g_boot_img_cfg[i].basic_cfg.group_image_offset,
core,
g_boot_img_cfg[i].cpu_cfg[core].image_address_offset);
LOG_F("bootentry %08x\r\n", g_boot_img_cfg[i].cpu_cfg[core].boot_entry);
}
}
}
}
#if BLSP_BOOT2_CPU_MAX > 1
LOG_F("group[%d],core[%d] halt cpu %d\r\n", 0, 1, g_boot_img_cfg[0].cpu_cfg[1].halt_cpu);
#endif
blsp_boot2_show_timer();
bflb_eflash_loader_if_set(BFLB_EFLASH_LOADER_IF_UART);
if (0 == bflb_eflash_loader_if_handshake_poll(0)) {
bflb_eflash_loader_main();
}
/* Prepare jump to entry*/
blsp_mediaboot_pre_jump();
/* We should never get here unless something is wrong */
return BFLB_BOOT2_FAIL;
}

View file

@ -0,0 +1,50 @@
/**
******************************************************************************
* @file blsp_media_boot.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BLSP_MEDIA_BOOT_H__
#define __BLSP_MEDIA_BOOT_H__
#include "stdint.h"
#include "stdio.h"
#include "string.h"
#include "blsp_bootinfo.h"
int32_t blsp_mediaboot_read(uint32_t addr, uint8_t *data, uint32_t len);
int32_t blsp_mediaboot_main(uint32_t cpu_boot_header_addr[BLSP_BOOT2_CPU_GROUP_MAX], uint8_t cpu_roll_back[BLSP_BOOT2_CPU_GROUP_MAX], uint8_t roll_back);
void blsp_boot2_show_timer(void);
#define BLSP_BOOT2_PSRAM_BASE 0x50000000
#endif /* __BLSP_MEDIA_BOOT_H__ */

View file

@ -0,0 +1,190 @@
/**
******************************************************************************
* @file blsp_port.c
* @version V1.2
* @date
* @brief This file is the peripheral case c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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 "stdio.h"
#include "stdint.h"
#include "string.h"
#include "blsp_port.h"
#include "blsp_bootinfo.h"
#include "blsp_common.h"
#include "blsp_media_boot.h"
#include "tzc_sec_reg.h"
extern uint32_t __boot2_pass_param_addr;
static uint32_t start_time = 0;
/****************************************************************************/ /**
* @brief Boot2 show timer for cal boot time
*
* @param None
*
* @return None
*
*******************************************************************************/
void blsp_boot2_start_timer(void)
{
start_time = (uint32_t)bflb_mtimer_get_time_ms();
}
/****************************************************************************/ /**
* @brief Boot2 show timer for cal boot time
*
* @param None
*
* @return None
*
*******************************************************************************/
void blsp_boot2_show_timer(void)
{
LOG_F("Counter value=%d\n", (unsigned int)bflb_mtimer_get_time_ms() - start_time);
}
/****************************************************************************/ /**
* @brief Read power save mode
*
* @param None
*
* @return BFLB_PSM_ACTIVE or BFLB_PSM_HBN
*
*******************************************************************************/
uint8_t blsp_read_power_save_mode(void)
{
if (hal_boot2_get_psmode_status() == HBN_STATUS_WAKEUP_FLAG) {
return BFLB_PSM_HBN;
} else {
return BFLB_PSM_ACTIVE;
}
}
/****************************************************************************/ /**
* @brief Boot2 Pass parameter to FW
*
* @param data: Data pointer to pass
* @param len: Data length
*
* @return None
*
*******************************************************************************/
void blsp_boot2_pass_parameter(void *data, uint32_t len)
{
}
/****************************************************************************/ /**
* @brief Release other CPU
*
* @param None
*
* @return None
*
*******************************************************************************/
void ATTR_TCM_SECTION blsp_boot2_releae_other_cpu(void)
{
#if BLSP_BOOT2_RAM_IMG_COUNT_MAX > 0
uint32_t i = 0;
pentry_t pentry;
#endif
#if BLSP_BOOT2_CPU_MAX > 1
uint32_t group, core;
/* deal Other CPUs' entry point and release*/
for (group = 0; group < BLSP_BOOT2_CPU_GROUP_MAX; group++) {
for (core = 1; core < BLSP_BOOT2_CPU_MAX; core++) {
if (g_boot_img_cfg[group].cpu_cfg[core].config_enable) {
if (g_boot_img_cfg[group].cpu_cfg[core].halt_cpu == 0) {
hal_boot2_release_cpu(core, g_boot_img_cfg[group].cpu_cfg[core].boot_entry);
}
}
}
}
#endif
#if BLSP_BOOT2_RAM_IMG_COUNT_MAX > 0
/* deal with ram image */
for (i = 0; i < BLSP_BOOT2_RAM_IMG_COUNT_MAX; i++) {
if (ram_img_config[i].valid && ram_img_config[i].core != 0 &&
ram_img_config[i].core != 0xf) {
hal_boot2_release_cpu(ram_img_config[i].core, ram_img_config[i].boot_addr);
}
}
for (i = 0; i < BLSP_BOOT2_RAM_IMG_COUNT_MAX; i++) {
if (ram_img_config[i].valid && ram_img_config[i].core == 0) {
pentry = (pentry_t)ram_img_config[i].boot_addr;
//cpu_global_irq_disable();
__disable_irq();
hal_boot2_clean_cache();
pentry();
}
}
#endif
}
/****************************************************************************/ /**
* @brief Set encryption config
*
* @param index: Region index
* @param g_boot_img_cfg: Boot image config pointer to hold parsed information
*
* @return BL_Err_Type
*
*******************************************************************************/
int32_t ATTR_TCM_SECTION blsp_boot2_set_encrypt(uint8_t index, boot2_image_config *g_boot_img_cfg)
{
uint32_t aes_enabled = 0;
uint32_t len = 0;
if (g_boot_img_cfg->img_valid == 0) {
return BFLB_BOOT2_SUCCESS;
}
/* FIXME:,1:lock, should be 1??*/
if (g_boot_img_cfg->basic_cfg.encrypt_type != 0) {
len = g_boot_img_cfg->basic_cfg.img_len_cnt;
if (len != 0) {
SF_Ctrl_AES_Set_Key_BE(index, NULL, (SF_Ctrl_AES_Key_Type)(g_boot_img_cfg->basic_cfg.encrypt_type - 1));
SF_Ctrl_AES_Set_IV_BE(index, g_boot_img_cfg->aes_iv, g_boot_img_cfg->basic_cfg.group_image_offset);
SF_Ctrl_AES_Set_Region(index, 1 /*enable this region*/, 1 /*hardware key*/,
g_boot_img_cfg->basic_cfg.group_image_offset,
g_boot_img_cfg->basic_cfg.group_image_offset + len - 1,
g_boot_img_cfg->basic_cfg.aes_region_lock /*lock*/);
aes_enabled = 1;
}
}
if (aes_enabled) {
SF_Ctrl_AES_Enable_BE();
SF_Ctrl_AES_Enable();
}
return BFLB_BOOT2_SUCCESS;
}

View file

@ -0,0 +1,80 @@
/**
******************************************************************************
* @file blsp_port.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __BLSP_PORT_H__
#define __BLSP_PORT_H__
#include "stdint.h"
#include "bflb_flash.h"
#include "xz_config.h"
#include "bflb_sec_sha.h"
#include "bflb_port_boot2.h"
#include "log.h"
#define MFG_START_REQUEST_OFFSET HAL_BOOT2_MFG_START_REQUEST_OFFSET
#define BLSP_BOOT2_XIP_BASE BL_FLASH_XIP_BASE
#define BLSP_BOOT2_ROLLBACK
#define BLSP_BOOT2_SUPPORT_DECOMPRESS HAL_BOOT2_SUPPORT_DECOMPRESS
#define BLSP_BOOT2_SUPPORT_USB_IAP HAL_BOOT2_SUPPORT_USB_IAP
#define BLSP_BOOT2_SUPPORT_EFLASH_LOADER_RAM HAL_BOOT2_SUPPORT_EFLASH_LOADER_RAM
#define BLSP_BOOT2_SUPPORT_EFLASH_LOADER_FLASH HAL_BOOT2_SUPPORT_EFLASH_LOADER_FLASH
#define BLSP_BOOT2_SUPPORT_SIGN_ENCRYPT HAL_BOOT2_SUPPORT_SIGN_ENCRYPT
#define BLSP_BOOT2_TCM_BASE 0
#define BOOT2_MODE_RELEASE 0x01
#define BOOT2_MODE_DEBUG 0x02
#ifdef CONFIG_DEBUG
#define BLSP_BOOT2_MODE BOOT2_MODE_DEBUG
#else
#define BLSP_BOOT2_MODE BOOT2_MODE_RELEASE
#endif
#define BLSP_BOOT2_CPU_GROUP_MAX HAL_BOOT2_CPU_GROUP_MAX
#define BLSP_BOOT2_CPU_MAX HAL_BOOT2_CPU_MAX
#define BLSP_BOOT2_RAM_IMG_COUNT_MAX HAL_BOOT2_RAM_IMG_COUNT_MAX
uint32_t blsp_boot2_get_cpu_count(void);
uint8_t blsp_read_power_save_mode(void);
void blsp_boot2_pass_parameter(void *data, uint32_t len);
void blsp_boot2_releae_other_cpu(void);
void blsp_boot2_start_timer(void);
void blsp_boot2_show_timer(void);
void blsp_boot2_init_sec_eng_pka(void);
extern struct bflb_device_s *sha;
extern struct bflb_device_s *uartx;
extern struct bflb_sha256_ctx_s ctx_sha256;
extern void bflb_uart_set_console(struct bflb_device_s *dev);
#endif /* __BLSP_PORT_H__ */

View file

@ -0,0 +1,231 @@
/**
******************************************************************************
* @file blsp_ram_image_boot.c
* @version V1.2
* @date
* @brief This file is the peripheral case c file
******************************************************************************
* @attention
*
* <h2><center>&copy; 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 "blsp_version.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);
//sec_hash_deinit(&hash_handle); //ToDo
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

View file

@ -0,0 +1,41 @@
/**
******************************************************************************
* @file blsp_version.h
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 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.
*
******************************************************************************
*/
#ifndef __MCU_SDK_VERSION_H__
#define __MCU_SDK_VERSION_H__
#define BL_SDK_VER "1.0.0"
#endif

583
examples/boot2_isp/main.c Normal file
View file

@ -0,0 +1,583 @@
/**
******************************************************************************
* @file main.c
* @version V1.2
* @date
* @brief This file is the peripheral case c file
******************************************************************************
* @attention
*
* <h2><center>&copy; 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 "blsp_version.h"
#include "partition.h"
#include "softcrc.h"
#include "bflb_flash.h"
#include "log.h"
#include "bflb_sec_sha.h"
enum blsp_boot2_pre_deal_ret_t {
BFLB_BOOT2_PRE_DEAL_SUSS = 0x0,
BFLB_BOOT2_PRE_DEAL_NEED_RETRY,
BFLB_BOOT2_PRE_DEAL_ENTRY_NOT_FOUND,
};
uint8_t *g_boot2_read_buf;
boot2_image_config g_boot_img_cfg[BLSP_BOOT2_CPU_GROUP_MAX];
boot2_efuse_hw_config g_efuse_cfg;
uint8_t g_ps_mode = BFLB_PSM_ACTIVE;
uint32_t g_user_hash_ignored = 0;
uint8_t g_usb_init_flag = 0;
struct bflb_device_s *sha;
ATTR_NOCACHE_NOINIT_RAM_SECTION struct bflb_sha256_ctx_s ctx_sha256;
int blsp_do_ram_image_boot(pt_table_id_type active_id, pt_table_stuff_config *pt_stuff,
pt_table_entry_config *pt_entry);
/****************************************************************************/ /**
* @brief Boot2 runs error call back function
*
* @param log: Log to print
*
* @return None
*
*******************************************************************************/
static void blsp_boot2_on_error(void *log)
{
while (1) {
#if BLSP_BOOT2_SUPPORT_USB_IAP
bflb_eflash_loader_if_set(BFLB_EFLASH_LOADER_IF_USB);
if (0 == g_usb_init_flag) {
bflb_eflash_loader_if_init();
g_usb_init_flag = 1;
}
if (0 == bflb_eflash_loader_if_handshake_poll(1)) {
bflb_eflash_loader_main();
}
#endif
bflb_eflash_loader_if_set(BFLB_EFLASH_LOADER_IF_UART);
if (0 == bflb_eflash_loader_if_handshake_poll(0)) {
bflb_eflash_loader_main();
}
LOG_E("%s\r\n", (char *)log);
arch_delay_ms(500);
}
}
/****************************************************************************/ /**
* @brief Boot2 Dump partition entry
*
* @param ptEntry: Partition entry pointer to dump
*
* @return None
*
*******************************************************************************/
void blsp_dump_pt_entry(pt_table_entry_config *pt_entry)
{
LOG_F("Name=%s\r\n", pt_entry->name);
LOG_F("Age=%d\r\n", (unsigned int)pt_entry->age);
LOG_F("active Index=%d\r\n", (unsigned int)pt_entry->active_index);
LOG_F("active start_address=%08x\r\n", (unsigned int)pt_entry->start_address[pt_entry->active_index & 0x01]);
}
/****************************************************************************/ /**
* @brief Boot2 check XZ FW and do decompression
*
* @param activeID: Active partition table ID
* @param ptStuff: Pointer of partition table stuff
* @param ptEntry: Pointer of active entry
*
* @return 1 for find XZ FW and decompress success, 0 for other cases
*
*******************************************************************************/
#if BLSP_BOOT2_SUPPORT_DECOMPRESS
static int blsp_boot2_check_xz_fw(pt_table_id_type activeID, pt_table_stuff_config *ptStuff, pt_table_entry_config *ptEntry)
{
uint8_t buf[6];
if (BFLB_BOOT2_SUCCESS != blsp_mediaboot_read(ptEntry->start_address[ptEntry->active_index], buf, sizeof(buf))) {
LOG_E("Read fw fail\r\n");
return 0;
}
if (blsp_boot2_verify_xz_header(buf) == 1) {
LOG_F("XZ image\r\n");
if (BFLB_BOOT2_SUCCESS == blsp_boot2_update_fw(activeID, ptStuff, ptEntry)) {
return 1;
} else {
LOG_E("Img decompress fail\r\n");
/* Set flag to make it not boot */
ptEntry->active_index = 0;
ptEntry->start_address[0] = 0;
return 0;
}
}
return 0;
}
#endif
/****************************************************************************/ /**
* @brief Boot2 copy firmware from OTA region to normal region
*
* @param activeID: Active partition table ID
* @param ptStuff: Pointer of partition table stuff
* @param ptEntry: Pointer of active entry
*
* @return BL_Err_Type
*
*******************************************************************************/
static int blsp_boot2_do_fw_copy(pt_table_id_type active_id, pt_table_stuff_config *pt_stuff, pt_table_entry_config *pt_entry)
{
uint8_t active_index = pt_entry->active_index;
uint32_t src_address = pt_entry->start_address[active_index & 0x01];
uint32_t dest_address = pt_entry->start_address[!(active_index & 0x01)];
uint32_t dest_max_size = pt_entry->max_len[!(active_index & 0x01)];
uint32_t total_len = pt_entry->len;
uint32_t deal_len = 0;
uint32_t cur_len = 0;
LOG_F("OTA copy src address %08x, dest address %08x, total len %d\r\n", src_address, dest_address, total_len);
if (SUCCESS != bflb_flash_erase(dest_address, dest_max_size)) {
LOG_E("Erase flash fail");
return BFLB_BOOT2_FLASH_ERASE_ERROR;
}
while (deal_len < total_len) {
cur_len = total_len - deal_len;
if (cur_len > BFLB_BOOT2_READBUF_SIZE) {
cur_len = BFLB_BOOT2_READBUF_SIZE;
}
if (BFLB_BOOT2_SUCCESS != blsp_mediaboot_read(src_address, g_boot2_read_buf, cur_len)) {
LOG_E("Read FW fail when copy\r\n");
return BFLB_BOOT2_FLASH_READ_ERROR;
}
if (SUCCESS != bflb_flash_write(dest_address, g_boot2_read_buf, cur_len)) {
LOG_E("Write flash fail");
return BFLB_BOOT2_FLASH_WRITE_ERROR;
}
src_address += cur_len;
dest_address += cur_len;
deal_len += cur_len;
}
return BFLB_BOOT2_SUCCESS;
}
/****************************************************************************/ /**
* @brief Boot2 deal with one firmware
*
* @param activeID: Active partition table ID
* @param ptStuff: Pointer of partition table stuff
* @param ptEntry: Pointer of active entry
* @param fwName: Firmware name pointer
* @param type: Firmware name ID
*
* @return 1 for partition table changed,need re-parse,0 for partition table or entry parsed successfully
*
*******************************************************************************/
static uint32_t blsp_boot2_deal_one_fw(pt_table_id_type active_id, pt_table_stuff_config *pt_stuff,
pt_table_entry_config *pt_entry, uint8_t *fw_name,
pt_table_entry_type type)
{
uint32_t ret;
if (fw_name != NULL) {
ret = pt_table_get_active_entries_by_name(pt_stuff, fw_name, pt_entry);
if (PT_ERROR_SUCCESS != ret) {
ret = BFLB_BOOT2_PRE_DEAL_ENTRY_NOT_FOUND;
LOG_F("entry %s not found\r\n", fw_name);
} else {
LOG_F("entry %s found\r\n", fw_name);
}
} else {
ret = pt_table_get_active_entries_by_id(pt_stuff, type, pt_entry);
if (PT_ERROR_SUCCESS != ret) {
ret = BFLB_BOOT2_PRE_DEAL_ENTRY_NOT_FOUND;
LOG_F("entry ID %d not found\r\n", type);
} else {
LOG_F("entry ID %d found\r\n", type);
}
}
if (PT_ERROR_SUCCESS == ret) {
#if BLSP_BOOT2_SUPPORT_DECOMPRESS
if (blsp_boot2_check_xz_fw(active_id, pt_stuff, pt_entry) == 1) {
/* xz image found, retry to get newest partition info */
return BFLB_BOOT2_PRE_DEAL_NEED_RETRY;
}
#endif
/* Check if this partition need copy */
if (pt_entry->active_index >= 2) {
LOG_F("Do image copy\r\n");
if (BFLB_BOOT2_SUCCESS == blsp_boot2_do_fw_copy(active_id, pt_stuff, pt_entry)) {
pt_entry->active_index = !(pt_entry->active_index & 0x01);
pt_entry->age++;
ret = pt_table_update_entry((pt_table_id_type)(!active_id), pt_stuff, pt_entry);
if (ret == PT_ERROR_SUCCESS) {
/* copy done, retry to get newest partition info */
LOG_F("Done\r\n");
return BFLB_BOOT2_PRE_DEAL_NEED_RETRY;
} else {
LOG_E("Update Partition table entry fail\r\n");
}
}
}
}
return ret;
}
/****************************************************************************/ /**
* @brief Boot2 Roll back pt entry
*
* @param activeID: Active partition table ID
* @param ptStuff: Pointer of partition table stuff
* @param ptEntry: Pointer of active entry
*
* @return boot_error_code
*
*******************************************************************************/
#ifdef BLSP_BOOT2_ROLLBACK
int32_t blsp_boot2_rollback_ptentry(pt_table_id_type active_id, pt_table_stuff_config *pt_stuff, pt_table_entry_config *pt_entry)
{
int32_t ret;
pt_entry->active_index = !(pt_entry->active_index & 0x01);
pt_entry->age++;
ret = pt_table_update_entry((pt_table_id_type)(!active_id), pt_stuff, pt_entry);
if (ret != PT_ERROR_SUCCESS) {
LOG_E("Update PT entry fail\r\n");
return BFLB_BOOT2_FAIL;
}
return BFLB_BOOT2_SUCCESS;
}
#endif
/****************************************************************************/ /**
* @brief Boot2 get mfg start up request
*
* @param activeID: Active partition table ID
* @param ptStuff: Pointer of partition table stuff
* @param ptEntry: Pointer of active entry
*
* @return 0 for partition table changed,need re-parse,1 for partition table or entry parsed successfully
*
*******************************************************************************/
static void blsp_boot2_get_mfg_startreq(pt_table_id_type active_id, pt_table_stuff_config *pt_stuff, pt_table_entry_config *pt_entry, uint8_t *user_fw_name)
{
uint32_t ret;
uint32_t len = 0;
uint8_t tmp[16 + 1] = { 0 };
/* case 1 0mfg and 1 mfg, should return and boot */
if ((arch_memcmp(user_fw_name, "0mfg", 4) == 0) || (arch_memcmp(user_fw_name, "1mfg", 4) == 0)) {
arch_memset(user_fw_name, 0, 4);
arch_memcpy(user_fw_name, "mfg", 3);
return;
}
/* case 2 other not 0 should return and boot */
if (user_fw_name[0] != 0) {
return;
}
ret = pt_table_get_active_entries_by_name(pt_stuff, (uint8_t *)"mfg", pt_entry);
if (PT_ERROR_SUCCESS == ret) {
LOG_F("read mfg flag addr:%08x\r\n", pt_entry->start_address[0] + MFG_START_REQUEST_OFFSET);
bflb_flash_read(pt_entry->start_address[0] + MFG_START_REQUEST_OFFSET, tmp, sizeof(tmp) - 1);
//LOG_F("%s\r\n", tmp);
if (tmp[0] == '0' || tmp[0] == '1') {
len = strlen((char *)tmp) - 1;
if (len < 9) {
arch_memcpy(user_fw_name, &tmp[1], len);
LOG_F("flag:%s\r\n", tmp);
}
}
} else {
LOG_F("MFG not found\r\n");
}
}
/****************************************************************************/ /**
* @brief Boot2 main function
*
* @param None
*
* @return Return value
*
*******************************************************************************/
int main(void)
{
uint32_t ret = 0, i = 0;
pt_table_stuff_config pt_table_stuff[2];
pt_table_id_type active_id;
/* Init to zero incase only one cpu boot up*/
pt_table_entry_config pt_entry[BLSP_BOOT2_CPU_GROUP_MAX] = { 0 };
uint32_t boot_header_addr[BLSP_BOOT2_CPU_GROUP_MAX] = { 0 };
uint8_t boot_need_rollback[BLSP_BOOT2_CPU_GROUP_MAX] = { 0 };
uint8_t user_fw_name[9] = { 0 };
uint32_t user_fw;
#ifdef BLSP_BOOT2_ROLLBACK
uint8_t roll_backed = 0;
#endif
uint8_t mfg_mode_flag = 0;
//boot_clk_config clk_cfg;
uint8_t flash_cfg_buf[4 + sizeof(SPI_Flash_Cfg_Type) + 4] = { 0 };
uint32_t crc;
uint8_t *flash_cfg = NULL;
uint32_t flash_cfg_len = 0;
hal_boot2_init_clock();
blsp_boot2_start_timer();
hal_boot2_get_efuse_cfg(&g_efuse_cfg);
bflb_eflash_loader_if_set(BFLB_EFLASH_LOADER_IF_UART);
bflb_eflash_loader_if_init();
#if (BLSP_BOOT2_MODE == BOOT2_MODE_RELEASE)
bflb_uart_set_console(NULL);
#endif
#if (BLSP_BOOT2_MODE == BOOT2_MODE_DEBUG)
bflb_uart_set_console(uartx);
#endif
simple_malloc_init(g_malloc_buf, sizeof(g_malloc_buf));
g_boot2_read_buf = vmalloc(BFLB_BOOT2_READBUF_SIZE);
ret = hal_boot2_custom(NULL);
LOG_F("custom 0x%04x\r\n", ret);
ret = bflb_flash_init();
if (ret) {
while (1) {
LOG_E("flash cfg err\r\n");
bflb_mtimer_delay_ms(500);
}
}
LOG_F("flash init %d\r\n", (int)ret);
LOG_F("BLSP Boot2 start:%s,%s\r\n", __DATE__, __TIME__);
LOG_F("Group=%d,CPU Count=%d\r\n", BLSP_BOOT2_CPU_GROUP_MAX, BLSP_BOOT2_CPU_MAX);
LOG_F("ver:%s\r\n", BL_SDK_VER);
/* Reset Sec_Eng */
hal_boot2_reset_sec_eng();
sha = bflb_device_get_by_name("sha");
bflb_group0_request_sha_access(sha);
/* Get power save mode */
g_ps_mode = blsp_read_power_save_mode();
/* Get User specified FW */
user_fw = hal_boot2_get_user_fw();
arch_memcpy(user_fw_name, &user_fw, 4);
LOG_F("user_fw %s\r\n", user_fw_name);
/* Set flash operation function, read via xip */
pt_table_set_flash_operation(bflb_flash_erase, bflb_flash_write, bflb_flash_read);
#if BLSP_BOOT2_SUPPORT_USB_IAP
if (memcmp(user_fw_name, (char *)"USB", 3) == 0) {
hal_boot2_clr_user_fw();
bflb_eflash_loader_if_set(BFLB_EFLASH_LOADER_IF_USB);
bflb_eflash_loader_if_init();
g_usb_init_flag = 1;
if (0 == bflb_eflash_loader_if_handshake_poll(user_fw_name[3])) {
bflb_eflash_loader_main();
}
}
#endif
#if BLSP_BOOT2_RAM_IMG_COUNT_MAX > 0
/* Deal with ram image: copy from flash to ram like */
do {
active_id = pt_table_get_active_partition_need_lock(pt_table_stuff);
if (PT_TABLE_ID_INVALID == active_id) {
blsp_boot2_on_error("No valid PT\r\n");
}
ret = blsp_do_ram_image_boot(active_id, &pt_table_stuff[active_id], &pt_entry[0]);
} while (ret != 0);
#endif
/* Deal with flash image */
while (1) {
do {
mfg_mode_flag = 0;
active_id = pt_table_get_active_partition_need_lock(pt_table_stuff);
if (PT_TABLE_ID_INVALID == active_id) {
blsp_boot2_on_error("No valid PT\r\n");
}
LOG_F("Active PT:%d,Age %d\r\n", active_id, pt_table_stuff[active_id].pt_table.age);
blsp_boot2_get_mfg_startreq(active_id, &pt_table_stuff[active_id], &pt_entry[0], user_fw_name);
/* Get entry and boot */
if (user_fw_name[0] != 0) {
ret = blsp_boot2_deal_one_fw(active_id, &pt_table_stuff[active_id], &pt_entry[0], user_fw_name, PT_ENTRY_FW_CPU0);
if (!ret) {
g_user_hash_ignored = 1;
mfg_mode_flag = 1;
} else {
ret = blsp_boot2_deal_one_fw(active_id, &pt_table_stuff[active_id], &pt_entry[0], NULL, PT_ENTRY_FW_CPU0);
if (!ret) {
/* go on get partition type 1 (group1) info */
if (BLSP_BOOT2_CPU_GROUP_MAX > 1) {
ret = blsp_boot2_deal_one_fw(active_id, &pt_table_stuff[active_id], &pt_entry[1], NULL, PT_ENTRY_FW_CPU1);
}
}
}
hal_boot2_clr_user_fw();
arch_memset(user_fw_name, 0, 4);
} else {
/* get partition type 0 (group0) info */
ret = blsp_boot2_deal_one_fw(active_id, &pt_table_stuff[active_id], &pt_entry[0], NULL, PT_ENTRY_FW_CPU0);
if (!ret) {
/* go on get partition type 1 (group1) info */
if (BLSP_BOOT2_CPU_GROUP_MAX > 1) {
ret = blsp_boot2_deal_one_fw(active_id, &pt_table_stuff[active_id], &pt_entry[1], NULL, PT_ENTRY_FW_CPU1);
}
}
}
if (ret == BFLB_BOOT2_PRE_DEAL_ENTRY_NOT_FOUND) {
blsp_boot2_on_error("No valid entry\r\n");
}
} while (ret);
/* Pass data to App*/
blsp_boot2_pass_parameter(NULL, 0);
/* Pass active partition table ID */
blsp_boot2_pass_parameter(&active_id, 4);
/* Pass active partition table content: table header+ entries +crc32 */
blsp_boot2_pass_parameter(&pt_table_stuff[active_id], sizeof(pt_table_config) + 4 +
pt_table_stuff[active_id].pt_table.entryCnt * sizeof(pt_table_entry_config));
/* Pass flash config */
if (pt_entry[0].start_address[pt_entry[0].active_index] != 0) {
/* Include magic and CRC32 */
bflb_flash_get_cfg(&flash_cfg, &flash_cfg_len);
arch_memcpy(flash_cfg_buf, "FCFG", 4);
arch_memcpy(flash_cfg_buf + 4, flash_cfg, flash_cfg_len);
crc = BFLB_Soft_CRC32(flash_cfg, flash_cfg_len);
arch_memcpy(flash_cfg_buf + 4 + flash_cfg_len, &crc, sizeof(crc));
blsp_boot2_pass_parameter(flash_cfg_buf, sizeof(flash_cfg_buf));
}
LOG_F("Boot start\r\n");
for (i = 0; i < BLSP_BOOT2_CPU_GROUP_MAX; i++) {
boot_header_addr[i] = pt_entry[i].start_address[pt_entry[i].active_index];
}
#ifdef BLSP_BOOT2_ROLLBACK
/* mfg mode do not need roll back */
if (roll_backed == 0 && mfg_mode_flag == 0) {
ret = blsp_mediaboot_main(boot_header_addr, boot_need_rollback, 1);
} else {
ret = blsp_mediaboot_main(boot_header_addr, boot_need_rollback, 0);
}
#else
ret = blsp_mediaboot_main(boot_header_addr, boot_need_rollback, 0);
#endif
if (mfg_mode_flag == 1) {
continue;
}
#ifdef BLSP_BOOT2_ROLLBACK
/* If rollback is done, we still fail, break */
if (roll_backed) {
break;
}
LOG_F("Boot return 0x%04x\r\nCheck Rollback\r\n", ret);
for (i = 0; i < BLSP_BOOT2_CPU_GROUP_MAX; i++) {
if (boot_need_rollback[i] != 0) {
LOG_F("Rollback group %d\r\n", i);
if (BFLB_BOOT2_SUCCESS == blsp_boot2_rollback_ptentry(active_id, &pt_table_stuff[active_id], &pt_entry[i])) {
roll_backed = 1;
}
}
}
/* If need no rollback, boot fail due to other reseaon instead of imgae issue,break */
if (roll_backed == 0) {
break;
}
#else
break;
#endif
}
/* We should never get here unless boot fail */
LOG_E("Media boot return %d\r\n", ret);
while (1) {
#if BLSP_BOOT2_SUPPORT_USB_IAP
bflb_eflash_loader_if_set(BFLB_EFLASH_LOADER_IF_USB);
if (0 == g_usb_init_flag) {
bflb_eflash_loader_if_init();
g_usb_init_flag = 1;
}
if (0 == bflb_eflash_loader_if_handshake_poll(1)) {
bflb_eflash_loader_main();
}
#endif
bflb_eflash_loader_if_set(BFLB_EFLASH_LOADER_IF_UART);
if (0 == bflb_eflash_loader_if_handshake_poll(0)) {
bflb_eflash_loader_main();
}
LOG_E("BLSP boot2 fail\r\n");
bflb_mtimer_delay_ms(500);
}
}
void bfl_main()
{
main();
}

View file

@ -0,0 +1,543 @@
/**
******************************************************************************
* @file partition.c
* @version V1.0
* @date
* @brief This file is the standard driver c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2019 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_core.h"
#include "partition.h"
#include "softcrc.h"
/** @addtogroup BFLB_Common_Driver
* @{
*/
/** @addtogroup PARTITION
* @{
*/
/** @defgroup PARTITION_Private_Macros
* @{
*/
/*@} end of group PARTITION_Private_Macros */
/** @defgroup PARTITION_Private_Types
* @{
*/
/*@} end of group PARTITION_Private_Types */
/** @defgroup PARTITION_Private_Variables
* @{
*/
p_pt_table_flash_erase gp_pt_table_flash_erase = NULL;
p_pt_table_flash_write gp_pt_table_flash_write = NULL;
p_pt_table_flash_read gp_pt_table_flash_read = NULL;
pt_table_iap_param_type p_iap_param;
/*@} end of group PARTITION_Private_Variables */
/** @defgroup PARTITION_Global_Variables
* @{
*/
extern int main(void);
/*@} end of group PARTITION_Global_Variables */
/** @defgroup PARTITION_Private_Fun_Declaration
* @{
*/
/*@} end of group PARTITION_Private_Fun_Declaration */
/** @defgroup PARTITION_Private_Functions
* @{
*/
/****************************************************************************/ /**
* @brief Judge partition table valid
*
* @param ptStuff: Partition table stuff pointer
*
* @return 0 for invalid and 1 for valid
*
*******************************************************************************/
static uint8_t pt_table_valid(pt_table_stuff_config *pt_stuff)
{
pt_table_config *pt_table = &pt_stuff->pt_table;
pt_table_entry_config *pt_entries = pt_stuff->pt_entries;
uint32_t *p_crc32;
uint32_t entriesLen = sizeof(pt_table_entry_config) * pt_table->entryCnt;
if (pt_table->magicCode == BFLB_PT_MAGIC_CODE) {
if (pt_table->entryCnt > PT_ENTRY_MAX) {
LOG_F("PT Entry Count Error\r\n");
return 0;
}
if (pt_table->crc32 !=
BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4)) {
LOG_F("PT CRC Error\r\n");
return 0;
}
/* ToDo it is a trap here, when entryCnt > 8, crc32 will overflow, comment by zhangcheng */
p_crc32 = (uint32_t *)((uintptr_t)pt_entries + entriesLen);
if (*p_crc32 != BFLB_Soft_CRC32((uint8_t *)pt_entries, entriesLen)) {
LOG_F("PT Entry CRC Error\r\n");
return 0;
}
return 1;
}
return 0;
}
/*@} end of group PARTITION_Private_Functions */
/** @defgroup PARTITION_Public_Functions
* @{
*/
/****************************************************************************/ /**
* @brief Register partition flash read write erase fucntion
*
* @param erase: Flash erase function
* @param write: Flash write function
* @param read: Flash read function
*
* @return None
*
*******************************************************************************/
void pt_table_set_flash_operation(p_pt_table_flash_erase erase, p_pt_table_flash_write write, p_pt_table_flash_read read)
{
gp_pt_table_flash_erase = erase;
gp_pt_table_flash_write = write;
gp_pt_table_flash_read = read;
}
/****************************************************************************/ /**
* @brief Get active partition table whole stuff
*
* @param ptStuff[2]: Partition table stuff pointer
*
* @return Active partition table ID
*
*******************************************************************************/
pt_table_id_type pt_table_get_active_partition_need_lock(pt_table_stuff_config ptStuff[2])
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_id_type activePtID;
if (ptStuff == NULL) {
return PT_TABLE_ID_INVALID;
}
activePtID = PT_TABLE_ID_INVALID;
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&ptStuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&ptStuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&ptStuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&ptStuff[1]);
if (pt_valid[0] == 1 && pt_valid[1] == 1) {
if (ptStuff[0].pt_table.age >= ptStuff[1].pt_table.age) {
activePtID = PT_TABLE_ID_0;
} else {
activePtID = PT_TABLE_ID_1;
}
} else if (pt_valid[0] == 1) {
activePtID = PT_TABLE_ID_0;
} else if (pt_valid[1] == 1) {
activePtID = PT_TABLE_ID_1;
}
return activePtID;
}
/****************************************************************************/ /**
* @brief Get partition entry according to entry ID
*
* @param ptStuff: Partition table stuff pointer
* @param type: Type of partition entry
* @param ptEntry: Partition entry pointer to store read data
*
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
*
*******************************************************************************/
pt_table_error_type pt_table_get_active_entries_by_id(pt_table_stuff_config *pt_stuff,
pt_table_entry_type type,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
if (pt_stuff == NULL || pt_entry == NULL) {
return PT_ERROR_PARAMETER;
}
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
if (pt_stuff->pt_entries[i].type == type) {
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
return PT_ERROR_SUCCESS;
}
}
return PT_ERROR_ENTRY_NOT_FOUND;
}
/****************************************************************************/ /**
* @brief Get partition entry according to entry name
*
* @param ptStuff: Partition table stuff pointer
* @param name: Name of partition entry
* @param ptEntry: Partition entry pointer to store read data
*
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
*
*******************************************************************************/
pt_table_error_type pt_table_get_active_entries_by_name(pt_table_stuff_config *pt_stuff,
uint8_t *name,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
uint32_t len = strlen((char *)name);
if (pt_stuff == NULL || pt_entry == NULL) {
return PT_ERROR_PARAMETER;
}
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
if (strlen((char *)pt_stuff->pt_entries[i].name) == len &&
memcmp((char *)pt_stuff->pt_entries[i].name, (char *)name, len) == 0) {
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
return PT_ERROR_SUCCESS;
}
}
return PT_ERROR_ENTRY_NOT_FOUND;
}
/****************************************************************************/ /**
* @brief Update partition entry
*
* @param targetTableID: Target partition table to update
* @param ptStuff: Partition table stuff pointer
* @param ptEntry: Partition entry pointer to update
*
* @return Partition update result
*
*******************************************************************************/
pt_table_error_type pt_table_update_entry(pt_table_id_type target_table_id,
pt_table_stuff_config *pt_stuff,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
BL_Err_Type ret;
uint32_t write_addr;
uint32_t entries_len;
pt_table_config *pt_table;
pt_table_entry_config *pt_entries;
uint32_t *crc32;
if (pt_entry == NULL || pt_stuff == NULL) {
return PT_ERROR_PARAMETER;
}
pt_table = &pt_stuff->pt_table;
pt_entries = pt_stuff->pt_entries;
if (target_table_id == PT_TABLE_ID_INVALID) {
return PT_ERROR_TABLE_NOT_VALID;
}
if (target_table_id == PT_TABLE_ID_0) {
write_addr = BFLB_PT_TABLE0_ADDRESS;
} else {
write_addr = BFLB_PT_TABLE1_ADDRESS;
}
for (i = 0; i < pt_table->entryCnt; i++) {
if (pt_entries[i].type == pt_entry->type) {
ARCH_MemCpy_Fast(&pt_entries[i], pt_entry, sizeof(pt_table_entry_config));
break;
}
}
if (i == pt_table->entryCnt) {
/* Not found this entry ,add new one */
if (pt_table->entryCnt < PT_ENTRY_MAX) {
ARCH_MemCpy_Fast(&pt_entries[pt_table->entryCnt], pt_entry, sizeof(pt_table_entry_config));
pt_table->entryCnt++;
} else {
return PT_ERROR_ENTRY_UPDATE_FAIL;
}
}
/* Prepare write back to flash */
/* Update age */
pt_table->age++;
pt_table->crc32 = BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4);
/* Update entries CRC */
entries_len = pt_table->entryCnt * sizeof(pt_table_entry_config);
crc32 = (uint32_t *)((uintptr_t)pt_entries + entries_len);
*crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_entries[0], entries_len);
/* Write back to flash */
/* Erase flash first */
//ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) + entries_len + 4 - 1);
ret = gp_pt_table_flash_erase(write_addr, sizeof(pt_table_config) + entries_len + 4);
if (ret != SUCCESS) {
//LOG_D_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_WRITE;
}
/* Write flash */
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)pt_stuff, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
//LOG_D_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
return PT_ERROR_SUCCESS;
}
/****************************************************************************/ /**
* @brief Create partition entry
*
* @param ptID: Partition table ID
*
* @return Partition create result
*
*******************************************************************************/
pt_table_error_type pt_table_create(pt_table_id_type pt_id)
{
uint32_t write_addr;
BL_Err_Type ret;
pt_table_config pt_table;
if (pt_id == PT_TABLE_ID_INVALID) {
return PT_ERROR_TABLE_NOT_VALID;
}
if (pt_id == PT_TABLE_ID_0) {
write_addr = BFLB_PT_TABLE0_ADDRESS;
} else {
write_addr = BFLB_PT_TABLE1_ADDRESS;
}
/* Prepare write back to flash */
pt_table.magicCode = BFLB_PT_MAGIC_CODE;
pt_table.version = 0;
pt_table.entryCnt = 0;
pt_table.age = 0;
pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_table, sizeof(pt_table_config) - 4);
/* Write back to flash */
//ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) - 1);
ret = gp_pt_table_flash_erase(write_addr, sizeof(pt_table_config));
if (ret != SUCCESS) {
//LOG_D_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)&pt_table, sizeof(pt_table_config));
if (ret != SUCCESS) {
//LOG_D_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_dump(void)
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_stuff_config pt_stuff[2];
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
if (pt_valid[0]) {
LOG_F("PT TABLE0 valid\r\n");
} else {
LOG_F("PT TABLE0 invalid\r\n");
}
if (pt_valid[1]) {
LOG_F("PT TABLE1 valid\r\n");
} else {
LOG_F("PT TABLE1 invalid\r\n");
}
#if 0
for (int i = 0; i < 2; i++) {
if (pt_valid[i] == 1) {
LOG_F("ptStuff[%d].pt_table.magicCode 0x%08x\r\n", i, pt_stuff[i].pt_table.magicCode);
LOG_F("ptStuff[%d].pt_table.version 0x%08x\r\n", i, pt_stuff[i].pt_table.version);
LOG_F("ptStuff[%d].pt_table.entryCnt 0x%08x\r\n", i, pt_stuff[i].pt_table.entryCnt);
LOG_F("ptStuff[%d].pt_table.age 0x%08x\r\n", i, pt_stuff[i].pt_table.age);
LOG_F("ptStuff[%d].pt_table.crc32 0x%08x\r\n", i, pt_stuff[i].pt_table.crc32);
for (int j = 0; j < pt_stuff[i].pt_table.entryCnt; j++) {
LOG_F("ptStuff[%d].pt_entries[%d].type 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].type);
LOG_F("ptStuff[%d].pt_entries[%d].device 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].device);
LOG_F("ptStuff[%d].pt_entries[%d].active_index 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].active_index);
LOG_F("ptStuff[%d].pt_entries[%d].Address[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[0]);
LOG_F("ptStuff[%d].pt_entries[%d].Address[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[1]);
LOG_F("ptStuff[%d].pt_entries[%d].maxLen[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[0]);
LOG_F("ptStuff[%d].pt_entries[%d].maxLen[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[1]);
LOG_F("ptStuff[%d].pt_entries[%d].len 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].len);
LOG_F("ptStuff[%d].pt_entries[%d].age 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].age);
}
}
}
#endif
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_get_iap_para(pt_table_iap_param_type *para)
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_stuff_config pt_stuff[2];
uint8_t active_index;
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
if ((pt_valid[0] == 1) && (pt_valid[1] == 1)) {
if (pt_stuff[0].pt_table.age >= pt_stuff[1].pt_table.age) {
active_index = pt_stuff[0].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 1;
} else {
active_index = pt_stuff[1].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 0;
}
} else if (pt_valid[1] == 1) {
active_index = pt_stuff[1].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 0;
} else if (pt_valid[0] == 1) {
active_index = pt_stuff[0].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 1;
} else {
return PT_ERROR_TABLE_NOT_VALID;
}
LOG_F("inactive_table_index %d, inactive index %d , IAP start addr %08x \r\n", para->inactive_table_index, para->inactive_index, para->iap_start_addr);
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_set_iap_para(pt_table_iap_param_type *para)
{
pt_table_stuff_config pt_stuff, pt_stuff_write;
int32_t ret;
uint32_t *p_crc32;
uint32_t entries_len;
if (para->inactive_table_index == 1) {
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
} else if (para->inactive_table_index == 0) {
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
}
ARCH_MemCpy_Fast((void *)&pt_stuff_write, (void *)&pt_stuff, sizeof(pt_table_stuff_config));
pt_stuff_write.pt_table.age += 1;
pt_stuff_write.pt_entries[0].active_index = !(pt_stuff_write.pt_entries[0].active_index & 0x01);
pt_stuff_write.pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_stuff_write, sizeof(pt_table_config) - 4);
entries_len = sizeof(pt_table_entry_config) * pt_stuff_write.pt_table.entryCnt;
//pt_stuff_write.crc32 = BFLB_Soft_CRC32((uint8_t*)pt_stuff_write.pt_entries,entries_len);
p_crc32 = (uint32_t *)((uintptr_t)pt_stuff_write.pt_entries + entries_len);
*p_crc32 = BFLB_Soft_CRC32((uint8_t *)pt_stuff_write.pt_entries, entries_len);
if (para->inactive_table_index == 1) {
//ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, BFLB_PT_TABLE1_ADDRESS + sizeof(pt_table_stuff_config) - 1);
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
//LOG_D_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
//LOG_D_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
} else if (para->inactive_table_index == 0) {
//ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, BFLB_PT_TABLE0_ADDRESS + sizeof(pt_table_stuff_config) - 1);
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
//LOG_D_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
//LOG_D_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
}
LOG_F("Update pt_table suss\r\n");
return PT_ERROR_SUCCESS;
}
/*@} end of group PARTITION_Public_Functions */
/*@} end of group PARTITION */
/*@} end of group BFLB_Common_Driver */

View file

@ -0,0 +1,210 @@
/**
******************************************************************************
* @file partition.h
* @version V1.0
* @date
* @brief This file is the standard driver header file
******************************************************************************
* @attention
*
* <h2><center>&copy; 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.
*
******************************************************************************
*/
#ifndef __PARTITION_H__
#define __PARTITION_H__
#include "blsp_port.h"
#include "bl616_common.h"
/** @addtogroup BFLB_Common_Driver
* @{
*/
/** @addtogroup PARTITION
* @{
*/
/** @defgroup PARTITION_Public_Types
* @{
*/
/**
* @brief Partition table error type definition
*/
typedef enum {
PT_ERROR_SUCCESS, /*!< Partition table error type:success */
PT_ERROR_TABLE_NOT_VALID, /*!< Partition table error type:table not found */
PT_ERROR_ENTRY_NOT_FOUND, /*!< Partition table error type:entry not found */
PT_ERROR_ENTRY_UPDATE_FAIL, /*!< Partition table error type:entry update fail */
PT_ERROR_CRC32, /*!< Partition table error type:crc32 error */
PT_ERROR_PARAMETER, /*!< Partition table error type:input parameter error */
PT_ERROR_FALSH_READ, /*!< Partition table error type:flash read error */
PT_ERROR_FALSH_WRITE, /*!< Partition table error type:flash write error */
PT_ERROR_FALSH_ERASE, /*!< Partition table error type:flash erase error */
} pt_table_error_type;
/**
* @brief Partition id type definition
*/
typedef enum {
PT_TABLE_ID_0, /*!< Partition table ID 0 */
PT_TABLE_ID_1, /*!< Partition table ID 1 */
PT_TABLE_ID_INVALID, /*!< Partition table ID invalid */
} pt_table_id_type;
/**
* @brief Partition id type definition
*/
typedef enum {
PT_ENTRY_FW_CPU0, /*!< Partition entry type:CPU0 firmware */
PT_ENTRY_FW_CPU1, /*!< Partition entry type:CPU1 firmware */
PT_ENTRY_MAX = 16, /*!< Partition entry type:Max */
} pt_table_entry_type;
/**
* @brief Partition table config definition
*/
typedef struct
{
uint32_t magicCode; /*!< Partition table magic code */
uint16_t version; /*!< Partition table verdion */
uint16_t entryCnt; /*!< Partition table entry count */
uint32_t age; /*!< Partition table age */
uint32_t crc32; /*!< Partition table CRC32 value */
} pt_table_config;
/**
* @brief Partition table entry config definition
*/
typedef struct
{
uint8_t type; /*!< Partition entry type */
uint8_t device; /*!< Partition entry device */
uint8_t active_index; /*!< Partition entry active index */
uint8_t name[9]; /*!< Partition entry name */
uint32_t start_address[2]; /*!< Partition entry start address */
uint32_t max_len[2]; /*!< Partition entry max length */
uint32_t len; /*!< Partition entry length */
uint32_t age; /*!< Partition entry age */
} pt_table_entry_config;
/**
* @brief Partition table stuff config definition
*/
typedef struct
{
pt_table_config pt_table; /*!< Partition table */
pt_table_entry_config pt_entries[PT_ENTRY_MAX]; /*!< Partition entries */
uint32_t crc32; /*!< Partition entries crc32 */
} pt_table_stuff_config;
/**
* @brief Partition table iap param definition
*/
typedef struct
{
uint32_t iap_start_addr;
uint32_t iap_write_addr;
uint32_t iap_img_len;
uint8_t inactive_index;
uint8_t inactive_table_index;
} pt_table_iap_param_type;
/*@} end of group PARTITION_Public_Types */
/** @defgroup PARTITION_Public_Constants
* @{
*/
/** @defgroup pt_table_error_type
* @{
*/
#define IS_PTTABLE_ERROR_TYPE(type) (((type) == PT_ERROR_SUCCESS) || \
((type) == PT_ERROR_TABLE_NOT_VALID) || \
((type) == PT_ERROR_ENTRY_NOT_FOUND) || \
((type) == PT_ERROR_ENTRY_UPDATE_FAIL) || \
((type) == PT_ERROR_CRC32) || \
((type) == PT_ERROR_PARAMETER) || \
((type) == PT_ERROR_FALSH_READ) || \
((type) == PT_ERROR_FALSH_WRITE) || \
((type) == PT_ERROR_FALSH_ERASE))
/** @defgroup pt_table_id_type
* @{
*/
#define IS_PTTABLE_ID_TYPE(type) (((type) == PT_TABLE_ID_0) || \
((type) == PT_TABLE_ID_1) || \
((type) == PT_TABLE_ID_INVALID))
/** @defgroup pt_table_entry_type
* @{
*/
#define IS_PTTABLE_ENTRY_TYPE(type) (((type) == PT_ENTRY_FW_CPU0) || \
((type) == PT_ENTRY_FW_CPU1) || \
((type) == PT_ENTRY_MAX))
/*@} end of group PARTITION_Public_Constants */
/** @defgroup PARTITION_Public_Macros
* @{
*/
#define BFLB_PT_TABLE0_ADDRESS 0xE000
#define BFLB_PT_TABLE1_ADDRESS 0xF000
#define BFLB_PT_MAGIC_CODE 0x54504642
typedef int (*p_pt_table_flash_erase)(uint32_t startaddr, uint32_t endaddr);
typedef int (*p_pt_table_flash_write)(uint32_t addr, uint8_t *data, uint32_t len);
typedef int (*p_pt_table_flash_read)(uint32_t addr, uint8_t *data, uint32_t len);
/*@} end of group PARTITION_Public_Macros */
/** @defgroup PARTITION_Public_Functions
* @{
*/
void pt_table_set_flash_operation(p_pt_table_flash_erase erase, p_pt_table_flash_write write, p_pt_table_flash_read read);
pt_table_id_type pt_table_get_active_partition_need_lock(pt_table_stuff_config ptStuff[2]);
pt_table_error_type pt_table_get_active_entries_by_id(pt_table_stuff_config *pt_stuff,
pt_table_entry_type type,
pt_table_entry_config *pt_entry);
pt_table_error_type pt_table_get_active_entries_by_name(pt_table_stuff_config *pt_stuff,
uint8_t *name,
pt_table_entry_config *pt_entry);
pt_table_error_type pt_table_update_entry(pt_table_id_type target_table_id,
pt_table_stuff_config *pt_stuff,
pt_table_entry_config *pt_entry);
pt_table_error_type pt_table_create(pt_table_id_type pt_id);
pt_table_error_type pt_table_dump(void);
pt_table_error_type pt_table_get_iap_para(pt_table_iap_param_type *para);
pt_table_error_type pt_table_set_iap_para(pt_table_iap_param_type *para);
/*@} end of group PARTITION_Public_Functions */
/*@} end of group PARTITION */
/*@} end of group BFLB_Common_Driver */
extern pt_table_iap_param_type p_iap_param;
#endif /* __PARTITION_H__ */

View file

@ -0,0 +1,869 @@
/**
* *****************************************************************************
* @file bflb_port_boot2.c
* @version 0.1
* @date 2022-11-23
* @brief
* *****************************************************************************
* @attention
*
* <h2><center>&copy; 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_port_boot2.h"
#include "bl616_ef_cfg.h"
#include "bl616_ef_ctrl.h"
#include "bl616_hbn.h"
#include "bl616_glb.h"
#include "bl616_xip_sflash.h"
#include "bl616_tzc_sec.h"
#include "softcrc.h"
#include "bl616_psram.h"
#include "bflb_flash.h"
/****************************************************************************/ /**
* @brief init boot2 system clock
*
* @param
*
* @return
*
*******************************************************************************/
void hal_boot2_init_clock(void)
{
CPU_Reset_MTimer();
/* set mtimer clock 1M */
CPU_Set_MTimer_CLK(ENABLE, BL_MTIMER_SOURCE_CLOCK_MCU_CLK, Clock_System_Clock_Get(BL_SYSTEM_CLOCK_MCU_CLK) / 1000000 - 1);
GLB_Set_UART_CLK(ENABLE, HBN_UART_CLK_XCLK, 0);
}
/****************************************************************************/ /**
* @brief init psram gpio
*
* @param
*
* @return
*
*******************************************************************************/
static void _bflb_init_psram_gpio(void)
{
GLB_GPIO_Cfg_Type cfg;
cfg.pullType = GPIO_PULL_NONE;
cfg.drive = 0;
cfg.smtCtrl = 1;
for (uint8_t i = 0; i < 12; i++) {
cfg.gpioPin = 41 + i;
cfg.gpioMode = GPIO_MODE_INPUT;
GLB_GPIO_Init(&cfg);
}
}
/****************************************************************************/ /**
* @brief psram_winbond_init_dqs
*
* @param
*
* @return
*
*******************************************************************************/
static uint16_t psram_winbond_init_dqs(int8_t burst_len, uint8_t is_fixLatency, uint8_t latency, uint16_t dqs_delay)
{
uint16_t reg_read = 0;
PSRAM_Ctrl_Cfg_Type psramCtrlCfg = {
.vendor = PSRAM_CTRL_VENDOR_WINBOND,
.ioMode = PSRAM_CTRL_X8_MODE,
.size = PSRAM_SIZE_32MB,
.dqs_delay = 0xffc0,
};
PSRAM_Winbond_Cfg_Type winbondCfg = {
.rst = DISABLE,
.clockType = PSRAM_CLOCK_DIFF,
.inputPowerDownMode = DISABLE,
.hybridSleepMode = DISABLE,
.linear_dis = ENABLE,
.PASR = PSRAM_PARTIAL_REFRESH_FULL,
.disDeepPowerDownMode = ENABLE,
.fixedLatency = DISABLE,
.brustLen = PSRAM_WINBOND_BURST_LENGTH_64_BYTES,
.brustType = PSRAM_WRAPPED_BURST,
.latency = PSRAM_WINBOND_6_CLOCKS_LATENCY,
.driveStrength = PSRAM_WINBOND_DRIVE_STRENGTH_35_OHMS_FOR_4M_115_OHMS_FOR_8M,
};
winbondCfg.brustLen = burst_len;
winbondCfg.fixedLatency = is_fixLatency;
winbondCfg.latency = latency;
psramCtrlCfg.dqs_delay = dqs_delay;
PSram_Ctrl_Init(PSRAM0_ID, &psramCtrlCfg);
// PSram_Ctrl_Winbond_Reset(PSRAM0_ID);
PSram_Ctrl_Winbond_Write_Reg(PSRAM0_ID, PSRAM_WINBOND_REG_CR0, &winbondCfg);
PSram_Ctrl_Winbond_Read_Reg(PSRAM0_ID, PSRAM_WINBOND_REG_ID0, &reg_read);
return reg_read;
}
#define PSRAM_BASIC_ADDR (0xA8000000)
#define TEST_MEMORY_SIZE (1 * 1024 * 1024)
uint32_t test_pattern_val[] = {
0xaa55aa55,
0x33cc33cc,
0x55aa55aa,
0xcc33cc33,
};
/****************************************************************************/ /**
* @brief psram_rw_check
*
* @param None
*
* @return uint8_t
*
*******************************************************************************/
uint8_t psram_rw_check(void)
{
uint32_t i = 0;
volatile uint32_t *p = (uint32_t *)PSRAM_BASIC_ADDR;
volatile uint32_t q = 0;
p[0] = 0xaa55aa55;
p[1] = 0x33cc33cc;
p[2] = 0x55aa55aa;
p[3] = 0xcc33cc33;
__ISB();
for (i = 0; i < 4; i++) {
q = p[i];
if (q != test_pattern_val[i]) {
/* MSG("RW ERROR 0x%x != 0x%x\r\n", i, q); */
return ERROR;
}
}
/* clear PSRAM 1M Byte */
for (i = 0; i < TEST_MEMORY_SIZE; i++) {
p[i] = 0xffffffff;
}
/* check PSRAM 1M Byte */
for (i = 0; i < TEST_MEMORY_SIZE; i++) {
p[i] = i;
}
for (i = 0; i < TEST_MEMORY_SIZE; i++) {
q = p[i];
if (q != i) {
/* MSG("RW ERROR 0x%x != 0x%x\r\n", i, q); */
return ERROR;
}
}
return SUCCESS;
}
/****************************************************************************/ /**
* @brief x8 psram calibration
*
* @param psram_dqs_win_num
*
* @return uint16_t
*
*******************************************************************************/
static uint16_t hal_boot2_x8_psram_calibration(int32_t *psram_dqs_win_num)
{
int16_t psram_id = 0, before_ef = 0;
int32_t left_flag = 0, right_flag = 0, c_val = 0;
int32_t dqs_win_min = 16, dqs_win_max = 0;
uint16_t dqs_val[] = {
0x8000,
0xC000,
0xE000,
0xF000,
0xF800,
0xFC00,
0xFE00,
0xFF00,
0xFF80,
0xFFC0,
0xFFE0,
0xFFF0,
0xFFF8,
0xFFFC,
0xFFFE,
0xFFFF,
};
#ifdef CONFIG_DEBUG
printf("r ef:0x%08lx\r\n", g_efuse_cfg.psram_dqs_cfg);
#endif
before_ef = g_efuse_cfg.psram_dqs_cfg;
if ((g_efuse_cfg.psram_dqs_cfg & (0x1000)) &&
(((g_efuse_cfg.psram_dqs_cfg & 0x800) >> 11) == EF_Ctrl_Get_Trim_Parity(g_efuse_cfg.psram_dqs_cfg, 11))) {
left_flag = ((g_efuse_cfg.psram_dqs_cfg & (0xf0)) >> 0x4);
right_flag = (g_efuse_cfg.psram_dqs_cfg & (0xf));
c_val = ((left_flag + right_flag) >> 0x1);
*psram_dqs_win_num = right_flag - left_flag;
// printf("ef window: 0x%02x ~ 0x%02x; c_val: 0x%02x; dqs:0x%04x; code num:%d\r\n", left_flag, right_flag, c_val, dqs_val[c_val], (right_flag - left_flag));
psram_id = psram_winbond_init_dqs(PSRAM_WINBOND_BURST_LENGTH_64_BYTES, 0, PSRAM_WINBOND_6_CLOCKS_LATENCY, dqs_val[c_val]);
if ((psram_id != HAL_BOOT2_PSRAM_ID1_WINBOND_4MB) && (psram_id != HAL_BOOT2_PSRAM_ID2_WINBOND_32MB)) {
return ERROR;
}
} else {
for (uint32_t dqs_index = 0; dqs_index < 16; dqs_index++) {
psram_id = psram_winbond_init_dqs(PSRAM_WINBOND_BURST_LENGTH_64_BYTES, 0, PSRAM_WINBOND_6_CLOCKS_LATENCY, dqs_val[dqs_index]);
// #if (!CONFIG_BUILD_TYPE)
// printf("psram id:%04x\r\n", psram_id);
// #endif
if ((psram_id == HAL_BOOT2_PSRAM_ID1_WINBOND_4MB) || (psram_id == HAL_BOOT2_PSRAM_ID2_WINBOND_32MB)) {
if (psram_rw_check() == SUCCESS) {
if (dqs_index < dqs_win_min) {
dqs_win_min = dqs_index;
dqs_win_max = dqs_index;
} else if (dqs_index > dqs_win_max) {
dqs_win_max = dqs_index;
}
}
}
}
left_flag = dqs_win_min;
right_flag = dqs_win_max;
c_val = ((left_flag + right_flag) >> 1);
// printf("window: 0x%02x ~ 0x%02x; c_val: 0x%02x; dqs:0x%04x; code num:%d\r\n", left_flag, right_flag, c_val, dqs_val[c_val], (right_flag - left_flag));
g_efuse_cfg.psram_dqs_cfg = (((left_flag << 0x4) | (right_flag)) & (0xff));
if (EF_Ctrl_Get_Trim_Parity(g_efuse_cfg.psram_dqs_cfg, 11)) {
g_efuse_cfg.psram_dqs_cfg = ((0x1800) | (g_efuse_cfg.psram_dqs_cfg));
} else {
g_efuse_cfg.psram_dqs_cfg = ((0x1000) | (g_efuse_cfg.psram_dqs_cfg));
}
#ifdef CONFIG_DEBUG
printf("c ef:0x%08lx\r\n", g_efuse_cfg.psram_dqs_cfg);
/* printf("window: 0x%02x ~ 0x%02x; c_val: 0x%02x; dqs:0x%08x; code num:%d\r\n", left_flag, right_flag, c_val, dqs_val[c_val], (right_flag - left_flag)); */
#endif
*psram_dqs_win_num = right_flag - left_flag;
if (((*psram_dqs_win_num) <= 4) || ((*psram_dqs_win_num) > 0xf)) {
return ERROR;
}
psram_id = psram_winbond_init_dqs(PSRAM_WINBOND_BURST_LENGTH_64_BYTES, 0, PSRAM_WINBOND_6_CLOCKS_LATENCY, dqs_val[c_val]);
if ((psram_id != HAL_BOOT2_PSRAM_ID1_WINBOND_4MB) && (psram_id != HAL_BOOT2_PSRAM_ID2_WINBOND_32MB)) {
return ERROR;
}
/* to do write efuse psram dqs delay */
if (!(before_ef & 0x1fff)) {
// EF_Ctrl_Write_Psram_Trim((Efuse_Psram_Trim_Type *)&g_efuse_cfg.psram_dqs_cfg, ENABLE);
}
}
return psram_id;
}
/****************************************************************************/ /**
* @brief customer init
*
* @param custom_param
*
* @return ret
*
*******************************************************************************/
uint32_t hal_boot2_custom(void *custom_param)
{
uint16_t ret = 0;
int32_t psram_dqs_win_num = 0;
if (((g_efuse_cfg.dev_info & HAL_BOOT2_PSRAM_INFO_MASK) >> HAL_BOOT2_PSRAM_INFO_POS) != 0) {
_bflb_init_psram_gpio();
GLB_Set_PSRAMB_CLK_Sel(ENABLE, GLB_PSRAMB_EMI_WIFIPLL_320M, 0);
/* psram init*/
psram_winbond_init_dqs(PSRAM_WINBOND_BURST_LENGTH_64_BYTES, 0, PSRAM_WINBOND_6_CLOCKS_LATENCY, 0xffc0);
Tzc_Sec_PSRAMB_Access_Release();
ret = hal_boot2_x8_psram_calibration(&psram_dqs_win_num);
/* Flush i-cache in case branch prediction logic is wrong when
psram is not inited by hal_boot2_custom but cpu has already prefetch psram */
__ISB();
if (ret == ERROR) {
while (1) {
printf("psram error:%d\r\n", (int)psram_dqs_win_num);
arch_delay_ms(500);
}
}
printf("psram suss:%d \r\n", (int)psram_dqs_win_num);
}
return ret;
}
/****************************************************************************/ /**
* @brief get efuse Boot2 config
*
* @param g_efuse_cfg
*
* @return None
*
*******************************************************************************/
void hal_boot2_get_efuse_cfg(boot2_efuse_hw_config *efuse_cfg)
{
uint32_t timeout_cnt = 0;
uint32_t i = 0;
struct boot_efuse_sw_cfg0_t sw_cfg0;
struct boot_efuse_sw_cfg1_t sw_cfg1;
/* #define EF_CTRL_LOAD_BEFORE_READ_R0 in ef_ctrl to speed up */
EF_Ctrl_Load_Efuse_R0();
while (EF_Ctrl_AutoLoad_Done() != SET && timeout_cnt < 80) {
arch_delay_us(1);
timeout_cnt++;
}
/* get hw cfg (signature and aes type) */
EF_Ctrl_Read_Secure_Boot((EF_Ctrl_SF_AES_Type *)efuse_cfg->encrypted);
for (i = 0; i < HAL_BOOT2_CPU_GROUP_MAX; i++) {
if (efuse_cfg->encrypted[i] == EF_CTRL_SF_AES_192) {
efuse_cfg->encrypted[i] = SF_CTRL_AES_192BITS + 1;
} else if (efuse_cfg->encrypted[i] == EF_CTRL_SF_AES_256) {
efuse_cfg->encrypted[i] = SF_CTRL_AES_256BITS + 1;
}
}
/* get sw uasge 0 */
EF_Ctrl_Read_Sw_Usage(0, (uint32_t *)&sw_cfg0);
/* get sw uasge 1 */
EF_Ctrl_Read_Sw_Usage(1, (uint32_t *)&sw_cfg1);
for (i = 0; i < HAL_BOOT2_CPU_GROUP_MAX; i++) {
efuse_cfg->sign[i] = ((struct boot_efuse_sw_cfg0_t)sw_cfg0).sign_cfg;
}
for (i = 1; i < HAL_BOOT2_CPU_GROUP_MAX; i++) {
efuse_cfg->encrypted[i] = EF_CTRL_SF_AES_NONE;
}
efuse_cfg->hbn_check_sign = (uint8_t)(sw_cfg0.hbn_check_sign);
efuse_cfg->sf_pin_cfg = (uint8_t)(sw_cfg0.sf_pin_cfg);
efuse_cfg->uart_download_cfg = (uint8_t)(sw_cfg1.uart_download_cfg);
efuse_cfg->keep_dbg_port_closed = (uint8_t)(sw_cfg0.keep_dbg_port_closed);
efuse_cfg->boot_pin_cfg = (uint8_t)(sw_cfg0.boot_pin_cfg);
// /* get psram dqs delay info */
// EF_Ctrl_Read_Psram_Trim((Efuse_Psram_Trim_Type *)&efuse_cfg->psram_dqs_cfg);
/* get device info */
//EF_Ctrl_Read_Device_Info((Efuse_Device_Info_Type *)&efuse_cfg->dev_info);
bflb_ef_ctrl_get_device_info((bflb_efuse_device_info_type *)&efuse_cfg->dev_info);
/* get chip id */
EF_Ctrl_Read_Chip_ID(efuse_cfg->chip_id);
/* get public key hash */
EF_Ctrl_Read_AES_Key(0, (uint32_t *)efuse_cfg->pk_hash_cpu0, HAL_BOOT2_PK_HASH_SIZE / 4);
//EF_Ctrl_Read_AES_Key(8, (uint32_t *)efuse_cfg->pk_hash_cpu1, HAL_EFUSE_PK_HASH_SIZE / 4);
}
/****************************************************************************/ /**
* @brief reset sec eng module
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_boot2_reset_sec_eng(void)
{
GLB_AHB_MCU_Software_Reset(GLB_AHB_MCU_SW_SEC_ENG);
GLB_Set_PKA_CLK_Sel(GLB_PKA_CLK_MCU_MUXPLL_160M);
}
/****************************************************************************/ /**
* @brief system soft reset
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_boot2_sw_system_reset(void)
{
GLB_SW_System_Reset();
}
/****************************************************************************/ /**
* @brief set power down sleep status flag
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_boot2_set_psmode_status(uint32_t flag)
{
HBN_Set_Status_Flag(flag);
}
/****************************************************************************/ /**
* @brief get power down sleep status flag
*
* @param None
*
* @return flag
*
*******************************************************************************/
uint32_t hal_boot2_get_psmode_status(void)
{
return HBN_Get_Status_Flag();
}
/****************************************************************************/ /**
* @brief get user fw flag
*
* @param None
*
* @return flag
*
*******************************************************************************/
uint32_t hal_boot2_get_user_fw(void)
{
return BL_RD_WORD(HBN_BASE + HBN_RSV0_OFFSET);
}
/****************************************************************************/ /**
* @brief clear user fw flag
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_boot2_clr_user_fw(void)
{
uint32_t *p = (uint32_t *)(HBN_BASE + HBN_RSV0_OFFSET);
*p = 0;
}
/****************************************************************************/ /**
* @brief sboot finish
*
* @param None
*
* @return None
*
*******************************************************************************/
void ATTR_TCM_SECTION hal_boot2_sboot_finish(void)
{
}
/****************************************************************************/ /**
* @brief init uart gpio
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_boot2_uart_gpio_init(void)
{
GLB_GPIO_Type pinList[] = { GLB_GPIO_PIN_21, GLB_GPIO_PIN_22 };
GLB_GPIO_Func_Init(GPIO_FUN_MD_UART, pinList, sizeof(pinList) / sizeof(pinList[0]));
}
/****************************************************************************/ /**
* @brief init uart tx gpio
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_boot2_debug_uart_gpio_init(void)
{
GLB_GPIO_Cfg_Type cfg;
cfg.pullType = GPIO_PULL_NONE;
cfg.drive = 0;
cfg.smtCtrl = 1;
cfg.gpioPin = GLB_GPIO_PIN_21;
cfg.gpioFun = GPIO_FUN_MD_UART;
cfg.gpioMode = GPIO_MODE_OUTPUT;
GLB_GPIO_Init(&cfg);
}
#if HAL_BOOT2_SUPPORT_USB_IAP
/****************************************************************************/ /**
* @brief init usb gpio
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_boot2_debug_usb_port_init(void)
{
}
#endif
/****************************************************************************/ /**
* @brief deinit uart gpio
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_boot2_debug_uart_gpio_deinit(void)
{
}
/****************************************************************************/ /**
* @brief Check bootheader crc
*
* @param data: bootheader data pointer
*
* @return boot_error_code type
*
*******************************************************************************/
static uint32_t hal_boot_check_bootheader(struct hal_bootheader_t *header)
{
uint32_t crc_pass = 0;
uint32_t crc;
if (header->basic_cfg.crc_ignore == 1 && header->crc32 == HAL_BOOT2_DEADBEEF_VAL) {
//MSG("Crc ignored\r\n");
crc_pass = 1;
} else {
crc = BFLB_Soft_CRC32((uint8_t *)header, sizeof(struct hal_bootheader_t) - sizeof(header->crc32));
if (header->crc32 == crc) {
crc_pass = 1;
}
}
return crc_pass;
}
/****************************************************************************/ /**
* @brief Check if the input public key is the same as burned in the efuse
*
* @param g_boot_img_cfg: Boot image config pointer
* @param data: Image data pointer
*
* @return boot_error_code type
*
*******************************************************************************/
int32_t hal_boot_parse_bootheader(boot2_image_config *boot_img_cfg, uint8_t *data)
{
struct hal_bootheader_t *header = (struct hal_bootheader_t *)data;
uint32_t crc_pass = 0;
uint32_t i = 0;
uint32_t *phash = (uint32_t *)header->basic_cfg.hash;
crc_pass = hal_boot_check_bootheader(header);
if (!crc_pass) {
//MSG_ERR("bootheader crc error\r\n");
//blsp_dump_data((uint8_t *)&crc, 4);
return 0x0204;
}
if (header->basic_cfg.notload_in_bootrom) {
return 0x0202;
}
/* Get which CPU's img it is*/
for (i = 0; i < HAL_BOOT2_CPU_MAX; i++) {
if (0 == memcmp((void *)&header->magiccode, HAL_BOOT2_CPU0_MAGIC,
sizeof(header->magiccode))) {
break;
} else if (0 == memcmp((void *)&header->magiccode, HAL_BOOT2_CPU1_MAGIC,
sizeof(header->magiccode))) {
break;
}
}
if (i == HAL_BOOT2_CPU_MAX) {
/* No cpu img magic match */
//MSG_ERR("Magic code error\r\n");
return 0x0203;
}
if (boot_img_cfg == NULL) {
return 0;
}
boot_img_cfg->pk_src = i;
boot_img_cfg->img_valid = 0;
arch_memcpy_fast(&boot_img_cfg->basic_cfg, &header->basic_cfg,
sizeof(header->basic_cfg));
/* Check encrypt and sign match*/
if (g_efuse_cfg.encrypted[i] != boot_img_cfg->basic_cfg.encrypt_type) {
if (boot_img_cfg->basic_cfg.xts_mode == 0) {
//("Encrypt not fit\r\n");
return 0x0205;
}
}
if (g_efuse_cfg.sign[i] != boot_img_cfg->basic_cfg.sign_type) {
//MSG_ERR("sign not fit\r\n");
boot_img_cfg->basic_cfg.sign_type = g_efuse_cfg.sign[i];
return 0x0206;
}
if (g_ps_mode == 1 && (!g_efuse_cfg.hbn_check_sign)) {
/* In HBN Mode, if user select to ignore hash and sign*/
boot_img_cfg->basic_cfg.hash_ignore = 1;
} else if ((boot_img_cfg->basic_cfg.hash_ignore == 1 && *phash != HAL_BOOT2_DEADBEEF_VAL) ||
g_efuse_cfg.sign[i] != 0) {
/* If signed or user not really want to ignore, hash can't be ignored*/
boot_img_cfg->basic_cfg.hash_ignore = 0;
}
if (g_user_hash_ignored) {
boot_img_cfg->basic_cfg.hash_ignore = 1;
}
if (boot_img_cfg->basic_cfg.img_len_cnt == 0) {
return 0x0207;
}
arch_memcpy_fast(&boot_img_cfg->cpu_cfg, &header->cpu_cfg,
sizeof(header->cpu_cfg));
return 0;
}
/****************************************************************************/ /**
* @brief clean cache
*
* @param None
*
* @return None
*
*******************************************************************************/
void ATTR_TCM_SECTION hal_boot2_clean_cache(void)
{
L1C_DCache_Clean_Invalid_All();
L1C_ICache_Invalid_All();
}
/****************************************************************************/ /**
* @brief set cache
*
* @param cont_read: contiune mode
* @param boot_img_cfg: cache param
*
* @return 0 suss,other faild
*
*******************************************************************************/
int32_t ATTR_TCM_SECTION hal_boot2_set_cache(uint8_t cont_read, boot2_image_config *boot_img_cfg)
{
return bflb_flash_set_cache(cont_read, boot_img_cfg->cpu_cfg[0].cache_enable,
boot_img_cfg->cpu_cfg[0].cache_way_dis,
boot_img_cfg->basic_cfg.group_image_offset);
}
/****************************************************************************/ /**
* @brief get the ram image name and count
*
* @param img_name: ram image name in partition
* @param ram_img_cnt: ram image count that support boot from flash
*
* @return None
*
*******************************************************************************/
void hal_boot2_get_ram_img_cnt(char *img_name[], uint32_t *ram_img_cnt)
{
*ram_img_cnt = 0;
//img_name[0] = "lp_fw";
//img_name[1] = "FW";
}
/****************************************************************************/ /**
* @brief get the ram image info
*
* @param data: bootheader information
* @param image_offset: ram image offset in flash(from of bootheader)
* @param img_len: ram image length
* @param hash: pointer to hash pointer
*
* @return None
*
*******************************************************************************/
void hal_boot2_get_img_info(uint8_t *data, uint32_t *image_offset, uint32_t *img_len, uint8_t **hash)
{
struct hal_bootheader_t *header = (struct hal_bootheader_t *)data;
uint32_t crc_pass = 0;
*img_len = 0;
uint8_t *phash = *hash;
uint8_t hash_ignore = 1;
crc_pass = hal_boot_check_bootheader(header);
if (!crc_pass) {
return;
}
if (0 != memcmp((void *)&header->magiccode, HAL_BOOT2_CPU0_MAGIC, sizeof(header->magiccode)) &&
0 != memcmp((void *)&header->magiccode, HAL_BOOT2_CPU1_MAGIC, sizeof(header->magiccode))) {
return;
}
/* for ram image, it always download in iot tab, so
it share the same group with core 0 but use different image offset and
boot entry */
*image_offset = 4096 * 1; //bootheader->basic_cfg.group_image_offset;
*img_len = header->basic_cfg.img_len_cnt;
if (g_ps_mode == 1 && (!g_efuse_cfg.hbn_check_sign)) {
/* In HBN Mode, if user select to ignore hash and sign*/
hash_ignore = 1;
} else if ((header->basic_cfg.hash_ignore == 1 && header->basic_cfg.hash[0] != HAL_BOOT2_DEADBEEF_VAL) ||
g_efuse_cfg.sign[0] != 0) {
/* If signed or user not really want to ignore, hash can't be ignored*/
hash_ignore = 0;
}
if (hash_ignore == 1) {
*hash = NULL;
} else {
memcpy(phash, header->basic_cfg.hash, sizeof(header->basic_cfg.hash));
}
}
/****************************************************************************/ /**
* @brief release other cpu to boot up
*
* @param core: core number
* @param boot_addr: boot address
*
* @return None
*
*******************************************************************************/
void ATTR_TCM_SECTION hal_boot2_release_cpu(uint32_t core, uint32_t boot_addr)
{
}
/****************************************************************************/ /**
* @brief get xip address according to flash addr
*
* @param flash_addr: flash address
*
* @return XIP Address
*
*******************************************************************************/
uint32_t hal_boot2_get_xip_addr(uint32_t flash_addr)
{
uint32_t img_offset = SF_Ctrl_Get_Flash_Image_Offset(0, SF_CTRL_FLASH_BANK0);
if (flash_addr >= img_offset) {
return BL616_FLASH_XIP_BASE + (flash_addr - img_offset);
} else {
return 0;
}
}
/****************************************************************************/ /**
* @brief get multi-group count
*
* @param None
*
* @return 1 for multi-group 0 for not
*
*******************************************************************************/
uint32_t hal_boot2_get_grp_count(void)
{
return 1;
}
/****************************************************************************/ /**
* @brief get cpu count
*
* @param None
*
* @return 1 for multi-group 0 for not
*
*******************************************************************************/
uint32_t hal_boot2_get_cpu_count(void)
{
return 1;
}
/****************************************************************************/ /**
* @brief get cpu count
*
* @param None
*
* @return 1 for multi-group 0 for not
*
*******************************************************************************/
uint32_t ATTR_TCM_SECTION hal_boot2_get_feature_flag(void)
{
return HAL_BOOT2_SP_FLAG;
}
/****************************************************************************/ /**
* @brief get boot header offset
*
* @param None
*
* @return bootheader offset
*
*******************************************************************************/
uint32_t hal_boot2_get_bootheader_offset(void)
{
return 0x00;
}
/****************************************************************************/ /**
* @brief config reboot option
*
* @param None
*
* @return None
*
*******************************************************************************/
void hal_reboot_config(hal_reboot_cfg_t rbot)
{
switch (rbot) {
case HAL_REBOOT_AS_BOOTPIN:
HBN_Set_User_Boot_Config(0);
break;
case HAL_REBOOT_FROM_INTERFACE:
HBN_Set_User_Boot_Config(1);
break;
case HAL_REBOOT_FROM_MEDIA:
HBN_Set_User_Boot_Config(2);
break;
default:
HBN_Set_User_Boot_Config(0);
break;
}
}

View file

@ -0,0 +1,322 @@
/**
* *****************************************************************************
* @file bflb_port_boot2.h
* @version 0.1
* @date 2022-11-23
* @brief
* *****************************************************************************
* @attention
*
* <h2><center>&copy; 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.
*
* *****************************************************************************
*/
#ifndef __BFLB_PORT_BOOT2_H__
#define __BFLB_PORT_BOOT2_H__
#include "bl616_sflash.h"
#include "bl616_glb.h"
#include "bl616_common.h"
#define BL_TCM_BASE BL616_TCM_BASE
#define BL_SYS_CLK_PLL GLB_SYS_CLK_PLL160M
#define BL_SFLASH_CLK GLB_SFLASH_CLK_80M
#define HAL_PLL_CFG_MAGICCODE "PCFG"
#define HAL_BOOT2_PK_HASH_SIZE 256 / 8
#define HAL_BOOT2_IMG_HASH_SIZE 256 / 8
#define HAL_BOOT2_ECC_KEYXSIZE 256 / 8
#define HAL_BOOT2_ECC_KEYYSIZE 256 / 8
#define HAL_BOOT2_SIGN_MAXSIZE (2048 / 8)
#define HAL_BOOT2_DEADBEEF_VAL 0xdeadbeef
#define HAL_BOOT2_CPU0_MAGIC "BFNP"
#define HAL_BOOT2_CPU1_MAGIC "BFAP"
#define HAL_BOOT2_CP_FLAG 0x02
#define HAL_BOOT2_MP_FLAG 0x01
#define HAL_BOOT2_SP_FLAG 0x00
#define HAL_BOOT2_SUPPORT_DECOMPRESS 1 /* 1 support decompress, 0 not support */
#define HAL_BOOT2_SUPPORT_USB_IAP 0 /* 1 support decompress, 0 not support */
#define HAL_BOOT2_SUPPORT_EFLASH_LOADER_RAM 0 /* 1 support decompress, 0 not support */
#define HAL_BOOT2_SUPPORT_EFLASH_LOADER_FLASH 0 /* 1 support decompress, 0 not support */
#define HAL_BOOT2_SUPPORT_SIGN_ENCRYPT 1 /* 1 support sign and encrypt, 0 not support */
#define HAL_BOOT2_CPU_GROUP_MAX 1
#define HAL_BOOT2_CPU_MAX 1
#define HAL_BOOT2_RAM_IMG_COUNT_MAX 0
#define HAL_BOOT2_FW_IMG_OFFSET_AFTER_HEADER 4 * 1024
#define HAL_BOOT2_MFG_START_REQUEST_OFFSET 8 * 1024
#define HAL_BOOT2_PSRAM_ID1_WINBOND_4MB 0x5f
#define HAL_BOOT2_PSRAM_ID2_WINBOND_32MB 0xe86
#define HAL_BOOT2_PSRAM_INFO_MASK (0x3000000)
#define HAL_BOOT2_PSRAM_INFO_POS (24)
typedef enum {
HAL_REBOOT_AS_BOOTPIN, /*!< reboot as bootpin level */
HAL_REBOOT_FROM_INTERFACE, /*!< reboot from interface, download mode */
HAL_REBOOT_FROM_MEDIA, /*!< reboot from media, running mode */
HAL_REBOOT_MAX /*!< reboot max value */
} hal_reboot_cfg_t;
struct __attribute__((packed, aligned(4))) boot_efuse_sw_cfg0_t {
uint32_t bootrom_protect : 1; /* ef_sw_usage_0 bit [0] */
uint32_t uart_log_disable : 1; /* ef_sw_usage_0 bit [1] */
uint32_t boot_pin_cfg : 1; /* ef_sw_usage_0 bit [2] */
uint32_t mediaboot_disable : 1; /* ef_sw_usage_0 bit [3] */
uint32_t uartboot_disable : 1; /* ef_sw_usage_0 bit [4] */
uint32_t usbboot_enable : 1; /* ef_sw_usage_0 bit [5] */
uint32_t uart_log_reopen : 1; /* ef_sw_usage_1 bit [6] */
uint32_t sign_cfg : 1; /* ef_sw_usage_0 bit [7] */
uint32_t dcache_disable : 1; /* ef_sw_usage_0 bit [8] */
uint32_t jtag_cfg : 3; /* ef_sw_usage_0 bit [11:9] */
uint32_t fix_key_sel : 1; /* ef_sw_usage_0 bit [12] */
uint32_t sdh_en : 1; /* ef_sw_usage_1 bit [13] */
uint32_t sf_pin_cfg : 6; /* ef_sw_usage_0 bit [19:14] */
uint32_t boot_pin_dly : 2; /* ef_sw_usage_0 bit [21:20] */
uint32_t power_trim_disable : 1; /* ef_sw_usage_0 bit [22] */
uint32_t trim_enable : 1; /* ef_sw_usage_0 bit [23] */
uint32_t flash_power_delay : 2; /* ef_sw_usage_0 bit [25:24] */
uint32_t boot_level_revert : 1; /* ef_sw_usage_0 bit [26] */
uint32_t tz_boot : 1; /* ef_sw_usage_0 bit [27] */
uint32_t usb_desc_cfg : 1; /* ef_sw_usage_0 bit [28] */
uint32_t hbn_check_sign : 1; /* ef_sw_usage_0 bit [29] */
uint32_t keep_dbg_port_closed : 1; /* ef_sw_usage_0 bit [30] */
uint32_t hbn_jump_disable : 1; /* ef_sw_usage_0 bit [31] */
};
struct __attribute__((packed, aligned(4))) boot_efuse_sw_cfg1_t {
uint32_t xtal_type : 3; /* ef_sw_usage_1 bit [2:0] */
uint32_t wifipll_pu : 1; /* ef_sw_usage_1 bit [3] */
uint32_t aupll_pu : 1; /* ef_sw_usage_1 bit [4] */
uint32_t product_id : 2; /* ef_sw_usage_1 bit [6:5] */
uint32_t sdioboot_enable : 1; /* ef_sw_usage_1 bit [7] */
uint32_t mcu_clk : 3; /* ef_sw_usage_1 bit [10:8] */
uint32_t mcu_clk_div : 1; /* ef_sw_usage_1 bit [11] */
uint32_t mcu_pbclk_div : 2; /* ef_sw_usage_1 bit [13:12] */
uint32_t uart_download_cfg : 2; /* ef_sw_usage_1 bit [15:14] */
uint32_t pin_func_0_init : 1; /* ef_sw_usage_1 bit [16] */
uint32_t always_uart : 1; /* ef_sw_usage_1 bit [17] */
uint32_t abt_shake_hands_dis : 1; /* ef_sw_usage_1 bit [18] */
uint32_t no_hd_boot_en : 1; /* ef_sw_usage_1 bit [19] */
uint32_t ocram_way_dis_cfg : 2; /* ef_sw_usage_1 bit [21:20] */
uint32_t xtal_level_revert : 1; /* ef_sw_usage_1 bit [22] */
uint32_t flash_clk_type : 3; /* ef_sw_usage_1 bit [25:23] */
uint32_t flash_clk_div : 1; /* ef_sw_usage_1 bit [26] */
uint32_t ldo18io_cfg_dis : 1; /* ef_sw_usage_1 bit [27] */
uint32_t bootlog_pin_cfg : 1; /* ef_sw_usage_1 bit [28] */
uint32_t abt_offset : 1; /* ef_sw_usage_1 bit [29] */
uint32_t boot_pull_cfg : 1; /* ef_sw_usage_1 bit [30] */
uint32_t usb_if_int_disable : 1; /* ef_sw_usage_1 bit [31] */
};
typedef struct
{
uint8_t encrypted[HAL_BOOT2_CPU_GROUP_MAX];
uint8_t sign[HAL_BOOT2_CPU_GROUP_MAX];
uint8_t hbn_check_sign;
uint8_t rsvd[3];
uint8_t chip_id[8];
uint8_t pk_hash_cpu0[HAL_BOOT2_PK_HASH_SIZE];
uint8_t pk_hash_cpu1[HAL_BOOT2_PK_HASH_SIZE];
uint8_t uart_download_cfg;
uint8_t sf_pin_cfg;
uint8_t keep_dbg_port_closed;
uint8_t boot_pin_cfg;
uint32_t psram_dqs_cfg;
uint32_t dev_info;
} boot2_efuse_hw_config;
struct __attribute__((packed, aligned(4))) hal_flash_config {
uint32_t magicCode; /*'FCFG'*/
SPI_Flash_Cfg_Type cfg;
uint32_t crc32;
};
struct __attribute__((packed, aligned(4))) hal_sys_clk_config {
uint8_t xtal_type;
uint8_t mcu_clk;
uint8_t mcu_clk_div;
uint8_t mcu_bclk_div;
uint8_t mcu_pbclk_div;
uint8_t emi_clk;
uint8_t emi_clk_div;
uint8_t flash_clk_type;
uint8_t flash_clk_div;
uint8_t wifipll_pu;
uint8_t aupll_pu;
uint8_t rsvd0;
};
typedef struct {
uint32_t magiccode;
struct hal_sys_clk_config cfg;
uint32_t crc32;
} hal_pll_config;
struct __attribute__((packed, aligned(4))) hal_basic_cfg_t {
uint32_t sign_type : 2; /* [1: 0] for sign */
uint32_t encrypt_type : 2; /* [3: 2] for encrypt */
uint32_t key_sel : 2; /* [5: 4] key slot */
uint32_t xts_mode : 1; /* [6] for xts mode */
uint32_t aes_region_lock : 1; /* [7] rsvd */
uint32_t no_segment : 1; /* [8] no segment info */
uint32_t boot2_enable : 1; /* [9] boot2 enable */
uint32_t boot2_rollback : 1; /* [10] boot2 rollback */
uint32_t cpu_master_id : 4; /* [14: 11] master id */
uint32_t notload_in_bootrom : 1; /* [15] notload in bootrom */
uint32_t crc_ignore : 1; /* [16] ignore crc */
uint32_t hash_ignore : 1; /* [17] hash ignore */
uint32_t power_on_mm : 1; /* [18] power on mm */
uint32_t em_sel : 3; /* [21: 19] em_sel */
uint32_t cmds_en : 1; /* [22] command spliter enable */
uint32_t cmds_wrap_mode : 2; /* [24: 23] cmds wrap mode */
uint32_t cmds_wrap_len : 4; /* [28: 25] cmds wrap len */
uint32_t icache_invalid : 1; /* [29] icache invalid */
uint32_t dcache_invalid : 1; /* [30] dcache invalid */
uint32_t fpga_halt_release : 1; /* [31] FPGA halt release function */
uint32_t group_image_offset; /* flash controller offset */
uint32_t aes_region_len; /* aes region length */
uint32_t img_len_cnt; /* image length or segment count */
uint32_t hash[8]; /* hash of the image */
};
struct __attribute__((packed, aligned(4))) hal_cpu_cfg_t {
uint8_t config_enable; /* coinfig this cpu */
uint8_t halt_cpu; /* halt this cpu */
uint8_t cache_enable : 1; /* cache setting */
uint8_t cache_wa : 1; /* cache setting */
uint8_t cache_wb : 1; /* cache setting */
uint8_t cache_wt : 1; /* cache setting */
uint8_t cache_way_dis : 4; /* cache setting */
uint8_t rsvd;
uint32_t image_address_offset; /* image address on flash */
uint32_t boot_entry; /* entry point of the m0 image */
uint32_t msp_val; /* msp value */
};
struct __attribute__((packed, aligned(4))) hal_patch_cfg_t {
uint32_t addr;
uint32_t value;
};
struct __attribute__((packed, aligned(4))) hal_bootheader_t {
uint32_t magiccode;
uint32_t rivison;
struct hal_flash_config flashCfg;
hal_pll_config clkCfg;
struct hal_basic_cfg_t basic_cfg;
struct hal_cpu_cfg_t cpu_cfg[HAL_BOOT2_CPU_MAX];
uint32_t boot2_pt_table_0; /* address of partition table 0 */
uint32_t boot2_pt_table_1; /* address of partition table 1 */
uint32_t flashCfgTableAddr; /* address of flashcfg table list */
uint32_t flashCfgTableLen; /* flashcfg table list len */
struct hal_patch_cfg_t patch_on_read[3]; /* do patch when read flash */
struct hal_patch_cfg_t patch_on_jump[3]; /* do patch when jump */
uint32_t rsvd;
uint32_t crc32;
};
typedef struct
{
uint8_t img_valid;
uint8_t pk_src;
uint8_t rsvd[2];
struct hal_basic_cfg_t basic_cfg;
struct hal_cpu_cfg_t cpu_cfg[HAL_BOOT2_CPU_MAX];
uint8_t aes_iv[16 + 4]; //iv in boot header
uint8_t eckye_x[HAL_BOOT2_ECC_KEYXSIZE]; //ec key in boot header
uint8_t eckey_y[HAL_BOOT2_ECC_KEYYSIZE]; //ec key in boot header
uint8_t eckey_x2[HAL_BOOT2_ECC_KEYXSIZE]; //ec key in boot header
uint8_t eckey_y2[HAL_BOOT2_ECC_KEYYSIZE]; //ec key in boot header
uint8_t signature[HAL_BOOT2_SIGN_MAXSIZE]; //signature in boot header
uint8_t signature2[HAL_BOOT2_SIGN_MAXSIZE]; //signature in boot header
} boot2_image_config;
extern boot2_efuse_hw_config g_efuse_cfg;
extern uint8_t g_ps_mode;
extern uint32_t g_user_hash_ignored;
extern struct device *dev_check_hash;
uint32_t hal_boot2_custom(void *custom_param);
uint32_t hal_boot2_get_psmode_status(void);
uint32_t hal_boot2_get_user_fw(void);
uint32_t hal_boot2_get_xip_addr(uint32_t flash_addr);
uint32_t hal_boot2_get_grp_count(void);
uint32_t hal_boot2_get_cpu_count(void);
uint32_t hal_boot2_get_feature_flag(void);
uint32_t hal_boot2_get_bootheader_offset(void);
int32_t hal_boot2_get_clk_cfg(hal_pll_config *cfg);
int32_t hal_boot_parse_bootheader(boot2_image_config *boot_img_cfg, uint8_t *data);
int32_t hal_boot2_set_cache(uint8_t cont_read, boot2_image_config *boot_img_cfg);
void hal_reboot_config(hal_reboot_cfg_t rbot);
void hal_boot2_init_clock(void);
void hal_boot2_get_ram_img_cnt(char *img_name[], uint32_t *ram_img_cnt);
void hal_boot2_get_img_info(uint8_t *data, uint32_t *image_offset, uint32_t *img_len, uint8_t **hash);
void hal_boot2_release_cpu(uint32_t core, uint32_t boot_addr);
void hal_boot2_reset_sec_eng(void);
void hal_boot2_sw_system_reset(void);
void hal_boot2_set_psmode_status(uint32_t flag);
void hal_boot2_clr_user_fw(void);
void hal_boot2_get_efuse_cfg(boot2_efuse_hw_config *efuse_cfg);
void hal_boot2_sboot_finish(void);
void hal_boot2_uart_gpio_init(void);
void hal_boot2_debug_uart_gpio_init(void);
void hal_boot2_debug_uart_gpio_deinit(void);
void hal_boot2_clean_cache(void);
#endif

View file

@ -0,0 +1,254 @@
/****************************************************************************************
* @file flash.ld
*
* @brief This file is the link script file (gnuarm or armgcc).
*
* Copyright (C) BouffaloLab 2021
*
****************************************************************************************
*/
/* configure the CPU type */
OUTPUT_ARCH( "riscv" )
/* link with the standard c library */
INPUT(-lc)
/* link with the standard GCC library */
INPUT(-lgcc)
/* configure the entry point */
ENTRY(__start)
StackSize = 0x0400; /* 1KB */
HeapMinSize = 0x1000; /* 4KB */
/* Not pass para to app since it will get itself */
PROVIDE(__boot2_pass_param_addr = 0);
MEMORY
{
xip_memory (rx) : ORIGIN = 0xA0000000, LENGTH = 48K
itcm_memory (rx) : ORIGIN = 0x62FC0000, LENGTH = 60K
dtcm_memory (rx) : ORIGIN = 0x62FCF000, LENGTH = 4K
nocache_ram_memory (!rx) : ORIGIN = 0x22FD0000, LENGTH = 84K
ram_memory (!rx) : ORIGIN = 0x62FE5000, LENGTH = 44K
}
SECTIONS
{
PROVIDE(__metal_chicken_bit = 0);
.text :
{
. = ALIGN(4);
__text_code_start__ = .;
KEEP (*(SORT_NONE(.init)))
*(.text)
*(.text.*)
/* section information for shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
/* section information for usb desc */
. = ALIGN(4);
_usb_desc_start = .;
KEEP(*(usb_desc))
. = ALIGN(4);
_usb_desc_end = .;
/*put .rodata**/
*(EXCLUDE_FILE( *bl616_glb*.o* \
*bl616_pds*.o* \
*bl616_common*.o* \
*bl616_sf_cfg*.o* \
*bl616_sf_ctrl*.o* \
*bl616_sflash*.o* \
*bl616_xip_sflash*.o* \
*bl616_ef_ctrl*.o* \
*bl616_romapi_patch*.o*) .rodata*)
*(.srodata)
*(.srodata.*)
. = ALIGN(4);
__text_code_end__ = .;
} > xip_memory
. = ALIGN(4);
__itcm_load_addr = .;
.itcm_region : AT (__itcm_load_addr)
{
. = ALIGN(4);
__tcm_code_start__ = .;
*(.tcm_code.*)
*(.tcm_const.*)
*(.sclock_rlt_code.*)
*(.sclock_rlt_const.*)
*bl616_glb*.o*(.rodata*)
*bl616_pds*.o*(.rodata*)
*bl616_common*.o*(.rodata*)
*bl616_sf_cfg*.o*(.rodata*)
*bl616_sf_ctrl*.o*(.rodata*)
*bl616_sflash*.o*(.rodata*)
*bl616_xip_sflash*.o*(.rodata*)
*bl616_ef_ctrl*.o*(.rodata*)
*bl616_romapi_patch*.o*(.rodata*)
. = ALIGN(4);
__tcm_code_end__ = .;
} > itcm_memory
__dtcm_load_addr = __itcm_load_addr + SIZEOF(.itcm_region);
.dtcm_region : AT (__dtcm_load_addr)
{
. = ALIGN(4);
__tcm_data_start__ = .;
*(.tcm_data)
/* *finger_print.o(.data*) */
. = ALIGN(4);
__tcm_data_end__ = .;
} > dtcm_memory
/*************************************************************************/
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (NOLOAD):
{
. = ALIGN(0x4);
. = . + StackSize;
. = ALIGN(0x4);
} > dtcm_memory
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(dtcm_memory) + LENGTH(dtcm_memory);
PROVIDE( __freertos_irq_stack_top = __StackTop);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __tcm_data_end__, "region RAM overflowed with stack")
/*************************************************************************/
__nocache_ram_load_addr = __dtcm_load_addr + SIZEOF(.dtcm_region);
.nocache_ram_region (NOLOAD) : AT (__nocache_ram_load_addr)
{
. = ALIGN(4);
__nocache_ram_data_start__ = .;
*(.nocache_ram)
. = ALIGN(4);
__nocache_ram_data_end__ = .;
} > nocache_ram_memory
__system_ram_load_addr = __nocache_ram_load_addr + SIZEOF(.nocache_ram_region);
.system_ram_data_region : AT (__system_ram_load_addr)
{
. = ALIGN(4);
__system_ram_data_start__ = .;
*(.system_ram)
. = ALIGN(4);
__system_ram_data_end__ = .;
} > ram_memory
.system_ram_noinit_data_region (NOLOAD) :
{
. = ALIGN(4);
*(.system_ram_noinit)
. = ALIGN(4);
} > ram_memory
__ram_load_addr = __system_ram_load_addr + SIZEOF(.system_ram_data_region);
/* Data section */
RAM_DATA : AT (__ram_load_addr)
{
. = ALIGN(4);
__ram_data_start__ = .;
PROVIDE( __global_pointer$ = . + 0x800 );
*(.data)
*(.data.*)
*(.sdata)
*(.sdata.*)
*(.sdata2)
*(.sdata2.*)
. = ALIGN(4);
__ram_data_end__ = .;
} > ram_memory
__etext_final = (__ram_load_addr + SIZEOF (RAM_DATA));
ASSERT(__etext_final <= ORIGIN(xip_memory) + LENGTH(xip_memory), "code memory overflow")
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(.sbss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > ram_memory
.noinit_data (NOLOAD) :
{
. = ALIGN(4);
__noinit_data_start__ = .;
*(.noinit_data*)
. = ALIGN(4);
__noinit_data_end__ = .;
} > ram_memory
.nocache_noinit_ram_region (NOLOAD) :
{
. = ALIGN(4);
__nocache_ram_data_start__ = .;
*(.nocache_noinit_ram)
. = ALIGN(4);
__nocache_ram_data_end__ = .;
} > nocache_ram_memory
.heap (NOLOAD):
{
. = ALIGN(4);
__HeapBase = .;
/*__end__ = .;*/
/*end = __end__;*/
KEEP(*(.heap*))
. = ALIGN(4);
__HeapLimit = .;
} > ram_memory
__HeapLimit = ORIGIN(ram_memory) + LENGTH(ram_memory);
ASSERT(__HeapLimit - __HeapBase >= HeapMinSize, "heap region overflow")
}

View file

@ -0,0 +1,8 @@
set(CONFIG_VLIBC 0)
set(CONFIG_BFLOG 0)
set(CONFIG_XZ 1)
set(CONFIG_DEBUG 1)
set(CONFIG_ROMAPI 1)
set(CONFIG_VSNPRINTF_NANO 1)
set(CONFIG_GCC_OPTIMISE_LEVEL -Os)

View file

@ -0,0 +1,187 @@
/**
* @file main.c
* @brief
*
* Copyright (c) 2022 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
/*
* a0: compressed data pool
* a1: decompressed data pool
* a2: total lengeth of the compressed data file
*/
/* void unlz4(const void *aSource, void *aDestination, uint32_t FileLen); */
.func unlz4
.global unlz4
.type unlz4,%function
.align 6
.section .tcm_code.unlz4.text
unlz4:
addi sp, sp, -64 /* save fp and return-address */
sw ra, 60(sp)
sw s0, 56(sp)
/* addi s0, sp, 64 */ /* no frame pointer needed */
sw s1, 0(sp)
sw s2, 4(sp)
sw s3, 8(sp)
sw s4, 12(sp)
sw s5, 16(sp)
sw s6, 20(sp)
sw s7, 24(sp)
sw s8, 28(sp)
sw s9, 32(sp)
sw s10, 36(sp)
sw s11, 40(sp)
mv s0, a0
mv s1, a1
add s9, a2,a0 /* s9 = end of the compressed data */
addi s0, s0, 7 /* !!! unaligned access needed !!! */
addi s9, s9, -8 /* remove EoS and checksum */
loadConst: li s10, 0xf /* getLength */
li s11, 0xff /* getLengthLoop */
blockStart:
lw s2, 0(s0) /* get block length of compressed data */
/* !!! unaligned access needed !!! */
/* s2 = compressed data len of current block */
addi s0,s0,4 /* advance source pointer, s0 -> first token */
add s5,s2,s0 /* point a5 to end of compressed data */
getToken:
lbuia s6,(s0),1,0 /* get token */
/* advance source pointer */
srli s4,s6, 4 /* get literal length, keep token in a6 */
and s8,s6, s10 /* match len in token: low 4-bit */
beqz s4, getOffset /* jump forward if there are no literals */
getLiteralLen: /* if length is 15, then more length info follows */
bne s10,s4,gotLiteralLen/* jump forward if we have the complete length */
getLiteralLenLoop: lbuia s3,(s0),1,0 /* read another byte */
/* advance source pointer */
/* check if end reached */
add s4,s4,s3 /* add byte to length */
/* if 0xff, get next length byte */
beq s11,s3,getLiteralLenLoop
gotLiteralLen:
/* copy literal */
copy_literal:
lbuia s3, (s0), 1, 0
addi s4, s4, -1
sbia s3, (s1), 1, 0
beqz s4, copy_literal_done
lbuia s3, (s0), 1, 0
addi s4, s4, -1
sbia s3, (s1), 1, 0
bnez s4, copy_literal
copy_literal_done:
mv s2,s0 /* update index */
beq s5,s2,blockDone /* no match data for last token in block */
getOffset:
lhu s7, 0(s0) /* !!! unaligned access needed !!! */
addi s0, s0, 2
sub s2, s1, s7 /* subtract from destination; this will become the match position */
getMatchLen:
/* if length is 15, then more length info follows */
bne s10,s8,gotMatchLen /* jump forward if we have the complete length */
getMatchLenLoop: lbuia s3,(s0),1,0 /* read another byte */
/* advance source pointer */
/* check if end reached */
add s8,s8,s3 /* add byte to length */
/* if 0xff, get another match len byte */
beq s11,s3,getMatchLenLoop
gotMatchLen:
/* minimum match length is 4 bytes */
/* copy 4 bytes */
copy_4bytes:
lbuia s3, (s2), 1, 0
sbia s3, (s1), 1, 0
lbuia s3, (s2), 1, 0
sbia s3, (s1), 1, 0
lbuia s3, (s2), 1, 0
sbia s3, (s1), 1, 0
lbuia s3, (s2), 1, 0
sbia s3, (s1), 1, 0
beqz s8, copy_match_done
/* copy left match data */
copy_match:
lbuia s3, (s2), 1, 0
addi s8, s8, -1
sbia s3, (s1), 1, 0
bnez s8, copy_match
copy_match_done:
/* check if we've reached the end of the compressed data */
blt s0,s5,getToken /* if not, go get the next token */
blockDone:
blt s0,s9,blockStart /* there is another block of compressed data */
unlz4_exit:
lw s1, 0(sp)
lw s2, 4(sp)
lw s3, 8(sp)
lw s4, 12(sp)
lw s5, 16(sp)
lw s6, 20(sp)
lw s7, 24(sp)
lw s8, 28(sp)
lw s9, 32(sp)
lw s10, 36(sp)
lw s11, 40(sp)
lw ra, 60(sp)
lw s0, 56(sp)
addi sp, sp, 64
ret /* restore fp, then return */
.size unlz4,.-unlz4
.endfunc

View file

@ -0,0 +1,207 @@
/**
* *****************************************************************************
* @file softcrc.c
* @version 1.0
* @date 2022-11-23
* @brief
* *****************************************************************************
* @attention
*
* <h2><center>&copy; 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_core.h"
#include "softcrc.h"
// ---------------- POPULAR POLYNOMIALS ----------------
// CCITT: x^16 + x^12 + x^5 + x^0 (0x1021,init 0x0000)
// CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005,init 0xFFFF)
// we use 0x8005 here and
const uint8_t chCRCHTalbe[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
const uint8_t chCRCLTalbe[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
uint16_t BFLB_Soft_CRC16(void *dataIn, uint32_t len)
{
uint8_t chCRCHi = 0xFF;
uint8_t chCRCLo = 0xFF;
uint16_t wIndex;
uint8_t *data = (uint8_t *)dataIn;
while (len--) {
wIndex = chCRCLo ^ *data++;
chCRCLo = chCRCHi ^ chCRCHTalbe[wIndex];
chCRCHi = chCRCLTalbe[wIndex];
}
return ((chCRCHi << 8) | chCRCLo);
}
/*
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*/
const uint32_t crc32Tab[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t BFLB_Soft_CRC32_Table(void *dataIn, uint32_t len)
{
uint32_t crc = 0;
uint8_t *data = (uint8_t *)dataIn;
crc = crc ^ 0xffffffff;
while (len--) {
crc = crc32Tab[(crc ^ *data++) & 0xFF] ^ (crc >> 8);
}
return crc ^ 0xffffffff;
}
/******************************************************************************
* Name: CRC-32 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
* Poly: 0x4C11DB7
* Init: 0xFFFFFFF
* Refin: True
* Refout: True
* Xorout: 0xFFFFFFF
* Alias: CRC_32/ADCCP
* Use: WinRAR,ect.
*****************************************************************************/
uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32_Ex(uint32_t initial, void *dataIn, uint32_t len)
{
uint8_t i;
uint32_t crc = ~initial; // Initial value
uint8_t *data = (uint8_t *)dataIn;
while (len--) {
crc ^= *data++; // crc ^= *data; data++;
for (i = 0; i < 8; ++i) {
if (crc & 1) {
crc = (crc >> 1) ^ 0xEDB88320; // 0xEDB88320= reverse 0x04C11DB7
} else {
crc = (crc >> 1);
}
}
}
return ~crc;
}
#ifndef BFLB_USE_ROM_DRIVER
__WEAK__
uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32(void *dataIn, uint32_t len)
{
return BFLB_Soft_CRC32_Ex(0, dataIn, len);
}
#endif

View file

@ -0,0 +1,45 @@
/**
* *****************************************************************************
* @file softcrc.h
* @version 1.0
* @date 2022-11-23
* @brief
* *****************************************************************************
* @attention
*
* <h2><center>&copy; 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.
*
* *****************************************************************************
*/
#ifndef __SOFTCRC_H__
#define __SOFTCRC_H__
#include "stdint.h"
uint16_t BFLB_Soft_CRC16(void *dataIn, uint32_t len);
uint32_t BFLB_Soft_CRC32_Ex(uint32_t initial, void *dataIn, uint32_t len);
uint32_t BFLB_Soft_CRC32(void *dataIn, uint32_t len);
#endif