mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
efuse: Fix the order of writing in batch mode for esp32s2 and s3
This commit is contained in:
parent
5bbd61d013
commit
f2c9c1e4ab
@ -18,7 +18,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define COUNT_EFUSE_BLOCKS 4 /* The number of blocks. */
|
||||
#define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */
|
||||
|
||||
#define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK3
|
||||
|
@ -18,7 +18,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define COUNT_EFUSE_BLOCKS 11 /* The number of blocks. */
|
||||
#define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */
|
||||
|
||||
#define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK0
|
||||
|
@ -18,7 +18,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define COUNT_EFUSE_BLOCKS 11 /* The number of blocks. */
|
||||
#define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */
|
||||
|
||||
#define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK0
|
||||
|
@ -23,7 +23,7 @@
|
||||
static const char *TAG = "efuse";
|
||||
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
extern uint32_t virt_blocks[COUNT_EFUSE_BLOCKS][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
#endif // CONFIG_EFUSE_VIRTUAL
|
||||
|
||||
/*Range addresses to read blocks*/
|
||||
@ -84,7 +84,7 @@ void esp_efuse_utility_burn_efuses(void)
|
||||
{
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses");
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(num_block);
|
||||
if (scheme == EFUSE_CODING_SCHEME_3_4) {
|
||||
uint8_t buf[COUNT_EFUSE_REG_PER_BLOCK * 4] = { 0 };
|
||||
@ -178,7 +178,7 @@ esp_err_t esp_efuse_utility_apply_new_coding_scheme()
|
||||
uint8_t buf_r_data[COUNT_EFUSE_REG_PER_BLOCK * 4];
|
||||
uint32_t reg[COUNT_EFUSE_REG_PER_BLOCK];
|
||||
// start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE.
|
||||
for (int num_block = 1; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(num_block);
|
||||
// check and apply a new coding scheme.
|
||||
if (scheme != EFUSE_CODING_SCHEME_NONE) {
|
||||
|
@ -24,7 +24,7 @@
|
||||
static const char *TAG = "efuse";
|
||||
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
extern uint32_t virt_blocks[COUNT_EFUSE_BLOCKS][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
#endif // CONFIG_EFUSE_VIRTUAL
|
||||
|
||||
/*Range addresses to read blocks*/
|
||||
@ -42,7 +42,7 @@ const esp_efuse_range_addr_t range_read_addr_blocks[] = {
|
||||
{EFUSE_RD_SYS_PART2_DATA0_REG, EFUSE_RD_SYS_PART2_DATA7_REG} // range address of EFUSE_BLK10 KEY6
|
||||
};
|
||||
|
||||
static uint32_t write_mass_blocks[COUNT_EFUSE_BLOCKS][COUNT_EFUSE_REG_PER_BLOCK] = { 0 };
|
||||
static uint32_t write_mass_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK] = { 0 };
|
||||
|
||||
/*Range addresses to write blocks (it is not real regs, it is buffer) */
|
||||
const esp_efuse_range_addr_t range_write_addr_blocks[] = {
|
||||
@ -80,7 +80,7 @@ void esp_efuse_utility_burn_efuses(void)
|
||||
{
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses");
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
|
||||
int subblock = 0;
|
||||
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
|
||||
virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block);
|
||||
@ -91,7 +91,8 @@ void esp_efuse_utility_burn_efuses(void)
|
||||
ESP_LOGE(TAG, "Efuse fields are not burnt");
|
||||
} else {
|
||||
// Permanently update values written to the efuse write registers
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
// It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks.
|
||||
for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
|
||||
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
|
||||
if (REG_READ(addr_wr_block) != 0) {
|
||||
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
|
||||
@ -118,7 +119,7 @@ void esp_efuse_utility_burn_efuses(void)
|
||||
esp_err_t esp_efuse_utility_apply_new_coding_scheme()
|
||||
{
|
||||
// start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE.
|
||||
for (int num_block = 1; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
|
||||
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
|
||||
if (REG_READ(addr_wr_block)) {
|
||||
|
@ -24,7 +24,7 @@
|
||||
static const char *TAG = "efuse";
|
||||
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
extern uint32_t virt_blocks[COUNT_EFUSE_BLOCKS][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
#endif // CONFIG_EFUSE_VIRTUAL
|
||||
|
||||
/*Range addresses to read blocks*/
|
||||
@ -42,7 +42,7 @@ const esp_efuse_range_addr_t range_read_addr_blocks[] = {
|
||||
{EFUSE_RD_SYS_PART2_DATA0_REG, EFUSE_RD_SYS_PART2_DATA7_REG} // range address of EFUSE_BLK10 KEY6
|
||||
};
|
||||
|
||||
static uint32_t write_mass_blocks[COUNT_EFUSE_BLOCKS][COUNT_EFUSE_REG_PER_BLOCK] = { 0 };
|
||||
static uint32_t write_mass_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK] = { 0 };
|
||||
|
||||
/*Range addresses to write blocks (it is not real regs, it is buffer) */
|
||||
const esp_efuse_range_addr_t range_write_addr_blocks[] = {
|
||||
@ -80,7 +80,7 @@ void esp_efuse_utility_burn_efuses(void)
|
||||
{
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses");
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
|
||||
int subblock = 0;
|
||||
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
|
||||
virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block);
|
||||
@ -91,7 +91,8 @@ void esp_efuse_utility_burn_efuses(void)
|
||||
ESP_LOGE(TAG, "Efuse fields are not burnt");
|
||||
} else {
|
||||
// Permanently update values written to the efuse write registers
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
// It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks.
|
||||
for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
|
||||
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
|
||||
if (REG_READ(addr_wr_block) != 0) {
|
||||
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
|
||||
@ -118,7 +119,7 @@ void esp_efuse_utility_burn_efuses(void)
|
||||
esp_err_t esp_efuse_utility_apply_new_coding_scheme()
|
||||
{
|
||||
// start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE.
|
||||
for (int num_block = 1; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
|
||||
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
|
||||
if (REG_READ(addr_wr_block)) {
|
||||
|
@ -24,7 +24,7 @@ static const char *TAG = "efuse";
|
||||
|
||||
// Array for emulate efuse registers.
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
uint32_t virt_blocks[COUNT_EFUSE_BLOCKS][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
|
||||
/* Call the update function to seed virtual efuses during initialization */
|
||||
__attribute__((constructor)) void esp_efuse_utility_update_virt_blocks(void);
|
||||
@ -145,7 +145,7 @@ esp_err_t esp_efuse_utility_write_cnt(unsigned int num_reg, esp_efuse_block_t ef
|
||||
void esp_efuse_utility_reset(void)
|
||||
{
|
||||
esp_efuse_utility_clear_program_registers();
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
|
||||
REG_WRITE(addr_wr_block, 0);
|
||||
}
|
||||
@ -165,7 +165,7 @@ void esp_efuse_utility_update_virt_blocks(void)
|
||||
{
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
ESP_LOGI(TAG, "Loading virtual efuse blocks from real efuses");
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
int subblock = 0;
|
||||
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4) {
|
||||
virt_blocks[num_block][subblock++] = REG_READ(addr_rd_block);
|
||||
@ -183,7 +183,7 @@ void esp_efuse_utility_debug_dump_blocks(void)
|
||||
{
|
||||
printf("EFUSE_BLKx:\n");
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
int num_reg = 0;
|
||||
printf("%d) ", num_block);
|
||||
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4, num_reg++) {
|
||||
@ -192,7 +192,7 @@ void esp_efuse_utility_debug_dump_blocks(void)
|
||||
printf("\n");
|
||||
}
|
||||
#else
|
||||
for (int num_block = 0; num_block < COUNT_EFUSE_BLOCKS; num_block++) {
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
printf("%d) ", num_block);
|
||||
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4) {
|
||||
printf("0x%08x ", REG_READ(addr_rd_block));
|
||||
|
@ -820,15 +820,17 @@ TEST_CASE("Test a real write (FPGA)", "[efuse]")
|
||||
30, 31};
|
||||
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY3, &new_key, 256));
|
||||
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(new_mac));
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
|
||||
ESP_LOGI(TAG, "3. Set a read protection for KEY3");
|
||||
TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK7));
|
||||
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
|
||||
for (int i = 0; i < sizeof(key); ++i) {
|
||||
TEST_ASSERT_EQUAL_INT(0, key[i]);
|
||||
}
|
||||
#ifndef CONFIG_EFUSE_VIRTUAL
|
||||
TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
|
||||
#endif // CONFIG_EFUSE_VIRTUAL
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
#endif // not CONFIG_IDF_TARGET_ESP32
|
||||
ESP_LOGI(TAG, "4. Write SECURE_VERSION");
|
||||
@ -856,3 +858,32 @@ TEST_CASE("Test chip_revision APIs return the same value", "[efuse]")
|
||||
esp_efuse_utility_update_virt_blocks();
|
||||
TEST_ASSERT_EQUAL_INT(esp_efuse_get_chip_ver(), bootloader_common_get_chip_revision());
|
||||
}
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
#if CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL
|
||||
TEST_CASE("Test writing order is BLK_MAX->BLK0", "[efuse]")
|
||||
{
|
||||
uint8_t new_key[32] = {33, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
|
||||
30, 31};
|
||||
esp_efuse_utility_erase_virt_blocks();
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
|
||||
TEST_ESP_OK(esp_efuse_batch_write_begin());
|
||||
|
||||
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY4, &new_key, 256));
|
||||
// If the order of writing blocks is wrong (ex. BLK0 -> BLK_MAX)
|
||||
// then the write protection bit will be set early and the key was left un-updated.
|
||||
TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY4));
|
||||
|
||||
TEST_ESP_OK(esp_efuse_batch_write_commit());
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
|
||||
uint8_t key[32] = { 0xEE };
|
||||
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY4, &key, 256));
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
|
||||
}
|
||||
|
||||
#endif // CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL
|
||||
#endif // not CONFIG_IDF_TARGET_ESP32
|
||||
|
Loading…
Reference in New Issue
Block a user