From 8d6352419a9dbba3b246cd3c7f6f9a5f5107b782 Mon Sep 17 00:00:00 2001 From: jzlv Date: Fri, 25 Nov 2022 20:16:20 +0800 Subject: [PATCH] [feat][boot2] add bl616 boot2 iap demo --- examples/boot2_isp/CMakeLists.txt | 37 + examples/boot2_isp/Makefile | 13 + examples/boot2_isp/bflb_eflash_loader.h | 142 +++ examples/boot2_isp/bflb_eflash_loader_cmds.c | 734 +++++++++++++++ examples/boot2_isp/bflb_eflash_loader_cmds.h | 267 ++++++ .../boot2_isp/bflb_eflash_loader_interface.c | 199 ++++ .../boot2_isp/bflb_eflash_loader_interface.h | 102 ++ examples/boot2_isp/bflb_eflash_loader_uart.c | 244 +++++ examples/boot2_isp/bflb_eflash_loader_uart.h | 62 ++ examples/boot2_isp/bflb_eflash_loader_usb.c | 316 +++++++ examples/boot2_isp/bflb_eflash_loader_usb.h | 57 ++ examples/boot2_isp/blsp_boot_decompress.c | 277 ++++++ examples/boot2_isp/blsp_boot_decompress.h | 45 + examples/boot2_isp/blsp_boot_parser.c | 250 +++++ examples/boot2_isp/blsp_boot_parser.h | 47 + examples/boot2_isp/blsp_bootinfo.h | 158 ++++ examples/boot2_isp/blsp_common.c | 197 ++++ examples/boot2_isp/blsp_common.h | 50 + examples/boot2_isp/blsp_media_boot.c | 404 ++++++++ examples/boot2_isp/blsp_media_boot.h | 50 + examples/boot2_isp/blsp_port.c | 190 ++++ examples/boot2_isp/blsp_port.h | 80 ++ examples/boot2_isp/blsp_ram_image_boot.c | 231 +++++ examples/boot2_isp/blsp_version.h | 41 + examples/boot2_isp/main.c | 583 ++++++++++++ examples/boot2_isp/partition.c | 543 +++++++++++ examples/boot2_isp/partition.h | 210 +++++ .../boot2_isp/port/bl616/bflb_port_boot2.c | 869 ++++++++++++++++++ .../boot2_isp/port/bl616/bflb_port_boot2.h | 322 +++++++ .../port/bl616/blsp_boot2_iap_flash.ld | 254 +++++ examples/boot2_isp/proj.conf | 8 + examples/boot2_isp/rv32i_xtheade_lz4.S | 187 ++++ examples/boot2_isp/softcrc.c | 207 +++++ examples/boot2_isp/softcrc.h | 45 + 34 files changed, 7421 insertions(+) create mode 100644 examples/boot2_isp/CMakeLists.txt create mode 100644 examples/boot2_isp/Makefile create mode 100644 examples/boot2_isp/bflb_eflash_loader.h create mode 100644 examples/boot2_isp/bflb_eflash_loader_cmds.c create mode 100644 examples/boot2_isp/bflb_eflash_loader_cmds.h create mode 100644 examples/boot2_isp/bflb_eflash_loader_interface.c create mode 100644 examples/boot2_isp/bflb_eflash_loader_interface.h create mode 100644 examples/boot2_isp/bflb_eflash_loader_uart.c create mode 100644 examples/boot2_isp/bflb_eflash_loader_uart.h create mode 100644 examples/boot2_isp/bflb_eflash_loader_usb.c create mode 100644 examples/boot2_isp/bflb_eflash_loader_usb.h create mode 100644 examples/boot2_isp/blsp_boot_decompress.c create mode 100644 examples/boot2_isp/blsp_boot_decompress.h create mode 100644 examples/boot2_isp/blsp_boot_parser.c create mode 100644 examples/boot2_isp/blsp_boot_parser.h create mode 100644 examples/boot2_isp/blsp_bootinfo.h create mode 100644 examples/boot2_isp/blsp_common.c create mode 100644 examples/boot2_isp/blsp_common.h create mode 100644 examples/boot2_isp/blsp_media_boot.c create mode 100644 examples/boot2_isp/blsp_media_boot.h create mode 100644 examples/boot2_isp/blsp_port.c create mode 100644 examples/boot2_isp/blsp_port.h create mode 100644 examples/boot2_isp/blsp_ram_image_boot.c create mode 100644 examples/boot2_isp/blsp_version.h create mode 100644 examples/boot2_isp/main.c create mode 100644 examples/boot2_isp/partition.c create mode 100644 examples/boot2_isp/partition.h create mode 100644 examples/boot2_isp/port/bl616/bflb_port_boot2.c create mode 100644 examples/boot2_isp/port/bl616/bflb_port_boot2.h create mode 100644 examples/boot2_isp/port/bl616/blsp_boot2_iap_flash.ld create mode 100644 examples/boot2_isp/proj.conf create mode 100644 examples/boot2_isp/rv32i_xtheade_lz4.S create mode 100644 examples/boot2_isp/softcrc.c create mode 100644 examples/boot2_isp/softcrc.h diff --git a/examples/boot2_isp/CMakeLists.txt b/examples/boot2_isp/CMakeLists.txt new file mode 100644 index 00000000..b8b9d894 --- /dev/null +++ b/examples/boot2_isp/CMakeLists.txt @@ -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) diff --git a/examples/boot2_isp/Makefile b/examples/boot2_isp/Makefile new file mode 100644 index 00000000..34b2f3fa --- /dev/null +++ b/examples/boot2_isp/Makefile @@ -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 diff --git a/examples/boot2_isp/bflb_eflash_loader.h b/examples/boot2_isp/bflb_eflash_loader.h new file mode 100644 index 00000000..9b033ed7 --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader.h @@ -0,0 +1,142 @@ +/** + ****************************************************************************** + * @file blsp_eflash_loader.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/bflb_eflash_loader_cmds.c b/examples/boot2_isp/bflb_eflash_loader_cmds.c new file mode 100644 index 00000000..a19b4241 --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader_cmds.c @@ -0,0 +1,734 @@ +/** + ****************************************************************************** + * @file blsp_eflash_loader_cmds.c + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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; +} diff --git a/examples/boot2_isp/bflb_eflash_loader_cmds.h b/examples/boot2_isp/bflb_eflash_loader_cmds.h new file mode 100644 index 00000000..202ff5b5 --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader_cmds.h @@ -0,0 +1,267 @@ +/** + ****************************************************************************** + * @file blsp_eflash_loader_cmds.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/bflb_eflash_loader_interface.c b/examples/boot2_isp/bflb_eflash_loader_interface.c new file mode 100644 index 00000000..fffebda3 --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader_interface.c @@ -0,0 +1,199 @@ +/** + * ***************************************************************************** + * @file bflb_eflash_loader_interface.c + * @version 0.1 + * @date 2022-11-23 + * @brief + * ***************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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; +} diff --git a/examples/boot2_isp/bflb_eflash_loader_interface.h b/examples/boot2_isp/bflb_eflash_loader_interface.h new file mode 100644 index 00000000..b6cfd320 --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader_interface.h @@ -0,0 +1,102 @@ +/** + * ***************************************************************************** + * @file bflb_eflash_loader_interface.h + * @version 0.1 + * @date 2022-11-23 + * @brief + * ***************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/bflb_eflash_loader_uart.c b/examples/boot2_isp/bflb_eflash_loader_uart.c new file mode 100644 index 00000000..a088ece0 --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader_uart.c @@ -0,0 +1,244 @@ +/** + ****************************************************************************** + * @file blsp_eflash_loader_uart.c + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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; +} diff --git a/examples/boot2_isp/bflb_eflash_loader_uart.h b/examples/boot2_isp/bflb_eflash_loader_uart.h new file mode 100644 index 00000000..8cfae7e3 --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader_uart.h @@ -0,0 +1,62 @@ +/** + ****************************************************************************** + * @file blsp_eflash_loader_uart.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/bflb_eflash_loader_usb.c b/examples/boot2_isp/bflb_eflash_loader_usb.c new file mode 100644 index 00000000..197a533b --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader_usb.c @@ -0,0 +1,316 @@ +/** + ****************************************************************************** + * @file blsp_eflash_loader_usb.c + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/bflb_eflash_loader_usb.h b/examples/boot2_isp/bflb_eflash_loader_usb.h new file mode 100644 index 00000000..51acb3c5 --- /dev/null +++ b/examples/boot2_isp/bflb_eflash_loader_usb.h @@ -0,0 +1,57 @@ +/** + ****************************************************************************** + * @file blsp_eflash_loader_usb.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/blsp_boot_decompress.c b/examples/boot2_isp/blsp_boot_decompress.c new file mode 100644 index 00000000..50f51e99 --- /dev/null +++ b/examples/boot2_isp/blsp_boot_decompress.c @@ -0,0 +1,277 @@ +/** + ****************************************************************************** + * @file blsp_boot_decompress.c + * @version V1.2 + * @date + * @brief This file is the peripheral case c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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; +} diff --git a/examples/boot2_isp/blsp_boot_decompress.h b/examples/boot2_isp/blsp_boot_decompress.h new file mode 100644 index 00000000..be04a24f --- /dev/null +++ b/examples/boot2_isp/blsp_boot_decompress.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * @file blsp_boot_decompress.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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__ */ diff --git a/examples/boot2_isp/blsp_boot_parser.c b/examples/boot2_isp/blsp_boot_parser.c new file mode 100644 index 00000000..91660c61 --- /dev/null +++ b/examples/boot2_isp/blsp_boot_parser.c @@ -0,0 +1,250 @@ +/** + ****************************************************************************** + * @file blsp_boot_parser.c + * @version V1.2 + * @date + * @brief This file is the peripheral case c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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; +} diff --git a/examples/boot2_isp/blsp_boot_parser.h b/examples/boot2_isp/blsp_boot_parser.h new file mode 100644 index 00000000..cc384713 --- /dev/null +++ b/examples/boot2_isp/blsp_boot_parser.h @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * @file blsp_boot_parser.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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__ */ diff --git a/examples/boot2_isp/blsp_bootinfo.h b/examples/boot2_isp/blsp_bootinfo.h new file mode 100644 index 00000000..ac4430be --- /dev/null +++ b/examples/boot2_isp/blsp_bootinfo.h @@ -0,0 +1,158 @@ +/** + ****************************************************************************** + * @file blsp_bootinfo.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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__ */ diff --git a/examples/boot2_isp/blsp_common.c b/examples/boot2_isp/blsp_common.c new file mode 100644 index 00000000..9870edbf --- /dev/null +++ b/examples/boot2_isp/blsp_common.c @@ -0,0 +1,197 @@ +/** + ****************************************************************************** + * @file blsp_common.c + * @version V1.2 + * @date + * @brief This file is the peripheral case c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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); + } +} diff --git a/examples/boot2_isp/blsp_common.h b/examples/boot2_isp/blsp_common.h new file mode 100644 index 00000000..6f26cafa --- /dev/null +++ b/examples/boot2_isp/blsp_common.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * @file blsp_common.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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__ */ diff --git a/examples/boot2_isp/blsp_media_boot.c b/examples/boot2_isp/blsp_media_boot.c new file mode 100644 index 00000000..03ab4eb2 --- /dev/null +++ b/examples/boot2_isp/blsp_media_boot.c @@ -0,0 +1,404 @@ +/** + ****************************************************************************** + * @file blsp_media_boot.c + * @version V1.2 + * @date + * @brief This file is the peripheral case c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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; +} diff --git a/examples/boot2_isp/blsp_media_boot.h b/examples/boot2_isp/blsp_media_boot.h new file mode 100644 index 00000000..d32d62bd --- /dev/null +++ b/examples/boot2_isp/blsp_media_boot.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * @file blsp_media_boot.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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__ */ diff --git a/examples/boot2_isp/blsp_port.c b/examples/boot2_isp/blsp_port.c new file mode 100644 index 00000000..a888e62e --- /dev/null +++ b/examples/boot2_isp/blsp_port.c @@ -0,0 +1,190 @@ +/** + ****************************************************************************** + * @file blsp_port.c + * @version V1.2 + * @date + * @brief This file is the peripheral case c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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; +} diff --git a/examples/boot2_isp/blsp_port.h b/examples/boot2_isp/blsp_port.h new file mode 100644 index 00000000..da5441ad --- /dev/null +++ b/examples/boot2_isp/blsp_port.h @@ -0,0 +1,80 @@ +/** + ****************************************************************************** + * @file blsp_port.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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__ */ diff --git a/examples/boot2_isp/blsp_ram_image_boot.c b/examples/boot2_isp/blsp_ram_image_boot.c new file mode 100644 index 00000000..58687a0a --- /dev/null +++ b/examples/boot2_isp/blsp_ram_image_boot.c @@ -0,0 +1,231 @@ +/** + ****************************************************************************** + * @file blsp_ram_image_boot.c + * @version V1.2 + * @date + * @brief This file is the peripheral case c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 \ No newline at end of file diff --git a/examples/boot2_isp/blsp_version.h b/examples/boot2_isp/blsp_version.h new file mode 100644 index 00000000..9027dc07 --- /dev/null +++ b/examples/boot2_isp/blsp_version.h @@ -0,0 +1,41 @@ +/** + ****************************************************************************** + * @file blsp_version.h + * @version V1.2 + * @date + * @brief This file is the peripheral case header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/main.c b/examples/boot2_isp/main.c new file mode 100644 index 00000000..5d1d8a28 --- /dev/null +++ b/examples/boot2_isp/main.c @@ -0,0 +1,583 @@ +/** + ****************************************************************************** + * @file main.c + * @version V1.2 + * @date + * @brief This file is the peripheral case c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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(); +} diff --git a/examples/boot2_isp/partition.c b/examples/boot2_isp/partition.c new file mode 100644 index 00000000..38b6f235 --- /dev/null +++ b/examples/boot2_isp/partition.c @@ -0,0 +1,543 @@ +/** + ****************************************************************************** + * @file partition.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 Bouffalo Lab

+ * + * 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 */ diff --git a/examples/boot2_isp/partition.h b/examples/boot2_isp/partition.h new file mode 100644 index 00000000..0d832d02 --- /dev/null +++ b/examples/boot2_isp/partition.h @@ -0,0 +1,210 @@ +/** + ****************************************************************************** + * @file partition.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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__ */ diff --git a/examples/boot2_isp/port/bl616/bflb_port_boot2.c b/examples/boot2_isp/port/bl616/bflb_port_boot2.c new file mode 100644 index 00000000..cde31bb9 --- /dev/null +++ b/examples/boot2_isp/port/bl616/bflb_port_boot2.c @@ -0,0 +1,869 @@ +/** + * ***************************************************************************** + * @file bflb_port_boot2.c + * @version 0.1 + * @date 2022-11-23 + * @brief + * ***************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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, ®_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; + } +} \ No newline at end of file diff --git a/examples/boot2_isp/port/bl616/bflb_port_boot2.h b/examples/boot2_isp/port/bl616/bflb_port_boot2.h new file mode 100644 index 00000000..809b1eef --- /dev/null +++ b/examples/boot2_isp/port/bl616/bflb_port_boot2.h @@ -0,0 +1,322 @@ +/** + * ***************************************************************************** + * @file bflb_port_boot2.h + * @version 0.1 + * @date 2022-11-23 + * @brief + * ***************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/port/bl616/blsp_boot2_iap_flash.ld b/examples/boot2_isp/port/bl616/blsp_boot2_iap_flash.ld new file mode 100644 index 00000000..55bbc74b --- /dev/null +++ b/examples/boot2_isp/port/bl616/blsp_boot2_iap_flash.ld @@ -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") + +} + diff --git a/examples/boot2_isp/proj.conf b/examples/boot2_isp/proj.conf new file mode 100644 index 00000000..28085a11 --- /dev/null +++ b/examples/boot2_isp/proj.conf @@ -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) + diff --git a/examples/boot2_isp/rv32i_xtheade_lz4.S b/examples/boot2_isp/rv32i_xtheade_lz4.S new file mode 100644 index 00000000..a106062d --- /dev/null +++ b/examples/boot2_isp/rv32i_xtheade_lz4.S @@ -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 diff --git a/examples/boot2_isp/softcrc.c b/examples/boot2_isp/softcrc.c new file mode 100644 index 00000000..c72ddb90 --- /dev/null +++ b/examples/boot2_isp/softcrc.c @@ -0,0 +1,207 @@ +/** + * ***************************************************************************** + * @file softcrc.c + * @version 1.0 + * @date 2022-11-23 + * @brief + * ***************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 diff --git a/examples/boot2_isp/softcrc.h b/examples/boot2_isp/softcrc.h new file mode 100644 index 00000000..4a517284 --- /dev/null +++ b/examples/boot2_isp/softcrc.h @@ -0,0 +1,45 @@ +/** + * ***************************************************************************** + * @file softcrc.h + * @version 1.0 + * @date 2022-11-23 + * @brief + * ***************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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