Merge branch 'feature/dis_uart_dl_mode_v4.0' into 'release/v4.0'
feature: Disable UART download mode (v4.0) See merge request espressif/esp-idf!10766
This commit is contained in:
@@ -535,5 +535,23 @@ menu "Security features"
|
||||
the wrong device. The device needs to have flash encryption already enabled using espefuse.py.
|
||||
|
||||
endmenu # Potentially Insecure
|
||||
|
||||
config SECURE_DISABLE_ROM_DL_MODE
|
||||
bool "Permanently disable ROM Download Mode"
|
||||
depends on ESP32_REV_MIN_3
|
||||
default n
|
||||
help
|
||||
If set, during startup the app will burn an eFuse bit to permanently disable the UART ROM
|
||||
Download Mode. This prevents any future use of esptool.py, espefuse.py and similar tools.
|
||||
|
||||
Once disabled, if the SoC is booted with strapping pins set for ROM Download Mode
|
||||
then an error is printed instead.
|
||||
|
||||
It is recommended to enable this option in any production application where Flash
|
||||
Encryption and/or Secure Boot is enabled and access to Download Mode is not required.
|
||||
|
||||
It is also possible to permanently disable Download Mode by calling
|
||||
esp_efuse_disable_rom_download_mode() at runtime.
|
||||
|
||||
endmenu # Security features
|
||||
|
||||
|
||||
@@ -121,6 +121,10 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
|
||||
* is enabled but secure boot is not used. This should protect against
|
||||
* serial re-flashing of an unauthorised code in absence of secure boot.
|
||||
*
|
||||
* @note On ESP32 V3 only, write protecting FLASH_CRYPT_CNT will also prevent
|
||||
* disabling UART Download Mode. If both are wanted, call
|
||||
* esp_efuse_disable_rom_download_mode() before calling this function.
|
||||
*
|
||||
*/
|
||||
void esp_flash_write_protect_crypt_cnt();
|
||||
|
||||
|
||||
@@ -210,16 +210,20 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
|
||||
|
||||
ESP_LOGD(TAG, "All flash regions checked for encryption pass");
|
||||
|
||||
uint32_t new_flash_crypt_cnt;
|
||||
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
|
||||
/* set flash_crypt_cnt to max to avoid needing to write protect it
|
||||
(which also write protects the download mode disable efuse) */
|
||||
new_flash_crypt_cnt = EFUSE_FLASH_CRYPT_CNT;
|
||||
#else
|
||||
/* Set least significant 0-bit in flash_crypt_cnt */
|
||||
int ffs_inv = __builtin_ffs((~flash_crypt_cnt) & EFUSE_RD_FLASH_CRYPT_CNT);
|
||||
/* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == EFUSE_RD_FLASH_CRYPT_CNT (0x7F) */
|
||||
uint32_t new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
|
||||
new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "FLASH_CRYPT_CNT 0x%x -> 0x%x", flash_crypt_cnt, new_flash_crypt_cnt);
|
||||
uint32_t wdata0_reg = ((new_flash_crypt_cnt & EFUSE_FLASH_CRYPT_CNT) << EFUSE_FLASH_CRYPT_CNT_S);
|
||||
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
|
||||
ESP_LOGI(TAG, "Write protecting FLASH_CRYPT_CNT eFuse");
|
||||
wdata0_reg |= EFUSE_WR_DIS_FLASH_CRYPT_CNT;
|
||||
#endif
|
||||
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, wdata0_reg);
|
||||
esp_efuse_burn_new_values();
|
||||
@@ -355,4 +359,4 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
|
||||
flash_failed:
|
||||
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,20 @@ void esp_flash_encryption_init_checks()
|
||||
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
if (esp_secure_boot_enabled() && esp_flash_encryption_enabled()) {
|
||||
uint8_t flash_crypt_cnt_wr_dis = 0;
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
|
||||
bool flash_crypt_cnt_wr_dis = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT);
|
||||
if (!flash_crypt_cnt_wr_dis) {
|
||||
ESP_LOGE(TAG, "Flash encryption & Secure Boot together requires FLASH_CRYPT_CNT efuse to be write protected. Fixing now...");
|
||||
esp_flash_write_protect_crypt_cnt();
|
||||
uint8_t flash_crypt_cnt = 0;
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_FLASH_CRYPT_CNT, &flash_crypt_cnt,
|
||||
ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count);
|
||||
if (flash_crypt_cnt == (1<<(ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count))-1) {
|
||||
// If encryption counter is already max, no need to write protect it
|
||||
// (this distinction is important on ESP32 ECO3 where write-procted FLASH_CRYPT_CNT also write-protects UART_DL_DIS)
|
||||
flash_crypt_cnt_wr_dis = 1;
|
||||
}
|
||||
if (!flash_crypt_cnt_wr_dis) {
|
||||
ESP_EARLY_LOGE(TAG, "Flash encryption & Secure Boot together requires FLASH_CRYPT_CNT efuse to be write protected. Fixing now...");
|
||||
esp_flash_write_protect_crypt_cnt();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_SECURE_BOOT_ENABLED
|
||||
@@ -61,35 +70,31 @@ void esp_flash_encryption_init_checks()
|
||||
|
||||
void esp_flash_write_protect_crypt_cnt()
|
||||
{
|
||||
uint8_t flash_crypt_cnt_wr_dis = 0;
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
|
||||
if (!flash_crypt_cnt_wr_dis) {
|
||||
esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, 1);
|
||||
}
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT);
|
||||
}
|
||||
|
||||
esp_flash_enc_mode_t esp_get_flash_encryption_mode()
|
||||
{
|
||||
uint8_t flash_crypt_cnt_wr_dis = 0;
|
||||
bool flash_crypt_cnt_wr_dis = false;
|
||||
uint8_t dis_dl_enc = 0, dis_dl_dec = 0, dis_dl_cache = 0;
|
||||
esp_flash_enc_mode_t mode = ESP_FLASH_ENC_MODE_DEVELOPMENT;
|
||||
|
||||
if (esp_flash_encryption_enabled()) {
|
||||
/* Check if FLASH CRYPT CNT is write protected */
|
||||
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
|
||||
flash_crypt_cnt_wr_dis = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT);
|
||||
if (!flash_crypt_cnt_wr_dis) {
|
||||
uint8_t flash_crypt_cnt = 0;
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_FLASH_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count);
|
||||
if (flash_crypt_cnt == (1 << (ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count)) - 1) {
|
||||
flash_crypt_cnt_wr_dis = 1;
|
||||
flash_crypt_cnt_wr_dis = true; // CRYPT_CNT at max is same as write protected
|
||||
}
|
||||
}
|
||||
|
||||
if (flash_crypt_cnt_wr_dis) {
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_CACHE, &dis_dl_cache, 1);
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_ENCRYPT, &dis_dl_enc, 1);
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_DECRYPT, &dis_dl_dec, 1);
|
||||
dis_dl_cache = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_CACHE);
|
||||
dis_dl_enc = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_ENCRYPT);
|
||||
dis_dl_dec = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_DECRYPT);
|
||||
|
||||
/* Check if DISABLE_DL_DECRYPT, DISABLE_DL_ENCRYPT & DISABLE_DL_CACHE are set */
|
||||
if ( dis_dl_cache && dis_dl_enc && dis_dl_dec ) {
|
||||
mode = ESP_FLASH_ENC_MODE_RELEASE;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <assert.h>
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
// md5_digest_table 2e23344575b3d07f01ecb695294e9770
|
||||
// md5_digest_table 11b691b6fa8546a3862a7a876be5f758
|
||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
|
||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
|
||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
|
||||
@@ -87,20 +87,24 @@ static const esp_efuse_desc_t DISABLE_DL_CACHE[] = {
|
||||
{EFUSE_BLK0, 201, 1}, // Flash encrypt. Disable UART bootloader MMU cache. EFUSE_DISABLE_DL_CACHE.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t DISABLE_JTAG[] = {
|
||||
{EFUSE_BLK0, 198, 1}, // Flash encrypt. Disable JTAG. EFUSE_RD_DISABLE_JTAG.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t CONSOLE_DEBUG_DISABLE[] = {
|
||||
{EFUSE_BLK0, 194, 1}, // Flash encrypt. Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t FLASH_CRYPT_CNT[] = {
|
||||
{EFUSE_BLK0, 20, 7}, // Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t DISABLE_JTAG[] = {
|
||||
{EFUSE_BLK0, 198, 1}, // Disable JTAG. EFUSE_RD_DISABLE_JTAG.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t CONSOLE_DEBUG_DISABLE[] = {
|
||||
{EFUSE_BLK0, 194, 1}, // Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t UART_DOWNLOAD_DIS[] = {
|
||||
{EFUSE_BLK0, 27, 1}, // Disable UART download mode. Valid for ESP32 V3 and newer,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t WR_DIS_FLASH_CRYPT_CNT[] = {
|
||||
{EFUSE_BLK0, 2, 1}, // Flash encrypt. Write protection FLASH_CRYPT_CNT. EFUSE_WR_DIS_FLASH_CRYPT_CNT,
|
||||
{EFUSE_BLK0, 2, 1}, // Flash encrypt. Write protection FLASH_CRYPT_CNT,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t WR_DIS_BLK1[] = {
|
||||
@@ -260,23 +264,28 @@ const esp_efuse_desc_t* ESP_EFUSE_DISABLE_DL_CACHE[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_DISABLE_JTAG[] = {
|
||||
&DISABLE_JTAG[0], // Flash encrypt. Disable JTAG. EFUSE_RD_DISABLE_JTAG.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_CONSOLE_DEBUG_DISABLE[] = {
|
||||
&CONSOLE_DEBUG_DISABLE[0], // Flash encrypt. Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_FLASH_CRYPT_CNT[] = {
|
||||
&FLASH_CRYPT_CNT[0], // Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_DISABLE_JTAG[] = {
|
||||
&DISABLE_JTAG[0], // Disable JTAG. EFUSE_RD_DISABLE_JTAG.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_CONSOLE_DEBUG_DISABLE[] = {
|
||||
&CONSOLE_DEBUG_DISABLE[0], // Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_UART_DOWNLOAD_DIS[] = {
|
||||
&UART_DOWNLOAD_DIS[0], // Disable UART download mode. Valid for ESP32 V3 and newer
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT[] = {
|
||||
&WR_DIS_FLASH_CRYPT_CNT[0], // Flash encrypt. Write protection FLASH_CRYPT_CNT. EFUSE_WR_DIS_FLASH_CRYPT_CNT
|
||||
&WR_DIS_FLASH_CRYPT_CNT[0], // Flash encrypt. Write protection FLASH_CRYPT_CNT
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -39,13 +39,16 @@ ENCRYPT_CONFIG, EFUSE_BLK0, 188, 4, Flash encrypt. EFUSE_FLASH_C
|
||||
DISABLE_DL_ENCRYPT, EFUSE_BLK0, 199, 1, Flash encrypt. Disable UART bootloader encryption. EFUSE_DISABLE_DL_ENCRYPT.
|
||||
DISABLE_DL_DECRYPT, EFUSE_BLK0, 200, 1, Flash encrypt. Disable UART bootloader decryption. EFUSE_DISABLE_DL_DECRYPT.
|
||||
DISABLE_DL_CACHE, EFUSE_BLK0, 201, 1, Flash encrypt. Disable UART bootloader MMU cache. EFUSE_DISABLE_DL_CACHE.
|
||||
DISABLE_JTAG, EFUSE_BLK0, 198, 1, Flash encrypt. Disable JTAG. EFUSE_RD_DISABLE_JTAG.
|
||||
CONSOLE_DEBUG_DISABLE, EFUSE_BLK0, 194, 1, Flash encrypt. Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.
|
||||
FLASH_CRYPT_CNT, EFUSE_BLK0, 20, 7, Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT.
|
||||
|
||||
# Misc Security #
|
||||
DISABLE_JTAG, EFUSE_BLK0, 198, 1, Disable JTAG. EFUSE_RD_DISABLE_JTAG.
|
||||
CONSOLE_DEBUG_DISABLE, EFUSE_BLK0, 194, 1, Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.
|
||||
UART_DOWNLOAD_DIS, EFUSE_BLK0, 27, 1, Disable UART download mode. Valid for ESP32 V3 and newer, only.
|
||||
|
||||
# Write protection #
|
||||
####################
|
||||
WR_DIS_FLASH_CRYPT_CNT, EFUSE_BLK0, 2, 1, Flash encrypt. Write protection FLASH_CRYPT_CNT. EFUSE_WR_DIS_FLASH_CRYPT_CNT
|
||||
WR_DIS_FLASH_CRYPT_CNT, EFUSE_BLK0, 2, 1, Flash encrypt. Write protection FLASH_CRYPT_CNT, UART_DOWNLOAD_DIS. EFUSE_WR_DIS_FLASH_CRYPT_CNT
|
||||
WR_DIS_BLK1, EFUSE_BLK0, 7, 1, Flash encrypt. Write protection encryption key. EFUSE_WR_DIS_BLK1
|
||||
WR_DIS_BLK2, EFUSE_BLK0, 8, 1, Security boot. Write protection security key. EFUSE_WR_DIS_BLK2
|
||||
WR_DIS_BLK3, EFUSE_BLK0, 9, 1, Write protection for EFUSE_BLK3. EFUSE_WR_DIS_BLK3
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 7 and column 87.
|
@@ -17,7 +17,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// md5_digest_table 2e23344575b3d07f01ecb695294e9770
|
||||
// md5_digest_table 11b691b6fa8546a3862a7a876be5f758
|
||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
|
||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
|
||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
|
||||
@@ -36,9 +36,10 @@ extern const esp_efuse_desc_t* ESP_EFUSE_ENCRYPT_CONFIG[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_DL_ENCRYPT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_DL_DECRYPT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_DL_CACHE[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_CRYPT_CNT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_JTAG[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_CONSOLE_DEBUG_DISABLE[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_CRYPT_CNT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_UART_DOWNLOAD_DIS[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK2[];
|
||||
|
||||
@@ -75,6 +75,23 @@ typedef struct {
|
||||
*/
|
||||
esp_err_t esp_efuse_read_field_blob(const esp_efuse_desc_t* field[], void* dst, size_t dst_size_bits);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read a single bit eFuse field as a boolean value.
|
||||
*
|
||||
* @note The value must exist and must be a single bit wide. If there is any possibility of an error
|
||||
* in the provided arguments, call esp_efuse_read_field_blob() and check the returned value instead.
|
||||
*
|
||||
* @note If assertions are enabled and the parameter is invalid, execution will abort
|
||||
*
|
||||
* @param[in] field A pointer to the structure describing the fields of efuse.
|
||||
* @return
|
||||
* - true: The field parameter is valid and the bit is set.
|
||||
* - false: The bit is not set, or the parameter is invalid and assertions are disabled.
|
||||
*
|
||||
*/
|
||||
bool esp_efuse_read_field_bit(const esp_efuse_desc_t *field[]);
|
||||
|
||||
/**
|
||||
* @brief Reads bits from EFUSE field and returns number of bits programmed as "1".
|
||||
*
|
||||
@@ -123,6 +140,23 @@ esp_err_t esp_efuse_write_field_blob(const esp_efuse_desc_t* field[], const void
|
||||
*/
|
||||
esp_err_t esp_efuse_write_field_cnt(const esp_efuse_desc_t* field[], size_t cnt);
|
||||
|
||||
/**
|
||||
* @brief Write a single bit eFuse field to 1
|
||||
*
|
||||
* For use with eFuse fields that are a single bit. This function will write the bit to value 1 if
|
||||
* it is not already set, or does nothing if the bit is already set.
|
||||
*
|
||||
* This is equivalent to calling esp_efuse_write_field_cnt() with the cnt parameter equal to 1,
|
||||
* except that it will return ESP_OK if the field is already set to 1.
|
||||
*
|
||||
* @param[in] field Pointer to the structure describing the efuse field.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: The operation was successfully completed, or the bit was already set to value 1.
|
||||
* - ESP_ERR_INVALID_ARG: Error in the passed arugments, including if the efuse field is not 1 bit wide.
|
||||
*/
|
||||
esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t* field[]);
|
||||
|
||||
/**
|
||||
* @brief Sets a write protection for the whole block.
|
||||
*
|
||||
@@ -301,6 +335,23 @@ void esp_efuse_disable_basic_rom_console(void);
|
||||
*/
|
||||
esp_err_t esp_efuse_apply_34_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len);
|
||||
|
||||
/* @brief Disable ROM Download Mode via eFuse
|
||||
*
|
||||
* Permanently disables the ROM Download Mode feature. Once disabled, if the SoC is booted with
|
||||
* strapping pins set for ROM Download Mode then an error is printed instead.
|
||||
*
|
||||
* @note Not all SoCs support this option. An error will be returned if called on an ESP32
|
||||
* with a silicon revision lower than 3, as these revisions do not support this option.
|
||||
*
|
||||
* @note If ROM Download Mode is already disabled, this function does nothing and returns success.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK If the eFuse was successfully burned, or had already been burned.
|
||||
* - ESP_ERR_NOT_SUPPORTED (ESP32 only) This SoC is not capable of disabling UART download mode
|
||||
* - ESP_ERR_INVALID_STATE (ESP32 only) This eFuse is write protected and cannot be written
|
||||
*/
|
||||
esp_err_t esp_efuse_disable_rom_download_mode(void);
|
||||
|
||||
/* @brief Write random data to efuse key block write registers
|
||||
*
|
||||
* @note Caller is responsible for ensuring efuse
|
||||
|
||||
@@ -48,6 +48,14 @@ esp_err_t esp_efuse_read_field_blob(const esp_efuse_desc_t* field[], void* dst,
|
||||
return err;
|
||||
}
|
||||
|
||||
bool esp_efuse_read_field_bit(const esp_efuse_desc_t *field[])
|
||||
{
|
||||
uint8_t value = 0;
|
||||
esp_err_t err = esp_efuse_read_field_blob(field, &value, 1);
|
||||
assert(err == ESP_OK);
|
||||
return (err == ESP_OK) && value;
|
||||
}
|
||||
|
||||
// read number of bits programmed as "1" in the particular field
|
||||
esp_err_t esp_efuse_read_field_cnt(const esp_efuse_desc_t* field[], size_t* out_cnt)
|
||||
{
|
||||
@@ -140,6 +148,25 @@ esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t* field[])
|
||||
{
|
||||
esp_err_t err;
|
||||
uint8_t existing = 0;
|
||||
const uint8_t one = 1;
|
||||
|
||||
if (field == NULL || field[0]->bit_count != 1) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Check existing value. esp_efuse_write_field_blob() also checks this, but will log an error */
|
||||
err = esp_efuse_read_field_blob(field, &existing, 1);
|
||||
if (err != ESP_OK || existing) {
|
||||
return err; // Error reading, or the bit is already written and we can no-op this
|
||||
}
|
||||
|
||||
return esp_efuse_write_field_blob(field, &one, 1);
|
||||
}
|
||||
|
||||
// get the length of the field in bits
|
||||
int esp_efuse_get_field_size(const esp_efuse_desc_t* field[])
|
||||
{
|
||||
|
||||
@@ -115,6 +115,33 @@ esp_err_t esp_efuse_apply_34_encoding(const uint8_t *in_bytes, uint32_t *out_wor
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_disable_rom_download_mode(void)
|
||||
{
|
||||
uint8_t dl_dis = 0;
|
||||
uint8_t wr_dis_flash_crypt_cnt = 0;
|
||||
#ifndef CONFIG_ESP32_REV_MIN_3
|
||||
/* Check if we support this revision at all */
|
||||
if(esp_efuse_get_chip_ver() < 3) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_UART_DOWNLOAD_DIS, &dl_dis, 1);
|
||||
if (dl_dis) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* WR_DIS_FLASH_CRYPT_CNT also covers UART_DOWNLOAD_DIS on ESP32 */
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &wr_dis_flash_crypt_cnt, 1);
|
||||
if(wr_dis_flash_crypt_cnt) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
dl_dis = 1;
|
||||
return esp_efuse_write_field_blob(ESP_EFUSE_UART_DOWNLOAD_DIS, &dl_dis, 1);
|
||||
}
|
||||
|
||||
|
||||
void esp_efuse_write_random_key(uint32_t blk_wdata0_reg)
|
||||
{
|
||||
uint32_t buf[8];
|
||||
|
||||
@@ -224,6 +224,32 @@ TEST_CASE("efuse test write_field_cnt", "[efuse]")
|
||||
test_write_cnt();
|
||||
}
|
||||
|
||||
TEST_CASE("efuse test single bit functions", "[efuse]")
|
||||
{
|
||||
esp_efuse_utility_erase_virt_blocks();
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
|
||||
uint8_t test_bit;
|
||||
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
|
||||
TEST_ASSERT_EQUAL_HEX8(0, test_bit);
|
||||
|
||||
test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
|
||||
TEST_ASSERT_EQUAL_HEX8(0, test_bit);
|
||||
|
||||
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
|
||||
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
|
||||
TEST_ASSERT_EQUAL_HEX8(1, test_bit);
|
||||
|
||||
test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
|
||||
TEST_ASSERT_EQUAL_HEX8(1, test_bit);
|
||||
|
||||
// Can write the bit again and it's a no-op
|
||||
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
|
||||
TEST_ASSERT_EQUAL_HEX8(1, esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1));
|
||||
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
}
|
||||
|
||||
void cut_tail_arr(uint8_t *arr, int num_used_bits, size_t count_bits)
|
||||
{
|
||||
if ((num_used_bits + count_bits) % 8) {
|
||||
|
||||
@@ -350,6 +350,14 @@ void start_cpu0_default(void)
|
||||
#if CONFIG_ESP32_BROWNOUT_DET
|
||||
esp_brownout_init();
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE
|
||||
esp_efuse_disable_basic_rom_console();
|
||||
#endif
|
||||
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
esp_efuse_disable_rom_download_mode();
|
||||
#endif
|
||||
|
||||
rtc_gpio_force_hold_dis_all();
|
||||
esp_vfs_dev_uart_register();
|
||||
esp_reent_init(_GLOBAL_REENT);
|
||||
|
||||
Reference in New Issue
Block a user