first commit

This commit is contained in:
2025-07-03 23:58:20 +08:00
commit ce2b3cdfd4
444 changed files with 65256 additions and 0 deletions

View 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
View 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.

View 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()

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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("=========================");
}
}

View 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;
}

View 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);
}

View 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;
}

View 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;
}

View 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;
}

View 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();
}

View 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;
}

View 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 (;;) { }
}

View 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

View 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

View 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;
}
}
}

View 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;
}