diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index 38285096e3..f5e8ccbb50 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -49,6 +49,16 @@ typedef struct { uint16_t bit_count; /**< Length of bit field [1..-]*/ } esp_efuse_desc_t; +/** + * @brief Type definition for ROM log scheme + */ +typedef enum { + ESP_EFUSE_ROM_LOG_ALWAYS_ON, /**< Always enable ROM logging */ + ESP_EFUSE_ROM_LOG_ON_GPIO_LOW, /**< ROM logging is enabled when specific GPIO level is low during start up */ + ESP_EFUSE_ROM_LOG_ON_GPIO_HIGH, /**< ROM logging is enabled when specific GPIO level is high during start up */ + ESP_EFUSE_ROM_LOG_ALWAYS_OFF /**< Disable ROM logging permanently */ +} esp_efuse_rom_log_scheme_t; + /** * @brief Reads bits from EFUSE field and writes it into an array. * @@ -347,6 +357,20 @@ void esp_efuse_disable_basic_rom_console(void); */ esp_err_t esp_efuse_disable_rom_download_mode(void); +/** + * @brief Set boot ROM log scheme via eFuse + * + * @note By default, the boot ROM will always print to console. This API can be called to set the log scheme only once per chip, + * once the value is changed from the default it can't be changed again. + * + * @param log_scheme Supported ROM log scheme + * @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 setting ROM log scheme + * - ESP_ERR_INVALID_STATE This eFuse is write protected or has been burned already + */ +esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme); + #if SOC_SUPPORTS_SECURE_DL_MODE /** * @brief Switch ROM Download Mode to Secure Download mode via eFuse diff --git a/components/efuse/src/esp32/esp_efuse_fields.c b/components/efuse/src/esp32/esp_efuse_fields.c index d94946e0f6..0745d14969 100644 --- a/components/efuse/src/esp32/esp_efuse_fields.c +++ b/components/efuse/src/esp32/esp_efuse_fields.c @@ -96,6 +96,11 @@ esp_err_t esp_efuse_disable_rom_download_mode(void) return esp_efuse_write_field_bit(ESP_EFUSE_UART_DOWNLOAD_DIS); } +esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme) +{ + return ESP_ERR_NOT_SUPPORTED; +} + void esp_efuse_write_random_key(uint32_t blk_wdata0_reg) { uint32_t buf[8]; diff --git a/components/efuse/src/esp32c3/esp_efuse_fields.c b/components/efuse/src/esp32c3/esp_efuse_fields.c index 7d41bf84d6..6ee77802ed 100644 --- a/components/efuse/src/esp32c3/esp_efuse_fields.c +++ b/components/efuse/src/esp32c3/esp_efuse_fields.c @@ -45,6 +45,18 @@ uint32_t esp_efuse_get_pkg_ver(void) return pkg_ver; } + +esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme) +{ + int cur_log_scheme = 0; + esp_efuse_read_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &cur_log_scheme, 2); + if (!cur_log_scheme) { // not burned yet + return esp_efuse_write_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &log_scheme, 2); + } else { + return ESP_ERR_INVALID_STATE; + } +} + void esp_efuse_write_random_key(uint32_t blk_wdata0_reg) { uint32_t buf[8]; diff --git a/components/efuse/src/esp32s2/esp_efuse_fields.c b/components/efuse/src/esp32s2/esp_efuse_fields.c index f9174ca9e2..95aa78b717 100644 --- a/components/efuse/src/esp32s2/esp_efuse_fields.c +++ b/components/efuse/src/esp32s2/esp_efuse_fields.c @@ -55,7 +55,7 @@ void esp_efuse_write_random_key(uint32_t blk_wdata0_reg) ESP_LOGV(TAG, "Writing random values to address 0x%08x", blk_wdata0_reg); for (int i = 0; i < 8; i++) { ESP_LOGV(TAG, "EFUSE_BLKx_WDATA%d_REG = 0x%08x", i, buf[i]); - REG_WRITE(blk_wdata0_reg + 4*i, buf[i]); + REG_WRITE(blk_wdata0_reg + 4 * i, buf[i]); } bzero(buf, sizeof(buf)); bzero(raw, sizeof(raw)); @@ -66,6 +66,17 @@ esp_err_t esp_efuse_disable_rom_download_mode(void) return esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE); } +esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme) +{ + int cur_log_scheme = 0; + esp_efuse_read_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &cur_log_scheme, 2); + if (!cur_log_scheme) { // not burned yet + return esp_efuse_write_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &log_scheme, 2); + } else { + return ESP_ERR_INVALID_STATE; + } +} + esp_err_t esp_efuse_enable_rom_secure_download_mode(void) { if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE)) { diff --git a/components/efuse/src/esp32s3/esp_efuse_fields.c b/components/efuse/src/esp32s3/esp_efuse_fields.c index 005793b432..35756062a2 100644 --- a/components/efuse/src/esp32s3/esp_efuse_fields.c +++ b/components/efuse/src/esp32s3/esp_efuse_fields.c @@ -55,7 +55,7 @@ void esp_efuse_write_random_key(uint32_t blk_wdata0_reg) ESP_LOGV(TAG, "Writing random values to address 0x%08x", blk_wdata0_reg); for (int i = 0; i < 8; i++) { ESP_LOGV(TAG, "EFUSE_BLKx_WDATA%d_REG = 0x%08x", i, buf[i]); - REG_WRITE(blk_wdata0_reg + 4*i, buf[i]); + REG_WRITE(blk_wdata0_reg + 4 * i, buf[i]); } bzero(buf, sizeof(buf)); bzero(raw, sizeof(raw)); @@ -66,6 +66,17 @@ esp_err_t esp_efuse_disable_rom_download_mode(void) return esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE); } +esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme) +{ + int cur_log_scheme = 0; + esp_efuse_read_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &cur_log_scheme, 2); + if (!cur_log_scheme) { // not burned yet + return esp_efuse_write_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &log_scheme, 2); + } else { + return ESP_ERR_INVALID_STATE; + } +} + esp_err_t esp_efuse_enable_rom_secure_download_mode(void) { if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE)) { diff --git a/components/esp_rom/Kconfig.projbuild b/components/esp_rom/Kconfig.projbuild new file mode 100644 index 0000000000..3ddf93d22d --- /dev/null +++ b/components/esp_rom/Kconfig.projbuild @@ -0,0 +1,35 @@ +menu "Boot ROM Behavior" + visible if !IDF_TARGET_ESP32 # no options ere currently supported on ESP32 + + choice BOOT_ROM_LOG_SCHEME + prompt "Permanently change Boot ROM output" + default BOOT_ROM_LOG_ALWAYS_ON + depends on !IDF_TARGET_ESP32 + help + Controls the Boot ROM log behavior. + The rom log behavior can only be changed for once, + specific eFuse bit(s) will be burned at app boot stage. + + config BOOT_ROM_LOG_ALWAYS_ON + bool "Always Log" + help + Always print ROM logs, this is the default behavior. + config BOOT_ROM_LOG_ALWAYS_OFF + bool "Permanently disable logging" + help + Don't print ROM logs. + config BOOT_ROM_LOG_ON_GPIO_HIGH + bool "Log on GPIO High" + help + Print ROM logs when GPIO level is high during start up. + The GPIO number is chip dependent, + e.g. on ESP32-S2, the control GPIO is GPIO46. + config BOOT_ROM_LOG_ON_GPIO_LOW + bool "Log on GPIO Low" + help + Print ROM logs when GPIO level is low during start up. + The GPIO number is chip dependent, + e.g. on ESP32-S2, the control GPIO is GPIO46. + endchoice + +endmenu # Boot ROM Behavior diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld index 2343f2adf4..5c6671d9a8 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld @@ -33,4 +33,3 @@ PROVIDE ( esp_rom_md5_final = MD5Final ); PROVIDE ( esp_rom_printf = ets_printf ); PROVIDE ( esp_rom_delay_us = ets_delay_us ); -PROVIDE ( esp_rom_install_uart_printf = ets_install_uart_printf ); diff --git a/components/esp_rom/include/esp32/rom/rtc.h b/components/esp_rom/include/esp32/rom/rtc.h index fa00b71bb9..79ad9b0acc 100644 --- a/components/esp_rom/include/esp32/rom/rtc.h +++ b/components/esp_rom/include/esp32/rom/rtc.h @@ -184,6 +184,24 @@ uint32_t calc_rtc_memory_crc(uint32_t start_addr, uint32_t crc_len); */ void set_rtc_memory_crc(void); +/** + * @brief Suppress ROM log by setting specific RTC control register. + * @note This is not a permanent disable of ROM logging since the RTC register can not retain after chip reset. + * + * @param None + * + * @return None + */ +static inline void rtc_suppress_rom_log(void) +{ + /* To disable logging in the ROM, only the least significant bit of the register is used, + * but since this register is also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG), + * you need to write to this register in the same format. + * Namely, the upper 16 bits and lower should be the same. + */ + REG_SET_BIT(RTC_CNTL_STORE4_REG, RTC_DISABLE_ROM_LOG); +} + /** * @brief Software Reset digital core. * diff --git a/components/esp_rom/include/esp32c3/rom/rtc.h b/components/esp_rom/include/esp32c3/rom/rtc.h index ef0c5daaba..fcbfddc1c0 100644 --- a/components/esp_rom/include/esp32c3/rom/rtc.h +++ b/components/esp_rom/include/esp32c3/rom/rtc.h @@ -71,6 +71,8 @@ extern "C" { #define RTC_RESET_CAUSE_REG RTC_CNTL_STORE6_REG #define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG +#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. + typedef enum { AWAKE = 0, // +#include #include "esp_attr.h" #include "sdkconfig.h" @@ -39,14 +40,14 @@ IRAM_ATTR void esp_rom_install_channel_putc(int channel, void (*putc)(char c)) } } -void esp_rom_disable_logging(void) +#if CONFIG_IDF_TARGET_ESP32C3 +IRAM_ATTR void esp_rom_install_uart_printf(void) { -#if CONFIG_IDF_TARGET_ESP32 // [refactor-todo]: ESP32S2 seem to also reference disabling logging in its ROM code - /* To disable logging in the ROM, only the least significant bit of the register is used, - * but since this register is also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG), - * you need to write to this register in the same format. - * Namely, the upper 16 bits and lower should be the same. - */ - REG_SET_BIT(RTC_CNTL_STORE4_REG, RTC_DISABLE_ROM_LOG); -#endif + extern void ets_install_uart_printf(void); + extern bool g_uart_print; + // If ROM log is disabled permanently via eFuse or temporarily via RTC storage register, + // this ROM symbol will be set to false, and cause ``esp_rom_printf`` can't work on esp-idf side. + g_uart_print = true; + ets_install_uart_printf(); } +#endif diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index beca4ae893..570a24e3e4 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -22,10 +22,11 @@ #include "esp_log.h" #include "esp_system.h" -#include "esp_rom_uart.h" - +#include "esp_efuse.h" #include "esp_clk_internal.h" + #include "esp_rom_efuse.h" +#include "esp_rom_uart.h" #include "esp_rom_sys.h" #include "sdkconfig.h" @@ -100,6 +101,19 @@ #endif // CONFIG_IDF_TARGET_ESP32C3 #endif // CONFIG_APP_BUILD_TYPE_ELF_RAM +// Set efuse ROM_LOG_MODE on first boot +// +// For CONFIG_BOOT_ROM_LOG_ALWAYS_ON (default) or undefined (ESP32), leave +// ROM_LOG_MODE undefined (no need to call this function during startup) +#if CONFIG_BOOT_ROM_LOG_ALWAYS_OFF +#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ALWAYS_OFF +#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW +#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_LOW +#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH +#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_HIGH +#endif + + #include "esp_private/startup_internal.h" #include "esp_private/system_internal.h" @@ -522,5 +536,9 @@ void IRAM_ATTR call_start_cpu0(void) } #endif +#ifdef ROM_LOG_MODE + esp_efuse_set_rom_log_scheme(ROM_LOG_MODE); +#endif + SYS_STARTUP_FN(); } diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index cbcd82b0ad..4a7476e9eb 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -1245,5 +1245,5 @@ static uint32_t get_power_down_flags(void) void esp_deep_sleep_disable_rom_logging(void) { - esp_rom_disable_logging(); + rtc_suppress_rom_log(); } diff --git a/examples/system/ulp_adc/main/ulp_adc_example_main.c b/examples/system/ulp_adc/main/ulp_adc_example_main.c index 9e38e9ff76..6eb7a9bb10 100644 --- a/examples/system/ulp_adc/main/ulp_adc_example_main.c +++ b/examples/system/ulp_adc/main/ulp_adc_example_main.c @@ -84,9 +84,7 @@ static void init_ulp_program(void) */ rtc_gpio_isolate(GPIO_NUM_12); rtc_gpio_isolate(GPIO_NUM_15); -#if CONFIG_IDF_TARGET_ESP32 esp_deep_sleep_disable_rom_logging(); // suppress boot messages -#endif } static void start_ulp_program(void) diff --git a/tools/ci/check_rom_apis.sh b/tools/ci/check_rom_apis.sh index 05b4c2f3ca..2e1ecead4c 100755 --- a/tools/ci/check_rom_apis.sh +++ b/tools/ci/check_rom_apis.sh @@ -6,7 +6,7 @@ set -uo pipefail cd ${IDF_PATH} # git ls-files operates on working directory only, make sure we're at the top directory deprecated_rom_apis=$(cat ${IDF_PATH}/components/esp_rom/esp32/ld/esp32.rom.api.ld | grep "esp_rom_" | cut -d "=" -f 2 | cut -d " " -f 2) -files_to_search=$(git ls-files --full-name '*.c') +files_to_search=$(git ls-files --full-name '*.c' ':!:components/esp_rom/') count=0 for api in $deprecated_rom_apis; do found_files=$(grep -E "\W+"$api"\W+" $files_to_search)