194 lines
6.5 KiB
C
194 lines
6.5 KiB
C
/*!
|
|
\file mbl_ns.c
|
|
\brief Non-secure MBL for GD32W51x WiFi SDK
|
|
|
|
\version 2021-10-30, V1.0.0, firmware for GD32W51x
|
|
*/
|
|
|
|
/*
|
|
Copyright (c) 2021, GigaDevice Semiconductor Inc.
|
|
|
|
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 the copyright holder 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 "gd32w51x.h"
|
|
#include "mbl_trace.h"
|
|
#include "mbl_region.h"
|
|
#include "mbl_image.h"
|
|
#include "mbl_sys.h"
|
|
#include "mbl_uart.h"
|
|
#include "mbl_flash.h"
|
|
#include "ebyte_e48.h"
|
|
#include "rom_region.h"
|
|
|
|
typedef void (*img_fptr_t) (void);
|
|
int32_t mbl_err_process = ERR_PROCESS_ENDLESS_LOOP;
|
|
int32_t mbl_trace_level = MBL_WARN;
|
|
struct rom_api_s_t *p_rom_api_s = (struct rom_api_s_t *)ROM_API_ARRAY_BASE;
|
|
|
|
#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
|
|
/* Macros to pick linker symbols */
|
|
#if defined (__ICCARM__)
|
|
#define REGION(a, b) a##b
|
|
#define REGION_NAME(a, b) REGION(a, b)
|
|
#define REGION_DECLARE(a, b) extern uint32_t REGION_NAME(a, b)
|
|
REGION_DECLARE(CSTACK, $$Base);
|
|
#else /* __CC_ARM or __GNUC__ */
|
|
#define REGION(a, b, c) a##b##c
|
|
#define REGION_NAME(a, b, c) REGION(a, b, c)
|
|
#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
|
|
REGION_DECLARE(Image$$, ARM_LIB_STACKHEAP, $$ZI$$Base);
|
|
#endif /* __ICCARM__ */
|
|
#endif
|
|
|
|
/*!
|
|
\brief jump to main image
|
|
\param[in] msp: top of stack pointer for main image
|
|
\param[in] reset: Reset Handler for main
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
static void jump_to_main_image(uint32_t msp, uint32_t reset)
|
|
{
|
|
static img_fptr_t img_reset;
|
|
|
|
img_reset = (img_fptr_t)reset;
|
|
|
|
__disable_irq();
|
|
#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
|
|
/* Restore the Main Stack Pointer Limit register's reset value
|
|
* before passing execution to runtime firmware to make the
|
|
* bootloader transparent to it.
|
|
*/
|
|
__set_MSPLIM(0);
|
|
#endif
|
|
__set_MSP(msp);
|
|
|
|
__DSB();
|
|
__ISB();
|
|
|
|
img_reset();
|
|
}
|
|
|
|
/*!
|
|
\brief main function
|
|
\param[in] none
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
int main(void)
|
|
{
|
|
int ret;
|
|
struct image_header hdr;
|
|
uint32_t boot_idx = 0, image_offset = 0, version;
|
|
uint32_t arm_vector[2];
|
|
#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
|
|
uint32_t msp_stack_bottom = 0;
|
|
|
|
#if defined (__ICCARM__)
|
|
msp_stack_bottom = (uint32_t)®ION_NAME(CSTACK, $$Base);
|
|
#else
|
|
msp_stack_bottom = (uint32_t)®ION_NAME(Image$$, ARM_LIB_STACKHEAP, $$ZI$$Base);
|
|
#endif
|
|
__set_MSPLIM(msp_stack_bottom);
|
|
#endif
|
|
|
|
/* Clear SRAM used by rom variables */
|
|
memset((uint32_t *)SRAM_BASE_NS, 0, RE_MBL_DATA_START);
|
|
|
|
/* Initialize UART for trace print */
|
|
log_uart_init();
|
|
printf("GIGA DEVICE\r\n");
|
|
|
|
/* Initialize flash for reading system info */
|
|
flash_init();
|
|
|
|
/* Init Systick */
|
|
systick_config();
|
|
|
|
/* Init Systick */
|
|
ebyte_main();
|
|
|
|
/* Initialize system status if empty or validate system status */
|
|
ret = sys_status_check();
|
|
if (ret < 0) {
|
|
mbl_trace(MBL_ERR, "Check sys status failed (ret = %d).\r\n", ret);
|
|
goto BootFailed;
|
|
}
|
|
|
|
/* Find the correct image to boot, Image 0 or Image 1 */
|
|
ret = boot_image_find(&boot_idx, &image_offset);
|
|
if (ret < 0) {
|
|
mbl_trace(MBL_ERR, "No image to boot (ret = %d).\r\n", ret);
|
|
goto BootFailed;
|
|
} else {
|
|
mbl_trace(MBL_ALWAYS, "MBL: Boot from Image %d.\r\n", boot_idx);
|
|
}
|
|
|
|
/* If boot from Image 1, config offset mapping */
|
|
if (boot_idx == IMAGE_1) {
|
|
flash_offset_mapping();
|
|
}
|
|
|
|
#ifdef CONFIG_IMAGE_VERIFICATION
|
|
/* Read and check if image header is valid */
|
|
flash_read(image_offset, (void *)&hdr, sizeof(struct image_header));
|
|
ret = image_header_check(&hdr);
|
|
if (ret < 0) {
|
|
mbl_trace(MBL_ERR, "Check image header failed (ret = %d).\r\n", ret);
|
|
sys_img_flag_set(boot_idx, IMG_FLAG_VERIFY_MASK, IMG_FLAG_VERIFY_FAIL);
|
|
goto BootFailed;
|
|
}
|
|
#endif
|
|
/* Update Image status and Running Image flag */
|
|
ret = sys_img_flag_set(boot_idx, IMG_FLAG_VERIFY_MASK, IMG_FLAG_VERIFY_OK);
|
|
ret |= sys_running_img_set(boot_idx);
|
|
|
|
#ifdef CONFIG_IMAGE_VERIFICATION
|
|
/* Update image version counter */
|
|
version = (hdr.ver_major << 24) | (hdr.ver_minor << 16) | hdr.ver_rev;
|
|
ret = sys_fw_version_set(IMG_TYPE_IMG, version);
|
|
if (ret < 0) {
|
|
mbl_trace(MBL_ERR, "Update image version counter failed(%d).\r\n", ret);
|
|
goto BootFailed;
|
|
} else if (ret == 0){
|
|
mbl_trace(MBL_ALWAYS, "Current image version is %d.%d.%d.\r\n",
|
|
hdr.ver_major, hdr.ver_minor, hdr.ver_rev);
|
|
}
|
|
#endif
|
|
/* Read the MSP and Reset_Handler of the main image */
|
|
flash_read((image_offset + IMAGE_HEADER_SIZE), arm_vector, 8);
|
|
if (!is_valid_flash_addr(arm_vector[1])) {
|
|
mbl_trace(MBL_ERR, "Image vector reset is invalid (%08x).\r\n", arm_vector[1]);
|
|
goto BootFailed;
|
|
}
|
|
log_uart_idle_wait();
|
|
|
|
/* Jump to main image */
|
|
jump_to_main_image(arm_vector[0], arm_vector[1]);
|
|
|
|
BootFailed:
|
|
while(1);
|
|
}
|