]> granicus.if.org Git - esp-idf/commitdiff
bootloader: Ensure bootloader never returns to caller
authorAngus Gratton <angus@espressif.com>
Thu, 19 Jul 2018 05:27:35 +0000 (15:27 +1000)
committerAngus Gratton <gus@projectgus.com>
Thu, 19 Jul 2018 06:24:11 +0000 (16:24 +1000)
* Fixes some "noreturn" functions in bootloader utils which did return (causing fatal CPU
  exceptions).
* Marks bootloader entry as "noreturn", preventing "user code done" from stalling boot
  Partial fix for https://github.com/espressif/esp-idf/issues/1814 TW20016
  (Comprehensive fix for this issue will be enabling WDT during bootloader, coming shortly.)

components/bootloader/subproject/main/bootloader_start.c
components/bootloader_support/include_priv/bootloader_utility.h
components/bootloader_support/src/bootloader_utility.c
components/esp32/include/rom/rtc.h

index d7c314b2e36cff6d1dcd6a21bf95631478eb9d16..6f7edc42eefc2021be4cbc60c4d2e4ab31e37a08 100644 (file)
@@ -34,18 +34,18 @@ static int selected_boot_partition(const bootloader_state_t *bs);
  * The hardware is mostly uninitialized, flash cache is down and the app CPU is in reset.
  * We do have a stack, so we can do the initialization in C.
  */
-void call_start_cpu0()
+void __attribute__((noreturn)) call_start_cpu0()
 {
     // 1. Hardware initialization
     if (bootloader_init() != ESP_OK) {
-        return;
+        bootloader_reset();
     }
 
     // 2. Select the number of boot partition
     bootloader_state_t bs = { 0 };
     int boot_index = select_partition_number(&bs);
     if (boot_index == INVALID_INDEX) {
-        return;
+        bootloader_reset();
     }
 
     // 3. Load the app image for booting
index d7231e6858be733234a68ead7a59ef84c46f2264..31213a0160d4e855a9a6d6801e1f638fd704e866 100644 (file)
@@ -52,3 +52,13 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
  * @param[in] start_index The index from which the search for images begins.
  */
 __attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
+
+
+/**
+ * @brief Software reset the ESP32
+ *
+ * Bootloader code should call this in the case that it cannot proceed.
+ *
+ * It is not recommended to call this function from an app (if called, the app will abort).
+ */
+__attribute__((noreturn)) void bootloader_reset(void);
index 6b0145a62906dec15eaed768654975aba1683c19..b079e90cc0fcf5ca7d977d5c9d06ba86de75b967 100644 (file)
@@ -49,6 +49,7 @@
 #include "bootloader_random.h"
 #include "bootloader_config.h"
 #include "bootloader_common.h"
+#include "bootloader_utility.h"
 
 static const char* TAG = "boot";
 
@@ -287,7 +288,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
             load_image(&image_data);
         } else {
             ESP_LOGE(TAG, "No bootable test partition in the partition table");
-            return;
+            bootloader_reset();
         }
     }
 
@@ -324,6 +325,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
 
     ESP_LOGE(TAG, "No bootable app partitions in the partition table");
     bzero(&image_data, sizeof(esp_image_metadata_t));
+    bootloader_reset();
 }
 
 // Copy loaded segments to RAM, set up caches for mapped segments, and start application.
@@ -360,8 +362,7 @@ static void load_image(const esp_image_metadata_t* image_data)
            so issue a system reset to ensure flash encryption
            cache resets properly */
         ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
-        REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
-        return;
+        bootloader_reset();
     }
 #endif
 
@@ -462,3 +463,17 @@ static void set_cache_and_start_app(
     // use "movsp" instruction to reset stack back to where ROM stack starts.
     (*entry)();
 }
+
+
+void bootloader_reset(void)
+{
+#ifdef BOOTLOADER_BUILD
+    uart_tx_flush(0);    /* Ensure any buffered log output is displayed */
+    uart_tx_flush(1);
+    ets_delay_us(1000); /* Allow last byte to leave FIFO */
+    REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
+    while (1) { }       /* This line will never be reached, used to keep gcc happy */
+#else
+    abort();            /* This function should really not be called from application code */
+#endif
+}
index 3161fb2748442146e0d4c5bfb87ef89a3062371a..08d8ace09426344376e3c41756d99a4afaaef7bb 100644 (file)
@@ -192,7 +192,7 @@ void set_rtc_memory_crc(void);
   *
   * @return None
   */
-void software_reset(void);
+void __attribute__((noreturn)) software_reset(void);
 
 /**
   * @brief Software Reset digital core.