Skip to content

Commit

Permalink
Merge branch 'featue/factory_reset_state' into 'master'
Browse files Browse the repository at this point in the history
bootloader_support: Adds API to detect Factory reset has happened

Closes IDFGH-9379

See merge request espressif/esp-idf!22822
  • Loading branch information
mahavirj committed Mar 24, 2023
2 parents ff88044 + efbafb8 commit f1465c6
Show file tree
Hide file tree
Showing 16 changed files with 124 additions and 33 deletions.
7 changes: 7 additions & 0 deletions components/app_update/test_apps/main/test_switch_ota.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,9 @@ static void test_flow4(void)
break;
case 3:
ESP_LOGI(TAG, "OTA0");
#ifdef BOOTLOADER_RESERVE_RTC_MEM
TEST_ASSERT_FALSE(bootloader_common_get_rtc_retain_mem_factory_reset_state());
#endif
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
mark_app_valid();
set_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
Expand All @@ -494,6 +497,10 @@ static void test_flow4(void)
case 4:
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
ESP_LOGI(TAG, "Factory");
#ifdef BOOTLOADER_RESERVE_RTC_MEM
TEST_ASSERT_TRUE(bootloader_common_get_rtc_retain_mem_factory_reset_state());
TEST_ASSERT_FALSE(bootloader_common_get_rtc_retain_mem_factory_reset_state());
#endif
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
erase_ota_data();
break;
Expand Down
14 changes: 13 additions & 1 deletion components/bootloader/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ menu "Bootloader config"
config BOOTLOADER_FACTORY_RESET
bool "GPIO triggers factory reset"
default N
select BOOTLOADER_RESERVE_RTC_MEM if SOC_RTC_FAST_MEM_SUPPORTED
help
Allows to reset the device to factory settings:
- clear one or more data partitions;
Expand Down Expand Up @@ -326,6 +327,7 @@ menu "Bootloader config"
# but - as noted in help - it invalidates the integrity of Secure Boot checks
depends on SOC_RTC_FAST_MEM_SUPPORTED && ((SECURE_BOOT && SECURE_BOOT_INSECURE) || !SECURE_BOOT)
default n
select BOOTLOADER_RESERVE_RTC_MEM
help
This option disables the normal validation of an image coming out of
deep sleep (checksums, SHA256, and signature). This is a trade-off
Expand Down Expand Up @@ -381,7 +383,7 @@ menu "Bootloader config"
config BOOTLOADER_RESERVE_RTC_SIZE
hex
depends on SOC_RTC_FAST_MEM_SUPPORTED
default 0x10 if BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP || BOOTLOADER_CUSTOM_RESERVE_RTC
default 0x10 if BOOTLOADER_RESERVE_RTC_MEM
default 0
help
Reserve RTC FAST memory for Skip image validation. This option in bytes.
Expand All @@ -393,6 +395,7 @@ menu "Bootloader config"
config BOOTLOADER_CUSTOM_RESERVE_RTC
bool "Reserve RTC FAST memory for custom purposes"
depends on SOC_RTC_FAST_MEM_SUPPORTED
select BOOTLOADER_RESERVE_RTC_MEM
default n
help
This option allows the customer to place data in the RTC FAST memory,
Expand All @@ -412,6 +415,15 @@ menu "Bootloader config"
in this area of memory, you can increase it. It must be a multiple of 4 bytes.
This area (rtc_retain_mem_t) is reserved and has access from the bootloader and an application.

config BOOTLOADER_RESERVE_RTC_MEM
bool
depends on SOC_RTC_FAST_MEM_SUPPORTED
help
This option reserves an area in RTC FAST memory for the following features:
- "Skip image validation when exiting deep sleep"
- "Reserve RTC FAST memory for custom purposes"
- "GPIO triggers factory reset"

config BOOTLOADER_FLASH_XMC_SUPPORT
bool "Enable the support for flash chips of XMC (READ HELP FIRST)"
default y
Expand Down
7 changes: 5 additions & 2 deletions components/bootloader/subproject/main/bootloader_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,12 @@ static int selected_boot_partition(const bootloader_state_t *bs)
if (bootloader_common_erase_part_type_data(list_erase, ota_data_erase) == false) {
ESP_LOGE(TAG, "Not all partitions were erased");
}
#ifdef CONFIG_BOOTLOADER_RESERVE_RTC_MEM
bootloader_common_set_rtc_retain_mem_factory_reset_state();
#endif
return bootloader_utility_get_selected_boot_partition(bs);
}
#endif
#endif // CONFIG_BOOTLOADER_FACTORY_RESET
// TEST firmware.
#ifdef CONFIG_BOOTLOADER_APP_TEST
bool app_test_level = false;
Expand All @@ -117,7 +120,7 @@ static int selected_boot_partition(const bootloader_state_t *bs)
return INVALID_INDEX;
}
}
#endif
#endif // CONFIG_BOOTLOADER_APP_TEST
// Customer implementation.
// if (gpio_pin_1 == true && ...){
// boot_index = required_boot_partition;
Expand Down
19 changes: 17 additions & 2 deletions components/bootloader_support/include/bootloader_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hd
*/
void bootloader_common_vddsdio_configure(void);

#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
/**
* @brief Returns partition from rtc_retain_mem
*
Expand Down Expand Up @@ -223,6 +223,21 @@ void bootloader_common_reset_rtc_retain_mem(void);
*/
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void);

/**
* @brief Returns True if Factory reset has happened
*
* Reset the status after reading it.
*
* @return True: Factory reset has happened
* False: No Factory reset
*/
bool bootloader_common_get_rtc_retain_mem_factory_reset_state(void);

/**
* @brief Sets Factory reset status
*/
void bootloader_common_set_rtc_retain_mem_factory_reset_state(void);

/**
* @brief Returns rtc_retain_mem
*
Expand All @@ -233,7 +248,7 @@ uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void);
*/
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void);

#endif
#endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM

#ifdef __cplusplus
}
Expand Down
18 changes: 12 additions & 6 deletions components/bootloader_support/include/esp_image_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ typedef enum {
typedef struct {
esp_partition_pos_t partition; /*!< Partition of application which worked before goes to the deep sleep. */
uint16_t reboot_counter; /*!< Reboot counter. Reset only when power is off. */
uint16_t reserve; /*!< Reserve */
union {
struct {
uint8_t factory_reset_state : 1; /* True when Factory reset has occurred */
uint8_t reserve : 7; /* Reserve */
};
uint8_t val;
} flags;
uint8_t reserve; /*!< Reserve */
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
uint8_t custom[CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE]; /*!< Reserve for custom propose */
#endif
Expand All @@ -57,26 +64,25 @@ typedef struct {

ESP_STATIC_ASSERT(offsetof(rtc_retain_mem_t, crc) == sizeof(rtc_retain_mem_t) - sizeof(uint32_t), "CRC field must be the last field of rtc_retain_mem_t structure");

#ifdef CONFIG_BOOTLOADER_RESERVE_RTC_MEM

#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
/* The custom field must be the penultimate field */
ESP_STATIC_ASSERT(offsetof(rtc_retain_mem_t, custom) == sizeof(rtc_retain_mem_t) - sizeof(uint32_t) - CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE,
"custom field in rtc_retain_mem_t structure must be the field before the CRC one");
#endif

#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
#endif

#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif

#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
ESP_STATIC_ASSERT(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved RTC area must exceed size of rtc_retain_mem_t");
#endif
#endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM

/**
* @brief Verify an app image.
Expand Down
35 changes: 29 additions & 6 deletions components/bootloader_support/src/bootloader_common_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
return active_otadata;
}

#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM

#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))

Expand Down Expand Up @@ -148,7 +148,7 @@ static uint32_t rtc_retain_mem_size(void) {
#endif
}

static bool check_rtc_retain_mem(void)
static bool is_retain_mem_valid(void)
{
return esp_rom_crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, rtc_retain_mem_size()) == rtc_retain_mem->crc && rtc_retain_mem->crc != UINT32_MAX;
}
Expand All @@ -165,15 +165,37 @@ NOINLINE_ATTR void bootloader_common_reset_rtc_retain_mem(void)

uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void)
{
if (check_rtc_retain_mem()) {
if (is_retain_mem_valid()) {
return rtc_retain_mem->reboot_counter;
}
return 0;
}

void bootloader_common_set_rtc_retain_mem_factory_reset_state(void)
{
if (!is_retain_mem_valid()) {
bootloader_common_reset_rtc_retain_mem();
}
rtc_retain_mem->flags.factory_reset_state = true;
update_rtc_retain_mem_crc();
}

bool bootloader_common_get_rtc_retain_mem_factory_reset_state(void)
{
if (is_retain_mem_valid()) {
bool factory_reset_state = rtc_retain_mem->flags.factory_reset_state;
if (factory_reset_state == true) {
rtc_retain_mem->flags.factory_reset_state = false;
update_rtc_retain_mem_crc();
}
return factory_reset_state;
}
return false;
}

esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void)
{
if (check_rtc_retain_mem()) {
if (is_retain_mem_valid()) {
return &rtc_retain_mem->partition;
}
return NULL;
Expand All @@ -182,7 +204,7 @@ esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void)
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter)
{
if (reboot_counter) {
if (!check_rtc_retain_mem()) {
if (!is_retain_mem_valid()) {
bootloader_common_reset_rtc_retain_mem();
}
if (++rtc_retain_mem->reboot_counter == 0) {
Expand All @@ -204,4 +226,5 @@ rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
{
return rtc_retain_mem;
}
#endif // defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )

#endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM
6 changes: 5 additions & 1 deletion components/bootloader_support/src/bootloader_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,10 +487,14 @@ static void set_actual_ota_seq(const bootloader_state_t *bs, int index)
update_anti_rollback(&bs->ota[index]);
#endif
}
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
esp_partition_pos_t partition = index_to_partition(bs, index);
bootloader_common_update_rtc_retain_mem(&partition, true);
#else
bootloader_common_update_rtc_retain_mem(NULL, true);
#endif
#endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM
}

#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
Expand Down
6 changes: 4 additions & 2 deletions components/esp_system/ld/esp32/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@
#define CONFIG_BTDM_RESERVE_DRAM 0
#endif

#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM

#if defined(CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE)

Expand Down
6 changes: 4 additions & 2 deletions components/esp_system/ld/esp32c3/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#include "sdkconfig.h"
#include "ld.common"

#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM

/**
* physical memory is mapped twice to the vritual address (IRAM and DRAM).
Expand Down
6 changes: 4 additions & 2 deletions components/esp_system/ld/esp32c6/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#include "sdkconfig.h"
#include "ld.common"

#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM

/**
* physical memory is mapped twice to the vritual address (IRAM and DRAM).
Expand Down
6 changes: 4 additions & 2 deletions components/esp_system/ld/esp32h2/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#include "sdkconfig.h"
#include "ld.common"

#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM

/**
* physical memory is mapped twice to the vritual address (IRAM and DRAM).
Expand Down
6 changes: 4 additions & 2 deletions components/esp_system/ld/esp32h4/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#include "sdkconfig.h"
#include "ld.common"

#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM

#define SRAM_IRAM_START 0x4037C000
#define SRAM_DRAM_START 0x3FC7C000
Expand Down
6 changes: 4 additions & 2 deletions components/esp_system/ld/esp32s2/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#include "sdkconfig.h"
#include "ld.common"

#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM

#ifdef CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB
#define CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE 0x2000
Expand Down
6 changes: 4 additions & 2 deletions components/esp_system/ld/esp32s3/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
#include "sdkconfig.h"
#include "ld.common"

#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM

/*
* 40370000 <- IRAM/Icache -> 40378000 <- D/IRAM (I) -> 403E0000
Expand Down
Loading

0 comments on commit f1465c6

Please sign in to comment.