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

168 lines
5.9 KiB
C

/*
* Copyright (c) CompanyNameMagicTag 2018-2020. All rights reserved.
* Description: BT CODELOADER CONFIGURATION MODULE
* Author:
* Create: 2018-10-15
*/
#include "panic.h"
#include "otp_map.h"
#ifdef EFUSE_INTERFACE_REPLACE
#include "efuse.h"
#else
#include "otp.h"
#endif
#include "codeloader_configuration.h"
/** Helper macro */
/** OTP Byte that has the Codeloader flags */
/** Codeloader permissions security lock mask */
#define codeloader_config_flags_core_locked_mask(x) BIT(x)
#define OTP_CODELOADER_FLAGS_BYTE_LEN 1
typedef struct {
uint8_t codeloader_flags;
} codeloader_config;
static const codeloader_config g_codeloader_configuration_default_config = { 0 };
static void codeloader_configuration_get_config(codeloader_config *config)
{
*config = g_codeloader_configuration_default_config;
return;
}
static bool codeloader_configuration_set_config(const codeloader_config *config)
{
UNUSED(config);
return true;
}
/* Get the codeloader permissions */
void codeloader_configuration_get_permissions(bool *sec_allowed, bool *prot_allowed, bool *apps_allowed)
{
uint8_t codeloader_flags = 0;
uint8_t cl_otp_config_flags = 0;
#if CHIP_BS21
errcode_t otp_return_code = OTP_RET_SUCC;
#else
// Read OTP flags
#ifdef EFUSE_INTERFACE_REPLACE
errcode_t otp_return_code = uapi_efuse_read_buffer(&cl_otp_config_flags,
OTP_CODELOADER_FLAGS_BYTE, OTP_CODELOADER_FLAGS_BYTE_LEN);
#else
otp_ret_t otp_return_code = otp_read_byte(&cl_otp_config_flags, OTP_CODELOADER_FLAGS_BYTE);
#endif
#endif
// Default to NOT allowed.
*sec_allowed = false;
*prot_allowed = false;
*apps_allowed = false;
// Check the OTP data is valid
#ifdef EFUSE_INTERFACE_REPLACE
if (otp_return_code == ERRCODE_SUCC) { // valid otp data
#else
if (otp_return_code == OTP_RET_SUCC) { // valid otp data
#endif
// load temporary lock flags as well
codeloader_config cl_flash_config;
codeloader_configuration_get_config(&cl_flash_config);
// the codeloader flags indicate locks and will be the or of both
codeloader_flags = cl_otp_config_flags | cl_flash_config.codeloader_flags;
*sec_allowed = ((codeloader_flags &
codeloader_config_flags_core_locked_mask(OTP_CODELOADER_FLAGS_LOCKED_CORES_BT_CORE_BIT)) == 0);
*prot_allowed = ((codeloader_flags &
codeloader_config_flags_core_locked_mask(OTP_CODELOADER_FLAGS_LOCKED_CORES_PROTOCOL_CORE_BIT)) == 0);
*apps_allowed = ((codeloader_flags &
codeloader_config_flags_core_locked_mask(OTP_CODELOADER_FLAGS_LOCKED_CORES_APPS_CORE_BIT)) == 0);
}
}
/* Lock permanently the permissions for a given core. */
void codeloader_configuration_permanent_lock_permissions(cores_t core)
{
uint8_t cl_otp_config_flags = 0;
// check the parameters
if (core >= CORES_MAX_NUMBER_PHYSICAL) {
return;
}
// Read OTP flags
#ifdef EFUSE_INTERFACE_REPLACE
errcode_t otp_return_code = uapi_efuse_read_buffer(&cl_otp_config_flags,
OTP_CODELOADER_FLAGS_BYTE, OTP_CODELOADER_FLAGS_BYTE_LEN);
// Check the OTP data is valid
if (otp_return_code == ERRCODE_SUCC) { // valid otp data
// write the new value only if it's necessary
if ((cl_otp_config_flags & codeloader_config_flags_core_locked_mask(core)) == 0) {
cl_otp_config_flags |= (uint8_t)codeloader_config_flags_core_locked_mask(core);
// using write bit in order to reduce the time
(void)uapi_efuse_write_buffer(OTP_CODELOADER_FLAGS_BYTE,
&cl_otp_config_flags, OTP_CODELOADER_FLAGS_BYTE_LEN);
}
} else {
panic(PANIC_CODELOADER, __LINE__);
}
#else
otp_ret_t otp_return_code = otp_read_byte(&cl_otp_config_flags, OTP_CODELOADER_FLAGS_BYTE);
// Check the OTP data is valid
if (otp_return_code == OTP_RET_SUCC) { // valid otp data
// write the new value only if it's necessary
if ((cl_otp_config_flags & codeloader_config_flags_core_locked_mask(core)) == 0) {
cl_otp_config_flags |= (uint8_t)codeloader_config_flags_core_locked_mask(core);
// using write bit in order to reduce the time
(void)otp_write_byte(OTP_CODELOADER_FLAGS_BYTE, cl_otp_config_flags);
}
} else {
panic(PANIC_CODELOADER, __LINE__);
}
#endif
}
/* Lock temporarily the permissions for a given core */
void codeloader_configuration_temporary_lock_permissions(cores_t core)
{
// check the parameters
if (core >= CORES_MAX_NUMBER_PHYSICAL) {
return;
}
// read the old configuration
codeloader_config cl_flash_config;
codeloader_configuration_get_config(&cl_flash_config);
// write the new configuration only if it is necessary
if ((cl_flash_config.codeloader_flags & codeloader_config_flags_core_locked_mask(core)) == 0) {
codeloader_config cl_new_flash_config;
cl_new_flash_config.codeloader_flags = cl_flash_config.codeloader_flags |
(uint8_t)codeloader_config_flags_core_locked_mask(core);
(void)codeloader_configuration_set_config(&cl_new_flash_config);
}
}
/* Unlock the temporal lock for a given core */
void codeloader_configuration_temporary_unlock_permissions(cores_t core)
{
// check the parameters
if (core >= CORES_MAX_NUMBER_PHYSICAL) {
return;
}
// read the old configuration
codeloader_config cl_flash_config;
codeloader_configuration_get_config(&cl_flash_config);
// write the new configuration only if it is necessary
if ((cl_flash_config.codeloader_flags & codeloader_config_flags_core_locked_mask(core)) != 0) {
codeloader_config cl_new_flash_config;
cl_new_flash_config.codeloader_flags = cl_flash_config.codeloader_flags &
~codeloader_config_flags_core_locked_mask(core);
(void)codeloader_configuration_set_config(&cl_new_flash_config);
}
}