efuse: Fix the order of writing in batch mode for esp32s2 and s3

This commit is contained in:
KonstantinKondrashov 2020-10-29 15:53:42 +08:00 committed by bot
parent 5bbd61d013
commit f2c9c1e4ab
8 changed files with 55 additions and 25 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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)) {

View File

@ -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)) {

View File

@ -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));

View File

@ -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