mcu_hi3321_watch/middleware/utils/bootloader/private/bootloader_configuration.c
2025-05-26 20:15:20 +08:00

313 lines
9.7 KiB
C

/*
* Copyright (c) CompanyNameMagicTag 2018-2022. All rights reserved.
* Description: BT BOOTLOADER CONFIGURATION MODULE
* Author:
* Create: 2018-10-15
*/
#include "bootloader_configuration.h"
#include "bootloader_utils.h"
#include "otp_map.h"
#ifdef EFUSE_INTERFACE_REPLACE
#include "efuse.h"
#else
#include "otp.h"
#endif
#include "non_os.h"
#include "platform_types.h"
/** mask for bit x */
/** Read bit y in x */
#define read_bit(x, y) (((x) >> (y)) & 1U)
#define ROM_VERSION_FORCE_MINIMAL_ROM 0x12
#define CRC_MASK 0xff000000
#define CRC_RIGHT_SHIFT_BIT 24
#ifdef EFUSE_INTERFACE_REPLACE
#define OTP_BOOTLOADER_BYTE_LEN 1
#define OTP_BOOTLOADER_FLASH_BYTE_LEN 1
#define OTP_BOOTLOADER_DOUBLE_BYTE_LEN 1
#endif
/**
* Default value for g_bootloader_configuration_flags before reading from the otp
*/
static uint8_t g_bootloader_configuration_flags = 0;
static uint8_t g_bootloader_configuration_flags_1 = 0;
#if EMBED_FLASH_EXIST == YES
static uint8_t g_bootloader_configuration_flags_2 = 0;
#endif
/**
* Perform ROM version specific configuration
*/
void bootloader_rom_specific_config(void)
{
static uint8_t cf;
if (bootloader_utils_get_rom_version() == ROM_VERSION_FORCE_MINIMAL_ROM) {
#ifdef EFUSE_INTERFACE_REPLACE
errcode_t efuse_ret;
efuse_ret = uapi_efuse_read_buffer(&cf, OTP_BOOTLOADER_BYTE, OTP_BOOTLOADER_BYTE_LEN);
// Check the OTP data is valid and if not write a default value.
if ((efuse_ret == ERRCODE_SUCC)
&& (read_bit(cf, OTP_BOOTLOADER_FSB_MINIMAL_ROM_BIT) == 0)) {
uint8_t value = (1 << OTP_BOOTLOADER_FSB_MINIMAL_ROM_BIT);
efuse_ret = uapi_efuse_write_buffer(OTP_BOOTLOADER_BYTE, &value, OTP_BOOTLOADER_BYTE_LEN);
UNUSED(efuse_ret);
}
#else
otp_ret_t otp_ret;
otp_ret = otp_read_byte(&cf, OTP_BOOTLOADER_BYTE);
// Check the OTP data is valid and if not write a default value.
if ((otp_ret == OTP_RET_SUCC) && (read_bit(cf, OTP_BOOTLOADER_FSB_MINIMAL_ROM_BIT) == 0)) {
otp_ret = otp_write_byte(OTP_BOOTLOADER_BYTE, (1 << OTP_BOOTLOADER_FSB_MINIMAL_ROM_BIT));
UNUSED(otp_ret);
}
#endif
}
}
void bootloader_configuration_init(void)
{
// Read OTP flags
// Use OTP full access API as iflash config has not yet been initialised so OTP regions have not been declared
#ifdef EFUSE_INTERFACE_REPLACE
(void)uapi_efuse_read_buffer(&g_bootloader_configuration_flags, OTP_BOOTLOADER_BYTE, OTP_BOOTLOADER_BYTE_LEN);
#if (CHIP_LIBRA || CHIP_SOCMN1 || CHIP_BS25 || CHIP_BRANDY)
(void)uapi_efuse_read_buffer(&g_bootloader_configuration_flags_1, OTP_BOOTLOADER_BYTE_1, OTP_BOOTLOADER_BYTE_LEN);
#endif
#if EMBED_FLASH_EXIST == YES
(void)uapi_efuse_read_buffer(&g_bootloader_configuration_flags_2,
OTP_BOOTLOADER_FLASH_BYTE, OTP_BOOTLOADER_FLASH_BYTE_LEN);
#endif
uint8_t config = 0;
(void)uapi_efuse_read_buffer(&config, OTP_BOOTLOADER_DOUBLE_BYTE, OTP_BOOTLOADER_DOUBLE_BYTE_LEN);
g_bootloader_configuration_flags &= config;
#if EMBED_FLASH_EXIST == YES
uint8_t config_1 = 0;
(void)uapi_efuse_read_buffer(&config_1, OTP_BOOTLOADER_FLASH_DOUBLE_BYTE, OTP_BOOTLOADER_DOUBLE_BYTE_LEN);
g_bootloader_configuration_flags_2 &= config_1;
#endif
#else
(void)otp_read_byte(&g_bootloader_configuration_flags, OTP_BOOTLOADER_BYTE);
#if (CHIP_LIBRA || CHIP_SOCMN1 || CHIP_BS25 || CHIP_BRANDY)
(void)otp_read_byte(&g_bootloader_configuration_flags_1, OTP_BOOTLOADER_BYTE_1);
#endif
#if EMBED_FLASH_EXIST == YES
(void)otp_read_byte(&g_bootloader_configuration_flags_2, OTP_BOOTLOADER_FLASH_BYTE);
#endif
uint8_t config = 0;
(void)otp_read_byte(&config, OTP_BOOTLOADER_DOUBLE_BYTE);
g_bootloader_configuration_flags &= config;
#if EMBED_FLASH_EXIST == YES
uint8_t config_1 = 0;
(void)otp_read_byte(&config_1, OTP_BOOTLOADER_FLASH_DOUBLE_BYTE);
g_bootloader_configuration_flags_2 &= config_1;
#endif
#endif
}
bool bootloader_configuration_execute_minimal_rom(void)
{
// check the flag
return (read_bit(g_bootloader_configuration_flags, OTP_BOOTLOADER_FSB_MINIMAL_ROM_BIT) == 1);
}
bool bootloader_configuration_disable_codeloader_mode(void)
{
return (read_bit(g_bootloader_configuration_flags, OTP_BOOTLOADER_FSB_DIS_CODELOADER_BIT) == 1);
}
bool bootloader_configuration_disable_ate_mode(void)
{
// check the flag
return (read_bit(g_bootloader_configuration_flags, OTP_BOOTLOADER_FSB_DIS_ATE_MODE_BIT) == 1);
}
bool bootloader_configuration_en_ssb_hash_in_rom(void)
{
return (read_bit(g_bootloader_configuration_flags, OTP_BOOTLOADER_FSB_EN_SSB_HASH_BIT) == 1);
}
#if EMBED_FLASH_EXIST == YES
bool bootloader_configuration_disable_eflash_mode(void)
{
#ifdef EFUSE_INTERFACE_REPLACE
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
uapi_efuse_init();
}
if (uapi_efuse_write_bit(OTP_BOOTLOADER_FLASH_BYTE, OTP_BOOTLOADER_FSB_DIS_EFLASH_BIT) != ERRCODE_SUCC) {
return false;
}
#else
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
otp_init();
}
if (otp_write_bit(OTP_BOOTLOADER_FLASH_BYTE, OTP_BOOTLOADER_FSB_DIS_EFLASH_BIT) != OTP_RET_SUCC) {
return false;
}
#endif
return true;
}
bool bootloader_configuration_is_enable_eflash_mode(void)
{
return (read_bit(g_bootloader_configuration_flags_2, OTP_BOOTLOADER_FSB_EN_EFLASH_BIT) == 1);
}
bool bootloader_configuration_is_disable_eflash_mode(void)
{
return (read_bit(g_bootloader_configuration_flags_2, OTP_BOOTLOADER_FSB_DIS_EFLASH_BIT) == 1);
}
flash_mode_t bootloader_configuration_get_flash_mode(void)
{
if (bootloader_configuration_is_enable_eflash_mode() &&
(!bootloader_configuration_is_disable_eflash_mode())) {
return EXTERNAL_FLASH_SPI;
} else {
return EMBED_FLASH_XIP;
}
}
#endif
bool bootloader_configuration_ssb_sha256_set(void)
{
uint32_t crc = 0;
bool ssb_sha256_set = true;
#ifdef EFUSE_INTERFACE_REPLACE
errcode_t efuse_ret;
#if CORE == MASTER_BY_ALL
efuse_ret = uapi_efuse_read_buffer((uint8_t *)&crc, OTP_SSB_CODE_SIZE_START, sizeof(uint32_t));
#elif CORE == SECURITY
efuse_ret = uapi_efuse_read_buffer((uint8_t *)&crc, OTP_SEC_SSB_CODE_SIZE_START, sizeof(uint32_t));
#endif
crc = (crc & CRC_MASK) >> CRC_RIGHT_SHIFT_BIT;
// if there is an error, default to set so we default to secure operation
if (efuse_ret == ERRCODE_SUCC && crc == 0) {
ssb_sha256_set = false;
}
#else
otp_ret_t otp_ret;
#if CORE == MASTER_BY_ALL
otp_ret = otp_read_buffer((uint8_t *)&crc, OTP_SSB_CODE_SIZE_START, sizeof(uint32_t));
#elif CORE == SECURITY
otp_ret = otp_read_buffer((uint8_t *)&crc, OTP_SEC_SSB_CODE_SIZE_START, sizeof(uint32_t));
#endif
crc = (crc & CRC_MASK) >> CRC_RIGHT_SHIFT_BIT;
// if there is an error, default to set so we default to secure operation
if (otp_ret == OTP_RET_SUCC && crc == 0) {
ssb_sha256_set = false;
}
#endif
return ssb_sha256_set;
}
bool bootloader_configuration_enable_single_rx_mode(void)
{
#ifdef EFUSE_INTERFACE_REPLACE
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
uapi_efuse_init();
}
if (uapi_efuse_write_bit(OTP_BOOTLOADER_BYTE, OTP_BOOTLOADER_FSB_EN_UART_RX_BIT) != ERRCODE_SUCC) {
return false;
}
#else
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
otp_init();
}
if (otp_write_bit(OTP_BOOTLOADER_BYTE, OTP_BOOTLOADER_FSB_EN_UART_RX_BIT) != OTP_RET_SUCC) {
return false;
}
#endif
return true;
}
bool bootloader_configuration_disable_single_rx_mode(void)
{
#ifdef EFUSE_INTERFACE_REPLACE
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
uapi_efuse_init();
}
if (uapi_efuse_write_bit(OTP_BOOTLOADER_BYTE, OTP_BOOTLOADER_FSB_DIS_UART_RX_BIT) != ERRCODE_SUCC) {
return false;
}
#else
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
otp_init();
}
if (otp_write_bit(OTP_BOOTLOADER_BYTE, OTP_BOOTLOADER_FSB_DIS_UART_RX_BIT) != OTP_RET_SUCC) {
return false;
}
#endif
return true;
}
bool bootloader_configuration_is_enable_single_rx_mode(void)
{
return (read_bit(g_bootloader_configuration_flags, OTP_BOOTLOADER_FSB_EN_UART_RX_BIT) == 1);
}
bool bootloader_configuration_is_disable_single_rx_mode(void)
{
return (read_bit(g_bootloader_configuration_flags, OTP_BOOTLOADER_FSB_DIS_UART_RX_BIT) == 1);
}
bool bootloader_configuration_enable_wait_mode(void)
{
#ifdef EFUSE_INTERFACE_REPLACE
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
uapi_efuse_init();
}
if (uapi_efuse_write_bit(OTP_BOOTLOADER_BYTE_1, OTP_BOOTLOADER_FSB_EN_WAIT_BIT) != ERRCODE_SUCC) {
return false;
}
#else
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
otp_init();
}
if (otp_write_bit(OTP_BOOTLOADER_BYTE_1, OTP_BOOTLOADER_FSB_EN_WAIT_BIT) != OTP_RET_SUCC) {
return false;
}
#endif
return true;
}
bool bootloader_configuration_disable_wait_mode(void)
{
#ifdef EFUSE_INTERFACE_REPLACE
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
uapi_efuse_init();
}
if (uapi_efuse_write_bit(OTP_BOOTLOADER_BYTE_1, OTP_BOOTLOADER_FSB_DIS_WAIT_BIT) != ERRCODE_SUCC) {
return false;
}
#else
if (non_os_is_driver_initialised(DRIVER_INIT_OTP) == false) {
otp_init();
}
if (otp_write_bit(OTP_BOOTLOADER_BYTE_1, OTP_BOOTLOADER_FSB_DIS_WAIT_BIT) != OTP_RET_SUCC) {
return false;
}
#endif
return true;
}
bool bootloader_configuration_is_enable_wait_mode(void)
{
return (read_bit(g_bootloader_configuration_flags_1, OTP_BOOTLOADER_FSB_EN_WAIT_BIT) == 1);
}
bool bootloader_configuration_is_disable_wait_mode(void)
{
return (read_bit(g_bootloader_configuration_flags_1, OTP_BOOTLOADER_FSB_DIS_WAIT_BIT) == 1);
}