1 /*
2 * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "string.h"
8 #include "sdkconfig.h"
9 #include "esp_err.h"
10 #include "esp_log.h"
11 #include "esp_rom_spiflash.h"
12 #include "esp_rom_crc.h"
13 #include "esp_rom_gpio.h"
14 #include "esp_flash_partitions.h"
15 #include "bootloader_flash.h"
16 #include "bootloader_common.h"
17 #include "soc/gpio_periph.h"
18 #include "soc/rtc.h"
19 #include "soc/efuse_reg.h"
20 #include "soc/chip_revision.h"
21 #include "hal/efuse_hal.h"
22 #include "hal/efuse_ll.h"
23 #include "hal/gpio_ll.h"
24 #include "esp_image_format.h"
25 #include "bootloader_sha.h"
26 #include "sys/param.h"
27 #include "bootloader_flash_priv.h"
28
29 #define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
30 #define IS_MAX_REV_SET(max_chip_rev_full) (((max_chip_rev_full) != 65535) && ((max_chip_rev_full) != 0))
31
32 static const char* TAG = "boot_comm";
33
bootloader_common_ota_select_crc(const esp_ota_select_entry_t * s)34 uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s)
35 {
36 return esp_rom_crc32_le(UINT32_MAX, (uint8_t*)&s->ota_seq, 4);
37 }
38
bootloader_common_ota_select_invalid(const esp_ota_select_entry_t * s)39 bool bootloader_common_ota_select_invalid(const esp_ota_select_entry_t *s)
40 {
41 return s->ota_seq == UINT32_MAX || s->ota_state == ESP_OTA_IMG_INVALID || s->ota_state == ESP_OTA_IMG_ABORTED;
42 }
43
bootloader_common_ota_select_valid(const esp_ota_select_entry_t * s)44 bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s)
45 {
46 return bootloader_common_ota_select_invalid(s) == false && s->crc == bootloader_common_ota_select_crc(s);
47 }
48
bootloader_common_get_active_otadata(esp_ota_select_entry_t * two_otadata)49 int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata)
50 {
51 if (two_otadata == NULL) {
52 return -1;
53 }
54 bool valid_two_otadata[2];
55 valid_two_otadata[0] = bootloader_common_ota_select_valid(&two_otadata[0]);
56 valid_two_otadata[1] = bootloader_common_ota_select_valid(&two_otadata[1]);
57 return bootloader_common_select_otadata(two_otadata, valid_two_otadata, true);
58 }
59
bootloader_common_check_chip_validity(const esp_image_header_t * img_hdr,esp_image_type type)60 esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type)
61 {
62 esp_err_t err = ESP_OK;
63 esp_chip_id_t chip_id = CONFIG_IDF_FIRMWARE_CHIP_ID;
64 if (chip_id != img_hdr->chip_id) {
65 ESP_LOGE(TAG, "mismatch chip ID, expected %d, found %d", chip_id, img_hdr->chip_id);
66 err = ESP_FAIL;
67 } else {
68 #ifndef CONFIG_IDF_ENV_FPGA
69 unsigned revision = efuse_hal_chip_revision();
70 unsigned int major_rev = revision / 100;
71 unsigned int minor_rev = revision % 100;
72 unsigned min_rev = img_hdr->min_chip_rev_full;
73 if (type == ESP_IMAGE_BOOTLOADER || type == ESP_IMAGE_APPLICATION) {
74 if (!ESP_CHIP_REV_ABOVE(revision, min_rev)) {
75 ESP_LOGE(TAG, "Image requires chip rev >= v%d.%d, but chip is v%d.%d",
76 min_rev / 100, min_rev % 100,
77 major_rev, minor_rev);
78 err = ESP_FAIL;
79 }
80 }
81 if (type == ESP_IMAGE_APPLICATION) {
82 unsigned max_rev = img_hdr->max_chip_rev_full;
83 if ((IS_MAX_REV_SET(max_rev) && (revision > max_rev) && !efuse_ll_get_disable_wafer_version_major())) {
84 ESP_LOGE(TAG, "Image requires chip rev <= v%d.%d, but chip is v%d.%d",
85 max_rev / 100, max_rev % 100,
86 major_rev, minor_rev);
87 err = ESP_FAIL;
88 }
89 }
90 #endif // CONFIG_IDF_ENV_FPGA
91 }
92
93 return err;
94 }
95
bootloader_common_select_otadata(const esp_ota_select_entry_t * two_otadata,bool * valid_two_otadata,bool max)96 int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max)
97 {
98 if (two_otadata == NULL || valid_two_otadata == NULL) {
99 return -1;
100 }
101 int active_otadata = -1;
102 if (valid_two_otadata[0] && valid_two_otadata[1]) {
103 uint32_t condition = (max == true) ? MAX(two_otadata[0].ota_seq, two_otadata[1].ota_seq) : MIN(two_otadata[0].ota_seq, two_otadata[1].ota_seq);
104 if (condition == two_otadata[0].ota_seq) {
105 active_otadata = 0;
106 } else {
107 active_otadata = 1;
108 }
109 ESP_LOGD(TAG, "Both OTA copies are valid");
110 } else {
111 for (int i = 0; i < 2; ++i) {
112 if (valid_two_otadata[i]) {
113 active_otadata = i;
114 ESP_LOGD(TAG, "Only otadata[%d] is valid", i);
115 break;
116 }
117 }
118 }
119 return active_otadata;
120 }
121
122 #if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
123
rtc_retain_mem_size(void)124 static uint32_t rtc_retain_mem_size(void) {
125 #ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
126 /* A custom memory has been reserved by the user, do not consider this memory into CRC calculation as it may change without
127 * the have the user updating the CRC. Return the offset of the custom field, which is equivalent to size of the structure
128 * minus the size of everything after (including) `custom` */
129 return offsetof(rtc_retain_mem_t, custom);
130 #else
131 return sizeof(rtc_retain_mem_t) - sizeof(bootloader_common_get_rtc_retain_mem()->crc);
132 #endif
133 }
134
is_retain_mem_valid(void)135 static bool is_retain_mem_valid(void)
136 {
137 rtc_retain_mem_t* rtc_retain_mem = bootloader_common_get_rtc_retain_mem();
138 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;
139 }
140
update_rtc_retain_mem_crc(void)141 static void update_rtc_retain_mem_crc(void)
142 {
143 rtc_retain_mem_t* rtc_retain_mem = bootloader_common_get_rtc_retain_mem();
144 rtc_retain_mem->crc = esp_rom_crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, rtc_retain_mem_size());
145 }
146
bootloader_common_reset_rtc_retain_mem(void)147 NOINLINE_ATTR void bootloader_common_reset_rtc_retain_mem(void)
148 {
149 hal_memset(bootloader_common_get_rtc_retain_mem(), 0, sizeof(rtc_retain_mem_t));
150 }
151
bootloader_common_get_rtc_retain_mem_reboot_counter(void)152 uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void)
153 {
154 if (is_retain_mem_valid()) {
155 return bootloader_common_get_rtc_retain_mem()->reboot_counter;
156 }
157 return 0;
158 }
159
bootloader_common_set_rtc_retain_mem_factory_reset_state(void)160 void bootloader_common_set_rtc_retain_mem_factory_reset_state(void)
161 {
162 if (!is_retain_mem_valid()) {
163 bootloader_common_reset_rtc_retain_mem();
164 }
165 bootloader_common_get_rtc_retain_mem()->flags.factory_reset_state = true;
166 update_rtc_retain_mem_crc();
167 }
168
bootloader_common_get_rtc_retain_mem_factory_reset_state(void)169 bool bootloader_common_get_rtc_retain_mem_factory_reset_state(void)
170 {
171 rtc_retain_mem_t* rtc_retain_mem = bootloader_common_get_rtc_retain_mem();
172 if (is_retain_mem_valid()) {
173 bool factory_reset_state = rtc_retain_mem->flags.factory_reset_state;
174 if (factory_reset_state == true) {
175 rtc_retain_mem->flags.factory_reset_state = false;
176 update_rtc_retain_mem_crc();
177 }
178 return factory_reset_state;
179 }
180 return false;
181 }
182
bootloader_common_get_rtc_retain_mem_partition(void)183 esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void)
184 {
185 if (is_retain_mem_valid()) {
186 return &bootloader_common_get_rtc_retain_mem()->partition;
187 }
188 return NULL;
189 }
190
bootloader_common_update_rtc_retain_mem(esp_partition_pos_t * partition,bool reboot_counter)191 void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter)
192 {
193 rtc_retain_mem_t* rtc_retain_mem = bootloader_common_get_rtc_retain_mem();
194 if (reboot_counter) {
195 if (!is_retain_mem_valid()) {
196 bootloader_common_reset_rtc_retain_mem();
197 }
198 if (++rtc_retain_mem->reboot_counter == 0) {
199 // do not allow to overflow. Stop it.
200 --rtc_retain_mem->reboot_counter;
201 }
202
203 }
204
205 if (partition != NULL) {
206 rtc_retain_mem->partition.offset = partition->offset;
207 rtc_retain_mem->partition.size = partition->size;
208 }
209
210 update_rtc_retain_mem_crc();
211 }
212
bootloader_common_get_rtc_retain_mem(void)213 rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
214 {
215 #ifdef BOOTLOADER_BUILD
216 #define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))
217 static rtc_retain_mem_t *const s_bootloader_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR;
218 return s_bootloader_retain_mem;
219 #else
220 static __attribute__((section(".bootloader_data_rtc_mem"))) rtc_retain_mem_t s_bootloader_retain_mem;
221 return &s_bootloader_retain_mem;
222 #endif // !BOOTLOADER_BUILD
223 }
224
225 #endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM
226