first commit
This commit is contained in:
15
bootloader/CMakeLists.txt
Executable file
15
bootloader/CMakeLists.txt
Executable file
@ -0,0 +1,15 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved.
|
||||
#===============================================================================
|
||||
add_subdirectory_if_exist(bootrom)
|
||||
add_subdirectory_if_exist(flashboot)
|
||||
add_subdirectory_if_exist(provision)
|
||||
|
||||
if ((${CHIP} STREQUAL "bs21") OR (${CHIP} STREQUAL "bs21a") OR (${CHIP} STREQUAL "ws63") OR (${CHIP} STREQUAL "sw39") OR (${CHIP} STREQUAL "sw21"))
|
||||
add_subdirectory_if_exist(commonboot)
|
||||
endif()
|
||||
|
||||
add_subdirectory_if_exist(provision_${CHIP})
|
||||
add_subdirectory_if_exist(flashboot_${CHIP})
|
||||
add_subdirectory_if_exist(bootrom_${CHIP})
|
81
bootloader/Kconfig
Executable file
81
bootloader/Kconfig
Executable file
@ -0,0 +1,81 @@
|
||||
#===============================================================================
|
||||
# @brief Kconfig file.
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved.
|
||||
#===============================================================================
|
||||
config BOOT_SUPPORT_SEC
|
||||
bool
|
||||
prompt "BOOT SEC"
|
||||
default n
|
||||
help
|
||||
This option means boot support sec.
|
||||
|
||||
if BOOT_SUPPORT_SEC
|
||||
menu "Boot Sec Configuration"
|
||||
comment "Boot hash"
|
||||
osource "bootloader/commonboot/Kconfig"
|
||||
endmenu
|
||||
endif
|
||||
|
||||
config BOOT_SUPPORT_SECURE_VERIFY
|
||||
bool
|
||||
prompt "BOOT VERIFY"
|
||||
default n
|
||||
help
|
||||
This option means boot support secure verify.
|
||||
|
||||
if BOOT_SUPPORT_SECURE_VERIFY
|
||||
menu "Boot Secure Verify Configuration"
|
||||
comment "Boot secure verify"
|
||||
osource "bootloader/commonboot/Kconfig"
|
||||
endmenu
|
||||
endif
|
||||
|
||||
config BOOT_SUPPORT_PARTITION
|
||||
bool
|
||||
prompt "BOOT PARTITION"
|
||||
default n
|
||||
help
|
||||
This option means boot support partition.
|
||||
|
||||
config LOADERBOOT_SUPPORT_EFUSE_BURN
|
||||
bool
|
||||
prompt "LOADERBOOT EFUSE BURN"
|
||||
default n
|
||||
help
|
||||
This option means loaderboot support efuse burn.
|
||||
|
||||
config LOADERBOOT_SUPPORT_FLASH_CHIP_ERASE
|
||||
bool
|
||||
prompt "LOADERBOOT FLASH CHIP ERASE"
|
||||
default n
|
||||
help
|
||||
This option means loaderboot support flash chip erase.
|
||||
|
||||
if LOADERBOOT_SUPPORT_EFUSE_BURN
|
||||
menu "Loaderboot Hash Configuration"
|
||||
comment "Boot hash"
|
||||
osource "bootloader/commonboot/Kconfig"
|
||||
endmenu
|
||||
endif
|
||||
|
||||
config LOADERBOOT_SUPPORT_UPLOAD_DATA
|
||||
bool
|
||||
prompt "LOADERBOOT UPLOAD DATA"
|
||||
default n
|
||||
help
|
||||
This option means loaderboot support data upload.
|
||||
|
||||
config LOADERBOOT_SUPPORT_READ_VERSION
|
||||
bool
|
||||
prompt "LOADERBOOT READ VERSION"
|
||||
default n
|
||||
help
|
||||
This option means loaderboot support version read.
|
||||
|
||||
|
||||
config LOADERBOOT_SUPPORT_SET_BUADRATE
|
||||
bool
|
||||
prompt "LOADERBOOT SET BUADRATE"
|
||||
default n
|
||||
help
|
||||
This option means loaderboot support set baudrate.
|
123
bootloader/commonboot/CMakeLists.txt
Executable file
123
bootloader/commonboot/CMakeLists.txt
Executable file
@ -0,0 +1,123 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved.
|
||||
#===============================================================================
|
||||
add_subdirectory_if_exist(libc)
|
||||
|
||||
set(COMPONENT_NAME "common_boot")
|
||||
|
||||
set(SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_reset.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_flash.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_debug.c
|
||||
)
|
||||
|
||||
if(${APPLICATION} STREQUAL "romboot")
|
||||
set(SOURCES
|
||||
${SOURCES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_uart_auth.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_verify.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_ymodem.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_load.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_jump.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_crc16.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(${APPLICATION} STREQUAL "loaderboot")
|
||||
set(SOURCES
|
||||
${SOURCES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_transfer.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_cmd_loop.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_ymodem.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_crc16.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_load.c
|
||||
)
|
||||
|
||||
if(DEFINED CONFIG_LOADERBOOT_SUPPORT_EFUSE_BURN)
|
||||
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/boot_efuse_opt.c")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(${APPLICATION} STREQUAL "flashboot")
|
||||
set(SOURCES
|
||||
${SOURCES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_jump.c
|
||||
)
|
||||
endif()
|
||||
|
||||
set(PUBLIC_HEADER
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
set(PRIVATE_HEADER
|
||||
)
|
||||
|
||||
set(PRIVATE_DEFINES
|
||||
)
|
||||
|
||||
set(PUBLIC_DEFINES
|
||||
)
|
||||
|
||||
# use this when you want to add ccflags like -include xxx
|
||||
set(COMPONENT_PUBLIC_CCFLAGS
|
||||
)
|
||||
|
||||
if (${CHIP} STREQUAL "sw39" OR ${CHIP} STREQUAL "sw21")
|
||||
set(COMPONENT_CCFLAGS
|
||||
)
|
||||
else()
|
||||
set(COMPONENT_CCFLAGS
|
||||
)
|
||||
endif()
|
||||
|
||||
set(WHOLE_LINK
|
||||
true
|
||||
)
|
||||
|
||||
set(MAIN_COMPONENT
|
||||
false
|
||||
)
|
||||
|
||||
build_component()
|
||||
|
||||
set(COMPONENT_NAME "flashboot_with_loadboot")
|
||||
|
||||
set(SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_transfer.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_cmd_loop.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_ymodem.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_crc16.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_load.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/boot_uart_auth.c
|
||||
)
|
||||
|
||||
set(PUBLIC_HEADER
|
||||
)
|
||||
|
||||
set(PRIVATE_HEADER
|
||||
)
|
||||
|
||||
set(PRIVATE_DEFINES
|
||||
)
|
||||
|
||||
set(PUBLIC_DEFINES
|
||||
)
|
||||
|
||||
# use this when you want to add ccflags like -include xxx
|
||||
set(COMPONENT_PUBLIC_CCFLAGS
|
||||
)
|
||||
|
||||
set(COMPONENT_CCFLAGS
|
||||
)
|
||||
|
||||
set(WHOLE_LINK
|
||||
true
|
||||
)
|
||||
|
||||
set(MAIN_COMPONENT
|
||||
false
|
||||
)
|
||||
|
||||
build_component()
|
101
bootloader/commonboot/Kconfig
Executable file
101
bootloader/commonboot/Kconfig
Executable file
@ -0,0 +1,101 @@
|
||||
#===============================================================================
|
||||
# @brief Kconfig file.
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved.
|
||||
#===============================================================================
|
||||
|
||||
config BOOT_SUPPORT_HASH
|
||||
bool
|
||||
prompt "Hash"
|
||||
default n
|
||||
depends on BOOT_SUPPORT_SEC
|
||||
help
|
||||
This option means boot support hash check.
|
||||
|
||||
config BOOT_SUPPORT_ECC_VERIFY
|
||||
bool
|
||||
prompt "Ecc Verify"
|
||||
default n
|
||||
depends on BOOT_SUPPORT_SECURE_VERIFY
|
||||
help
|
||||
This option means boot support ecc verify.
|
||||
|
||||
config BOOT_SUPPORT_SM2_VERIFY
|
||||
bool
|
||||
prompt "Sm2 Verify"
|
||||
default n
|
||||
depends on BOOT_SUPPORT_SECURE_VERIFY
|
||||
help
|
||||
This option means boot support sm2 verify.
|
||||
|
||||
config BOOT_SUPPORT_RSA3072_VERIFY
|
||||
bool
|
||||
prompt "Rsa3072 Verify"
|
||||
default n
|
||||
depends on BOOT_SUPPORT_SECURE_VERIFY
|
||||
help
|
||||
This option means boot support rsa3072 verify.
|
||||
|
||||
config BOOT_SUPPORT_RSA4096_VERIFY
|
||||
bool
|
||||
prompt "Rsa4096 Verify"
|
||||
default n
|
||||
depends on BOOT_SUPPORT_SECURE_VERIFY
|
||||
help
|
||||
This option means boot support rsa4096 verify.
|
||||
|
||||
config BOOT_SUPPORT_SOFT_VERIFY
|
||||
bool
|
||||
prompt "Soft Verify"
|
||||
default n
|
||||
depends on BOOT_SUPPORT_SECURE_VERIFY
|
||||
help
|
||||
This option means boot support soft verify.
|
||||
|
||||
config FLASH_BOOT_SUPPORT_ROM_API
|
||||
bool
|
||||
prompt "flashboot support rom API"
|
||||
default n
|
||||
depends on BOOT_SUPPORT_SECURE_VERIFY
|
||||
help
|
||||
This option means flashboot support rom API.
|
||||
|
||||
if CHIP_WS63 || CHIP_WS53
|
||||
config ROM_EXPEND_SUPPORT_NOT_ALIGNED
|
||||
bool
|
||||
prompt "expand rom sha256 API to support data_length not 64 bytes aligned. only need by ws63 & ws53."
|
||||
default n
|
||||
depends on FLASH_BOOT_SUPPORT_ROM_API
|
||||
help
|
||||
This option means the sha256 data_length support not 64 bytes aligned.
|
||||
endif
|
||||
|
||||
config LOADERBOOT_SUPPORT_SW_HASH
|
||||
bool
|
||||
prompt "Loaderboot Support Software Hash"
|
||||
default n
|
||||
depends on LOADERBOOT_SUPPORT_EFUSE_BURN
|
||||
help
|
||||
This option means flashboot support software hash.
|
||||
|
||||
config LOADERBOOT_SUPPORT_DYNAMIC_PACKET_SIZE
|
||||
bool
|
||||
prompt "Loaderboot Support Dynamic Download Packet Size."
|
||||
default n
|
||||
help
|
||||
This option means loaderboot support dynamic packet size.
|
||||
|
||||
config YMODEM_PACKET_BUFFER_SZIE
|
||||
int
|
||||
prompt "ymodem buffer size in loaderboot."
|
||||
depends on LOADERBOOT_SUPPORT_DYNAMIC_PACKET_SIZE
|
||||
default 1024
|
||||
help
|
||||
This option means the max buffer size to store ymodem packet.
|
||||
|
||||
config FLASH_WRITE_SIZE
|
||||
int
|
||||
prompt "flash write size for one time in loaderboot."
|
||||
depends on LOADERBOOT_SUPPORT_DYNAMIC_PACKET_SIZE
|
||||
default 1024
|
||||
help
|
||||
This option means write flash size for one time.
|
44
bootloader/commonboot/libc/CMakeLists.txt
Executable file
44
bootloader/commonboot/libc/CMakeLists.txt
Executable file
@ -0,0 +1,44 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved.
|
||||
#===============================================================================
|
||||
set(COMPONENT_NAME "common_boot_libc")
|
||||
|
||||
set(SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/string/memset.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/string/memcpy.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/string/memcmp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/string/strcmp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/string/strlen.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/string/memmove.c
|
||||
)
|
||||
|
||||
set(PUBLIC_HEADER
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
set(PRIVATE_HEADER
|
||||
)
|
||||
|
||||
set(PRIVATE_DEFINES
|
||||
)
|
||||
|
||||
set(PUBLIC_DEFINES
|
||||
)
|
||||
|
||||
# use this when you want to add ccflags like -include xxx
|
||||
set(COMPONENT_PUBLIC_CCFLAGS
|
||||
)
|
||||
|
||||
set(COMPONENT_CCFLAGS
|
||||
)
|
||||
|
||||
set(WHOLE_LINK
|
||||
true
|
||||
)
|
||||
|
||||
set(MAIN_COMPONENT
|
||||
false
|
||||
)
|
||||
|
||||
build_component()
|
22
bootloader/commonboot/libc/src/string/memcmp.c
Executable file
22
bootloader/commonboot/libc/src/string/memcmp.c
Executable file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2019. All rights reserved.
|
||||
* Description: Boot string function implementation.
|
||||
*
|
||||
* Create: 2012-12-22
|
||||
*/
|
||||
|
||||
/**
|
||||
* memcmp - Compare two areas of memory
|
||||
* @cs: One area of memory
|
||||
* @ct: Another area of memory
|
||||
* @count: The size of the area.
|
||||
*/
|
||||
int memcmp(const void *cs, const void *ct, unsigned int count)
|
||||
{
|
||||
unsigned int cnt = count;
|
||||
const unsigned char *l = cs;
|
||||
const unsigned char *r = ct;
|
||||
for (; (cnt != 0) && (*l == *r); cnt--, l++, r++) {
|
||||
};
|
||||
return (cnt != 0) ? *l - *r : 0;
|
||||
}
|
183
bootloader/commonboot/libc/src/string/memcpy.c
Executable file
183
bootloader/commonboot/libc/src/string/memcpy.c
Executable file
@ -0,0 +1,183 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define LS >>
|
||||
#define RS <<
|
||||
#else
|
||||
#define LS <<
|
||||
#define RS >>
|
||||
#endif
|
||||
|
||||
#define MEMCPY_BYTE_BITS 8
|
||||
#define MEMCPY_ALIGH_UNIT_BYTES_4 4
|
||||
#define MEMCPY_FAST_COPY_UNIT_NUM_4 4
|
||||
#define MEMCPY_FAST_COPY_UNIT_BYTES (MEMCPY_ALIGH_UNIT_BYTES_4 * MEMCPY_FAST_COPY_UNIT_NUM_4)
|
||||
|
||||
#define MEMCPY_ALIGH_UNIT_BITS (MEMCPY_BYTE_BITS * MEMCPY_ALIGH_UNIT_BYTES_4)
|
||||
|
||||
#define MEMCPY_FAST_COPY_OFFSET_UNIT_0 (MEMCPY_ALIGH_UNIT_BYTES_4 * 0)
|
||||
#define MEMCPY_FAST_COPY_OFFSET_UNIT_1 (MEMCPY_ALIGH_UNIT_BYTES_4 * 1)
|
||||
#define MEMCPY_FAST_COPY_OFFSET_UNIT_2 (MEMCPY_ALIGH_UNIT_BYTES_4 * 2)
|
||||
#define MEMCPY_FAST_COPY_OFFSET_UNIT_3 (MEMCPY_ALIGH_UNIT_BYTES_4 * 3)
|
||||
|
||||
#define MEMCPY_NOT_ALIGN_FAST_COPY_THRESHOLD (MEMCPY_FAST_COPY_UNIT_BYTES * 2)
|
||||
|
||||
#define MEMCPY_OFFSET_BYTES_1 1
|
||||
#define MEMCPY_ALIGH_OFFSET_BYTES_1 (MEMCPY_ALIGH_UNIT_BYTES_4 - MEMCPY_OFFSET_BYTES_1)
|
||||
#define MEMCPY_OFFSET_BITS_1 (MEMCPY_BYTE_BITS * MEMCPY_OFFSET_BYTES_1)
|
||||
#define MEMCPY_OFFSET_ALIGN_BITS_1 (MEMCPY_BYTE_BITS * MEMCPY_ALIGH_OFFSET_BYTES_1)
|
||||
|
||||
#define MEMCPY_OFFSET_BYTES_2 2
|
||||
#define MEMCPY_ALIGH_OFFSET_BYTES_2 (MEMCPY_ALIGH_UNIT_BYTES_4 - MEMCPY_OFFSET_BYTES_2)
|
||||
#define MEMCPY_OFFSET_BITS_2 (MEMCPY_BYTE_BITS * MEMCPY_OFFSET_BYTES_2)
|
||||
#define MEMCPY_OFFSET_ALIGN_BITS_2 (MEMCPY_BYTE_BITS * MEMCPY_ALIGH_OFFSET_BYTES_2)
|
||||
|
||||
#define MEMCPY_OFFSET_BYTES_3 3
|
||||
#define MEMCPY_ALIGH_OFFSET_BYTES_3 (MEMCPY_ALIGH_UNIT_BYTES_4 - MEMCPY_OFFSET_BYTES_3)
|
||||
#define MEMCPY_OFFSET_BITS_3 (MEMCPY_BYTE_BITS * MEMCPY_OFFSET_BYTES_3)
|
||||
#define MEMCPY_OFFSET_ALIGN_BITS_3 (MEMCPY_BYTE_BITS * MEMCPY_ALIGH_OFFSET_BYTES_3)
|
||||
|
||||
#define MEMCPY_BYTE_CHECK_NUM_1 0x01
|
||||
#define MEMCPY_BYTE_CHECK_NUM_2 0x02
|
||||
#define MEMCPY_BYTE_CHECK_NUM_4 0x04
|
||||
#define MEMCPY_BYTE_CHECK_NUM_8 0x08
|
||||
#define MEMCPY_BYTE_CHECK_NUM_16 0x10
|
||||
#endif
|
||||
|
||||
void *memcpy(void *restrict dest, const void *restrict src, size_t num)
|
||||
{
|
||||
unsigned char *d = dest;
|
||||
const unsigned char *s = src;
|
||||
size_t n = num;
|
||||
|
||||
#ifdef __GNUC__
|
||||
typedef uint32_t __attribute__((__may_alias__)) u32;
|
||||
uint32_t w, x;
|
||||
|
||||
for (; (uintptr_t)s % MEMCPY_ALIGH_UNIT_BYTES_4 && n; n--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if ((uintptr_t)d % MEMCPY_ALIGH_UNIT_BYTES_4 == 0) {
|
||||
for (; n >= MEMCPY_FAST_COPY_UNIT_BYTES; s += MEMCPY_FAST_COPY_UNIT_BYTES,
|
||||
d += MEMCPY_FAST_COPY_UNIT_BYTES, n -= MEMCPY_FAST_COPY_UNIT_BYTES) {
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_0) = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_0);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_1) = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_1);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_2) = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_2);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_3) = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_3);
|
||||
}
|
||||
if (n & MEMCPY_FAST_COPY_OFFSET_UNIT_2) {
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_0) = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_0);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_1) = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_1);
|
||||
d += MEMCPY_FAST_COPY_OFFSET_UNIT_2;
|
||||
s += MEMCPY_FAST_COPY_OFFSET_UNIT_2;
|
||||
}
|
||||
if (n & MEMCPY_FAST_COPY_OFFSET_UNIT_1) {
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_0) = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_0);
|
||||
d += MEMCPY_FAST_COPY_OFFSET_UNIT_1;
|
||||
s += MEMCPY_FAST_COPY_OFFSET_UNIT_1;
|
||||
}
|
||||
if (n & MEMCPY_BYTE_CHECK_NUM_2) {
|
||||
*d++ = *s++; *d++ = *s++;
|
||||
}
|
||||
if (n & MEMCPY_BYTE_CHECK_NUM_1) {
|
||||
*d = *s;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (n >= MEMCPY_NOT_ALIGN_FAST_COPY_THRESHOLD) {
|
||||
switch ((uintptr_t)d % MEMCPY_ALIGH_UNIT_BYTES_4) {
|
||||
case MEMCPY_OFFSET_BYTES_1:
|
||||
w = *(u32 *)s;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
n -= MEMCPY_ALIGH_OFFSET_BYTES_1;
|
||||
for (; n >= MEMCPY_FAST_COPY_UNIT_BYTES + MEMCPY_OFFSET_BYTES_1; s += MEMCPY_FAST_COPY_UNIT_BYTES,
|
||||
d += MEMCPY_FAST_COPY_UNIT_BYTES, n -= MEMCPY_FAST_COPY_UNIT_BYTES) {
|
||||
x = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_0 + MEMCPY_OFFSET_BYTES_1);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_0) =
|
||||
(w LS MEMCPY_OFFSET_ALIGN_BITS_1) | (x RS MEMCPY_OFFSET_BITS_1);
|
||||
w = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_1 + MEMCPY_OFFSET_BYTES_1);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_1) =
|
||||
(x LS MEMCPY_OFFSET_ALIGN_BITS_1) | (w RS MEMCPY_OFFSET_BITS_1);
|
||||
x = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_2 + MEMCPY_OFFSET_BYTES_1);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_2) =
|
||||
(w LS MEMCPY_OFFSET_ALIGN_BITS_1) | (x RS MEMCPY_OFFSET_BITS_1);
|
||||
w = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_3 + MEMCPY_OFFSET_BYTES_1);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_3) =
|
||||
(x LS MEMCPY_OFFSET_ALIGN_BITS_1) | (w RS MEMCPY_OFFSET_BITS_1);
|
||||
}
|
||||
break;
|
||||
case MEMCPY_OFFSET_BYTES_2:
|
||||
w = *(u32 *)s;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
n -= MEMCPY_ALIGH_OFFSET_BYTES_2;
|
||||
for (; n >= MEMCPY_FAST_COPY_UNIT_BYTES + MEMCPY_OFFSET_BYTES_2; s += MEMCPY_FAST_COPY_UNIT_BYTES,
|
||||
d += MEMCPY_FAST_COPY_UNIT_BYTES, n -= MEMCPY_FAST_COPY_UNIT_BYTES) {
|
||||
x = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_0 + MEMCPY_OFFSET_BYTES_2);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_0) =
|
||||
(w LS MEMCPY_OFFSET_ALIGN_BITS_2) | (x RS MEMCPY_OFFSET_BITS_2);
|
||||
w = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_1 + MEMCPY_OFFSET_BYTES_2);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_1) =
|
||||
(x LS MEMCPY_OFFSET_ALIGN_BITS_2) | (w RS MEMCPY_OFFSET_BITS_2);
|
||||
x = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_2 + MEMCPY_OFFSET_BYTES_2);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_2) =
|
||||
(w LS MEMCPY_OFFSET_ALIGN_BITS_2) | (x RS MEMCPY_OFFSET_BITS_2);
|
||||
w = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_3 + MEMCPY_OFFSET_BYTES_2);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_3) =
|
||||
(x LS MEMCPY_OFFSET_ALIGN_BITS_2) | (w RS MEMCPY_OFFSET_BITS_2);
|
||||
}
|
||||
break;
|
||||
case MEMCPY_OFFSET_BYTES_3:
|
||||
w = *(u32 *)s;
|
||||
*d++ = *s++;
|
||||
n -= MEMCPY_ALIGH_OFFSET_BYTES_3;
|
||||
for (; n >= MEMCPY_FAST_COPY_UNIT_BYTES + MEMCPY_OFFSET_BYTES_3; s += MEMCPY_FAST_COPY_UNIT_BYTES,
|
||||
d += MEMCPY_FAST_COPY_UNIT_BYTES, n -= MEMCPY_FAST_COPY_UNIT_BYTES) {
|
||||
x = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_0 + MEMCPY_OFFSET_BYTES_3);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_0) =
|
||||
(w LS MEMCPY_OFFSET_ALIGN_BITS_3) | (x RS MEMCPY_OFFSET_BITS_3);
|
||||
w = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_1 + MEMCPY_OFFSET_BYTES_3);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_1) =
|
||||
(x LS MEMCPY_OFFSET_ALIGN_BITS_3) | (w RS MEMCPY_OFFSET_BITS_3);
|
||||
x = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_2 + MEMCPY_OFFSET_BYTES_3);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_2) =
|
||||
(w LS MEMCPY_OFFSET_ALIGN_BITS_3) | (x RS MEMCPY_OFFSET_BITS_3);
|
||||
w = *(u32 *)(s + MEMCPY_FAST_COPY_OFFSET_UNIT_3 + MEMCPY_OFFSET_BYTES_3);
|
||||
*(u32 *)(d + MEMCPY_FAST_COPY_OFFSET_UNIT_3) =
|
||||
(x LS MEMCPY_OFFSET_ALIGN_BITS_3) | (w RS MEMCPY_OFFSET_BITS_3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n & MEMCPY_BYTE_CHECK_NUM_16) {
|
||||
*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
|
||||
*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
|
||||
*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
|
||||
*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
|
||||
}
|
||||
if (n & MEMCPY_BYTE_CHECK_NUM_8) {
|
||||
*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
|
||||
*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
|
||||
}
|
||||
if (n & MEMCPY_BYTE_CHECK_NUM_4) {
|
||||
*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
|
||||
}
|
||||
if (n & MEMCPY_BYTE_CHECK_NUM_2) {
|
||||
*d++ = *s++; *d++ = *s++;
|
||||
}
|
||||
if (n & MEMCPY_BYTE_CHECK_NUM_1) {
|
||||
*d = *s;
|
||||
}
|
||||
return dest;
|
||||
#endif
|
||||
|
||||
for (; n; n--) *d++ = *s++;
|
||||
return dest;
|
||||
}
|
60
bootloader/commonboot/libc/src/string/memmove.c
Executable file
60
bootloader/commonboot/libc/src/string/memmove.c
Executable file
@ -0,0 +1,60 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
typedef __attribute__((__may_alias__)) size_t WT;
|
||||
#define WS (sizeof(WT))
|
||||
#endif
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t size)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
|
||||
if (d == s) {
|
||||
return d;
|
||||
}
|
||||
|
||||
if ((uintptr_t)s-(uintptr_t)d-size <= -2*size) {
|
||||
return memcpy(d, s, size);
|
||||
}
|
||||
|
||||
if (d < s) {
|
||||
#ifdef __GNUC__
|
||||
if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
|
||||
while ((uintptr_t)d % WS) {
|
||||
if (!size--) {
|
||||
return dest;
|
||||
}
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
for (; size>=WS; size-=WS, d+=WS, s+=WS) {
|
||||
*(WT *)d = *(WT *)s;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (; size; size--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
} else {
|
||||
#ifdef __GNUC__
|
||||
if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
|
||||
while ((uintptr_t)(d+size) % WS) {
|
||||
if (!size--) {
|
||||
return dest;
|
||||
}
|
||||
d[size] = s[size];
|
||||
}
|
||||
while (size>=WS) {
|
||||
size-=WS, *(WT *)(d+size) = *(WT *)(s+size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while (size) {
|
||||
size--, d[size] = s[size];
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
99
bootloader/commonboot/libc/src/string/memset.c
Executable file
99
bootloader/commonboot/libc/src/string/memset.c
Executable file
@ -0,0 +1,99 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#if defined(__LITEOS__) && defined(LOSCFG_BASE_MEM_NODE_SIZE_CHECK)
|
||||
#include "los_memory.h"
|
||||
static int __memset_check(void *dest, unsigned int nodeLength)
|
||||
{
|
||||
unsigned int ret;
|
||||
unsigned int totalSize = 0;
|
||||
unsigned int availSize = 0;
|
||||
unsigned char *pool = m_aucSysMem1;
|
||||
|
||||
ret = LOS_MemNodeSizeCheck(pool, dest, &totalSize, &availSize);
|
||||
if ((ret == 0) && (nodeLength > availSize)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void *memset(void *dest, int c, size_t n)
|
||||
{
|
||||
typedef uint32_t __attribute__((__may_alias__)) u32;
|
||||
typedef uint64_t __attribute__((__may_alias__)) u64;
|
||||
|
||||
unsigned char *s = dest;
|
||||
|
||||
if (!n) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
s[0] = c;
|
||||
s[n-1] = c;
|
||||
|
||||
if (n <= 2) { // 2 bytes mem
|
||||
return dest;
|
||||
}
|
||||
|
||||
s[1] = c;
|
||||
s[2] = c;
|
||||
s[n-2] = c;
|
||||
s[n-3] = c;
|
||||
|
||||
if (n <= 6) { // 6 bytes mem
|
||||
return dest;
|
||||
}
|
||||
|
||||
s[3] = c;
|
||||
s[n-4] = c;
|
||||
|
||||
if (n <= 8) { // 8 bytes mem
|
||||
return dest;
|
||||
}
|
||||
|
||||
size_t k = -(uintptr_t)s & 3; // 3 : 4-byte boundary process
|
||||
s += k;
|
||||
n -= k;
|
||||
n &= -4;
|
||||
|
||||
u32 c32 = ((u32)-1) / 255 * (unsigned char)c;
|
||||
|
||||
*(u32 *)(s + 0) = c32;
|
||||
*(u32 *)(s + n - 4) = c32;
|
||||
if (n <= 8) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
*(u32 *)(s + 4) = c32;
|
||||
*(u32 *)(s + 8) = c32;
|
||||
*(u32 *)(s + n - 12) = c32;
|
||||
*(u32 *)(s + n - 8) = c32;
|
||||
|
||||
if (n <= 24) { // 24 bytes mem
|
||||
return dest;
|
||||
}
|
||||
|
||||
*(u32 *)(s + 12) = c32;
|
||||
*(u32 *)(s + 16) = c32;
|
||||
*(u32 *)(s + 20) = c32;
|
||||
*(u32 *)(s + 24) = c32;
|
||||
*(u32 *)(s + n - 28) = c32;
|
||||
*(u32 *)(s + n - 24) = c32;
|
||||
*(u32 *)(s + n - 20) = c32;
|
||||
*(u32 *)(s + n - 16) = c32;
|
||||
|
||||
k = 24 + ((uintptr_t)s & 4);
|
||||
s += k;
|
||||
n -= k;
|
||||
|
||||
u64 c64 = c32 | ((u64)c32 << 32);
|
||||
for (; n >= 32; n -= 32, s += 32) {
|
||||
*(u64 *)(s + 0) = c64;
|
||||
*(u64 *)(s + 8) = c64;
|
||||
*(u64 *)(s + 16) = c64;
|
||||
*(u64 *)(s + 24) = c64;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
7
bootloader/commonboot/libc/src/string/strcmp.c
Executable file
7
bootloader/commonboot/libc/src/string/strcmp.c
Executable file
@ -0,0 +1,7 @@
|
||||
#include <string.h>
|
||||
|
||||
int strcmp(const char *l, const char *r)
|
||||
{
|
||||
for (; *l==*r && *l; l++, r++);
|
||||
return *(unsigned char *)l - *(unsigned char *)r;
|
||||
}
|
25
bootloader/commonboot/libc/src/string/strlen.c
Executable file
25
bootloader/commonboot/libc/src/string/strlen.c
Executable file
@ -0,0 +1,25 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef __LITEOS__
|
||||
#undef ALIGN
|
||||
#endif
|
||||
#define ALIGN (sizeof(size_t))
|
||||
#define ONES ((size_t)-1/UCHAR_MAX)
|
||||
#define HIGHS (ONES * (UCHAR_MAX/2+1))
|
||||
#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS)
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *a = s;
|
||||
#ifdef __GNUC__
|
||||
typedef size_t __attribute__((__may_alias__)) word;
|
||||
const word *w;
|
||||
for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a;
|
||||
for (w = (const void *)s; !HASZERO(*w); w++);
|
||||
s = (const void *)w;
|
||||
#endif
|
||||
for (; *s; s++);
|
||||
return s-a;
|
||||
}
|
345
bootloader/commonboot/src/boot_cmd_loop.c
Executable file
345
bootloader/commonboot/src/boot_cmd_loop.c
Executable file
@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: boot Cmd
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
#include "boot_def.h"
|
||||
#include "boot_watchdog.h"
|
||||
#include "boot_transfer.h"
|
||||
#include "boot_delay.h"
|
||||
#include "boot_reset.h"
|
||||
#include "boot_ymodem.h"
|
||||
#include "boot_load.h"
|
||||
#include "boot_crc.h"
|
||||
#include "securec.h"
|
||||
#include "boot_cmd_loop.h"
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_READ_VERSION
|
||||
#include "boot_init.h"
|
||||
#endif
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_EFUSE_BURN
|
||||
#include "boot_efuse_opt.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_FLASH_CHIP_ERASE
|
||||
#include "boot_flash.h"
|
||||
#include "boot_erase.h"
|
||||
#include "sfc_porting.h"
|
||||
#endif
|
||||
|
||||
#define CMD_RX_DELAY_MS 100 /* 100ms */
|
||||
#define US_PER_MS 1000
|
||||
#define CMD_FRAME_TIMEOUT 2000 /* 2 s */
|
||||
#define CMD_ABNORMAL_MAX 100
|
||||
#define CHECKSUM_SIZE 2
|
||||
#define ACK_LEN 0x0C
|
||||
#define BIT_U8 8
|
||||
|
||||
typedef enum {
|
||||
CMD_RX_STATUS_WAIT_START_0,
|
||||
CMD_RX_STATUS_WAIT_START_1,
|
||||
CMD_RX_STATUS_WAIT_START_2,
|
||||
CMD_RX_STATUS_WAIT_START_3,
|
||||
CMD_RX_STATUS_WAIT_SIZE_0,
|
||||
CMD_RX_STATUS_WAIT_SIZE_1,
|
||||
CMD_RX_STATUS_WAIT_TYPE,
|
||||
CMD_RX_STATUS_WAIT_PAD,
|
||||
CMD_RX_STATUS_WAIT_DATA,
|
||||
CMD_RX_STATUS_WAIT_CS_0,
|
||||
CMD_RX_STATUS_WAIT_CS_1,
|
||||
} cmd_rx_status;
|
||||
|
||||
typedef uint32_t(*cmd_func) (const uart_ctx *cmd_ctx);
|
||||
|
||||
typedef struct {
|
||||
uint8_t cmd_type;
|
||||
cmd_func cmdfunc;
|
||||
} loader_cmd;
|
||||
|
||||
const loader_cmd g_loader_cmdtable[] = {
|
||||
{ CMD_DL_IMAGE, loader_download_image },
|
||||
{ CMD_RESET, loader_reset },
|
||||
{ CMD_FACTORY_IMAGE, loader_download_image },
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_EFUSE_BURN
|
||||
{ CMD_BURN_EFUSE, loader_burn_efuse },
|
||||
{ CMD_READ_EFUSE, loader_read_efuse },
|
||||
#endif
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_UPLOAD_DATA
|
||||
{ CMD_UL_DATA, loader_upload_data },
|
||||
#endif
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_READ_VERSION
|
||||
{ CMD_VERSION, loader_read_ver },
|
||||
#endif
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_SET_BUADRATE
|
||||
{ CMD_SET_BUADRATE, loader_set_baudrate },
|
||||
#endif
|
||||
};
|
||||
|
||||
uint32_t loader_reset(const uart_ctx *cmd_ctx)
|
||||
{
|
||||
unused(cmd_ctx);
|
||||
boot_msg0("\nReset device...\n");
|
||||
loader_ack(ACK_SUCCESS);
|
||||
mdelay(5); /* delay 5ms */
|
||||
reset();
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
uint32_t loader_download_image(const uart_ctx *cmd_ctx)
|
||||
{
|
||||
uint32_t flash_size = FLASH_MEM_SIZE;
|
||||
uint32_t download_addr = *(uint32_t *)(&cmd_ctx->packet.payload[0]);
|
||||
uint32_t file_len = *(uint32_t *)(&cmd_ctx->packet.payload[4]); /* offset 4 is file length */
|
||||
uint32_t erase_size = *(uint32_t *)(&cmd_ctx->packet.payload[8]); /* offset 8 is erase size */
|
||||
uint8_t burn_efuse = cmd_ctx->packet.payload[12]; /* offset 12 is burn efuse flag */
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_FLASH_CHIP_ERASE
|
||||
uint32_t ret;
|
||||
bool write_flash = false;
|
||||
|
||||
ret = loader_erase_all_process(cmd_ctx, &write_flash);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("Chip Erase failure!", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!write_flash) {
|
||||
// erase all only, no need to write flash, return.
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
#endif
|
||||
if (file_len == 0 || (erase_size != 0 && erase_size < file_len) || (file_len > flash_size)) {
|
||||
boot_msg0("Invalid params");
|
||||
serial_puts("download_addr ");
|
||||
serial_puthex(download_addr, 1);
|
||||
serial_puts(" file_len ");
|
||||
serial_puthex(file_len, 1);
|
||||
serial_puts(" erase_size ");
|
||||
serial_puthex(erase_size, 1);
|
||||
serial_puts("\r\n");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
if (cmd_ctx->packet.head.type == CMD_FACTORY_IMAGE) {
|
||||
return download_factory_image(download_addr, erase_size, flash_size, burn_efuse);
|
||||
}
|
||||
|
||||
return download_image(download_addr, erase_size, flash_size, burn_efuse);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_UPLOAD_DATA
|
||||
uint32_t loader_upload_data(const uart_ctx *cmd_ctx)
|
||||
{
|
||||
uint32_t file_len = *(uint32_t *)(&cmd_ctx->packet.payload[0]);
|
||||
uint32_t upload_addr = *(uint32_t *)(&cmd_ctx->packet.payload[4]); /* offset 4 is read addr */
|
||||
|
||||
if (file_len == 0 || file_len > FLASH_MEM_SIZE) {
|
||||
boot_msg0("Upload length error");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
if ((upload_addr & 0x3) != 0) {
|
||||
boot_msg0("Upload addr error");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
if ((upload_addr + file_len) > FLASH_MEM_SIZE) {
|
||||
boot_msg0("Upload addr exceeds flash capacity");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return upload_data(upload_addr, file_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_READ_VERSION
|
||||
uint32_t loader_read_ver(const uart_ctx *cmd_ctx)
|
||||
{
|
||||
unused(cmd_ctx);
|
||||
errno_t ret;
|
||||
uint8_t version[VERSION_STR_LEN] = { 0 };
|
||||
ret = memcpy_s(version, VERSION_STR_LEN, (const void *)VERSION_STR_ADDR, VERSION_STR_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
serial_put_buf((const char *)version, VERSION_STR_LEN);
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t loader_frame_head_rx(uart_ctx *ctx)
|
||||
{
|
||||
uint8_t ch;
|
||||
bool reset_flag = false;
|
||||
uint16_t rcv = 0;
|
||||
|
||||
packet_data_head *head = &ctx->packet.head;
|
||||
uint8_t *payload = (uint8_t *)head;
|
||||
|
||||
while (rcv <= CMD_ABNORMAL_MAX) {
|
||||
boot_wdt_kick();
|
||||
uint32_t ret = serial_getc_timeout(CMD_FRAME_TIMEOUT * US_PER_MS, &ch); /* read timeout < wdt timeout */
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rcv++;
|
||||
if (reset_flag == true) {
|
||||
reset_flag = false;
|
||||
head->start_flag = 0;
|
||||
ctx->status = CMD_RX_STATUS_WAIT_START_0;
|
||||
}
|
||||
if (ctx->status <= CMD_RX_STATUS_WAIT_START_3) {
|
||||
uint32_t start_flag = UART_PACKET_START_FLAG;
|
||||
uint8_t *start_byte = (uint8_t *)&start_flag;
|
||||
if (ch == start_byte[ctx->status]) {
|
||||
payload[ctx->status] = ch;
|
||||
ctx->status++;
|
||||
continue;
|
||||
} else if (ch == 0xEF) {
|
||||
payload[CMD_RX_STATUS_WAIT_START_0] = ch;
|
||||
ctx->status = CMD_RX_STATUS_WAIT_START_1;
|
||||
continue;
|
||||
}
|
||||
reset_flag = true;
|
||||
continue;
|
||||
} else {
|
||||
payload[ctx->status] = ch;
|
||||
if (ctx->status >= CMD_RX_STATUS_WAIT_START_1 && (head->packet_size > UART_PACKET_PAYLOAD_MAX)) {
|
||||
reset_flag = true;
|
||||
continue;
|
||||
}
|
||||
ctx->status++;
|
||||
if (ctx->status >= CMD_RX_STATUS_WAIT_DATA) {
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
static uint32_t loader_frame_data_rx(uart_ctx *ctx)
|
||||
{
|
||||
uint8_t ch;
|
||||
uint32_t ret;
|
||||
ctx->received = 0;
|
||||
|
||||
packet_data_head *head = &ctx->packet.head;
|
||||
uint8_t *payload = ctx->packet.payload;
|
||||
|
||||
while (ctx->received < (head->packet_size - sizeof(packet_data_head))) {
|
||||
ret = serial_getc_timeout(CMD_RX_DELAY_MS * US_PER_MS, &ch);
|
||||
if (ret == ERRCODE_SUCC) {
|
||||
payload[ctx->received++] = ch;
|
||||
continue;
|
||||
}
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
ctx->packet.check_sum = (payload[head->packet_size - 9] << 8) | payload[head->packet_size - 10]; /* 8,9,10: sub */
|
||||
payload[head->packet_size - 9] = 0; /* 9: sub 9 */
|
||||
payload[head->packet_size - 10] = 0; /* 10: sub 10 */
|
||||
|
||||
if (ctx->received == (head->packet_size - sizeof(packet_data_head))) {
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_SET_BUADRATE
|
||||
uint32_t loader_set_baudrate(const uart_ctx *cmd_ctx)
|
||||
{
|
||||
uart_param_stru *uart;
|
||||
|
||||
uart = uart_baudrate_rcv(cmd_ctx);
|
||||
if (uart == NULL) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
return serial_port_set_baudrate(uart);
|
||||
}
|
||||
#endif
|
||||
|
||||
void loader_ack(uint8_t err_code)
|
||||
{
|
||||
uart_ctx ctx = { 0 };
|
||||
packet_data_head *head = &ctx.packet.head;
|
||||
|
||||
head->start_flag = UART_PACKET_START_FLAG;
|
||||
head->type = CMD_ACK;
|
||||
head->pad = (uint8_t)(~(CMD_ACK));
|
||||
head->packet_size = ACK_LEN;
|
||||
ctx.packet.payload[0] = err_code;
|
||||
ctx.packet.payload[1] = ~err_code;
|
||||
ctx.packet.check_sum = crc16_ccitt(0, (uint8_t *)&(ctx.packet), head->packet_size - CHECKSUM_SIZE);
|
||||
|
||||
serial_put_buf((const char *)&(ctx.packet), (int)(head->packet_size - CHECKSUM_SIZE));
|
||||
serial_put_buf((const char *)&(ctx.packet.check_sum), CHECKSUM_SIZE);
|
||||
}
|
||||
|
||||
static uint32_t loader_read_frame(uart_ctx *ctx)
|
||||
{
|
||||
packet_data_info *packet = &ctx->packet;
|
||||
packet_data_head *head = &packet->head;
|
||||
uint32_t ret;
|
||||
|
||||
/* Reset receiving status.CNcomment:复位接收状态 */
|
||||
ctx->status = CMD_RX_STATUS_WAIT_START_0;
|
||||
ctx->received = 0;
|
||||
if (memset_s(packet, sizeof(packet_data_info), 0, sizeof(packet_data_info)) != EOK) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
ret = loader_frame_head_rx(ctx);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
ret = loader_frame_data_rx(ctx);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
uint16_t cs = crc16_ccitt(0, (uint8_t *)packet, head->packet_size - CHECKSUM_SIZE);
|
||||
if (cs == packet->check_sum) {
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
static uint32_t loader_exe_cmd(uart_ctx *ctx)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
packet_data_info *packet = &ctx->packet;
|
||||
packet_data_head *head = &packet->head;
|
||||
for (i = 0; i < sizeof(g_loader_cmdtable) / sizeof(g_loader_cmdtable[0]); i++) {
|
||||
if (head->type == g_loader_cmdtable[i].cmd_type) {
|
||||
if (g_loader_cmdtable[i].cmdfunc != NULL) {
|
||||
return g_loader_cmdtable[i].cmdfunc(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boot_msg1("Unsupport CMD:", head->type);
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
void cmd_loop(uart_ctx *ctx)
|
||||
{
|
||||
uint32_t ret;
|
||||
for (;;) {
|
||||
ret = loader_read_frame(ctx);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
loader_ack(ACK_FAILURE);
|
||||
continue;
|
||||
}
|
||||
ret = loader_exe_cmd(ctx);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
loader_ack(ACK_FAILURE);
|
||||
continue;
|
||||
}
|
||||
boot_wdt_kick();
|
||||
loader_ack(ACK_SUCCESS);
|
||||
boot_msg0("Execution Successful");
|
||||
boot_msg0("=========================");
|
||||
}
|
||||
}
|
63
bootloader/commonboot/src/boot_crc16.c
Executable file
63
bootloader/commonboot/src/boot_crc16.c
Executable file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: CRC
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_crc.h"
|
||||
#include "boot_def.h"
|
||||
|
||||
/* Table of CRC constants - implements x^16+x^12+x^5+1 */
|
||||
const uint16_t g_crc16_tab[] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
|
||||
};
|
||||
|
||||
uint16_t crc16_ccitt(uint16_t crc_start, uint8_t *buf, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
uint16_t cksum;
|
||||
uint8_t *input_buf = buf;
|
||||
|
||||
if ((input_buf == NULL) || (len == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cksum = crc_start;
|
||||
for (i = 0; i < len; i++) {
|
||||
cksum = g_crc16_tab[((cksum >> 8) ^ *input_buf++) & 0xff] ^ (cksum << 8); /* 8 : shift move left or right */
|
||||
}
|
||||
|
||||
return cksum;
|
||||
}
|
20
bootloader/commonboot/src/boot_debug.c
Executable file
20
bootloader/commonboot/src/boot_debug.c
Executable file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: debug
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_debug.h"
|
||||
#include "boot_def.h"
|
||||
#include "boot_init.h"
|
||||
|
||||
void set_boot_status(hi_boot_start_status status)
|
||||
{
|
||||
uapi_reg_write16(STATUS_DEBUG_REG_ADDR, status);
|
||||
}
|
||||
|
||||
uint16_t get_boot_status(void)
|
||||
{
|
||||
return uapi_reg_read_val16(STATUS_DEBUG_REG_ADDR);
|
||||
}
|
188
bootloader/commonboot/src/boot_efuse_opt.c
Executable file
188
bootloader/commonboot/src/boot_efuse_opt.c
Executable file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
|
||||
* Description: boot Cmd
|
||||
*
|
||||
* Create: 2024-01-15
|
||||
*/
|
||||
#if defined(CONFIG_LOADERBOOT_SUPPORT_SW_HASH)
|
||||
#include "sha256/sha256.h"
|
||||
#else
|
||||
#include "drv_rom_cipher.h"
|
||||
#endif
|
||||
#include "efuse_porting.h"
|
||||
#include "efuse.h"
|
||||
#include "boot_serial.h"
|
||||
#include "string.h"
|
||||
#include "soc_errno.h"
|
||||
#include "boot_cmd_loop.h"
|
||||
#include "boot_load.h"
|
||||
|
||||
#define SHA_256_LENGTH 32
|
||||
#define THREE_BITS_OFFSET 3
|
||||
|
||||
typedef struct {
|
||||
uint8_t hash[SHA_256_LENGTH]; /* hash of configuration file. */
|
||||
uint8_t stru_ver; /* default 0. */
|
||||
uint8_t stru_size; /* sizeof(struct otp_config_header). */
|
||||
uint16_t number; /* Item number to be burn. */
|
||||
uint32_t file_size; /* Configuration file size. */
|
||||
uint32_t reserved[2]; /* Reserved 2 u32. */
|
||||
uint8_t data[0]; /* Item: size = file_size - stru_size. */
|
||||
} efuse_config_header;
|
||||
|
||||
typedef struct {
|
||||
uint8_t stru_ver; /* default 0. */
|
||||
uint8_t stru_size; /* sizeof(struct otp_config_item) */
|
||||
uint16_t start_bit; /* Start bit of OTP */
|
||||
uint16_t bit_width; /* Bit width */
|
||||
uint16_t value_len; /* Length of value Byte(s), 4-byte-aligned. */
|
||||
uint8_t value[0]; /* Item, offset: stru_size. */
|
||||
} efuse_config_item;
|
||||
|
||||
static uint32_t efuse_cfg_verify(uintptr_t file_addr, uint32_t file_len)
|
||||
{
|
||||
uint8_t hash[SHA_256_LENGTH] = {0};
|
||||
efuse_config_header *header = (efuse_config_header *)file_addr;
|
||||
#if defined(CONFIG_LOADERBOOT_SUPPORT_SW_HASH)
|
||||
sha256_context_t md;
|
||||
(void)sha256_init(&md);
|
||||
(void)SHA256Update(&md, (unsigned char *)((uintptr_t)&(header->stru_ver)), (file_len - SHA_256_LENGTH));
|
||||
(void)sha256_final(&md, (unsigned char *)hash, SHA256_HASH_SIZE);
|
||||
#else
|
||||
uint32_t ret = (uint32_t)drv_rom_cipher_init();
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("drv_rom_cipher_init !!! ret = ", ret);
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
ret = (uint32_t)drv_rom_cipher_sha256(&(header->stru_ver), file_len - SHA_256_LENGTH, hash, SHA_256_LENGTH);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("drv_rom_cipher_sha256 !!! ret = ", ret);
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
ret = (uint32_t)drv_rom_cipher_deinit();
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("drv_rom_cipher_deinit !!! ret = ", ret);
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (memcmp(header->hash, hash, SHA_256_LENGTH) != EOK) {
|
||||
boot_msg0("hash commpare fail!!!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
if (header->number > (EFUSE_IDX_MAX)) {
|
||||
boot_msg0("exceed efuse index!!!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static uint32_t efuse_write_bits(uint16_t start_bit, uint16_t size, const uint8_t *key_data)
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
uint16_t a;
|
||||
uint16_t b;
|
||||
uint32_t ret;
|
||||
uint16_t zero_count = 0;
|
||||
|
||||
/* j: the current bit offset of key_data. */
|
||||
for (i = start_bit, j = 0; i < (start_bit + size); i++, j++) {
|
||||
a = j >> THREE_BITS_OFFSET; /* subscript of receive array. */
|
||||
b = j & 0x7; /* bit offset in one byte. */
|
||||
if ((key_data[a] & (uint8_t)(1 << b)) != 0) {
|
||||
ret = uapi_efuse_write_bit((i >> THREE_BITS_OFFSET), (i & 0x7));
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
zero_count++;
|
||||
}
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static uint32_t efuse_burn(uintptr_t file_addr, uint32_t file_len)
|
||||
{
|
||||
uint32_t ret = efuse_cfg_verify(file_addr, file_len);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("Efuse config file invalid");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
efuse_config_header *header = (efuse_config_header *)file_addr;
|
||||
efuse_config_item *item = (efuse_config_item *)(file_addr + header->stru_size);
|
||||
for (uint8_t i = 0; i < header->number; i++) {
|
||||
if (item == NULL) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
ret = efuse_write_bits(item->start_bit, item->bit_width, item->value);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("efuse write error, index:", i);
|
||||
serial_puts("Start bit: ");
|
||||
serial_puthex(item->start_bit, 1);
|
||||
serial_puts(" len(bits)=");
|
||||
serial_puthex(item->bit_width, 1);
|
||||
serial_puts("\n");
|
||||
}
|
||||
|
||||
item = (efuse_config_item *)((uintptr_t)item + item->stru_size + item->value_len);
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static uint32_t loady_file(uintptr_t ram_addr)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
loader_ack(ACK_SUCCESS);
|
||||
ret = loader_serial_ymodem(ram_addr, 0, sizeof(efuse_config_header), EFUSE_CFG_MAX_LEN);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t loader_burn_efuse(const uart_ctx *cmd_ctx)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint32_t file_len = *(uint32_t *)(&cmd_ctx->packet.payload[0]);
|
||||
if (file_len <= EFUSE_CFG_MIN_LEN || file_len > EFUSE_CFG_MAX_LEN) {
|
||||
boot_msg1("File length error : ", file_len);
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
ret = loady_file((uintptr_t)BURN_EFUSE_BIN_ADDR);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("Loady efuse file failed:", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = efuse_burn((uintptr_t)BURN_EFUSE_BIN_ADDR, file_len);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
uint32_t loader_read_efuse(const uart_ctx *cmd_ctx)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint16_t efuse_id = *(uint16_t *)(&cmd_ctx->packet.payload[0]);
|
||||
uint8_t data[EFUSE_READ_MAX_BYTE] = { 0 };
|
||||
boot_msg0("Efuse read");
|
||||
serial_puts("Start bit: ");
|
||||
serial_puthex(efuse_id, 1);
|
||||
serial_puts("\r\n");
|
||||
if (efuse_id >= EFUSE_IDX_MAX) {
|
||||
boot_msg0("Params err");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
ret = efuse_read_item(efuse_id, data, EFUSE_READ_MAX_BYTE);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
for (uint8_t i = 0; i < EFUSE_READ_MAX_BYTE; i++) {
|
||||
serial_puthex(data[i], 1);
|
||||
serial_puts(" ");
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
76
bootloader/commonboot/src/boot_erase.c
Executable file
76
bootloader/commonboot/src/boot_erase.c
Executable file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: boot erase
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
#include "boot_def.h"
|
||||
#include "boot_watchdog.h"
|
||||
#include "boot_transfer.h"
|
||||
#include "boot_delay.h"
|
||||
#include "securec.h"
|
||||
#include "boot_flash.h"
|
||||
#include "sfc_porting.h"
|
||||
#include "boot_cmd_loop.h"
|
||||
#include "boot_erase.h"
|
||||
|
||||
static bool g_flash_all_erased = false;
|
||||
bool loader_download_is_flash_all_erased(void)
|
||||
{
|
||||
return g_flash_all_erased;
|
||||
}
|
||||
|
||||
void loader_download_set_flash_all_erase(bool all_erased)
|
||||
{
|
||||
g_flash_all_erased = all_erased;
|
||||
}
|
||||
|
||||
static uint32_t loader_get_erasing_writing(const uart_ctx *cmd_ctx, bool *need_erase_all, bool *need_write)
|
||||
{
|
||||
uint32_t file_len = *(uint32_t *)(&cmd_ctx->packet.payload[4]); /* offset 4 is file length */
|
||||
uint32_t erase_size = *(uint32_t *)(&cmd_ctx->packet.payload[8]); /* offset 8 is erase size */
|
||||
|
||||
if (cmd_ctx->packet.head.type != CMD_DL_IMAGE) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
*need_erase_all = false;
|
||||
*need_write = false;
|
||||
if (erase_size == FLASH_CHIP_ERASE_SIZE) {
|
||||
*need_erase_all = true;
|
||||
}
|
||||
|
||||
if (file_len != FLASH_CHIP_ERASE_FILE_LEN) {
|
||||
*need_write = true;
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
uint32_t loader_erase_all_process(const uart_ctx *cmd_ctx, bool *write_flash)
|
||||
{
|
||||
uint32_t ret;
|
||||
bool need_erase_all = false;
|
||||
bool need_write = false;
|
||||
|
||||
ret = loader_get_erasing_writing(cmd_ctx, &need_erase_all, &need_write);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (need_erase_all) {
|
||||
flash_cmd_func *flash = boot_get_flash_funcs();
|
||||
if (flash == NULL) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
boot_wdt_kick();
|
||||
ret = flash->erase(0, FLASH_CHIP_ERASE_SIZE);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ret;
|
||||
}
|
||||
loader_download_set_flash_all_erase(true);
|
||||
}
|
||||
|
||||
*write_flash = need_write;
|
||||
return ERRCODE_SUCC;
|
||||
}
|
25
bootloader/commonboot/src/boot_flash.c
Executable file
25
bootloader/commonboot/src/boot_flash.c
Executable file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: flash
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_errcode.h"
|
||||
#include "securec.h"
|
||||
#include "boot_flash.h"
|
||||
|
||||
static flash_cmd_func g_flash_cmd_funcs;
|
||||
|
||||
flash_cmd_func *boot_get_flash_funcs(void)
|
||||
{
|
||||
return &g_flash_cmd_funcs;
|
||||
}
|
||||
|
||||
uint32_t boot_regist_flash_cmd(const flash_cmd_func *funcs)
|
||||
{
|
||||
if (memcpy_s(&g_flash_cmd_funcs, sizeof(flash_cmd_func), funcs, sizeof(flash_cmd_func)) != EOK) {
|
||||
return ERRCODE_MEMCPY;
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
16
bootloader/commonboot/src/boot_jump.c
Executable file
16
bootloader/commonboot/src/boot_jump.c
Executable file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: jump
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_jump.h"
|
||||
#include "boot_reset.h"
|
||||
|
||||
void jump_to_execute_addr(uint32_t addr)
|
||||
{
|
||||
void (*entry)(void) = (void*)(uintptr_t)(addr);
|
||||
entry();
|
||||
boot_fail();
|
||||
}
|
96
bootloader/commonboot/src/boot_load.c
Executable file
96
bootloader/commonboot/src/boot_load.c
Executable file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: load
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_def.h"
|
||||
#include "boot_ymodem.h"
|
||||
#include "boot_serial.h"
|
||||
#include "boot_flash.h"
|
||||
#include "boot_watchdog.h"
|
||||
#include "securec.h"
|
||||
#ifdef PROVISION_WRITE_WITH_CMD
|
||||
#include "boot_flash.h"
|
||||
#endif
|
||||
#include "boot_load.h"
|
||||
|
||||
static uint8_t g_ymodem_buf[READ_SIZE] = { 0 };
|
||||
|
||||
static uint32_t receive_file(uint32_t length, uint32_t erased_size, uintptr_t addr, uint32_t *size)
|
||||
{
|
||||
uint32_t read_len;
|
||||
uint32_t file_length = length;
|
||||
uintptr_t store_addr = addr;
|
||||
while (file_length > 0) {
|
||||
uint32_t read_size = (uint32_t)min(file_length, READ_SIZE);
|
||||
read_len = ymodem_read(g_ymodem_buf, read_size);
|
||||
if (read_len == 0 || file_length < read_len) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
#ifdef PROVISION_WRITE_WITH_INTERFACE
|
||||
unused(erased_size);
|
||||
flash_cmd_func *flash_ctr = boot_get_flash_funcs();
|
||||
uint32_t ret = flash_ctr->write(store_addr - FLASH_START, read_len, g_ymodem_buf, 0);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("flash write fail", ret);
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
#else
|
||||
if (erased_size == 0) {
|
||||
if (memcpy_s((void *)store_addr, (uint32_t)file_length, g_ymodem_buf, read_len) != EOK) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
} else {
|
||||
if (memcpy_s((void *)store_addr, (uint32_t)file_length, g_ymodem_buf, read_len) != EOK) {
|
||||
boot_msg0("flash write fail");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
file_length -= read_len;
|
||||
(*size) += read_len;
|
||||
store_addr += (uint32_t)read_len;
|
||||
boot_wdt_kick();
|
||||
}
|
||||
|
||||
(void)ymodem_read(g_ymodem_buf, READ_SIZE);
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
uint32_t loader_serial_ymodem(uint32_t offset, uint32_t erased_size, uint32_t min, uint32_t max)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
uintptr_t store_addr = offset;
|
||||
uint32_t file_length, ret;
|
||||
|
||||
ret = ymodem_open();
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
file_length = ymodem_get_length();
|
||||
if (file_length <= min || file_length > max) {
|
||||
boot_msg1("file length err : ", file_length);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((erased_size != 0) && (erased_size < file_length)) {
|
||||
boot_msg0("file_size > erase_size");
|
||||
goto err;
|
||||
}
|
||||
if (receive_file(file_length, erased_size, store_addr, &size) != ERRCODE_SUCC) {
|
||||
goto err;
|
||||
}
|
||||
if ((uint32_t)size == file_length) {
|
||||
boot_msg1("total size:", (uint32_t)size);
|
||||
ymodem_close();
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
err:
|
||||
ymodem_close();
|
||||
return ERRCODE_FAIL;
|
||||
}
|
27
bootloader/commonboot/src/boot_reset.c
Executable file
27
bootloader/commonboot/src/boot_reset.c
Executable file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: reset
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_reset.h"
|
||||
#include "boot_def.h"
|
||||
#include "boot_init.h"
|
||||
#include "non_os.h"
|
||||
|
||||
#ifdef SUPPORT_GPIO
|
||||
#include "hal_gpio.h"
|
||||
#endif
|
||||
void reset(void)
|
||||
{
|
||||
update_reset_count();
|
||||
uapi_reg_write16(BOOT_PORTING_RESET_REG, BOOT_PORTING_RESET_VALUE);
|
||||
for (;;) { }
|
||||
}
|
||||
|
||||
void boot_fail(void)
|
||||
{
|
||||
/* wait for it... */
|
||||
for (;;) { }
|
||||
}
|
346
bootloader/commonboot/src/boot_transfer.c
Executable file
346
bootloader/commonboot/src/boot_transfer.c
Executable file
@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: transfer
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_def.h"
|
||||
#include "boot_serial.h"
|
||||
#include "boot_load.h"
|
||||
#include "boot_cmd_loop.h"
|
||||
#include "boot_crc.h"
|
||||
#include "boot_flash.h"
|
||||
#include "boot_delay.h"
|
||||
#include "boot_watchdog.h"
|
||||
#include "boot_transfer.h"
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_UPLOAD_DATA
|
||||
#include "boot_malloc.h"
|
||||
#endif
|
||||
#include "boot_erase.h"
|
||||
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_UPLOAD_DATA
|
||||
upload_context *g_upload_ctx = NULL;
|
||||
#endif
|
||||
|
||||
static uint32_t download_to_flash(uint32_t flash_offset, uint32_t erase_size, uint32_t flash_size)
|
||||
{
|
||||
uint32_t size = erase_size;
|
||||
uint32_t ret = ERRCODE_FAIL;
|
||||
flash_cmd_func *flash_ctr = boot_get_flash_funcs();
|
||||
boot_wdt_kick();
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_FLASH_CHIP_ERASE
|
||||
if ((size == FLASH_CHIP_ERASE_SIZE) && !loader_download_is_flash_all_erased()) {
|
||||
#else
|
||||
if (size == FLASH_CHIP_ERASE_SIZE) {
|
||||
#endif
|
||||
ret = flash_ctr->erase(0, FLASH_CHIP_ERASE_SIZE);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_put_errno(ERRCODE_BOOT_FLASH_ERASE_ERR);
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
} else if (size != 0) {
|
||||
ret = flash_ctr->erase(flash_offset, size);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_put_errno(ERRCODE_BOOT_FLASH_ERASE_ERR);
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
} else { /* 0x0 indicates not erase */
|
||||
size = FLASH_CHIP_ERASE_SIZE;
|
||||
}
|
||||
boot_wdt_kick();
|
||||
boot_msg0("Ready for download");
|
||||
loader_ack(ACK_SUCCESS);
|
||||
ret = loader_serial_ymodem(flash_offset, size, 0, flash_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t download_image(uint32_t addr, uint32_t erase_size, uint32_t flash_size, uint8_t burn_efuse)
|
||||
{
|
||||
uint32_t ret;
|
||||
unused(burn_efuse);
|
||||
|
||||
ret = download_to_flash(addr, erase_size, flash_size);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
uint32_t download_factory_image(uint32_t addr, uint32_t erase_size, uint32_t flash_size, uint8_t burn_efuse)
|
||||
{
|
||||
uint32_t ret;
|
||||
unused(burn_efuse);
|
||||
ret = download_to_flash(addr, erase_size, flash_size);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_UPLOAD_DATA
|
||||
static uint32_t upload_malloc_init(void)
|
||||
{
|
||||
if (g_upload_ctx == NULL) {
|
||||
g_upload_ctx = (upload_context *)boot_malloc(sizeof(upload_context));
|
||||
}
|
||||
|
||||
if (g_upload_ctx == NULL) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
(void)memset_s(g_upload_ctx, sizeof(upload_context), 0, sizeof(upload_context));
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static uint32_t upload_malloc_deinit(void)
|
||||
{
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static void upload_send_file_info(void)
|
||||
{
|
||||
upload_context *ctx = g_upload_ctx;
|
||||
uint8_t name_length = UPLOAD_FILE_NAME_LEN;
|
||||
uint8_t *data = NULL;
|
||||
int32_t temp_length = (int32_t)ctx->file_length;
|
||||
int32_t count = 0;
|
||||
uint8_t temp_char;
|
||||
uint16_t crc;
|
||||
int32_t i;
|
||||
|
||||
if (ctx->retry > 0) {
|
||||
serial_put_buf((const char *)ctx->buffer, SOH_MSG_TOTAL_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
(void)memset_s(ctx->buffer, sizeof(ctx->buffer), 0, sizeof(ctx->buffer));
|
||||
ctx->buffer[0] = MODEM_SOH;
|
||||
ctx->buffer[1] = ctx->seq;
|
||||
ctx->buffer[2] = (uint8_t)~ctx->buffer[1]; /* buffer[2] is buffer[1] invert val */
|
||||
|
||||
if (memcpy_s(ctx->buffer + MSG_START_LEN, SOH_MSG_LEN, ctx->file_name, name_length) != EOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
data = ctx->buffer + MSG_START_LEN + name_length;
|
||||
|
||||
while (temp_length > 0) {
|
||||
data[count++] = (uint8_t)((uint8_t)'0' + (temp_length % DECIMAL));
|
||||
temp_length /= DECIMAL;
|
||||
}
|
||||
|
||||
/* 64 bytes, enough for storing 32-bit decimal digits
|
||||
CNcomment:64字节足够存放32位10进制数 */
|
||||
for (i = 0; i < count / 2; i++) { /* count should be divided by 2 */
|
||||
temp_char = data[i];
|
||||
data[i] = data[count - i - 1];
|
||||
data[count - i - 1] = temp_char;
|
||||
}
|
||||
|
||||
crc = crc16_ccitt(0, ctx->buffer + MSG_START_LEN, SOH_MSG_LEN);
|
||||
ctx->buffer[131] = (uint8_t)(crc >> 8); /* buffer[131] is crc high 8 bit */
|
||||
ctx->buffer[132] = (uint8_t)crc; /* buffer[132] is crc low 8 bit */
|
||||
|
||||
serial_put_buf((const char *)ctx->buffer, SOH_MSG_TOTAL_LEN);
|
||||
|
||||
ctx->status = UPLOAD_WAIT_INIT_ACK;
|
||||
}
|
||||
|
||||
static void upload_send_data(void)
|
||||
{
|
||||
upload_context *ctx = g_upload_ctx;
|
||||
uint32_t remain = ctx->file_length - ctx->offset;
|
||||
uint16_t crc;
|
||||
|
||||
if (ctx->retry > 0) {
|
||||
if (ctx->buffer[0] == MODEM_SOH) {
|
||||
serial_put_buf((const char *)ctx->buffer, SOH_MSG_TOTAL_LEN);
|
||||
} else {
|
||||
serial_put_buf((const char *)ctx->buffer, UPLOAD_BUFF_LEN);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->status = UPLOAD_WAIT_FINAL_ACK;
|
||||
(void)memset_s(ctx->buffer, sizeof(ctx->buffer), MODEM_EOF, sizeof(ctx->buffer));
|
||||
|
||||
ctx->buffer[0] = MODEM_STX;
|
||||
ctx->buffer[1] = ++ctx->seq;
|
||||
ctx->buffer[2] = (uint8_t)~ctx->buffer[1]; /* buffer[2] is buffer[1] invert val */
|
||||
|
||||
if (remain <= SOH_MSG_LEN) {
|
||||
ctx->buffer[0] = MODEM_SOH;
|
||||
if (memcpy_s(ctx->buffer + MSG_START_LEN, SOH_MSG_LEN,
|
||||
(const void *)(uintptr_t)(ctx->file_addr + ctx->offset), remain) != EOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
crc = crc16_ccitt(0, ctx->buffer + MSG_START_LEN, SOH_MSG_LEN);
|
||||
ctx->buffer[131] = (uint8_t)(crc >> 8); /* buffer[131] is crc high 8 bit */
|
||||
ctx->buffer[132] = (uint8_t)crc; /* buffer[132] is crc low 8 bit */
|
||||
serial_put_buf((const char *)ctx->buffer, SOH_MSG_TOTAL_LEN);
|
||||
} else {
|
||||
if (remain > UPLOAD_DATA_SIZE) {
|
||||
remain = UPLOAD_DATA_SIZE;
|
||||
ctx->status = UPLOAD_WAIT_INTER_ACK;
|
||||
}
|
||||
|
||||
if (memcpy_s(ctx->buffer + MSG_START_LEN, UPLOAD_DATA_SIZE,
|
||||
(const void *)(uintptr_t)(ctx->file_addr + ctx->offset), remain) != EOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
crc = crc16_ccitt(0, ctx->buffer + MSG_START_LEN, UPLOAD_DATA_SIZE);
|
||||
ctx->buffer[1027] = (uint8_t)(crc >> 8); /* buffer[1027] is crc high 8 bit */
|
||||
ctx->buffer[1028] = (uint8_t)crc; /* buffer[1028] is crc low 8 bit */
|
||||
serial_put_buf((const char *)ctx->buffer, UPLOAD_BUFF_LEN);
|
||||
}
|
||||
ctx->offset += remain;
|
||||
boot_wdt_kick();
|
||||
}
|
||||
|
||||
static void upload_send_null_info(void)
|
||||
{
|
||||
upload_context *ctx = g_upload_ctx;
|
||||
uint16_t crc;
|
||||
|
||||
(void)memset_s(ctx->buffer, sizeof(ctx->buffer), 0, SOH_MSG_LEN);
|
||||
ctx->buffer[0] = MODEM_SOH;
|
||||
ctx->buffer[1] = 0;
|
||||
ctx->buffer[2] = 0xFF; /* buffer[2] is buffer[1] invert val */
|
||||
|
||||
crc = crc16_ccitt(0, ctx->buffer + MSG_START_LEN, SOH_MSG_LEN);
|
||||
ctx->buffer[131] = (uint8_t)(crc >> 8); /* buffer[131] is crc high 8 bit */
|
||||
ctx->buffer[132] = (uint8_t)crc; /* buffer[132] is crc low 8 bit */
|
||||
serial_put_buf((const char *)ctx->buffer, SOH_MSG_TOTAL_LEN);
|
||||
|
||||
ctx->status = UPLOAD_WAIT_ZERO_ACK;
|
||||
}
|
||||
|
||||
static int32_t upload_modem_nak_step(uint8_t *status, uint32_t *timeout)
|
||||
{
|
||||
switch (*status) {
|
||||
case UPLOAD_WAIT_INIT_ACK:
|
||||
*timeout = UPLOAD_WAIT_START_C_TIME;
|
||||
upload_send_file_info();
|
||||
return 1;
|
||||
case UPLOAD_WAIT_INTER_ACK:
|
||||
case UPLOAD_WAIT_FINAL_ACK:
|
||||
upload_send_data();
|
||||
return 1;
|
||||
case UPLOAD_WAIT_EOT_C:
|
||||
serial_putc(MODEM_EOT);
|
||||
*status = UPLOAD_WAIT_EOT_C;
|
||||
return 1;
|
||||
case UPLOAD_WAIT_ZERO_ACK:
|
||||
upload_send_null_info();
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t upload_modem_c_step(uint8_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case UPLOAD_WAIT_START_C:
|
||||
upload_send_file_info();
|
||||
return 1;
|
||||
case UPLOAD_WAIT_TRANS_C:
|
||||
upload_send_data();
|
||||
return 1;
|
||||
case UPLOAD_WAIT_EOT_C:
|
||||
upload_send_null_info();
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t upload_modem_ack_step(uint8_t *status, uint32_t *timeout)
|
||||
{
|
||||
switch (*status) {
|
||||
case UPLOAD_WAIT_INIT_ACK:
|
||||
*timeout = UPLOAD_WAIT_DEFAULT_TIME;
|
||||
*status = UPLOAD_WAIT_TRANS_C;
|
||||
return 1;
|
||||
case UPLOAD_WAIT_INTER_ACK:
|
||||
upload_send_data();
|
||||
return 1;
|
||||
case UPLOAD_WAIT_FINAL_ACK:
|
||||
serial_putc(MODEM_EOT);
|
||||
*status = UPLOAD_WAIT_EOT_C;
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t upload_serial_ymodem(void)
|
||||
{
|
||||
upload_context *ctx = g_upload_ctx;
|
||||
uint8_t ch;
|
||||
uint32_t timeout = UPLOAD_WAIT_START_C_TIME;
|
||||
|
||||
for (;;) {
|
||||
uint32_t ret = serial_getc_timeout(timeout, &ch);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == MODEM_C) {
|
||||
ctx->can_cnt = 0;
|
||||
ctx->retry = 0;
|
||||
if (upload_modem_c_step(ctx->status) == 1) {
|
||||
continue;
|
||||
}
|
||||
} else if (ch == MODEM_ACK) {
|
||||
ctx->can_cnt = 0;
|
||||
ctx->retry = 0;
|
||||
if (ctx->status == UPLOAD_WAIT_ZERO_ACK) {
|
||||
mdelay(WAIT_ZERO_ACK_DELAY);
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
if (upload_modem_ack_step(&ctx->status, (uint32_t *)&timeout) == 1) {
|
||||
continue;
|
||||
}
|
||||
} else if (ch == MODEM_NAK) {
|
||||
ctx->can_cnt = 0;
|
||||
if (++ctx->retry == RETRY_COUNT) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
if (upload_modem_nak_step(&ctx->status, &timeout) == 1) {
|
||||
continue;
|
||||
}
|
||||
} else if (ch == MODEM_CAN) {
|
||||
ctx->retry = 0;
|
||||
if (++ctx->can_cnt == CAN_COUNT) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t upload_data(uint32_t addr, uint32_t length)
|
||||
{
|
||||
if (upload_malloc_init() != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
g_upload_ctx->file_addr = addr + FLASH_ADDR_OFFSET;
|
||||
g_upload_ctx->file_length = length;
|
||||
g_upload_ctx->file_name = UPLOAD_FILE_NAME;
|
||||
g_upload_ctx->status = UPLOAD_WAIT_START_C;
|
||||
|
||||
loader_ack(ACK_SUCCESS);
|
||||
|
||||
if (upload_serial_ymodem() == ERRCODE_SUCC) {
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
upload_malloc_deinit();
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
#endif
|
238
bootloader/commonboot/src/boot_uart_auth.c
Executable file
238
bootloader/commonboot/src/boot_uart_auth.c
Executable file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: uart auth
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_uart_auth.h"
|
||||
#include "boot_crc.h"
|
||||
#include "boot_delay.h"
|
||||
#include "boot_debug.h"
|
||||
#include "boot_watchdog.h"
|
||||
#include "securec.h"
|
||||
#include "boot_cmd_loop.h"
|
||||
|
||||
|
||||
#define UART_RX_DELAY_MS 100 /* 100ms */
|
||||
#define US_PER_MS 1000
|
||||
#define UTM_DISABLE 1
|
||||
#define SDC_DISABLE 0
|
||||
#define UART_ABNORMAL_MAX 32
|
||||
#define RANDOM_RETRY_MAX 100
|
||||
#define CHECKSUM_SIZE 2
|
||||
#define UART_CFG_LEN 8
|
||||
#define INTER_DATA_LEN 0x12
|
||||
#define ACK_LEN 0x0C
|
||||
#define ACK_SUCCESS 0x5A
|
||||
#define ACK_FAILURE 0xA5
|
||||
|
||||
typedef enum {
|
||||
RX_STATUS_WAIT_START_0,
|
||||
RX_STATUS_WAIT_START_1,
|
||||
RX_STATUS_WAIT_START_2,
|
||||
RX_STATUS_WAIT_START_3,
|
||||
RX_STATUS_WAIT_SIZE_0,
|
||||
RX_STATUS_WAIT_SIZE_1,
|
||||
RX_STATUS_WAIT_TYPE,
|
||||
RX_STATUS_WAIT_PAD,
|
||||
RX_STATUS_WAIT_DATA,
|
||||
RX_STATUS_WAIT_CS_0,
|
||||
RX_STATUS_WAIT_CS_1,
|
||||
} rx_status;
|
||||
|
||||
uart_param_stru g_uart_param = { 0 };
|
||||
static uint32_t g_uart_int_type = UART_TYPE_ROMBOOT_HANDSHAKE;
|
||||
static uint8_t g_encrypt_flag = 0;
|
||||
|
||||
static uint32_t uart_frame_rx(uart_ctx *ctx, uint32_t first_byte_timeout_ms);
|
||||
static uint32_t uart_frame_head_rx(uart_ctx *ctx, uint32_t first_byte_timeout_ms);
|
||||
static uint32_t uart_frame_data_rx(uart_ctx *ctx);
|
||||
static uint32_t uart_wait_usr_interrupt(uart_ctx *ctx, uint32_t interrupt_timeout_ms);
|
||||
static uint32_t uart_usr_interrupt_verify(uart_ctx *ctx);
|
||||
|
||||
static uint32_t uart_frame_rx(uart_ctx *ctx, uint32_t first_byte_timeout_ms)
|
||||
{
|
||||
packet_data_info *packet = &ctx->packet;
|
||||
packet_data_head *head = &packet->head;
|
||||
uint32_t ret = ERRCODE_FAIL;
|
||||
|
||||
/* 复位接收状态 */
|
||||
ctx->status = RX_STATUS_WAIT_START_0;
|
||||
ctx->received = 0;
|
||||
(void)memset_s(packet, sizeof(packet_data_info), 0, sizeof(packet_data_info));
|
||||
|
||||
ret = uart_frame_head_rx(ctx, first_byte_timeout_ms);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = uart_frame_data_rx(ctx);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
uint32_t cs = crc16_ccitt(0, (uint8_t *)packet, head->packet_size - CHECKSUM_SIZE);
|
||||
if (cs == packet->check_sum) {
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
static uint32_t uart_frame_head_rx(uart_ctx *ctx, uint32_t first_byte_timeout_ms)
|
||||
{
|
||||
uint8_t ch;
|
||||
bool reset_flag = false;
|
||||
uint16_t rcv = 0;
|
||||
uint32_t ret = ERRCODE_FAIL;
|
||||
|
||||
packet_data_head *head = &ctx->packet.head;
|
||||
uint8_t *payload = (uint8_t *)head;
|
||||
|
||||
while (rcv <= UART_ABNORMAL_MAX) {
|
||||
if (ctx->status == RX_STATUS_WAIT_START_0) {
|
||||
ret = serial_getc_timeout(first_byte_timeout_ms * US_PER_MS, &ch);
|
||||
} else {
|
||||
ret = serial_getc_timeout(UART_RX_DELAY_MS * US_PER_MS, &ch);
|
||||
}
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return (ctx->status == RX_STATUS_WAIT_START_0) ? UART_FIRST_CHAR_TIMEOUT : ERRCODE_FAIL;
|
||||
}
|
||||
rcv++;
|
||||
if (reset_flag == true) {
|
||||
reset_flag = false;
|
||||
head->start_flag = 0;
|
||||
ctx->status = RX_STATUS_WAIT_START_0;
|
||||
}
|
||||
if (ctx->status <= RX_STATUS_WAIT_START_3) {
|
||||
uint32_t start_flag = UART_PACKET_START_FLAG;
|
||||
uint8_t *start_byte = (uint8_t *)&start_flag;
|
||||
if (ch == start_byte[ctx->status]) {
|
||||
payload[ctx->status] = ch;
|
||||
ctx->status++;
|
||||
continue;
|
||||
} else if (ch == 0xEF) {
|
||||
payload[RX_STATUS_WAIT_START_0] = ch;
|
||||
ctx->status = RX_STATUS_WAIT_START_1;
|
||||
continue;
|
||||
}
|
||||
reset_flag = true;
|
||||
continue;
|
||||
} else {
|
||||
payload[ctx->status] = ch;
|
||||
if (ctx->status >= RX_STATUS_WAIT_SIZE_1 && (head->packet_size > UART_PACKET_PAYLOAD_MAX)) {
|
||||
reset_flag = true;
|
||||
continue;
|
||||
}
|
||||
ctx->status++;
|
||||
if (ctx->status >= RX_STATUS_WAIT_DATA) {
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
}
|
||||
boot_wdt_kick();
|
||||
}
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
static uint32_t uart_frame_data_rx(uart_ctx *ctx)
|
||||
{
|
||||
uint8_t ch;
|
||||
ctx->received = 0;
|
||||
uint32_t ret = ERRCODE_FAIL;
|
||||
packet_data_head *head = &ctx->packet.head;
|
||||
uint8_t *payload = ctx->packet.payload;
|
||||
|
||||
while (ctx->received < (head->packet_size - sizeof(packet_data_head))) {
|
||||
ret = serial_getc_timeout(UART_RX_DELAY_MS * US_PER_MS, &ch);
|
||||
if (ret == ERRCODE_SUCC) {
|
||||
payload[ctx->received++] = ch;
|
||||
continue;
|
||||
}
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
ctx->packet.check_sum = (payload[head->packet_size - 9] << 8) | payload[head->packet_size - 10]; /* 8,9,10: sub */
|
||||
payload[head->packet_size - 9] = 0; /* 9: sub 9 */
|
||||
payload[head->packet_size - 10] = 0; /* 10: sub 10 */
|
||||
|
||||
if (ctx->received == (head->packet_size - sizeof(packet_data_head))) {
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
static void uart_ack(uart_ctx *ctx)
|
||||
{
|
||||
packet_data_head *head = &ctx->packet.head;
|
||||
|
||||
head->start_flag = UART_PACKET_START_FLAG;
|
||||
head->type = UART_TYPE_ACK;
|
||||
head->pad = (uint8_t)(~(UART_TYPE_ACK));
|
||||
head->packet_size = ACK_LEN;
|
||||
ctx->packet.payload[0] = ACK_SUCCESS;
|
||||
ctx->packet.payload[1] = g_encrypt_flag;
|
||||
ctx->packet.check_sum = crc16_ccitt(0, (uint8_t *)&(ctx->packet), head->packet_size - CHECKSUM_SIZE);
|
||||
|
||||
serial_put_buf ((const char *)&(ctx->packet), (int)(head->packet_size - CHECKSUM_SIZE));
|
||||
serial_put_buf ((const char *)&(ctx->packet.check_sum), CHECKSUM_SIZE);
|
||||
}
|
||||
|
||||
uint32_t uart_process(uint32_t interrupt_timeout_ms)
|
||||
{
|
||||
uart_ctx uart_ctx = { 0 };
|
||||
set_boot_status(HI_BOOT_WAIT_UART_INTERRUPT);
|
||||
if (uart_wait_usr_interrupt(&uart_ctx, interrupt_timeout_ms) != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
uart_ack(&uart_ctx);
|
||||
uart_ack(&uart_ctx);
|
||||
uart_ack(&uart_ctx);
|
||||
|
||||
/* wait transmit ok */
|
||||
mdelay(5); /* 5: wait 5 ms */
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static uint32_t uart_wait_usr_interrupt(uart_ctx *ctx, uint32_t interrupt_timeout_ms)
|
||||
{
|
||||
volatile uint32_t ret = ERRCODE_FAIL;
|
||||
ret = uart_frame_rx(ctx, interrupt_timeout_ms);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return uart_usr_interrupt_verify(ctx);
|
||||
}
|
||||
|
||||
static uint32_t uart_usr_interrupt_verify(uart_ctx *ctx)
|
||||
{
|
||||
packet_data_head *head = &ctx->packet.head;
|
||||
if ((head->packet_size == INTER_DATA_LEN) && (g_uart_int_type == head->type)) {
|
||||
if (head->type == UART_TYPE_ROMBOOT_HANDSHAKE) {
|
||||
(void)memcpy_s((void *)&g_uart_param, sizeof(uart_param_stru),
|
||||
(void *)(ctx->packet.payload), UART_CFG_LEN);
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_SET_BUADRATE
|
||||
uart_param_stru* uart_baudrate_rcv(const uart_ctx *ctx)
|
||||
{
|
||||
uart_ctx uart = { 0 };
|
||||
packet_data_head *head = &(((uart_ctx*)ctx)->packet.head);
|
||||
|
||||
if ((head->packet_size != INTER_DATA_LEN) || (head->type != CMD_SET_BUADRATE)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)memcpy_s((void *)&g_uart_param, sizeof(uart_param_stru), (void *)(ctx->packet.payload), UART_CFG_LEN);
|
||||
uart_ack(&uart);
|
||||
mdelay(5); /* 5: wait 5 ms for transmit ok */
|
||||
return &g_uart_param;
|
||||
}
|
||||
#endif
|
416
bootloader/commonboot/src/boot_ymodem.c
Executable file
416
bootloader/commonboot/src/boot_ymodem.c
Executable file
@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: ymodem
|
||||
*
|
||||
* Create: 2023-01-09
|
||||
*/
|
||||
|
||||
#include "boot_errcode.h"
|
||||
#include "boot_def.h"
|
||||
#include "boot_crc.h"
|
||||
#include "boot_delay.h"
|
||||
#include "boot_serial.h"
|
||||
#include "boot_watchdog.h"
|
||||
#include "securec.h"
|
||||
#include "boot_ymodem.h"
|
||||
#ifndef CONFIG_LOADERBOOT_SUPPORT_DYNAMIC_PACKET_SIZE
|
||||
#define YMODEM_PACKET_SIZE 1024 /* packet size: 1024 Bytes */
|
||||
#else
|
||||
#define YMODEM_PACKET_SIZE CONFIG_YMODEM_PACKET_BUFFER_SZIE
|
||||
#endif
|
||||
#define YMODEM_SOH 0x01 /* start packet, size 128 Bytes */
|
||||
#define YMODEM_STX 0x02 /* data packet, size 1024 Bytes */
|
||||
#define YMODEM_EOT 0x04 /* End of transfer */
|
||||
#define YMODEM_ACK 0x06 /* receive success */
|
||||
#define YMODEM_STX_A 0x0a
|
||||
#define YMODEM_STX_B 0x0b
|
||||
#define YMODEM_STX_C 0x0c
|
||||
#define YMODEM_CAN 0x18 /* receiver cancel */
|
||||
#define YMODEM_C 0x43 /* asscii 'C' */
|
||||
#define YMODEM_MAX_RETRIES 20
|
||||
#define YMODEM_CAN_MAX 3
|
||||
#define YMODEM_LEN_SHORT 128
|
||||
#define YMODEM_LEN_1K 1024
|
||||
#define YMODEM_LEN_2K 2048
|
||||
#define YMODEM_LEN_4K 4096
|
||||
#define YMODEM_LEN_8K 8192
|
||||
#define YMODEM_DELAY 20 /* 20 us */
|
||||
#define YMODEM_DELAY_MAX 1000000 /* 50000 * 20us value 1s */
|
||||
|
||||
typedef struct {
|
||||
uint32_t packet_len;
|
||||
uint8_t packet[YMODEM_PACKET_SIZE];
|
||||
bool rx_eof;
|
||||
bool tx_ack;
|
||||
uint8_t blk;
|
||||
uint8_t expected_blk;
|
||||
uint32_t file_length;
|
||||
uint32_t read_length;
|
||||
} ymodem_context;
|
||||
|
||||
static ymodem_context g_ymodem;
|
||||
|
||||
static uint32_t ymodem_get_packet(void);
|
||||
static int32_t ymodem_getc(void);
|
||||
static uint32_t ymodem_getc_timeout(uint8_t *ch);
|
||||
static void ymodem_flush(void);
|
||||
static uint32_t ymodem_parse_length(const uint8_t *buffer, uint32_t *length, uint32_t parse_max);
|
||||
|
||||
static uint32_t is_hex(int8_t ch)
|
||||
{
|
||||
if (((ch >= '0') && (ch <= '9')) ||
|
||||
((ch >= 'A') && (ch <= 'F')) ||
|
||||
((ch >= 'a') && (ch <= 'f'))) {
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
static uint32_t convert_hex(int8_t ch)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
if ((ch >= '0') && (ch <= '9')) {
|
||||
val = (uint32_t)(int32_t)(ch - '0');
|
||||
} else if ((ch >= 'a') && (ch <= 'f')) {
|
||||
val = (uint32_t)(int32_t)(ch - 'a' + 10); /* 10: add 10 */
|
||||
} else if ((ch >= 'A') && (ch <= 'F')) {
|
||||
val = (uint32_t)(int32_t)(ch - 'A' + 10); /* 10: add 10 */
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int32_t ymodem_getc(void)
|
||||
{
|
||||
if (uapi_uart_rx_fifo_is_empty(g_hiburn_uart) == false) {
|
||||
return serial_getc();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ymodem_getc_timeout(uint8_t *ch)
|
||||
{
|
||||
return serial_getc_timeout(YMODEM_DELAY_MAX, ch);
|
||||
}
|
||||
|
||||
static uint32_t ymodem_get_head_process(void)
|
||||
{
|
||||
uint32_t ret = ERRCODE_FAIL, hdr_ch_cnt = 0, can_count = 0;
|
||||
uint8_t ch = 0xff; /* set to invalid value 0xff. */
|
||||
bool hdr_flag = false;
|
||||
while (hdr_flag == false) {
|
||||
ret = ymodem_getc_timeout(&ch);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
ymodem_flush();
|
||||
mdelay(20); /* delay 20 ms. */
|
||||
return ERRCODE_BOOT_YMODEM_TIMEOUT;
|
||||
}
|
||||
|
||||
hdr_ch_cnt++;
|
||||
switch (ch) {
|
||||
case YMODEM_SOH:
|
||||
hdr_flag = true;
|
||||
g_ymodem.packet_len = YMODEM_LEN_SHORT;
|
||||
break;
|
||||
case YMODEM_STX:
|
||||
hdr_flag = true;
|
||||
g_ymodem.packet_len = YMODEM_LEN_1K;
|
||||
break;
|
||||
case YMODEM_STX_A:
|
||||
hdr_flag = true;
|
||||
g_ymodem.packet_len = YMODEM_LEN_2K;
|
||||
break;
|
||||
case YMODEM_STX_B:
|
||||
hdr_flag = true;
|
||||
g_ymodem.packet_len = YMODEM_LEN_4K;
|
||||
break;
|
||||
case YMODEM_STX_C:
|
||||
hdr_flag = true;
|
||||
g_ymodem.packet_len = YMODEM_LEN_8K;
|
||||
break;
|
||||
|
||||
case YMODEM_CAN:
|
||||
if (++can_count == YMODEM_CAN_MAX) {
|
||||
return ERRCODE_BOOT_YMODEM_CANCEL;
|
||||
}
|
||||
|
||||
/* wait for more CAN */
|
||||
break;
|
||||
|
||||
case YMODEM_EOT:
|
||||
if (hdr_ch_cnt == 1) {
|
||||
serial_putc(YMODEM_ACK);
|
||||
return ERRCODE_BOOT_YMODEM_EOT;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
uint32_t ymodem_get_packet(void)
|
||||
{
|
||||
uint8_t crc_lo = 0xff; /* set to invalid value 0xff. */
|
||||
uint8_t crc_hi = 0xff; /* set to invalid value 0xff. */
|
||||
uint8_t blk = 0xff; /* set to invalid value 0xff. */
|
||||
uint8_t cblk = 0xff; /* set to invalid value 0xff. */
|
||||
uint32_t ret = ERRCODE_FAIL;
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
if (g_ymodem.tx_ack == true) {
|
||||
serial_putc(YMODEM_ACK);
|
||||
g_ymodem.tx_ack = false;
|
||||
}
|
||||
|
||||
ret = ymodem_get_head_process();
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* header found, start read data */
|
||||
ret = ymodem_getc_timeout(&blk);
|
||||
if (ret == ERRCODE_FAIL) {
|
||||
return ERRCODE_BOOT_YMODEM_TIMEOUT;
|
||||
}
|
||||
|
||||
ret = ymodem_getc_timeout(&cblk);
|
||||
if (ret == ERRCODE_FAIL) {
|
||||
return ERRCODE_BOOT_YMODEM_TIMEOUT;
|
||||
}
|
||||
udelay(3); /* delay 3 us. */
|
||||
for (i = 0; i < g_ymodem.packet_len; i++) {
|
||||
ret = ymodem_getc_timeout(&g_ymodem.packet[i]);
|
||||
if (ret == ERRCODE_FAIL) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = ymodem_getc_timeout(&crc_hi);
|
||||
if (ret == ERRCODE_FAIL) {
|
||||
return ERRCODE_BOOT_YMODEM_TIMEOUT;
|
||||
}
|
||||
|
||||
ret = ymodem_getc_timeout(&crc_lo);
|
||||
if (ret == ERRCODE_FAIL) {
|
||||
return ERRCODE_BOOT_YMODEM_TIMEOUT;
|
||||
}
|
||||
|
||||
/* verify the packet */
|
||||
if ((blk ^ cblk) != 0xFF) {
|
||||
return ERRCODE_BOOT_YMODEM_FRAME;
|
||||
}
|
||||
|
||||
uint16_t cs = crc16_ccitt(0, g_ymodem.packet, g_ymodem.packet_len);
|
||||
if (cs != makeu16(crc_lo, crc_hi)) {
|
||||
return ERRCODE_BOOT_YMODEM_CS;
|
||||
}
|
||||
|
||||
g_ymodem.blk = (uint8_t)blk;
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static uint32_t ymodem_get_info(void)
|
||||
{
|
||||
if (g_ymodem.blk == 0) {
|
||||
udelay(3); /* delay 3 us. */
|
||||
uint8_t *buffer = g_ymodem.packet;
|
||||
uint32_t counter_times = YMODEM_LEN_SHORT;
|
||||
/* skip file name */
|
||||
while (*buffer++ != '\0') {
|
||||
if (counter_times-- <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* get file length */
|
||||
if (ymodem_parse_length((const uint8_t *)buffer, &g_ymodem.file_length, YMODEM_LEN_SHORT) != ERRCODE_SUCC) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
if (g_ymodem.file_length < LOAD_MIN_SIZE || g_ymodem.file_length > LOAD_MAX_SIZE) {
|
||||
return ERRCODE_BOOT_YMODEM_LENTH;
|
||||
}
|
||||
g_ymodem.tx_ack = true;
|
||||
}
|
||||
g_ymodem.expected_blk = 1;
|
||||
g_ymodem.packet_len = 0;
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
uint32_t ymodem_open(void)
|
||||
{
|
||||
g_ymodem.packet_len = 0;
|
||||
g_ymodem.file_length = 0;
|
||||
g_ymodem.read_length = 0;
|
||||
g_ymodem.tx_ack = false;
|
||||
g_ymodem.rx_eof = false;
|
||||
|
||||
serial_putc(YMODEM_C);
|
||||
int32_t retries = YMODEM_MAX_RETRIES;
|
||||
boot_wdt_kick();
|
||||
uint32_t ret = 0;
|
||||
|
||||
while (retries-- > 0) {
|
||||
ret = ymodem_get_packet();
|
||||
if (ret == ERRCODE_SUCC) {
|
||||
return ymodem_get_info();
|
||||
}
|
||||
if (ret == ERRCODE_BOOT_YMODEM_CANCEL) {
|
||||
break;
|
||||
}
|
||||
if (ret == ERRCODE_BOOT_YMODEM_TIMEOUT) {
|
||||
if (retries < 0) {
|
||||
return ERRCODE_BOOT_YMODEM_TIMEOUT;
|
||||
}
|
||||
boot_wdt_kick();
|
||||
mdelay(20); /* delay 20 ms */
|
||||
serial_putc(YMODEM_C);
|
||||
}
|
||||
}
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
void ymodem_close(void)
|
||||
{
|
||||
for (;;) {
|
||||
if (ymodem_getc() < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void get_packet_len(void)
|
||||
{
|
||||
g_ymodem.tx_ack = true;
|
||||
g_ymodem.expected_blk = (g_ymodem.expected_blk + 1) & 0xff;
|
||||
g_ymodem.read_length += (uint32_t)g_ymodem.packet_len;
|
||||
if (g_ymodem.read_length > g_ymodem.file_length) {
|
||||
g_ymodem.packet_len -= (uint32_t)(g_ymodem.read_length - g_ymodem.file_length);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t ymodem_check_packet(void)
|
||||
{
|
||||
uint32_t ret = ERRCODE_FAIL;
|
||||
int32_t retries = YMODEM_MAX_RETRIES;
|
||||
while (retries-- > 0) {
|
||||
ret = ymodem_get_packet();
|
||||
if (ret == ERRCODE_SUCC) {
|
||||
if (g_ymodem.blk == g_ymodem.expected_blk) {
|
||||
get_packet_len();
|
||||
break;
|
||||
} else if (g_ymodem.blk == ((g_ymodem.expected_blk - 1) & 0xff)) {
|
||||
serial_putc(YMODEM_ACK);
|
||||
continue;
|
||||
} else {
|
||||
ret = ERRCODE_BOOT_YMODEM_SEQ;
|
||||
}
|
||||
}
|
||||
if (ret == ERRCODE_BOOT_YMODEM_CANCEL) {
|
||||
break;
|
||||
}
|
||||
if (ret == ERRCODE_BOOT_YMODEM_EOT) {
|
||||
serial_putc(YMODEM_ACK);
|
||||
serial_putc(YMODEM_C);
|
||||
ret = ymodem_get_packet();
|
||||
serial_putc(YMODEM_ACK);
|
||||
|
||||
g_ymodem.rx_eof = true;
|
||||
break;
|
||||
}
|
||||
ymodem_flush();
|
||||
serial_putc(YMODEM_C);
|
||||
boot_wdt_kick();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t ymodem_read(uint8_t* buf, uint32_t size)
|
||||
{
|
||||
uint8_t* read_buf = buf;
|
||||
uint32_t read_size = size;
|
||||
uint32_t rx_total = 0;
|
||||
/* read 'read_size' bytes into 'buf' */
|
||||
while ((g_ymodem.rx_eof == false) && (read_size > 0)) {
|
||||
if (g_ymodem.packet_len == 0) {
|
||||
if (ymodem_check_packet() != ERRCODE_SUCC) {
|
||||
return rx_total;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ymodem.rx_eof == false) {
|
||||
uint32_t length = min(read_size, g_ymodem.packet_len);
|
||||
|
||||
errcode_t ret = memcpy_s(read_buf, (uint32_t)read_size, g_ymodem.packet, length);
|
||||
if (ret != EOK) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
read_size -= length;
|
||||
read_buf += length;
|
||||
rx_total += length;
|
||||
g_ymodem.packet_len = 0;
|
||||
}
|
||||
}
|
||||
return rx_total;
|
||||
}
|
||||
|
||||
uint32_t ymodem_parse_length(const uint8_t *buffer, uint32_t *length, uint32_t parse_max)
|
||||
{
|
||||
const uint8_t *read_buffer = buffer;
|
||||
uint32_t value = 0;
|
||||
uint32_t radix = DECIMAL;
|
||||
uint32_t count = parse_max;
|
||||
if (read_buffer == NULL || length == NULL) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
/* skip 'space' */
|
||||
while (*read_buffer == ' ' && count > 0) {
|
||||
read_buffer++;
|
||||
count--;
|
||||
}
|
||||
/* 1: makesure >= 2 */
|
||||
if ((read_buffer[0] == '0') && ((read_buffer[1] == 'x') || (read_buffer[1] == 'X')) && count > 1) {
|
||||
radix = HEXADECIMAL;
|
||||
read_buffer += 2; /* 2: add 2 */
|
||||
count -= 2; /* 2: sub 2 */
|
||||
}
|
||||
|
||||
while (*read_buffer != '\0' && count > 0) {
|
||||
int8_t ch = (int8_t)*read_buffer++;
|
||||
if (is_hex(ch) == ERRCODE_FAIL) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
uint32_t tmp = convert_hex(ch);
|
||||
if (tmp <= radix) {
|
||||
value *= radix;
|
||||
value += tmp;
|
||||
}
|
||||
}
|
||||
|
||||
*length = value;
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
uint32_t ymodem_get_length(void)
|
||||
{
|
||||
return g_ymodem.file_length;
|
||||
}
|
||||
|
||||
void ymodem_flush(void)
|
||||
{
|
||||
for (;;) {
|
||||
uint8_t ch = 0xff;
|
||||
uint32_t ret = ymodem_getc_timeout(&ch);
|
||||
if (ret == ERRCODE_FAIL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
741
bootloader/commonboot/src/secure_verify_boot.c
Executable file
741
bootloader/commonboot/src/secure_verify_boot.c
Executable file
@ -0,0 +1,741 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
* Description: Secure Verify for Loaderboot and Flashboot
|
||||
*
|
||||
* Create: 2023-03-09
|
||||
*/
|
||||
|
||||
#include "boot_serial.h"
|
||||
#include "securec.h"
|
||||
#include "efuse_wrap.h"
|
||||
#include "drv_rom_cipher.h"
|
||||
#include "boot_errcode.h"
|
||||
#include "secure_verify_boot.h"
|
||||
|
||||
#define MAINTENANCE_MODE_EN 0x2A13C812
|
||||
|
||||
#define OEM_ROOT_PUBLIC_KEY_IMAGE_ID 0x4BA5C31E
|
||||
#define PROVISION_KEY_AREA_IMAGE_ID 0x4BD2F01E
|
||||
#define PROVISION_CODE_INFO_IMAGE_ID 0x4BD2F02D
|
||||
#define PARAMS_KEY_AREA_IMAGE_ID 0x4B87A51E
|
||||
#define PARAMS_AREA_INFO_IMAGE_ID 0x4B87A52D
|
||||
#define PARAMS_AREA_IMAGE_ID 0x4B87A54B
|
||||
#define FLASHBOOT_KEY_AREA_IMAGE_ID 0x4B1E3C1E
|
||||
#define FLASHBOOT_CODE_INFO_IMAGE_ID 0x4B1E3C2D
|
||||
#define FLASHBOOT_BACKUP_KEY_AREA_IMAGE_ID 0x4B69871E
|
||||
#define FLASHBOOT_BACKUP_CODE_INFO_IMAGE_ID 0x4B69872D
|
||||
#define APPBOOT_KEY_AREA_IMAGE_ID 0x4B0F2D1E
|
||||
#define APPBOOT_CODE_INFO_IMAGE_ID 0x4B0F2D2D
|
||||
|
||||
#define boot_array_size(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
typedef struct {
|
||||
image_type_t image_type;
|
||||
area_type_t erea_type;
|
||||
uint32_t image_id;
|
||||
efuse_idx efuse_type;
|
||||
} verify_table_item_t;
|
||||
|
||||
uint32_t g_rootkey_status = 0;
|
||||
|
||||
static verify_table_item_t g_verify_table[] = {
|
||||
{
|
||||
.image_type = LOADER_BOOT_TYPE, .erea_type = KEY_EREA_TYPE,
|
||||
.image_id = PROVISION_KEY_AREA_IMAGE_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = LOADER_BOOT_TYPE, .erea_type = CODE_INFO_TYPE,
|
||||
.image_id = PROVISION_CODE_INFO_IMAGE_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = FLASH_BOOT_TYPE, .erea_type = KEY_EREA_TYPE,
|
||||
.image_id = FLASHBOOT_KEY_AREA_IMAGE_ID,
|
||||
.efuse_type = EFUSE_FLASHBOOT_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = FLASH_BOOT_TYPE, .erea_type = CODE_INFO_TYPE,
|
||||
.image_id = FLASHBOOT_CODE_INFO_IMAGE_ID,
|
||||
.efuse_type = EFUSE_FLASHBOOT_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = FLASH_BOOT_BACK_UP_TYPE, .erea_type = KEY_EREA_TYPE,
|
||||
.image_id = FLASHBOOT_BACKUP_KEY_AREA_IMAGE_ID,
|
||||
.efuse_type = EFUSE_FLASHBOOT_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = FLASH_BOOT_BACK_UP_TYPE, .erea_type = CODE_INFO_TYPE,
|
||||
.image_id = FLASHBOOT_BACKUP_CODE_INFO_IMAGE_ID,
|
||||
.efuse_type = EFUSE_FLASHBOOT_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = SECOND_FLASH_BOOT_TYPE, .erea_type = KEY_EREA_TYPE,
|
||||
.image_id = FLASHBOOT_KEY_AREA_IMAGE_ID,
|
||||
.efuse_type = EFUSE_FLASHBOOT_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = SECOND_FLASH_BOOT_TYPE, .erea_type = CODE_INFO_TYPE,
|
||||
.image_id = FLASHBOOT_CODE_INFO_IMAGE_ID,
|
||||
.efuse_type = EFUSE_FLASHBOOT_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = SECOND_FLASH_BOOT_BACK_UP_TYPE, .erea_type = KEY_EREA_TYPE,
|
||||
.image_id = FLASHBOOT_BACKUP_KEY_AREA_IMAGE_ID,
|
||||
.efuse_type = EFUSE_FLASHBOOT_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = SECOND_FLASH_BOOT_BACK_UP_TYPE, .erea_type = CODE_INFO_TYPE,
|
||||
.image_id = FLASHBOOT_BACKUP_CODE_INFO_IMAGE_ID,
|
||||
.efuse_type = EFUSE_FLASHBOOT_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = PARAMS_BOOT_TYPE, .erea_type = PARAMS_KEY_AREA_TYPE,
|
||||
.image_id = PARAMS_KEY_AREA_IMAGE_ID,
|
||||
.efuse_type = EFUSE_PARAMS_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = PARAMS_BOOT_TYPE, .erea_type = PARAMS_AREA_INFO_TYPE,
|
||||
.image_id = PARAMS_AREA_INFO_IMAGE_ID,
|
||||
.efuse_type = EFUSE_PARAMS_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = APP_BOOT_TYPE, .erea_type = KEY_EREA_TYPE,
|
||||
.image_id = APPBOOT_KEY_AREA_IMAGE_ID,
|
||||
.efuse_type = EFUSE_MCU_VER_ID
|
||||
},
|
||||
|
||||
{
|
||||
.image_type = APP_BOOT_TYPE, .erea_type = CODE_INFO_TYPE,
|
||||
.image_id = APPBOOT_CODE_INFO_IMAGE_ID,
|
||||
.efuse_type = EFUSE_MCU_VER_ID
|
||||
},
|
||||
};
|
||||
|
||||
static errcode_t check_image_id(image_type_t image_type, area_type_t erea_type, uint32_t image_id)
|
||||
{
|
||||
uint32_t image_id_check = 0;
|
||||
|
||||
for (uint32_t i = 0; i < boot_array_size(g_verify_table); i++) {
|
||||
if (image_type == g_verify_table[i].image_type && erea_type == g_verify_table[i].erea_type) {
|
||||
image_id_check = g_verify_table[i].image_id;
|
||||
break;
|
||||
}
|
||||
if (i == boot_array_size(g_verify_table)) {
|
||||
boot_msg0("get key erea iamge id failed!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (image_id != image_id_check) {
|
||||
boot_msg0("image id error!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static uint32_t count_bit_num(uint32_t input)
|
||||
{
|
||||
uint32_t count = 0; /* count accumulates the total bits set in input */
|
||||
uint32_t input_copy = input;
|
||||
|
||||
for (count = 0; input_copy >= 1; count++) {
|
||||
input_copy &= input_copy - 1; /* clear the least significant bit set */
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static errcode_t check_version(image_type_t image_type, uint32_t version, uint32_t version_mask)
|
||||
{
|
||||
uint32_t efuse_version = 0;
|
||||
uint32_t efuse_idx = 0;
|
||||
uint32_t ret = 0;
|
||||
|
||||
for (uint32_t i = 0; i < boot_array_size(g_verify_table); i++) {
|
||||
if (image_type == g_verify_table[i].image_type) {
|
||||
efuse_idx = g_verify_table[i].efuse_type;
|
||||
break;
|
||||
}
|
||||
if (i == boot_array_size(g_verify_table)) {
|
||||
boot_msg0("get key erea iamge id failed!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* read otp version */
|
||||
/* sizeof(efuse_version) = 4 */
|
||||
ret = efuse_read_item(efuse_idx, (uint8_t *)&efuse_version, (uint16_t)sizeof(efuse_version));
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("version efuse_read_item fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
if (count_bit_num(version & version_mask) < count_bit_num(efuse_version & version_mask)) {
|
||||
boot_msg0("version compare fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static errcode_t check_msid(uint32_t msid, uint32_t msid_mask)
|
||||
{
|
||||
uint32_t efuse_msid = 0;
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* sizeof(efuse_msid) = 4 */
|
||||
ret = efuse_read_item(EFUSE_MSID_ID, (uint8_t *)&efuse_msid, (uint16_t)sizeof(efuse_msid));
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("version efuse_read_item fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
if ((msid & msid_mask) != (efuse_msid & msid_mask)) {
|
||||
boot_msg0("msid compare fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static errcode_t check_die_id(uint8_t *die_id, uint32_t die_id_length)
|
||||
{
|
||||
uint8_t efuse_die_id[DIE_ID_LEN] = { 0 };
|
||||
uint32_t ret = 0;
|
||||
|
||||
if (die_id_length != DIE_ID_LEN) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
/* sizeof(efuse_die_id) = 16 */
|
||||
ret = efuse_read_item(EFUSE_DIE_ID, (uint8_t *)efuse_die_id, (uint16_t)sizeof(efuse_die_id));
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("die_id efuse_read_item fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
ret = memcmp(efuse_die_id, die_id, die_id_length);
|
||||
if (ret != 0) {
|
||||
boot_msg0("die id memcmp fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static errcode_t check_verify_enable(void)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
uint8_t verify_enable = 0xff;
|
||||
|
||||
/* sizeof(verify_enable) = 1 */
|
||||
ret = efuse_read_item(EFUSE_SEC_VERIFY_ENABLE, &verify_enable, (uint16_t)sizeof(verify_enable));
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("efuse_read_item verify enable fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
if (verify_enable == 0) {
|
||||
return ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BOOT_SUPPORT_ECC_VERIFY)
|
||||
static errcode_t secure_authenticate(const uint8_t *key, const uint8_t *data, uint32_t data_length,
|
||||
const uint8_t *sign_buff, uint32_t sign_length)
|
||||
{
|
||||
uint8_t hash_result[HASH_LEN];
|
||||
drv_rom_cipher_ecc_point input_pub_key = { 0 };
|
||||
drv_rom_cipher_data input_hash = { 0 };
|
||||
drv_rom_cipher_ecc_sig input_sig = { 0 };
|
||||
uint32_t ret = 0;
|
||||
|
||||
ret = drv_rom_cipher_sha256(data, data_length, hash_result, (uint32_t)HASH_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("secure_authenticate drv_rom_cipher_sha256 fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
input_pub_key.x = (uint8_t *)key;
|
||||
input_pub_key.y = (uint8_t *)(key + 32); /* 32 is ecc bp256 key length */
|
||||
input_pub_key.length = 32; /* 32 is ecc bp256 key length */
|
||||
input_hash.data = hash_result;
|
||||
input_hash.length = HASH_LEN;
|
||||
input_sig.r = (uint8_t *)sign_buff;
|
||||
input_sig.s = (uint8_t *)(sign_buff + sign_length / 2); /* 2: sign = r + s */
|
||||
input_sig.length = sign_length / 2; /* 2: sign = r + s */
|
||||
|
||||
ret = (uint32_t)drv_rom_cipher_pke_bp256r_verify(&input_pub_key, &input_hash, &input_sig);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("secure_authenticate drv_rom_cipher_pke_bp256r_verify fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BOOT_SUPPORT_SM2_VERIFY)
|
||||
static errcode_t secure_authenticate(const uint8_t *key, const uint8_t *data, uint32_t data_length,
|
||||
const uint8_t *sign_buff, uint32_t sign_length)
|
||||
{
|
||||
uint8_t hash_result[HASH_LEN] = { 0 };
|
||||
drv_rom_cipher_ecc_point input_pub_key = { 0 };
|
||||
drv_rom_cipher_pke_msg input_msg = { 0 };
|
||||
drv_rom_cipher_data input_hash = { 0 };
|
||||
drv_rom_cipher_ecc_sig input_sig = { 0 };
|
||||
uint8_t sm2_id[18] = "\x42\x4c\x49\x43\x45\x31\x32\x33\x40\x59\x41\x48\x4f\x4f\x2\x43\x4f\x11";
|
||||
uint32_t ret = 0;
|
||||
|
||||
input_pub_key.x = (uint8_t *)key;
|
||||
input_pub_key.y = (uint8_t *)(key + 32); /* 32 is sm2 key length */
|
||||
input_pub_key.length = 32; /* 32 is sm2 key length */
|
||||
input_msg.data = (uint8_t *)data;
|
||||
input_msg.length = data_length;
|
||||
input_hash.data = hash_result;
|
||||
input_hash.length = sizeof(hash_result);
|
||||
ret = drv_rom_cipher_pke_sm2_dsa_hash(sm2_id, &input_pub_key, &input_msg, &input_hash);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("secure_authenticate drv_rom_cipher_pke_sm2_dsa_hash fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
input_sig.r = (uint8_t *)sign_buff;
|
||||
input_sig.s = (uint8_t *)(sign_buff + sign_length / 2); /* 2: sign = r + s */
|
||||
input_sig.length = sign_length / 2; /* 2: sign = r + s */
|
||||
ret = drv_rom_cipher_pke_sm2_verify(input_pub_key, input_hash, input_sig);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("secure_authenticate drv_rom_cipher_pke_sm2_verify fail!");
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static errcode_t verify_params_key_area(const params_key_area_t *key_area, const uint8_t *public_key)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* check verify enable */
|
||||
ret = check_verify_enable();
|
||||
if (ret == ERRCODE_NOT_SUPPORT) {
|
||||
return ERRCODE_SUCC;
|
||||
} else if (ret == ERRCODE_FAIL) {
|
||||
boot_msg0("verify_params_key_area secure verify error!");
|
||||
return ERRCODE_BOOT_VERIFY_CHECK_ENABLE;
|
||||
}
|
||||
|
||||
if (g_rootkey_status != 0x5) {
|
||||
boot_msg0("verify_params_key_area rootkey_status invalid!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_ROOT_KEY;
|
||||
}
|
||||
|
||||
/* check image id */
|
||||
ret = check_image_id(PARAMS_BOOT_TYPE, PARAMS_KEY_AREA_TYPE, key_area->image_id);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_key_area image id error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_IMAGE_ID;
|
||||
}
|
||||
|
||||
/* verify key area with rootkey */
|
||||
ret = secure_authenticate(public_key, (uint8_t *)key_area, KEY_AREA_STRUCTURE_LENGTH - BOOT_SIG_LEN,
|
||||
key_area->sig_params_key_area, BOOT_PUBLIC_KEY_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_key_area secure_authenticate fail!");
|
||||
return ERRCODE_BOOT_VERIFY_PKE_VERIFY;
|
||||
}
|
||||
|
||||
/* check key version ext */
|
||||
ret = check_version(PARAMS_BOOT_TYPE,
|
||||
key_area->params_key_version_ext, key_area->mask_params_key_version_ext);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_key_area key version error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_VERSION;
|
||||
}
|
||||
|
||||
/* check key msid */
|
||||
ret = check_msid(key_area->msid_ext, key_area->mask_msid_ext);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_key_area msid error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_MSID;
|
||||
}
|
||||
|
||||
/* check maintention mode */
|
||||
if (key_area->maintenance_mode == MAINTENANCE_MODE_EN) {
|
||||
ret = check_die_id((uint8_t *)key_area->die_id, DIE_ID_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_key_area die id error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_DIE_ID;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static errcode_t verify_params_area_info(const params_area_info_t *area_info, const uint8_t *public_key)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* check verify enable */
|
||||
ret = check_verify_enable();
|
||||
if (ret == ERRCODE_NOT_SUPPORT) {
|
||||
return ERRCODE_SUCC;
|
||||
} else if (ret == ERRCODE_FAIL) {
|
||||
boot_msg0("verify_params_area_info secure verify error!");
|
||||
return ERRCODE_BOOT_VERIFY_CHECK_ENABLE;
|
||||
}
|
||||
|
||||
/* check image id */
|
||||
ret = check_image_id(PARAMS_BOOT_TYPE, PARAMS_AREA_INFO_TYPE, area_info->image_id);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_area_info image id error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_IMAGE_ID;
|
||||
}
|
||||
|
||||
/* verify code info with external public key */
|
||||
ret = secure_authenticate(public_key, (uint8_t *)area_info,
|
||||
CODE_INFO_STRUCTURE_LENGTH - BOOT_SIG_LEN - BOOT_EXT_SIG_LEN, area_info->sig_params_info, BOOT_PUBLIC_KEY_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_area_info secure_authenticate fail!");
|
||||
return ERRCODE_BOOT_VERIFY_PKE_VERIFY;
|
||||
}
|
||||
|
||||
/* check version ext */
|
||||
ret = check_version(PARAMS_BOOT_TYPE,
|
||||
area_info->params_version_ext, area_info->mask_params_version_ext);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_area_info key version error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_VERSION;
|
||||
}
|
||||
|
||||
/* check msid */
|
||||
ret = check_msid(area_info->msid_ext, area_info->mask_msid_ext);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_area_info msid error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_MSID;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static errcode_t verify_params_area(const params_area_info_t *area_info, const uint8_t *area_addr)
|
||||
{
|
||||
uint32_t area_length = 0;
|
||||
uint8_t hash_result[HASH_LEN] = { 0 };
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* caculate code area hash */
|
||||
area_length = area_info->params_area_len;
|
||||
ret = drv_rom_cipher_sha256((unsigned char *)(uintptr_t)area_addr, area_length, hash_result, (uint32_t)HASH_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_area drv_rom_cipher_sha256 fail!");
|
||||
return ERRCODE_BOOT_VERIFY_HASH_CALCULATION;
|
||||
}
|
||||
|
||||
ret = memcmp(hash_result, area_info->params_area_hash, (uint32_t)HASH_LEN);
|
||||
if (ret != 0) {
|
||||
boot_msg0("verify_params_area hash memcmp fail!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_HASH_RESULT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static errcode_t verify_image_key_area(image_type_t image_type, area_type_t erea_type,
|
||||
const image_key_area_t *key_area, const uint8_t *public_key)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* check verify enable */
|
||||
ret = check_verify_enable();
|
||||
if (ret == ERRCODE_NOT_SUPPORT) {
|
||||
boot_msg0("verify_image_key_area secure verify disable!");
|
||||
return ERRCODE_SUCC;
|
||||
} else if (ret == ERRCODE_FAIL) {
|
||||
boot_msg0("verify_image_key_area secure verify error!");
|
||||
return ERRCODE_BOOT_VERIFY_CHECK_ENABLE;
|
||||
}
|
||||
|
||||
if ((image_type == LOADER_BOOT_TYPE) || (image_type == FLASH_BOOT_TYPE) ||
|
||||
(image_type == FLASH_BOOT_BACK_UP_TYPE)) {
|
||||
if (g_rootkey_status != 0x5) {
|
||||
boot_msg0("verify_image_key_area rootkey_status invalid!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_ROOT_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
/* check image id */
|
||||
ret = check_image_id(image_type, erea_type, key_area->image_id);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_key_area image id error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_IMAGE_ID;
|
||||
}
|
||||
|
||||
/* verify key area with rootkey */
|
||||
ret = secure_authenticate(public_key, (uint8_t *)key_area, KEY_AREA_STRUCTURE_LENGTH - BOOT_SIG_LEN,
|
||||
key_area->sig_key_area, BOOT_PUBLIC_KEY_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_key_area secure_authenticate!");
|
||||
return ERRCODE_BOOT_VERIFY_PKE_VERIFY;
|
||||
}
|
||||
|
||||
/* check key version ext */
|
||||
if (image_type != LOADER_BOOT_TYPE) {
|
||||
ret = check_version(image_type, key_area->key_version_ext, key_area->mask_key_version_ext);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_key_area key version error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_VERSION;
|
||||
}
|
||||
}
|
||||
|
||||
/* check key msid */
|
||||
ret = check_msid(key_area->msid_ext, key_area->mask_msid_ext);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_key_area msid error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_MSID;
|
||||
}
|
||||
|
||||
/* check maintention mode */
|
||||
if (key_area->maintenance_mode == MAINTENANCE_MODE_EN) {
|
||||
ret = check_die_id((uint8_t *)key_area->die_id, DIE_ID_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_key_area die id error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_DIE_ID;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static errcode_t verify_image_code_info(image_type_t image_type, area_type_t erea_type,
|
||||
const image_code_info_t *code_info, const uint8_t *public_key)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* check verify enable */
|
||||
ret = check_verify_enable();
|
||||
if (ret == ERRCODE_NOT_SUPPORT) {
|
||||
boot_msg0("verify_image_code_info secure verify disable!");
|
||||
return ERRCODE_SUCC;
|
||||
} else if (ret == ERRCODE_FAIL) {
|
||||
boot_msg0("verify_image_code_info secure verify error!");
|
||||
return ERRCODE_BOOT_VERIFY_CHECK_ENABLE;
|
||||
}
|
||||
|
||||
/* check image id */
|
||||
ret = check_image_id(image_type, erea_type, code_info->image_id);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_code_info image id error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_IMAGE_ID;
|
||||
}
|
||||
|
||||
/* verify code info with external public key */
|
||||
ret = secure_authenticate(public_key, (uint8_t *)code_info,
|
||||
CODE_INFO_STRUCTURE_LENGTH - BOOT_SIG_LEN - BOOT_EXT_SIG_LEN, code_info->sig_code_info, BOOT_PUBLIC_KEY_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_code_info secure_authenticate!");
|
||||
return ERRCODE_BOOT_VERIFY_PKE_VERIFY;
|
||||
}
|
||||
|
||||
/* check version ext */
|
||||
if (image_type != LOADER_BOOT_TYPE) {
|
||||
ret = check_version(image_type, code_info->version_ext, code_info->mask_version_ext);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_code_info key version error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_VERSION;
|
||||
}
|
||||
}
|
||||
|
||||
/* check msid */
|
||||
ret = check_msid(code_info->msid_ext, code_info->mask_msid_ext);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_code_info msid error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_MSID;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static errcode_t verify_image_code_area(const image_code_info_t *code_info, const uint8_t *code_addr)
|
||||
{
|
||||
uint32_t code_length = 0;
|
||||
uint8_t hash_result[HASH_LEN] = { 0 };
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* caculate code area hash */
|
||||
code_length = code_info->code_area_len;
|
||||
ret = drv_rom_cipher_sha256((unsigned char *)(uintptr_t)code_addr, code_length, hash_result, (uint32_t)HASH_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_code_area drv_rom_cipher_sha256!");
|
||||
return ERRCODE_BOOT_VERIFY_HASH_CALCULATION;
|
||||
}
|
||||
ret = memcmp(hash_result, code_info->code_area_hash, (uint32_t)HASH_LEN);
|
||||
if (ret != 0) {
|
||||
boot_msg0("verify_image_code_area hash memcmp fail!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_HASH_RESULT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t verify_public_rootkey(uint32_t rootkey_buff_addr)
|
||||
{
|
||||
uint8_t hash_result[HASH_LEN] = { 0 };
|
||||
uint8_t hash_from_otp[HASH_LEN] = { 0 };
|
||||
uint32_t ret = ERRCODE_SUCC;
|
||||
const root_public_key_area_t *rootkey_buff = (root_public_key_area_t *)(uintptr_t)rootkey_buff_addr;
|
||||
|
||||
if (rootkey_buff == NULL) {
|
||||
return ERRCODE_BOOT_VERIFY_PARAM_NULL;
|
||||
}
|
||||
|
||||
g_rootkey_status = 0xA;
|
||||
|
||||
/* check verify enable */
|
||||
ret = check_verify_enable();
|
||||
if (ret == ERRCODE_NOT_SUPPORT) {
|
||||
return ERRCODE_SUCC;
|
||||
} else if (ret == ERRCODE_FAIL) {
|
||||
boot_msg0("verify_public_rootkey secure verify error!");
|
||||
return ERRCODE_BOOT_VERIFY_CHECK_ENABLE;
|
||||
}
|
||||
|
||||
boot_msg0("secure boot.");
|
||||
|
||||
/* check rootkey_buff->image_id */
|
||||
if (rootkey_buff->image_id != OEM_ROOT_PUBLIC_KEY_IMAGE_ID) {
|
||||
boot_msg0("verify_public_rootkey image id error!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_IMAGE_ID;
|
||||
}
|
||||
|
||||
/* caculate rootkey hash */
|
||||
ret = drv_rom_cipher_sha256((unsigned char *)rootkey_buff, ROOT_PUBLIC_KEY_STRUCTURE_LENGTH,
|
||||
hash_result, (uint32_t)HASH_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_public_rootkey drv_rom_cipher_sha256 fail!");
|
||||
return ERRCODE_BOOT_VERIFY_HASH_CALCULATION;
|
||||
}
|
||||
|
||||
/* read efuse rootkey hash */
|
||||
/* sizeof(hash_from_otp) = 32 */
|
||||
ret = efuse_read_item(EFUSE_HASH_ROOT_PUBLIC_KEY_ID, hash_from_otp, (uint16_t)sizeof(hash_from_otp));
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_public_rootkey efuse_read_item fail!");
|
||||
return ERRCODE_BOOT_VERIFY_EFUSE_READ;
|
||||
}
|
||||
|
||||
/* check hash */
|
||||
ret = memcmp(hash_from_otp, hash_result, (uint32_t)HASH_LEN);
|
||||
if (ret != 0) {
|
||||
boot_msg0("verify_public_rootkey hash memcmp fail!");
|
||||
return ERRCODE_BOOT_VERIFY_INVALID_HASH_RESULT;
|
||||
}
|
||||
|
||||
g_rootkey_status = 0x5;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t verify_image_head(image_type_t image_type, uint32_t public_key_addr, uint32_t boot_head_addr)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
image_key_area_t *key_area = (image_key_area_t *)(uintptr_t)boot_head_addr;
|
||||
image_code_info_t *code_info = (image_code_info_t *)(uintptr_t)((uintptr_t)key_area + KEY_AREA_STRUCTURE_LENGTH);
|
||||
|
||||
if (key_area == NULL || code_info == NULL) {
|
||||
return ERRCODE_BOOT_VERIFY_PARAM_NULL;
|
||||
}
|
||||
|
||||
ret = verify_image_key_area(image_type, KEY_EREA_TYPE, key_area, (uint8_t *)(uintptr_t)public_key_addr);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_key_area fail!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = verify_image_code_info(image_type, CODE_INFO_TYPE, code_info, key_area->ext_pulic_key_area);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_code_info fail!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t verify_image_body(uint32_t boot_head_addr, uint32_t boot_body_addr)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
const image_code_info_t *code_info = (image_code_info_t *)(uintptr_t)(boot_head_addr + KEY_AREA_STRUCTURE_LENGTH);
|
||||
const uint8_t *code_addr = (uint8_t *)(uintptr_t)boot_body_addr;
|
||||
|
||||
if (code_info == NULL || code_addr == NULL) {
|
||||
return ERRCODE_BOOT_VERIFY_PARAM_NULL;
|
||||
}
|
||||
|
||||
ret = verify_image_code_area(code_info, code_addr);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_image_code_area fail!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t verify_params_head(uint32_t root_public_key_addr, uint32_t params_head_addr)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
root_public_key_area_t *public_rootkey = (root_public_key_area_t *)(uintptr_t)root_public_key_addr;
|
||||
params_key_area_t *key_area = (params_key_area_t *)(uintptr_t)params_head_addr;
|
||||
params_area_info_t *area_info = (params_area_info_t *)(uintptr_t)((uintptr_t)key_area + KEY_AREA_STRUCTURE_LENGTH);
|
||||
|
||||
if (public_rootkey == NULL || key_area == NULL || area_info == NULL) {
|
||||
return ERRCODE_BOOT_VERIFY_PARAM_NULL;
|
||||
}
|
||||
|
||||
ret = verify_params_key_area(key_area, public_rootkey->root_key_area);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_key_area fail!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = verify_params_area_info(area_info, key_area->params_ext_key_area);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_area_info fail!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t verify_params_body(uint32_t params_head_addr, uint32_t params_body_addr)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
const params_area_info_t *area_info =
|
||||
(params_area_info_t *)(uintptr_t)(params_head_addr + KEY_AREA_STRUCTURE_LENGTH);
|
||||
const uint8_t *area_addr = (uint8_t *)(uintptr_t)params_body_addr;
|
||||
|
||||
if (area_info == NULL || area_addr == NULL) {
|
||||
return ERRCODE_BOOT_VERIFY_PARAM_NULL;
|
||||
}
|
||||
|
||||
ret = verify_params_area(area_info, area_addr);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("verify_params_area fail!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
55
bootloader/flashboot_ws63/CMakeLists.txt
Executable file
55
bootloader/flashboot_ws63/CMakeLists.txt
Executable file
@ -0,0 +1,55 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved.
|
||||
#===============================================================================
|
||||
set(COMPONENT_NAME "flashboot_common")
|
||||
|
||||
if("flashboot" IN_LIST BIN_NAME)
|
||||
set(SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/startup/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/startup/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/startup/riscv_init.S
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../commonboot/src/secure_verify_boot.c
|
||||
)
|
||||
|
||||
set(PUBLIC_HEADER
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../commonboot/include
|
||||
)
|
||||
elseif ("ssb" IN_LIST BIN_NAME)
|
||||
set(SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ssb/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ssb/riscv_init.S
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../commonboot/src/secure_verify_boot.c
|
||||
)
|
||||
|
||||
set(PUBLIC_HEADER
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../commonboot/include
|
||||
)
|
||||
endif()
|
||||
|
||||
set(PRIVATE_HEADER
|
||||
)
|
||||
|
||||
set(PRIVATE_DEFINES
|
||||
)
|
||||
|
||||
set(PUBLIC_DEFINES
|
||||
)
|
||||
|
||||
# use this when you want to add ccflags like -include xxx
|
||||
set(COMPONENT_PUBLIC_CCFLAGS
|
||||
)
|
||||
|
||||
set(COMPONENT_CCFLAGS
|
||||
)
|
||||
|
||||
set(WHOLE_LINK
|
||||
true
|
||||
)
|
||||
|
||||
set(MAIN_COMPONENT
|
||||
false
|
||||
)
|
||||
|
||||
build_component()
|
780
bootloader/flashboot_ws63/startup/main.c
Executable file
780
bootloader/flashboot_ws63/startup/main.c
Executable file
@ -0,0 +1,780 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
* Description: main
|
||||
*
|
||||
* Create: 2021-03-09
|
||||
*/
|
||||
|
||||
#include "boot_serial.h"
|
||||
#include "boot_init.h"
|
||||
#include "boot_reset.h"
|
||||
#include "boot_verify.h"
|
||||
#include "secure_verify_boot.h"
|
||||
#include "efuse.h"
|
||||
#include "efuse_porting.h"
|
||||
#include "chip_io.h"
|
||||
#include "pinctrl.h"
|
||||
#include "boot_flash.h"
|
||||
#include "sfc.h"
|
||||
#include "boot_delay.h"
|
||||
#include "boot_jump.h"
|
||||
#include "tcxo.h"
|
||||
#include "watchdog.h"
|
||||
#include "drv_pmp.h"
|
||||
#include "pmp_cfg.h"
|
||||
#include "malloc_porting.h"
|
||||
#include "upg_porting.h"
|
||||
#include "upg_common.h"
|
||||
#include "upg_alloc.h"
|
||||
#include "soc_porting.h"
|
||||
#include "drv_flashboot_cipher.h"
|
||||
#ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
|
||||
#include "upg_ab.h"
|
||||
#endif
|
||||
#include "factory.h"
|
||||
#include "sfc_protect.h"
|
||||
#include "reset_porting.h"
|
||||
|
||||
#define FLASHBOOT_UART_DEFAULT_PARAM {115200, 8, 1, 0, 0, 2, 1, 4, 0}
|
||||
#define APP_START_INSTRUCTION 0x40006f
|
||||
#define DELAY_100MS 100
|
||||
#define REG_CMU_CFG0 0x40003408
|
||||
#define APP_IMAGE_HEADER_LEN ((KEY_AREA_STRUCTURE_LENGTH) + (CODE_INFO_STRUCTURE_LENGTH))
|
||||
#define BOOT_WATCH_DOG_TIMOUT 7 // 7s
|
||||
#define FLASH_KEY_SALT_LEN 28
|
||||
#define FLASH_ENCRY_ADDR_ALINE 256
|
||||
#define FLASH_NO_ENCRY_FLAG 0x3C7896E1
|
||||
#define FLASHBOOT_RAM_ADDR 0xA28000
|
||||
|
||||
#define FLASH_BOOT_TYPE_REG 0x40000024
|
||||
#define FLASH_BOOT_TYPE_REG_MAIN 0xA5A5A5A5
|
||||
#define FLASH_BOOT_TYPE_REG_BKUP 0x5A5A5A5A
|
||||
|
||||
const sfc_flash_config_t sfc_cfg = {
|
||||
.read_type = FAST_READ_QUAD_OUTPUT,
|
||||
.write_type = PAGE_PROGRAM,
|
||||
.mapping_addr = 0x200000,
|
||||
.mapping_size = 0x800000,
|
||||
};
|
||||
#if 1 //ADD LYL 2024 1122 --------
|
||||
|
||||
#define USERPAGE 0x003F2000 //AT参数存储区
|
||||
#define BLE_CONKEYLEN 16
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
int8_t updateflag; //update flag
|
||||
int8_t validflag; //valid flag
|
||||
int8_t tmode_mode;
|
||||
int8_t wmode_mode;
|
||||
|
||||
//STA, 140 bytes
|
||||
uint8_t sta_ssid[33];
|
||||
uint8_t sta_key[65];
|
||||
int8_t wsauth;
|
||||
int8_t wsencry;
|
||||
uint8_t wslko;
|
||||
uint8_t pmk_av;
|
||||
uint8_t sta_padding[6];
|
||||
uint8_t pmk[32];
|
||||
|
||||
//AP, 144 bytes
|
||||
int8_t wap_mode;
|
||||
int8_t wap_channel;
|
||||
int8_t waauth;
|
||||
int8_t waencry;
|
||||
uint8_t walk_led;
|
||||
uint8_t max_sta_num;
|
||||
uint8_t ap_enable_hide;
|
||||
uint8_t ap_ssid[33];
|
||||
uint8_t ap_key[65];
|
||||
uint8_t ap_pmk_av;
|
||||
uint8_t ap_pmk[32];
|
||||
uint8_t ap_padding[6];
|
||||
|
||||
//UART, 20 bytes
|
||||
int8_t baudrate;
|
||||
int8_t data_bits;
|
||||
int8_t stop_bits;
|
||||
int8_t parity;
|
||||
int8_t ctsrts;
|
||||
|
||||
int8_t uart1_baudrate;
|
||||
int8_t uart1_data_bits;
|
||||
int8_t uart1_stop_bits;
|
||||
int8_t uart1_parity;
|
||||
int8_t uart1_debug;
|
||||
int8_t uartfable;
|
||||
int8_t fuartte_mode;
|
||||
uint16_t uarttm;
|
||||
uint16_t uartbuf;
|
||||
uint8_t uart_padding[4];
|
||||
|
||||
//NETP, 108 bytes
|
||||
int8_t protocol;
|
||||
int8_t app_mode;
|
||||
uint8_t maxsocket;
|
||||
char cipadd[101];
|
||||
uint16_t pro_port;
|
||||
uint16_t tcpto;
|
||||
|
||||
//SOCKB, 112 bytes
|
||||
uint16_t sockb_port;
|
||||
uint16_t sockb_tcpto;
|
||||
int8_t sockb_pro;
|
||||
char sockb_cipadd[101];
|
||||
int8_t tcpdis;
|
||||
int8_t tcpdisb;
|
||||
|
||||
uint16_t udp_localporta;
|
||||
uint16_t udp_localportb;
|
||||
|
||||
//NETWORK, 108 bytes
|
||||
char wann_ipaddr[16];
|
||||
char wann_mask[16];
|
||||
char wann_gateway[16];
|
||||
char lann_ipaddr[16];
|
||||
char lann_mask[16];
|
||||
uint8_t wann_mode;
|
||||
uint8_t network_padding[2];
|
||||
uint8_t domain_name[21];
|
||||
uint32_t dns_addr;
|
||||
|
||||
//UTILS, 124 bytes
|
||||
int8_t echo;
|
||||
int8_t rlden;
|
||||
uint8_t debug_level;
|
||||
char wel_msg[11];
|
||||
uint8_t event_onoff;
|
||||
uint8_t noise_filter;
|
||||
uint8_t wifi_switch;
|
||||
uint8_t sta_dtim;
|
||||
uint8_t utils_padding[40];
|
||||
uint8_t dis_power_saving;
|
||||
int8_t modechange;
|
||||
uint8_t ps_interval;
|
||||
uint8_t mid[21];
|
||||
uint8_t aswd[21];
|
||||
uint8_t cmdpw[21];
|
||||
|
||||
//HTTPD, 36 bytes
|
||||
char user_name[16];
|
||||
char user_password[16];
|
||||
int8_t web_switch;
|
||||
uint8_t web_language;
|
||||
uint8_t web_encode_format;
|
||||
uint8_t httpd_padding;
|
||||
|
||||
//DHCPD, 4 bytes
|
||||
int8_t dhcpsw;
|
||||
uint8_t dhcpd_addr_start;
|
||||
uint8_t dhcpd_addr_end;
|
||||
uint8_t dhcpd_padding;
|
||||
|
||||
//UPDATE, 124 bytes
|
||||
char update_url[101];
|
||||
char update_file[21];
|
||||
uint8_t update_padding[2];
|
||||
|
||||
//NTP, 8 bytes
|
||||
uint8_t ntp_time;
|
||||
uint8_t ntp_enable;
|
||||
uint8_t ntp_padding;
|
||||
int8_t time_zone;
|
||||
uint32_t ntpserver;
|
||||
|
||||
//SMTLK, 16 bytes
|
||||
uint32_t smtlk_sign;
|
||||
uint8_t smtlk_mode;
|
||||
uint8_t smtlk_protocol;
|
||||
uint8_t smtlk_rtype;
|
||||
uint8_t smtlk_ak_random;
|
||||
uint8_t connect_flag;
|
||||
uint8_t sta_channel;
|
||||
uint8_t sta_bssid[6];
|
||||
|
||||
//SMARTAPLINK, 44 bytes
|
||||
uint8_t smartaplink_enable;
|
||||
uint8_t smartaplink_padding;
|
||||
uint8_t smartaplink_prefix[21];
|
||||
uint8_t smartaplink_key[21];
|
||||
|
||||
//NETPID, 24 bytes
|
||||
uint8_t netpa_iden;
|
||||
char netpa_id[11];
|
||||
uint8_t netpb_iden;
|
||||
char netpb_id[11];
|
||||
|
||||
//NETPREG, 264 bytes
|
||||
uint8_t netpa_regen;
|
||||
uint8_t netpa_regtype;
|
||||
uint8_t netpa_reg_padding;
|
||||
char netpa_regdata[129];
|
||||
uint8_t netpb_regen;
|
||||
uint8_t netpb_regtype;
|
||||
uint8_t netpb_reg_padding;
|
||||
char netpb_regdata[129];
|
||||
|
||||
//HEART, 124 bytes
|
||||
uint16_t heart_netp_time;
|
||||
uint16_t heart_sockb_time;
|
||||
uint16_t heart_uart_time;
|
||||
char heart_netp_data[39];
|
||||
char heart_sockb_data[39];
|
||||
char heart_uart_data[39];
|
||||
uint8_t heart_padding;
|
||||
|
||||
//HTTP, 236 bytes
|
||||
uint8_t http_type;
|
||||
uint8_t http_version;
|
||||
uint8_t http_connect_type;
|
||||
uint8_t http_recv_time;
|
||||
char http_url[51];
|
||||
char http_header[181];
|
||||
|
||||
//MQTT, 224 bytes
|
||||
char mqtt_username[33];
|
||||
char mqtt_password[33];
|
||||
char mqtt_clientid[33];
|
||||
char mqtt_pub_topic[61];
|
||||
char mqtt_sub_topic[61];
|
||||
uint8_t mqtt_qos;
|
||||
uint16_t mqtt_heart_time;
|
||||
|
||||
//BLE, 188 bytes
|
||||
uint16_t conn_min;
|
||||
uint16_t conn_max;
|
||||
uint16_t conn_latency;
|
||||
uint16_t supervisionTO;
|
||||
|
||||
uint16_t adver_min;
|
||||
uint16_t adver_max;
|
||||
|
||||
uint8_t ble_name[27]; //BLE广播名
|
||||
uint8_t ble_dms_name[27]; //BLE配网名
|
||||
uint8_t ble_adver_data[27];
|
||||
|
||||
uint8_t ble_adver_data_len;
|
||||
uint8_t ble_switch;
|
||||
uint8_t ble_uuid_server;
|
||||
uint8_t dms_type;
|
||||
uint8_t ble_padding;
|
||||
|
||||
uint8_t uuid_ntf_server[17];
|
||||
uint8_t uuid_ntf_read[17];
|
||||
uint8_t uuid_ntf_write[17];
|
||||
uint8_t uuid_ind_server[17];
|
||||
uint8_t uuid_ind_read[17];
|
||||
uint8_t uuid_ind_write[17];
|
||||
|
||||
uint8_t adver_type;
|
||||
uint8_t adver_channel;
|
||||
uint8_t ble_ind;
|
||||
uint8_t smartconfiglink;
|
||||
|
||||
uint8_t ble_conenable;
|
||||
uint8_t ble_conkey[BLE_CONKEYLEN];
|
||||
uint8_t ble_contimeout;
|
||||
uint8_t netpc_iden;
|
||||
char netpc_id[11];
|
||||
uint8_t netpc_idflag;
|
||||
|
||||
uint8_t ble_padding2[17];
|
||||
|
||||
uint8_t mqtt_tls;
|
||||
uint8_t mqtt_padding[3];
|
||||
|
||||
char iot_productkey[12];
|
||||
char iot_devicename[48];
|
||||
char iot_devicesecret[48];
|
||||
char iot_pubtopic[96];
|
||||
char iot_subtopic[96];
|
||||
char iot_mode;
|
||||
char iot_padding[3];
|
||||
|
||||
uint8_t product_mode;
|
||||
|
||||
int8_t ctsrts_pin;
|
||||
|
||||
char instance_flag;
|
||||
char instance_id[32];
|
||||
|
||||
char ntp_domain_server[33];
|
||||
int8_t smk_find;
|
||||
|
||||
uint32_t mcu_ota_size;
|
||||
uint8_t scan_ch14;
|
||||
|
||||
|
||||
uint32_t module_reset_reason;
|
||||
uint8_t reserved1[60+512-4];
|
||||
|
||||
uint8_t validflag_magic;
|
||||
int8_t validflag_end; //valid flag
|
||||
}HF_CONFIG_FILE;
|
||||
#pragma pack(pop)
|
||||
|
||||
HF_CONFIG_FILE g_hf_config_file_boot = {0};
|
||||
|
||||
int hfdbg_get_sw(void)
|
||||
{
|
||||
if(g_hf_config_file_boot.debug_level > 0 && g_hf_config_file_boot.debug_level<=20) //1~20允许打印
|
||||
return 0;
|
||||
|
||||
if(g_hf_config_file_boot.uart1_debug == 1) //1允许打印
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static uint32_t sfc_flash_init(void)
|
||||
{
|
||||
return uapi_sfc_init((sfc_flash_config_t *)&sfc_cfg);
|
||||
}
|
||||
static uint32_t sfc_flash_read(uint32_t flash_addr, uint32_t read_size, uint8_t *read_buffer)
|
||||
{
|
||||
return uapi_sfc_reg_read(flash_addr, read_buffer, read_size);
|
||||
}
|
||||
static uint32_t sfc_flash_write(uint32_t flash_addr, uint32_t flash_write_size, const uint8_t *p_flash_write_data,
|
||||
bool do_erase)
|
||||
{
|
||||
unused(do_erase);
|
||||
return uapi_sfc_reg_write(flash_addr, (uint8_t *)p_flash_write_data, flash_write_size);
|
||||
}
|
||||
|
||||
static uint32_t sfc_flash_erase(uint32_t flash_addr, uint32_t flash_erase_size)
|
||||
{
|
||||
return uapi_sfc_reg_erase(flash_addr - sfc_cfg.mapping_addr, flash_erase_size);
|
||||
}
|
||||
|
||||
static void boot_flash_init(void)
|
||||
{
|
||||
flash_cmd_func flash_funcs = {0};
|
||||
flash_funcs.init = sfc_flash_init;
|
||||
flash_funcs.read = sfc_flash_read;
|
||||
flash_funcs.write = sfc_flash_write;
|
||||
flash_funcs.erase = sfc_flash_erase;
|
||||
boot_regist_flash_cmd(&flash_funcs);
|
||||
|
||||
uint32_t ret = sfc_flash_init();
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("Flash Init Fail! ret = ", ret);
|
||||
} else {
|
||||
uapi_sfc_reg_read(USERPAGE, (unsigned char *)&g_hf_config_file_boot, sizeof(HF_CONFIG_FILE));
|
||||
boot_msg0("Flash Init Succ!");
|
||||
}
|
||||
hf_boot_msg1("BootLoader debug_level = ", g_hf_config_file_boot.debug_level);
|
||||
switch_flash_clock_to_pll();
|
||||
config_sfc_ctrl_ds();
|
||||
}
|
||||
|
||||
#define FAMA_REMAP_SRC_BASE_ADDR 0x44007800
|
||||
#define FAMA_REMAP_LEN_BASE_ADDR 0x44007820
|
||||
#define FAMA_REMAP_DST_BASE_ADDR 0x44007840
|
||||
#define FAMA_REMAP_REGION_OFFSET 0x4
|
||||
#define FAMA_REMAP_LOW_BITS 12
|
||||
static void dmmu_set(uint32_t src_start_addr, uint32_t src_end_addr, uint32_t dst_start_addr, uint32_t region)
|
||||
{
|
||||
uint32_t src_reg_addr = FAMA_REMAP_SRC_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET;
|
||||
uint32_t len_reg_addr = FAMA_REMAP_LEN_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET;
|
||||
uint32_t dst_reg_addr = FAMA_REMAP_DST_BASE_ADDR + region * FAMA_REMAP_REGION_OFFSET;
|
||||
uint32_t src_start_align_addr = src_start_addr >> FAMA_REMAP_LOW_BITS;
|
||||
uint32_t src_end_align_addr = src_end_addr >> FAMA_REMAP_LOW_BITS;
|
||||
uint32_t dst_start_align_addr = dst_start_addr >> FAMA_REMAP_LOW_BITS;
|
||||
uint32_t dst_src_offset = 0;
|
||||
if (region >= FAMA_REMAP_LOW_BITS) {
|
||||
return ;
|
||||
}
|
||||
writel(src_reg_addr, src_start_align_addr);
|
||||
writel(len_reg_addr, src_end_align_addr);
|
||||
if (src_start_align_addr > dst_start_align_addr) {
|
||||
dst_src_offset = src_start_align_addr - dst_start_align_addr;
|
||||
dst_src_offset = ~dst_src_offset;
|
||||
dst_src_offset = dst_src_offset + 1;
|
||||
} else {
|
||||
dst_src_offset = dst_start_align_addr - src_start_align_addr;
|
||||
}
|
||||
writel(dst_reg_addr, dst_src_offset);
|
||||
}
|
||||
|
||||
static bool flashboot_need_recovery(void)
|
||||
{
|
||||
uint32_t reg = readl(FLASH_BOOT_TYPE_REG);
|
||||
writel(FLASH_BOOT_TYPE_REG, 0);
|
||||
return (reg == FLASH_BOOT_TYPE_REG_BKUP) ? true : false;
|
||||
}
|
||||
|
||||
static void ws63_flashboot_recovery(void)
|
||||
{
|
||||
if (!flashboot_need_recovery()) {
|
||||
return;
|
||||
}
|
||||
uapi_watchdog_kick();
|
||||
boot_msg0("Flashboot backup is working!");
|
||||
partition_information_t src_img_info = {0};
|
||||
partition_information_t dst_img_info = {0};
|
||||
errcode_t ret;
|
||||
ret = uapi_partition_get_info(PARTITION_FLASH_BOOT_IMAGE_BACKUP, &src_img_info);
|
||||
ret |= uapi_partition_get_info(PARTITION_FLASH_BOOT_IMAGE, &dst_img_info);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("Flashboot partition info get fail!");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = uapi_sfc_reg_erase(dst_img_info.part_info.addr_info.addr, dst_img_info.part_info.addr_info.size);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("flashboot recovery erase failed!! ret = ", ret);
|
||||
}
|
||||
ret = uapi_sfc_reg_write(dst_img_info.part_info.addr_info.addr,
|
||||
(uint8_t *)(uintptr_t)(src_img_info.part_info.addr_info.addr + FLASH_START),
|
||||
src_img_info.part_info.addr_info.size);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("flashboot recovery write failed!! ret = ", ret);
|
||||
}
|
||||
boot_msg0("Flashboot fix ok!");
|
||||
}
|
||||
|
||||
#define UPG_FIX_RETRY_CNT_REG RESET_COUNT_REG
|
||||
#define VERIFY_RETRY_CNT_THRES 0x3
|
||||
#define UPG_FIX_RETRY_CNT_THRES (VERIFY_RETRY_CNT_THRES + 0x3)
|
||||
#define UPG_AB_RETRY_CNT_THRES (VERIFY_RETRY_CNT_THRES + 0x3)
|
||||
|
||||
static uint8_t ws63_get_try_fix_cnt(void)
|
||||
{
|
||||
gp_reg1_union gp;
|
||||
gp.u32 = readl(UPG_FIX_RETRY_CNT_REG);
|
||||
return gp.bits.fota_fix_app_cnt;
|
||||
}
|
||||
|
||||
static void ws63_set_try_fix_cnt(uint8_t cnt)
|
||||
{
|
||||
gp_reg1_union gp;
|
||||
gp.u32 = readl(UPG_FIX_RETRY_CNT_REG);
|
||||
gp.bits.fota_fix_app_cnt = cnt & 0xF;
|
||||
writel(UPG_FIX_RETRY_CNT_REG, gp.u32);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
|
||||
static void ws63_try_fix_app(void)
|
||||
{
|
||||
uint8_t try_cnt = ws63_get_try_fix_cnt() + 1;
|
||||
ws63_set_try_fix_cnt(try_cnt);
|
||||
|
||||
/* 启动分区连续验签失败次数等于阈值倍数时,切换启动分区 */
|
||||
if (try_cnt % VERIFY_RETRY_CNT_THRES) { // 1 2 4 5 7 8 a b d e
|
||||
return;
|
||||
} else { // 3 6 9 c f
|
||||
boot_msg0("switch booting");
|
||||
upg_set_run_region(upg_get_upg_region());
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else // 压缩
|
||||
/* 尝试ota修复运行区镜像 */
|
||||
static void ws63_try_fix_app(void)
|
||||
{
|
||||
uint8_t try_cnt = ws63_get_try_fix_cnt();
|
||||
/* 连续验签失败次数小于阈值不做处理 */
|
||||
if (try_cnt < VERIFY_RETRY_CNT_THRES) {
|
||||
ws63_set_try_fix_cnt(try_cnt + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 修复app超次数阈值后不再尝试 */
|
||||
if (try_cnt >= UPG_FIX_RETRY_CNT_THRES) {
|
||||
return;
|
||||
}
|
||||
ws63_set_try_fix_cnt(try_cnt + 1);
|
||||
|
||||
/* 重置升级标记 */
|
||||
errcode_t ret = uapi_upg_reset_upgrade_flag();
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("reset_upgrade_flag fail, ret = ", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 请求升级 */
|
||||
ret = uapi_upg_request_upgrade(false);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg0("request_upgrade fail, fota_pkt_not_exit.");
|
||||
return;
|
||||
}
|
||||
boot_msg0("fota_pkt exit, try_fota_fix_app.");
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool ws63_upg_need_upgrade(void)
|
||||
{
|
||||
uint32_t fota_address = 0;
|
||||
partition_information_t info;
|
||||
errcode_t ret_val = uapi_partition_get_info(PARTITION_FOTA_DATA, &info);
|
||||
if (ret_val != ERRCODE_SUCC || info.type != PARTITION_BY_ADDRESS) {
|
||||
boot_msg1("uapi_partition_get_info failed ", __LINE__);
|
||||
return false;
|
||||
}
|
||||
upg_get_upgrade_flag_flash_start_addr(&fota_address);
|
||||
fota_upgrade_flag_area_t upg_flag_info;
|
||||
ret_val = upg_flash_read(fota_address, sizeof(fota_upgrade_flag_area_t), (uint8_t *)(&upg_flag_info));
|
||||
if (ret_val != ERRCODE_SUCC) {
|
||||
boot_msg1("upg_flash_read failed ", ret_val);
|
||||
return false;
|
||||
}
|
||||
if (!(upg_flag_info.head_magic == UPG_HEAD_MAGIC &&
|
||||
upg_flag_info.head_end_magic == UPG_END_MAGIC &&
|
||||
upg_flag_info.complete_flag != 0)) {
|
||||
/* 不需要升级直接返回 */
|
||||
boot_msg0("No need to upgrade...");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ws63_upg_check(void)
|
||||
{
|
||||
(void)ws63_upg_init();
|
||||
#ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
|
||||
return;
|
||||
#endif
|
||||
if (ws63_upg_need_upgrade()) {
|
||||
boot_msg0("need upgrade");
|
||||
errcode_t ret = uapi_upg_start();
|
||||
// 1, 没有升级包、或者升级标记区结果已经设置的情况不需要重启
|
||||
// 2, 升级模块没有初始化不需要重启
|
||||
// 3, 升级成功需要重启
|
||||
// 4, 升级失败的时候需要重启重新进入升级流程,尝试三次未成功,后会变为1的情况
|
||||
if (!(ret == ERRCODE_UPG_NOT_NEED_TO_UPDATE || ret == ERRCODE_UPG_NOT_INIT || ret == ERRCODE_SUCC)) {
|
||||
boot_msg0("--------------------------");
|
||||
boot_msg0("upgrade failed, reset now");
|
||||
} else {
|
||||
// 升级后重启
|
||||
boot_msg0("--------------------------");
|
||||
boot_msg0("upgrade success, reset now");
|
||||
}
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
#define PMU_CMU_CTL_POC_COEX 0x40003238
|
||||
#define RG_POC_SEL_SW_MODE 0x2
|
||||
#define PMU_VDD_FLAG_3V3 0
|
||||
#define POC_SEL_SW_MODE 1
|
||||
#define POC_VALUE_3V3 0
|
||||
|
||||
#define LEVEL_3V3 0x33
|
||||
#define LEVEL_1V8 0x18
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t rg_poc_value : 1; /* [0] */
|
||||
uint32_t rg_poc_sel : 1; /* [1] */
|
||||
uint32_t pmu_vdd3318_flag : 1; /* [2] */
|
||||
uint32_t ms1c : 1; /* [3] */
|
||||
uint32_t rsv : 28; /* [31:4] */
|
||||
} bits;
|
||||
uint32_t u32;
|
||||
} u_poc_coex;
|
||||
|
||||
static void fix_io_level(void)
|
||||
{
|
||||
u_poc_coex poc_coex = {0};
|
||||
|
||||
poc_coex.u32 = readl(PMU_CMU_CTL_POC_COEX);
|
||||
if (poc_coex.bits.ms1c == poc_coex.bits.pmu_vdd3318_flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (poc_coex.bits.pmu_vdd3318_flag != PMU_VDD_FLAG_3V3) {
|
||||
return;
|
||||
}
|
||||
|
||||
poc_coex.bits.rg_poc_value = POC_VALUE_3V3;
|
||||
poc_coex.bits.rg_poc_sel = POC_SEL_SW_MODE;
|
||||
writel(PMU_CMU_CTL_POC_COEX, poc_coex.u32);
|
||||
}
|
||||
|
||||
static void dump_io_level(void)
|
||||
{
|
||||
u_poc_coex poc_coex = {0};
|
||||
uint32_t chip_level = LEVEL_3V3;
|
||||
uint32_t sw_level = LEVEL_3V3;
|
||||
|
||||
poc_coex.u32 = readl(PMU_CMU_CTL_POC_COEX);
|
||||
if (poc_coex.bits.rg_poc_sel == POC_SEL_SW_MODE) {
|
||||
sw_level = (poc_coex.bits.rg_poc_value == POC_VALUE_3V3) ? LEVEL_3V3 : LEVEL_1V8;
|
||||
chip_level = (poc_coex.bits.ms1c == POC_VALUE_3V3) ? LEVEL_3V3 : LEVEL_1V8;
|
||||
boot_msg2("io level work in sw mode, level[sw:chip]:", sw_level, chip_level);
|
||||
} else {
|
||||
chip_level = (poc_coex.bits.ms1c == POC_VALUE_3V3) ? LEVEL_3V3 : LEVEL_1V8;
|
||||
boot_msg1("io level work in hw mode, level[chip]:", chip_level);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t ws63_flashboot_init(void)
|
||||
{
|
||||
errcode_t err;
|
||||
uart_param_stru uart_param = FLASHBOOT_UART_DEFAULT_PARAM;
|
||||
uapi_tcxo_init();
|
||||
hiburn_uart_init(uart_param, HIBURN_CODELOADER_UART);
|
||||
boot_msg0("Flashboot Uart Init Succ!");
|
||||
uapi_partition_init();
|
||||
pmp_enable();
|
||||
malloc_port_init();
|
||||
boot_flash_init();
|
||||
boot_msg0("Flashboot Uart Init Succ!");
|
||||
boot_msg0("Flashboot Malloc Init Succ!");
|
||||
err = sfc_port_fix_sr();
|
||||
if (err != ERRCODE_SUCC) {
|
||||
boot_msg1("SFC fix SR ret =", err);
|
||||
}
|
||||
dump_io_level();
|
||||
print_str("flashboot version : %s\r\n", SDK_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static errcode_t ws63_verify_app(uint32_t addr)
|
||||
{
|
||||
errcode_t ret = ERRCODE_SUCC;
|
||||
image_key_area_t *flashboot_key_area = (image_key_area_t *)(FLASHBOOT_RAM_ADDR);
|
||||
|
||||
ret = verify_image_head(APP_BOOT_TYPE, (uint32_t)(uintptr_t)flashboot_key_area->ext_pulic_key_area, addr);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("flashboot verify_image_app_head failed!! ret = ", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = verify_image_body(addr, addr + APP_IMAGE_HEADER_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("verify_image_app_body failed!! ret = ", ret);
|
||||
return ret;
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static void ws63_verify_app_handle(uint32_t addr)
|
||||
{
|
||||
errcode_t ret = ws63_verify_app(addr);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
ws63_try_fix_app();
|
||||
reset();
|
||||
}
|
||||
set_reset_count(0);
|
||||
ws63_set_try_fix_cnt(0);
|
||||
}
|
||||
|
||||
static void ws63_flash_encrypt_config(uint32_t image_addr, uint32_t image_size)
|
||||
{
|
||||
image_code_info_t *img_info = (image_code_info_t *)(uintptr_t)(image_addr + sizeof(image_key_area_t));
|
||||
crypto_klad_effective_key flash_key = {0};
|
||||
uint32_t start_addr = image_addr + APP_IMAGE_HEADER_LEN;
|
||||
uint32_t end_addr = image_addr + image_size;
|
||||
int32_t ret = ERRCODE_SUCC;
|
||||
|
||||
if (img_info->code_enc_flag == FLASH_NO_ENCRY_FLAG) {
|
||||
boot_msg0("flash_encrypt disable.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (start_addr % FLASH_ENCRY_ADDR_ALINE != 0 || end_addr % FLASH_ENCRY_ADDR_ALINE != 0) {
|
||||
boot_msg2("app_image start or end addr err, must 256byte alignment ", image_addr, end_addr);
|
||||
reset();
|
||||
}
|
||||
boot_msg0("flash_encrypt enable.");
|
||||
flash_key.kdf_hard_alg = CRYPTO_KDF_HARD_ALG_SHA256;
|
||||
flash_key.key_parity = TD_FALSE;
|
||||
flash_key.key_size = CRYPTO_KLAD_KEY_SIZE_128BIT;
|
||||
flash_key.salt = img_info->protection_key_l1;
|
||||
flash_key.salt_length = FLASH_KEY_SALT_LEN;
|
||||
flash_key.oneway = TD_TRUE;
|
||||
ret = drv_rom_cipher_config_odrk1(flash_key);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("fapc_set_config drv_rom_cipher_config_odrk1 err = ", (uint32_t)ret);
|
||||
reset();
|
||||
}
|
||||
ret = drv_rom_cipher_fapc_config(0, start_addr, end_addr, img_info->iv, IV_LEN);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("fapc_set_config drv_rom_cipher_fapc_config err = ", (uint32_t)ret);
|
||||
reset();
|
||||
}
|
||||
|
||||
ret = drv_rom_cipher_fapc_bypass_config(1, end_addr, FLASH_MAX_END, TD_TRUE);
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("fapc_set_config drv_rom_cipher_fapc_bypass_config err = ", (uint32_t)ret);
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t ws63_ftm_mode_init(uint32_t image_addr)
|
||||
{
|
||||
uint32_t image_size = 0;
|
||||
uint32_t jump_addr = 0;
|
||||
mfg_factory_config_t mfg_factory_cfg = {0};
|
||||
uint32_t run_region = mfg_get_ftm_run_region(&mfg_factory_cfg);
|
||||
if (run_region == FTM_REGION_SERVICE) {
|
||||
return 0;
|
||||
}
|
||||
jump_addr = mfg_factory_cfg.factory_addr_start;
|
||||
image_size = mfg_factory_cfg.factory_size;
|
||||
image_key_area_t *mfg_key_area = (image_key_area_t *)(uintptr_t)(jump_addr);
|
||||
|
||||
if (mfg_key_area->image_id == FACTORYBOOT_KEY_AREA_IMAGE_ID && mfg_factory_cfg.factory_valid == MFG_FACTORY_VALID) {
|
||||
dmmu_set(image_addr, image_addr + image_size, jump_addr, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the entry of C. */
|
||||
void start_fastboot(void)
|
||||
{
|
||||
partition_information_t img_info = {0};
|
||||
uint32_t image_addr = 0;
|
||||
uint32_t image_size = 0;
|
||||
errcode_t err;
|
||||
|
||||
fix_io_level();
|
||||
// 关闭CMU假负载
|
||||
uapi_reg_setbits(REG_CMU_CFG0, 3, 3, 0x7); // 0x7 -> 0x40003408 bit 5:3 (3 bits)
|
||||
|
||||
boot_clock_adapt();
|
||||
dmmu_set(0, 0, 0, FAMA_REMAP_LOW_BITS);
|
||||
uapi_watchdog_init(BOOT_WATCH_DOG_TIMOUT);
|
||||
uapi_watchdog_enable(WDT_MODE_RESET);
|
||||
ws63_flashboot_init();
|
||||
set_efuse_period();
|
||||
uapi_efuse_init();
|
||||
ws63_upg_check(); // 升级模式判断
|
||||
err = uapi_partition_get_info(PARTITION_APP_IMAGE, &img_info);
|
||||
if (err != ERRCODE_SUCC) {
|
||||
boot_msg0("Flashboot get app partition failed!, boot abort!");
|
||||
reset();
|
||||
}
|
||||
image_addr = img_info.part_info.addr_info.addr + FLASH_START;
|
||||
image_size = img_info.part_info.addr_info.size;
|
||||
#ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_AB
|
||||
char *boot_str = "A";
|
||||
uint32_t jump_addr = upg_get_region_addr(upg_get_run_region()) + FLASH_START;
|
||||
*boot_str = (image_addr == jump_addr) ? 'A' : 'B';
|
||||
boot_msg0(boot_str);
|
||||
ws63_flash_encrypt_config(jump_addr, image_size); // flash在线加解密配置
|
||||
ws63_verify_app_handle(jump_addr); // A/B验签
|
||||
if (image_addr != jump_addr) {
|
||||
// 0x1000: dmmu配置都是闭区间,且需要是4K对齐的地址, 0: 第0组dmmu配置
|
||||
dmmu_set(image_addr, image_addr + image_size - 0x1000, jump_addr, 0);
|
||||
// 0x1000: dmmu配置都是闭区间,且需要是4K对齐的地址, 1: 第1组dmmu配置
|
||||
dmmu_set(jump_addr, jump_addr + image_size - 0x1000, image_addr, 1);
|
||||
}
|
||||
#else // 压缩
|
||||
ws63_flash_encrypt_config(image_addr, image_size); // flash在线加解密配置
|
||||
ws63_verify_app_handle(image_addr); // app验签
|
||||
#endif
|
||||
ws63_ftm_mode_init(image_addr);
|
||||
ws63_flashboot_recovery();
|
||||
uapi_watchdog_kick();
|
||||
jump_to_execute_addr(image_addr + APP_IMAGE_HEADER_LEN);
|
||||
}
|
93
bootloader/flashboot_ws63/startup/riscv_init.S
Executable file
93
bootloader/flashboot_ws63/startup/riscv_init.S
Executable file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
* Description: main
|
||||
*
|
||||
* Create: 2021-03-09
|
||||
*/
|
||||
|
||||
.section .text.entry
|
||||
.global _start
|
||||
.option norvc
|
||||
_start:
|
||||
j Reset_Handler
|
||||
|
||||
Reset_Handler:
|
||||
li t0,0x0
|
||||
csrw pmpcfg0,t0
|
||||
li t0,0x0
|
||||
csrw pmpcfg1,t0
|
||||
li t0,0x0
|
||||
csrw pmpcfg2,t0
|
||||
li t0,0x0
|
||||
csrw pmpcfg3,t0
|
||||
li t0,0x0
|
||||
csrw 0x7d9,t0
|
||||
la t0, __flash_boot_flag_begin__
|
||||
mv t1, a0
|
||||
lw t3, (t1)
|
||||
sw t3, (t0)
|
||||
la t0, trap_vector
|
||||
addi t0, t0, 1
|
||||
csrw mtvec, t0
|
||||
csrwi mstatus, 0
|
||||
csrwi mie, 0
|
||||
|
||||
# initialize global pointer
|
||||
la gp, _gp_
|
||||
|
||||
# initialize stack pointer
|
||||
la sp, __stack_top__
|
||||
|
||||
/* init stack */
|
||||
la t0, g_system_stack_begin
|
||||
la t1, g_system_stack_end
|
||||
beq t0, t1, end_set_stack_loop
|
||||
li t2, 0xefbeadde
|
||||
|
||||
set_stack_loop:
|
||||
sw t2, (t0)
|
||||
addi t0, t0, 4
|
||||
blt t0, t1, set_stack_loop
|
||||
end_set_stack_loop:
|
||||
|
||||
/* clear reg */
|
||||
li ra, 0
|
||||
li tp, 0
|
||||
li s0, 0
|
||||
li s1, 0
|
||||
li a0, 0
|
||||
li a1, 0
|
||||
li a2, 0
|
||||
li a3, 0
|
||||
li a4, 0
|
||||
li a5, 0
|
||||
li a6, 0
|
||||
li a7, 0
|
||||
li s2, 0
|
||||
li s3, 0
|
||||
li s4, 0
|
||||
li s5, 0
|
||||
li s6, 0
|
||||
li s7, 0
|
||||
li s8, 0
|
||||
li s9, 0
|
||||
li s10, 0
|
||||
li s11, 0
|
||||
li t3, 0
|
||||
li t4, 0
|
||||
li t5, 0
|
||||
li t6, 0
|
||||
|
||||
/* clear bss section */
|
||||
la t0, __bss_begin__
|
||||
la t1, __bss_end__
|
||||
beq t0, t1, end_clear_bss_loop
|
||||
li t2, 0x00000000
|
||||
|
||||
clear_bss_loop:
|
||||
sw t2, (t0)
|
||||
addi t0, t0, 4
|
||||
blt t0, t1, clear_bss_loop
|
||||
end_clear_bss_loop:
|
||||
|
||||
j start_fastboot
|
45
bootloader/provision_ws63/CMakeLists.txt
Executable file
45
bootloader/provision_ws63/CMakeLists.txt
Executable file
@ -0,0 +1,45 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved.
|
||||
#===============================================================================
|
||||
set(COMPONENT_NAME "loaderboot_common")
|
||||
|
||||
set(SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/startup/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/startup/riscv_init.S
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../commonboot/src/boot_uart_auth.c
|
||||
)
|
||||
|
||||
if(DEFINED CONFIG_LOADERBOOT_SUPPORT_FLASH_CHIP_ERASE)
|
||||
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../commonboot/src/boot_erase.c")
|
||||
endif()
|
||||
|
||||
set(PUBLIC_HEADER
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
set(PRIVATE_HEADER
|
||||
)
|
||||
|
||||
set(PRIVATE_DEFINES
|
||||
)
|
||||
|
||||
set(PUBLIC_DEFINES
|
||||
)
|
||||
|
||||
# use this when you want to add ccflags like -include xxx
|
||||
set(COMPONENT_PUBLIC_CCFLAGS
|
||||
)
|
||||
|
||||
set(COMPONENT_CCFLAGS
|
||||
)
|
||||
|
||||
set(WHOLE_LINK
|
||||
true
|
||||
)
|
||||
|
||||
set(MAIN_COMPONENT
|
||||
false
|
||||
)
|
||||
|
||||
build_component()
|
423
bootloader/provision_ws63/startup/main.c
Executable file
423
bootloader/provision_ws63/startup/main.c
Executable file
@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
* Description: main
|
||||
*
|
||||
* Create: 2021-03-09
|
||||
*/
|
||||
|
||||
#include "boot_cmd_loop.h"
|
||||
#include "boot_serial.h"
|
||||
#include "boot_flash.h"
|
||||
#include "sfc.h"
|
||||
#include "chip_io.h"
|
||||
#include "pinctrl.h"
|
||||
#include "boot_delay.h"
|
||||
#include "tcxo.h"
|
||||
#include "watchdog.h"
|
||||
#include "soc_porting.h"
|
||||
#include "efuse.h"
|
||||
#include "efuse_porting.h"
|
||||
#include "boot_malloc.h"
|
||||
#include "boot_erase.h"
|
||||
#include "sfc_protect.h"
|
||||
|
||||
#define DELAY_100MS 100
|
||||
|
||||
__attribute__((section("BOOT_UART"))) uart_param_stru g_uart_prag;
|
||||
|
||||
const sfc_flash_config_t sfc_cfg = {
|
||||
.read_type = FAST_READ_QUAD_OUTPUT,
|
||||
.write_type = PAGE_PROGRAM,
|
||||
.mapping_addr = 0x200000,
|
||||
.mapping_size = 0x800000,
|
||||
};
|
||||
#if 1 //ADD LYL 2024 1122 --------
|
||||
|
||||
#define USERPAGE 0x003F2000 //AT参数存储区
|
||||
#define BLE_CONKEYLEN 16
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
int8_t updateflag; //update flag
|
||||
int8_t validflag; //valid flag
|
||||
int8_t tmode_mode;
|
||||
int8_t wmode_mode;
|
||||
|
||||
//STA, 140 bytes
|
||||
uint8_t sta_ssid[33];
|
||||
uint8_t sta_key[65];
|
||||
int8_t wsauth;
|
||||
int8_t wsencry;
|
||||
uint8_t wslko;
|
||||
uint8_t pmk_av;
|
||||
uint8_t sta_padding[6];
|
||||
uint8_t pmk[32];
|
||||
|
||||
//AP, 144 bytes
|
||||
int8_t wap_mode;
|
||||
int8_t wap_channel;
|
||||
int8_t waauth;
|
||||
int8_t waencry;
|
||||
uint8_t walk_led;
|
||||
uint8_t max_sta_num;
|
||||
uint8_t ap_enable_hide;
|
||||
uint8_t ap_ssid[33];
|
||||
uint8_t ap_key[65];
|
||||
uint8_t ap_pmk_av;
|
||||
uint8_t ap_pmk[32];
|
||||
uint8_t ap_padding[6];
|
||||
|
||||
//UART, 20 bytes
|
||||
int8_t baudrate;
|
||||
int8_t data_bits;
|
||||
int8_t stop_bits;
|
||||
int8_t parity;
|
||||
int8_t ctsrts;
|
||||
|
||||
int8_t uart1_baudrate;
|
||||
int8_t uart1_data_bits;
|
||||
int8_t uart1_stop_bits;
|
||||
int8_t uart1_parity;
|
||||
int8_t uart1_debug;
|
||||
int8_t uartfable;
|
||||
int8_t fuartte_mode;
|
||||
uint16_t uarttm;
|
||||
uint16_t uartbuf;
|
||||
uint8_t uart_padding[4];
|
||||
|
||||
//NETP, 108 bytes
|
||||
int8_t protocol;
|
||||
int8_t app_mode;
|
||||
uint8_t maxsocket;
|
||||
char cipadd[101];
|
||||
uint16_t pro_port;
|
||||
uint16_t tcpto;
|
||||
|
||||
//SOCKB, 112 bytes
|
||||
uint16_t sockb_port;
|
||||
uint16_t sockb_tcpto;
|
||||
int8_t sockb_pro;
|
||||
char sockb_cipadd[101];
|
||||
int8_t tcpdis;
|
||||
int8_t tcpdisb;
|
||||
|
||||
uint16_t udp_localporta;
|
||||
uint16_t udp_localportb;
|
||||
|
||||
//NETWORK, 108 bytes
|
||||
char wann_ipaddr[16];
|
||||
char wann_mask[16];
|
||||
char wann_gateway[16];
|
||||
char lann_ipaddr[16];
|
||||
char lann_mask[16];
|
||||
uint8_t wann_mode;
|
||||
uint8_t network_padding[2];
|
||||
uint8_t domain_name[21];
|
||||
uint32_t dns_addr;
|
||||
|
||||
//UTILS, 124 bytes
|
||||
int8_t echo;
|
||||
int8_t rlden;
|
||||
uint8_t debug_level;
|
||||
char wel_msg[11];
|
||||
uint8_t event_onoff;
|
||||
uint8_t noise_filter;
|
||||
uint8_t wifi_switch;
|
||||
uint8_t sta_dtim;
|
||||
uint8_t utils_padding[40];
|
||||
uint8_t dis_power_saving;
|
||||
int8_t modechange;
|
||||
uint8_t ps_interval;
|
||||
uint8_t mid[21];
|
||||
uint8_t aswd[21];
|
||||
uint8_t cmdpw[21];
|
||||
|
||||
//HTTPD, 36 bytes
|
||||
char user_name[16];
|
||||
char user_password[16];
|
||||
int8_t web_switch;
|
||||
uint8_t web_language;
|
||||
uint8_t web_encode_format;
|
||||
uint8_t httpd_padding;
|
||||
|
||||
//DHCPD, 4 bytes
|
||||
int8_t dhcpsw;
|
||||
uint8_t dhcpd_addr_start;
|
||||
uint8_t dhcpd_addr_end;
|
||||
uint8_t dhcpd_padding;
|
||||
|
||||
//UPDATE, 124 bytes
|
||||
char update_url[101];
|
||||
char update_file[21];
|
||||
uint8_t update_padding[2];
|
||||
|
||||
//NTP, 8 bytes
|
||||
uint8_t ntp_time;
|
||||
uint8_t ntp_enable;
|
||||
uint8_t ntp_padding;
|
||||
int8_t time_zone;
|
||||
uint32_t ntpserver;
|
||||
|
||||
//SMTLK, 16 bytes
|
||||
uint32_t smtlk_sign;
|
||||
uint8_t smtlk_mode;
|
||||
uint8_t smtlk_protocol;
|
||||
uint8_t smtlk_rtype;
|
||||
uint8_t smtlk_ak_random;
|
||||
uint8_t connect_flag;
|
||||
uint8_t sta_channel;
|
||||
uint8_t sta_bssid[6];
|
||||
|
||||
//SMARTAPLINK, 44 bytes
|
||||
uint8_t smartaplink_enable;
|
||||
uint8_t smartaplink_padding;
|
||||
uint8_t smartaplink_prefix[21];
|
||||
uint8_t smartaplink_key[21];
|
||||
|
||||
//NETPID, 24 bytes
|
||||
uint8_t netpa_iden;
|
||||
char netpa_id[11];
|
||||
uint8_t netpb_iden;
|
||||
char netpb_id[11];
|
||||
|
||||
//NETPREG, 264 bytes
|
||||
uint8_t netpa_regen;
|
||||
uint8_t netpa_regtype;
|
||||
uint8_t netpa_reg_padding;
|
||||
char netpa_regdata[129];
|
||||
uint8_t netpb_regen;
|
||||
uint8_t netpb_regtype;
|
||||
uint8_t netpb_reg_padding;
|
||||
char netpb_regdata[129];
|
||||
|
||||
//HEART, 124 bytes
|
||||
uint16_t heart_netp_time;
|
||||
uint16_t heart_sockb_time;
|
||||
uint16_t heart_uart_time;
|
||||
char heart_netp_data[39];
|
||||
char heart_sockb_data[39];
|
||||
char heart_uart_data[39];
|
||||
uint8_t heart_padding;
|
||||
|
||||
//HTTP, 236 bytes
|
||||
uint8_t http_type;
|
||||
uint8_t http_version;
|
||||
uint8_t http_connect_type;
|
||||
uint8_t http_recv_time;
|
||||
char http_url[51];
|
||||
char http_header[181];
|
||||
|
||||
//MQTT, 224 bytes
|
||||
char mqtt_username[33];
|
||||
char mqtt_password[33];
|
||||
char mqtt_clientid[33];
|
||||
char mqtt_pub_topic[61];
|
||||
char mqtt_sub_topic[61];
|
||||
uint8_t mqtt_qos;
|
||||
uint16_t mqtt_heart_time;
|
||||
|
||||
//BLE, 188 bytes
|
||||
uint16_t conn_min;
|
||||
uint16_t conn_max;
|
||||
uint16_t conn_latency;
|
||||
uint16_t supervisionTO;
|
||||
|
||||
uint16_t adver_min;
|
||||
uint16_t adver_max;
|
||||
|
||||
uint8_t ble_name[27]; //BLE广播名
|
||||
uint8_t ble_dms_name[27]; //BLE配网名
|
||||
uint8_t ble_adver_data[27];
|
||||
|
||||
uint8_t ble_adver_data_len;
|
||||
uint8_t ble_switch;
|
||||
uint8_t ble_uuid_server;
|
||||
uint8_t dms_type;
|
||||
uint8_t ble_padding;
|
||||
|
||||
uint8_t uuid_ntf_server[17];
|
||||
uint8_t uuid_ntf_read[17];
|
||||
uint8_t uuid_ntf_write[17];
|
||||
uint8_t uuid_ind_server[17];
|
||||
uint8_t uuid_ind_read[17];
|
||||
uint8_t uuid_ind_write[17];
|
||||
|
||||
uint8_t adver_type;
|
||||
uint8_t adver_channel;
|
||||
uint8_t ble_ind;
|
||||
uint8_t smartconfiglink;
|
||||
|
||||
uint8_t ble_conenable;
|
||||
uint8_t ble_conkey[BLE_CONKEYLEN];
|
||||
uint8_t ble_contimeout;
|
||||
uint8_t netpc_iden;
|
||||
char netpc_id[11];
|
||||
uint8_t netpc_idflag;
|
||||
|
||||
uint8_t ble_padding2[17];
|
||||
|
||||
uint8_t mqtt_tls;
|
||||
uint8_t mqtt_padding[3];
|
||||
|
||||
char iot_productkey[12];
|
||||
char iot_devicename[48];
|
||||
char iot_devicesecret[48];
|
||||
char iot_pubtopic[96];
|
||||
char iot_subtopic[96];
|
||||
char iot_mode;
|
||||
char iot_padding[3];
|
||||
|
||||
uint8_t product_mode;
|
||||
|
||||
int8_t ctsrts_pin;
|
||||
|
||||
char instance_flag;
|
||||
char instance_id[32];
|
||||
|
||||
char ntp_domain_server[33];
|
||||
int8_t smk_find;
|
||||
|
||||
uint32_t mcu_ota_size;
|
||||
uint8_t scan_ch14;
|
||||
|
||||
|
||||
uint32_t module_reset_reason;
|
||||
uint8_t reserved1[60+512-4];
|
||||
|
||||
uint8_t validflag_magic;
|
||||
int8_t validflag_end; //valid flag
|
||||
}HF_CONFIG_FILE;
|
||||
#pragma pack(pop)
|
||||
|
||||
HF_CONFIG_FILE g_hf_config_file_boot = {0};
|
||||
|
||||
int hfdbg_get_sw(void)
|
||||
{
|
||||
if(g_hf_config_file_boot.debug_level > 0 && g_hf_config_file_boot.debug_level<=20) //1~20允许打印
|
||||
return 0;
|
||||
|
||||
if(g_hf_config_file_boot.uart1_debug == 1) //1允许打印
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
static uint32_t sfc_flash_init(void)
|
||||
{
|
||||
return uapi_sfc_init((sfc_flash_config_t *)&sfc_cfg);
|
||||
}
|
||||
|
||||
static uint32_t sfc_flash_read(uint32_t flash_addr, uint32_t read_size, uint8_t *read_buffer)
|
||||
{
|
||||
return uapi_sfc_reg_read(flash_addr, read_buffer, read_size);
|
||||
}
|
||||
|
||||
// addr 不是总线地址,没有 FLASH_START 偏移
|
||||
static bool is_flash_addr(uint32_t addr, uint32_t size)
|
||||
{
|
||||
return ((addr >= 0) && (addr + size < FLASH_LEN));
|
||||
}
|
||||
|
||||
static uint32_t sfc_flash_write(uint32_t flash_addr, uint32_t flash_write_size, const uint8_t *p_flash_write_data,
|
||||
bool do_erase)
|
||||
{
|
||||
unused(do_erase);
|
||||
|
||||
if (is_flash_addr(flash_addr, flash_write_size)) {
|
||||
return uapi_sfc_reg_write(flash_addr, (uint8_t *)p_flash_write_data, flash_write_size);
|
||||
}
|
||||
|
||||
// 使用memcpy_s时,操作的是总线地址,需要加回偏移FLASH_START
|
||||
uintptr_t store_addr = (uintptr_t)((int)flash_addr + (int)FLASH_START);
|
||||
if (memcpy_s((void *)store_addr, flash_write_size, p_flash_write_data, flash_write_size) != EOK) {
|
||||
return ERRCODE_FAIL;
|
||||
}
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
|
||||
static uint32_t sfc_flash_erase(uint32_t flash_addr, uint32_t flash_erase_size)
|
||||
{
|
||||
if (flash_erase_size == FLASH_CHIP_ERASE_SIZE) {
|
||||
return uapi_sfc_reg_erase_chip();
|
||||
}
|
||||
|
||||
return uapi_sfc_reg_erase(flash_addr - sfc_cfg.mapping_addr, flash_erase_size);
|
||||
}
|
||||
|
||||
static void boot_flash_init(void)
|
||||
{
|
||||
flash_cmd_func flash_funcs = {0};
|
||||
flash_funcs.init = sfc_flash_init;
|
||||
flash_funcs.read = sfc_flash_read;
|
||||
flash_funcs.write = sfc_flash_write;
|
||||
flash_funcs.erase = sfc_flash_erase;
|
||||
boot_regist_flash_cmd(&flash_funcs);
|
||||
#define REG_PMU_CMU_CTL_PMU_SIG 0x40003154
|
||||
#define PMU_FLASH_SW_EN_BIT 24
|
||||
#define DELAY_5MS 5
|
||||
reg32_setbit(REG_PMU_CMU_CTL_PMU_SIG, PMU_FLASH_SW_EN_BIT);
|
||||
mdelay(DELAY_5MS);
|
||||
|
||||
uint32_t ret = sfc_flash_init();
|
||||
if (ret != ERRCODE_SUCC) {
|
||||
boot_msg1("Flash Init Fail! ret = ", ret);
|
||||
} else {
|
||||
boot_msg0("Flash Init Succ!");
|
||||
}
|
||||
switch_flash_clock_to_pll();
|
||||
config_sfc_ctrl_ds();
|
||||
}
|
||||
|
||||
static uint32_t ws63_loaderboot_init(void)
|
||||
{
|
||||
errcode_t err;
|
||||
uapi_tcxo_init();
|
||||
hiburn_uart_init(g_uart_prag, HIBURN_CODELOADER_UART);
|
||||
boot_msg0("Loadboot Uart Init Succ!");
|
||||
boot_flash_init();
|
||||
err = sfc_port_fix_sr();
|
||||
if (err != ERRCODE_SUCC) {
|
||||
boot_msg1("SFC fix SR ret =", err);
|
||||
}
|
||||
set_efuse_period();
|
||||
uapi_efuse_init(); // efuse函数初始化
|
||||
boot_malloc_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BOOT_WATCH_DOG_TIMOUT 15 // 15s
|
||||
/* the entry of C. */
|
||||
void start_loaderboot(void)
|
||||
{
|
||||
uart_ctx cmd_ctx = { 0 };
|
||||
boot_clock_adapt();
|
||||
uapi_watchdog_init(BOOT_WATCH_DOG_TIMOUT);
|
||||
uapi_watchdog_enable(WDT_MODE_RESET);
|
||||
ws63_loaderboot_init();
|
||||
/* Enter the waiting command cycle. */
|
||||
loader_ack(ACK_SUCCESS);
|
||||
boot_msg0("================ Load Cmd Loop ================\r\n");
|
||||
cmd_loop(&cmd_ctx);
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOADERBOOT_SUPPORT_SET_BUADRATE
|
||||
uint32_t serial_port_set_baudrate(const uart_param_stru *uart)
|
||||
{
|
||||
#define CLDO_CRG_CLK_SEL 0x44001134
|
||||
#define CLDO_SUB_CRG_CKEN_CTL1 0x44001104
|
||||
#define UART_PLL_CLOCK 160000000
|
||||
hiburn_uart_deinit();
|
||||
// 切uart时钟
|
||||
reg_clrbit(CLDO_SUB_CRG_CKEN_CTL1, 0, POS_18); // close uart clock
|
||||
reg_setbit(CLDO_CRG_CLK_SEL, 0, POS_1); // switch uart clock to pll
|
||||
reg_setbit(CLDO_SUB_CRG_CKEN_CTL1, 0, POS_18); // open uart clock
|
||||
uart_port_set_clock_value(UART_BUS_0, UART_PLL_CLOCK);
|
||||
hiburn_uart_init(*uart, HIBURN_CODELOADER_UART);
|
||||
return ERRCODE_SUCC;
|
||||
}
|
||||
#endif
|
105
bootloader/provision_ws63/startup/riscv_init.S
Executable file
105
bootloader/provision_ws63/startup/riscv_init.S
Executable file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
* Description: main
|
||||
*
|
||||
* Create: 2021-03-09
|
||||
*/
|
||||
|
||||
.section .text.entry
|
||||
.global _start
|
||||
.option norvc
|
||||
_start:
|
||||
j Reset_Handler
|
||||
|
||||
Reset_Handler:
|
||||
la t0, __boot_uart_begin__
|
||||
mv t1, a0
|
||||
mv t2, a1
|
||||
set_arg_loop:
|
||||
lw t3, (t1)
|
||||
sw t3, (t0)
|
||||
addi t0, t0, 4
|
||||
addi t1, t1, 4
|
||||
addi t2, t2, -4
|
||||
blt x0, t2, set_arg_loop
|
||||
|
||||
la t0, trap_vector
|
||||
addi t0, t0, 1
|
||||
csrw mtvec, t0
|
||||
csrwi mstatus, 0
|
||||
csrwi mie, 0
|
||||
|
||||
# initialize global pointer
|
||||
la gp, _gp_
|
||||
|
||||
# initialize stack pointer
|
||||
la sp, __stack_top__
|
||||
|
||||
/* init stack */
|
||||
la t0, g_system_stack_begin
|
||||
la t1, g_system_stack_end
|
||||
beq t0, t1, end_set_stack_loop
|
||||
li t2, 0xefbeadde
|
||||
|
||||
set_stack_loop:
|
||||
sw t2, (t0)
|
||||
addi t0, t0, 4
|
||||
blt t0, t1, set_stack_loop
|
||||
end_set_stack_loop:
|
||||
|
||||
/* clear reg */
|
||||
li ra, 0
|
||||
li tp, 0
|
||||
li s0, 0
|
||||
li s1, 0
|
||||
li a0, 0
|
||||
li a1, 0
|
||||
li a2, 0
|
||||
li a3, 0
|
||||
li a4, 0
|
||||
li a5, 0
|
||||
li a6, 0
|
||||
li a7, 0
|
||||
li s2, 0
|
||||
li s3, 0
|
||||
li s4, 0
|
||||
li s5, 0
|
||||
li s6, 0
|
||||
li s7, 0
|
||||
li s8, 0
|
||||
li s9, 0
|
||||
li s10, 0
|
||||
li s11, 0
|
||||
li t3, 0
|
||||
li t4, 0
|
||||
li t5, 0
|
||||
li t6, 0
|
||||
|
||||
/* set data section */
|
||||
la t0, __data_begin__
|
||||
la t1, __data_load__
|
||||
la t2, __data_size__
|
||||
beq t2, x0, end_set_data_loop
|
||||
|
||||
set_data_loop:
|
||||
lw t3, (t1)
|
||||
sw t3, (t0)
|
||||
addi t0, t0, 4
|
||||
addi t1, t1, 4
|
||||
addi t2, t2, -4
|
||||
blt x0, t2, set_data_loop
|
||||
end_set_data_loop:
|
||||
|
||||
/* clear bss section */
|
||||
la t0, __bss_begin__
|
||||
la t1, __bss_end__
|
||||
beq t0, t1, end_clear_bss_loop
|
||||
li t2, 0x00000000
|
||||
|
||||
clear_bss_loop:
|
||||
sw t2, (t0)
|
||||
addi t0, t0, 4
|
||||
blt t0, t1, clear_bss_loop
|
||||
end_clear_bss_loop:
|
||||
|
||||
j start_loaderboot
|
Reference in New Issue
Block a user