88 lines
2.8 KiB
C
88 lines
2.8 KiB
C
/**
|
|
* Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
|
|
*
|
|
* Description: Codeloader efuse source file \n
|
|
* Author: @CompanyNameTag \n
|
|
* History: \n
|
|
* 2023-03-04, Create file. \n
|
|
*/
|
|
|
|
#ifdef EFUSE_INTERFACE_REPLACE
|
|
#include "efuse.h"
|
|
#else
|
|
#include "otp.h"
|
|
#endif
|
|
#include "sha256/sha256.h"
|
|
#include "securec.h"
|
|
#include "chip_io.h"
|
|
#include "codeloader_efuse.h"
|
|
|
|
#define BYTES_PER_EFUSE 2
|
|
|
|
typedef struct {
|
|
uint8_t hash[SHA256_HASH_SIZE]; /* hash of configuration file. */
|
|
uint8_t stru_ver; /* default 0. */
|
|
uint8_t stru_size; /* sizeof(struct efuse_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 efuse_config_item) */
|
|
uint16_t start_byte; /* Start byte of efuse */
|
|
uint16_t byte_width; /* Byte 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 bool efuse_cfg_verify(const uint8_t *input_buffer, uint32_t bytes_to_write)
|
|
{
|
|
efuse_config_header *header = (efuse_config_header *)input_buffer;
|
|
char sha256[SHA256_HASH_SIZE] = { 0 };
|
|
sha256_context_t md;
|
|
|
|
if ((header->file_size > bytes_to_write) || (header->file_size < header->stru_size)) {
|
|
return false;
|
|
}
|
|
|
|
sha256_init(&md);
|
|
SHA256Update(&md, (unsigned char *)(input_buffer + SHA256_HASH_SIZE), header->file_size - SHA256_HASH_SIZE);
|
|
sha256_final(&md, (unsigned char *)sha256, SHA256_HASH_SIZE);
|
|
|
|
if (memcmp(sha256, input_buffer, SHA256_HASH_SIZE) != 0) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool codeloader_efuse_set_byte(const uint8_t *input_buffer_to_write, uint32_t bytes_to_write)
|
|
{
|
|
if (!efuse_cfg_verify(input_buffer_to_write, bytes_to_write)) {
|
|
return false;
|
|
}
|
|
|
|
efuse_config_header *header = (efuse_config_header *)input_buffer_to_write;
|
|
efuse_config_item *item = (efuse_config_item *)(input_buffer_to_write + header->stru_size);
|
|
for (uint8_t i = 0; i < header->number; i++) {
|
|
if (item == NULL) {
|
|
return false;
|
|
}
|
|
#ifdef EFUSE_INTERFACE_REPLACE
|
|
if (uapi_efuse_write_buffer(item->start_byte, item->value, item->value_len) != ERRCODE_SUCC) {
|
|
return false;
|
|
}
|
|
#else
|
|
if (otp_write_buffer(item->start_byte, item->value, item->value_len) != OTP_RET_SUCC) {
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
item = (efuse_config_item *)((uintptr_t)item + item->stru_size + item->value_len);
|
|
}
|
|
|
|
return true;
|
|
} |