Ver código fonte

Merge branch 'feature/can_disable_rom_log_from_kconfig' into 'master'

efuse: can disable boot ROM log from Kconfig

Closes IDF-1857

See merge request espressif/esp-idf!12165
Angus Gratton 5 anos atrás
pai
commit
6936dbf4a1

+ 24 - 0
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

+ 5 - 0
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];

+ 12 - 0
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];

+ 12 - 1
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)) {

+ 12 - 1
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)) {

+ 35 - 0
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

+ 0 - 1
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 );

+ 18 - 0
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.
   *

+ 20 - 0
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,             //<CPU ON
@@ -164,6 +166,24 @@ WAKEUP_REASON rtc_get_wakeup_cause(void);
   */
 uint32_t calc_rtc_memory_crc(uint32_t start_addr, uint32_t crc_len);
 
+/**
+  * @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 Set CRC of Fast RTC memory 0-0x7ff into RTC STORE7.
   *

+ 20 - 0
components/esp_rom/include/esp32s2/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,             //<CPU ON
     LIGHT_SLEEP = BIT0,    //CPU waiti, PLL ON.  We don't need explicitly set this mode.
@@ -172,6 +174,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 Fetch entry from RTC memory and RTC STORE reg
   *

+ 19 - 0
components/esp_rom/include/esp32s3/rom/rtc.h

@@ -65,6 +65,7 @@ extern "C" {
 #define RTC_ENTRY_ADDR_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,             //<CPU ON
@@ -159,6 +160,24 @@ WAKEUP_REASON rtc_get_wakeup_cause(void);
   */
 uint32_t calc_rtc_memory_crc(uint32_t start_addr, uint32_t crc_len);
 
+/**
+  * @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 Set CRC of Fast RTC memory 0-0x7ff into RTC STORE7.
   *

+ 1 - 6
components/esp_rom/include/esp_rom_sys.h

@@ -47,13 +47,8 @@ void esp_rom_delay_us(uint32_t us);
 void esp_rom_install_channel_putc(int channel, void (*putc)(char c));
 
 /**
- *  @brief Disable logging from the ROM code.
+ * @brief Install UART1 as the default console channel, equivalent to `esp_rom_install_channel_putc(1, esp_rom_uart_putc)`
  */
-void esp_rom_disable_logging(void);
-
-/**
-  * @brief Install UART1 as the default console channel, equivalent to `esp_rom_install_channel_putc(1, esp_rom_uart_putc)`
-  */
 void esp_rom_install_uart_printf(void);
 
 #ifdef __cplusplus

+ 10 - 9
components/esp_rom/patches/esp_rom_sys.c

@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include <stdint.h>
+#include <stdbool.h>
 #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

+ 20 - 2
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();
 }

+ 1 - 1
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();
 }

+ 0 - 2
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)

+ 1 - 1
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)