diff --git a/components/bootloader/subproject/main/CMakeLists.txt b/components/bootloader/subproject/main/CMakeLists.txt index 3dfdf825a..e04c31433 100644 --- a/components/bootloader/subproject/main/CMakeLists.txt +++ b/components/bootloader/subproject/main/CMakeLists.txt @@ -1,18 +1,8 @@ -set(COMPONENT_SRCS "bootloader_start.c") -set(COMPONENT_ADD_INCLUDEDIRS "") -set(COMPONENT_REQUIRES bootloader bootloader_support) -register_component() +idf_component_register(SRCS "bootloader_start.c" + REQUIRES bootloader bootloader_support) idf_build_get_property(target IDF_TARGET) +set(scripts "ld/${target}/bootloader.ld" + "ld/${target}/bootloader.rom.ld") -target_linker_script(${COMPONENT_LIB} - "ld/${target}/bootloader.ld" - "ld/${target}/bootloader.rom.ld" -) - -set(scripts - "${IDF_PATH}/components/esp_rom/${target}/ld/${target}.rom.ld" - "${IDF_PATH}/components/esp_rom/${target}/ld/${target}.rom.newlib-funcs.ld" - "${IDF_PATH}/components/${target}/ld/${target}.peripherals.ld") - -target_linker_script(${COMPONENT_LIB} ${scripts}) +target_linker_script(${COMPONENT_LIB} "${scripts}") diff --git a/components/bootloader/subproject/main/bootloader_start.c b/components/bootloader/subproject/main/bootloader_start.c index 0363d60a8..638292fbf 100644 --- a/components/bootloader/subproject/main/bootloader_start.c +++ b/components/bootloader/subproject/main/bootloader_start.c @@ -29,7 +29,7 @@ #include "esp32s2beta/rom/spi_flash.h" #endif -static const char* TAG = "boot"; +static const char *TAG = "boot"; static int select_partition_number (bootloader_state_t *bs); static int selected_boot_partition(const bootloader_state_t *bs); @@ -95,7 +95,7 @@ static int selected_boot_partition(const bootloader_state_t *bs) return bootloader_utility_get_selected_boot_partition(bs); } #endif - // TEST firmware. + // TEST firmware. #ifdef CONFIG_BOOTLOADER_APP_TEST if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) { ESP_LOGI(TAG, "Detect a boot condition of the test firmware"); diff --git a/components/bootloader/subproject/main/ld/esp32s2beta/bootloader.rom.ld b/components/bootloader/subproject/main/ld/esp32s2beta/bootloader.rom.ld index 32d94a070..6a9e880fe 100644 --- a/components/bootloader/subproject/main/ld/esp32s2beta/bootloader.rom.ld +++ b/components/bootloader/subproject/main/ld/esp32s2beta/bootloader.rom.ld @@ -5,10 +5,10 @@ PROVIDE ( ets_update_cpu_frequency = 0x4000d954 ); /* ToDo: Following address may need modification */ -PROVIDE ( MD5Final = 0x4005db1c ); -PROVIDE ( MD5Init = 0x4005da7c ); -PROVIDE ( MD5Update = 0x4005da9c ); +PROVIDE ( MD5Final = 0x400056e8 ); +PROVIDE ( MD5Init = 0x40005648 ); +PROVIDE ( MD5Update = 0x40005668 ); /* bootloader will use following functions from xtensa hal library */ -xthal_get_ccount = 0x4000c050; -xthal_get_ccompare = 0x4000c078; -xthal_set_ccompare = 0x4000c058; +xthal_get_ccount = 0x40015cbc; +xthal_get_ccompare = 0x40015ce8; +xthal_set_ccompare = 0x40015cc4; diff --git a/components/bootloader_support/CMakeLists.txt b/components/bootloader_support/CMakeLists.txt index d1373be30..3b0ce529c 100644 --- a/components/bootloader_support/CMakeLists.txt +++ b/components/bootloader_support/CMakeLists.txt @@ -15,7 +15,9 @@ if(BOOTLOADER_BUILD) "src/${IDF_TARGET}/bootloader_sha.c" "src/${IDF_TARGET}/flash_encrypt.c" "src/${IDF_TARGET}/secure_boot_signatures.c" - "src/${IDF_TARGET}/secure_boot.c") + "src/${IDF_TARGET}/secure_boot.c" + "src/${IDF_TARGET}/bootloader_${IDF_TARGET}.c" + "src/${IDF_TARGET}/bootloader_clock_${IDF_TARGET}.c") if(CONFIG_SECURE_SIGNED_APPS) get_filename_component(secure_boot_verification_key diff --git a/components/bootloader_support/component.mk b/components/bootloader_support/component.mk index 202e35769..9990ae831 100644 --- a/components/bootloader_support/component.mk +++ b/components/bootloader_support/component.mk @@ -46,10 +46,10 @@ $(ORIG_SECURE_BOOT_VERIFICATION_KEY): $(SECURE_BOOT_VERIFICATION_KEY): $(ORIG_SECURE_BOOT_VERIFICATION_KEY) $(SDKCONFIG_MAKEFILE) $(summary) CP $< $@ cp $< $@ -endif +endif #CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY) COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY) -endif +endif #CONFIG_SECURE_SIGNED_APPS diff --git a/components/bootloader_support/include/bootloader_clock.h b/components/bootloader_support/include/bootloader_clock.h index 9eaba46a8..369f39dcd 100644 --- a/components/bootloader_support/include/bootloader_clock.h +++ b/components/bootloader_support/include/bootloader_clock.h @@ -19,3 +19,7 @@ * Called by bootloader, or by the app if the bootloader version is old (pre v2.1). */ void bootloader_clock_configure(void); + +/** @brief Return the rated maximum frequency of this chip + */ +int bootloader_clock_get_rated_freq_mhz(void); diff --git a/components/bootloader_support/include/bootloader_common.h b/components/bootloader_support/include/bootloader_common.h index eb5864125..2fe2aa5e0 100644 --- a/components/bootloader_support/include/bootloader_common.h +++ b/components/bootloader_support/include/bootloader_common.h @@ -78,6 +78,13 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat */ bool bootloader_common_label_search(const char *list, char *label); +/** + * @brief Configure default SPI pin modes and drive strengths + * + * @param drv GPIO drive level (determined by clock frequency) + */ +void bootloader_configure_spi_pins(int drv); + /** * @brief Calculates a sha-256 for a given partition or returns a appended digest. * @@ -125,7 +132,7 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, /** * @brief Returns esp_app_desc structure for app partition. This structure includes app version. - * + * * Returns a description for the requested app partition. * @param[in] partition App partition description. * @param[out] app_desc Structure of info about app. diff --git a/components/bootloader_support/include/esp_flash_encrypt.h b/components/bootloader_support/include/esp_flash_encrypt.h index fd8c9fed0..4abeb58d7 100644 --- a/components/bootloader_support/include/esp_flash_encrypt.h +++ b/components/bootloader_support/include/esp_flash_encrypt.h @@ -21,6 +21,7 @@ #include "esp_spi_flash.h" #endif #include "soc/efuse_periph.h" +#include "sdkconfig.h" /** * @file esp_partition.h @@ -35,11 +36,17 @@ * * @return true if flash encryption is enabled. */ -static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_enabled(void) { - uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT); +static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_enabled(void) +{ + uint32_t flash_crypt_cnt; +#if CONFIG_IDF_TARGET_ESP32 + flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + flash_crypt_cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_SPI_BOOT_CRYPT_CNT); +#endif /* __builtin_parity is in flash, so we calculate parity inline */ bool enabled = false; - while(flash_crypt_cnt) { + while (flash_crypt_cnt) { if (flash_crypt_cnt & 1) { enabled = !enabled; } @@ -110,7 +117,7 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length); * is enabled but secure boot is not used. This should protect against * serial re-flashing of an unauthorised code in absence of secure boot. * - * @return + * @return */ void esp_flash_write_protect_crypt_cnt(); diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index 299c4959d..bf0425633 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -18,6 +18,9 @@ #include "soc/efuse_periph.h" #include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/efuse.h" +#endif #ifdef CONFIG_SECURE_BOOT_ENABLED #if !defined(CONFIG_SECURE_SIGNED_ON_BOOT) || !defined(CONFIG_SECURE_SIGNED_ON_UPDATE) || !defined(CONFIG_SECURE_SIGNED_APPS) @@ -36,14 +39,18 @@ extern "C" { /** @brief Is secure boot currently enabled in hardware? * - * Secure boot is enabled if the ABS_DONE_0 efuse is blown. This means - * that the ROM bootloader code will only boot a verified secure - * bootloader digest from now on. + * This means that the ROM bootloader code will only boot + * a verified secure bootloader from now on. * * @return true if secure boot is enabled. */ -static inline bool esp_secure_boot_enabled(void) { +static inline bool esp_secure_boot_enabled(void) +{ +#if CONFIG_IDF_TARGET_ESP32 return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + return ets_efuse_secure_boot_enabled(); +#endif } /** @brief Generate secure digest from bootloader image diff --git a/components/bootloader_support/include_bootloader/bootloader_utility.h b/components/bootloader_support/include_bootloader/bootloader_utility.h index 84d0cb48f..388d0e3ff 100644 --- a/components/bootloader_support/include_bootloader/bootloader_utility.h +++ b/components/bootloader_support/include_bootloader/bootloader_utility.h @@ -15,6 +15,7 @@ #include "bootloader_config.h" #include "esp_image_format.h" +#include "bootloader_config.h" /** * @brief Load partition table. @@ -86,3 +87,14 @@ __attribute__((noreturn)) void bootloader_reset(void); * ESP_ERR_INVALID_ARG: Error in the passed arguments */ esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len); + +/** + * @brief Debug log contents of a buffer as hexadecimal + * + * @note Only works if component log level is DEBUG or higher. + * + * @param buffer Buffer to log + * @param length Length of buffer in bytes. Maximum length 128 bytes. + * @param label Label to print at beginning of log line. + */ +void bootloader_debug_buffer(const void *buffer, size_t length, const char *label); diff --git a/components/bootloader_support/src/bootloader_clock.c b/components/bootloader_support/src/bootloader_clock.c index fda86b207..059ea3623 100644 --- a/components/bootloader_support/src/bootloader_clock.c +++ b/components/bootloader_support/src/bootloader_clock.c @@ -27,23 +27,30 @@ void bootloader_clock_configure() // and will be done with the bootloader much earlier than UART FIFO is empty. uart_tx_wait_idle(0); - /* Set CPU to 80MHz. Keep other clocks unmodified. */ - int cpu_freq_mhz = 80; - /* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to * 240 MHz may cause the chip to lock up (see section 3.5 of the errata * document). For rev. 0, switch to 240 instead if it has been enabled * previously. */ +#if CONFIG_IDF_TARGET_ESP32 + /* Set CPU to 80MHz. Keep other clocks unmodified. */ + int cpu_freq_mhz = 80; + uint32_t chip_ver_reg = REG_READ(EFUSE_BLK0_RDATA3_REG); if ((chip_ver_reg & EFUSE_RD_CHIP_VER_REV1_M) == 0 && DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL) == DPORT_CPUPERIOD_SEL_240) { cpu_freq_mhz = 240; } +#endif rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT(); +#ifdef CONFIG_IDF_TARGET_ESP32 clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ; clk_cfg.cpu_freq_mhz = cpu_freq_mhz; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ; + clk_cfg.cpu_freq = RTC_CPU_FREQ_80M; +#endif clk_cfg.slow_freq = rtc_clk_slow_freq_get(); clk_cfg.fast_freq = rtc_clk_fast_freq_get(); rtc_clk_init(clk_cfg); diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index ed0169a96..222d54f50 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -19,7 +19,6 @@ #include "esp_log.h" #include "esp32/rom/crc.h" #include "esp32/rom/gpio.h" -#include "esp_secure_boot.h" #include "esp_flash_partitions.h" #include "bootloader_flash.h" #include "bootloader_common.h" diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index 5b4a555e1..c58f9fa05 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -17,6 +17,9 @@ #include #include /* including in bootloader for error values */ #include +#if CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/spi_flash.h" +#endif #ifndef BOOTLOADER_BUILD /* Normal app version maps to esp_spi_flash.h operations... @@ -32,7 +35,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) return NULL; /* existing mapping in use... */ } const void *result = NULL; - uint32_t src_page = src_addr & ~(SPI_FLASH_MMU_PAGE_SIZE-1); + uint32_t src_page = src_addr & ~(SPI_FLASH_MMU_PAGE_SIZE - 1); size += (src_addr - src_page); esp_err_t err = spi_flash_mmap(src_page, size, SPI_FLASH_MMAP_DATA, &result, &map); if (err != ESP_OK) { @@ -44,7 +47,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) void bootloader_munmap(const void *mapping) { - if(mapping && map) { + if (mapping && map) { spi_flash_munmap(map); } map = 0; @@ -62,7 +65,11 @@ esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size, bool allow_ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted) { if (write_encrypted) { +#if CONFIG_IDF_TARGET_ESP32 return spi_flash_write_encrypted(dest_addr, src, size); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + return SPI_Encrypt_Write(dest_addr, src, size); +#endif } else { return spi_flash_write(dest_addr, src, size); } @@ -81,16 +88,30 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) #else /* Bootloader version, uses ROM functions only */ #include +#if CONFIG_IDF_TARGET_ESP32 #include #include - +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include +#include +#endif static const char *TAG = "bootloader_flash"; +#if CONFIG_IDF_TARGET_ESP32 /* Use first 50 blocks in MMU for bootloader_mmap, 50th block for bootloader_flash_read */ -#define MMU_BLOCK0_VADDR 0x3f400000 -#define MMU_BLOCK50_VADDR 0x3f720000 +#define MMU_BLOCK0_VADDR SOC_DROM_LOW +#define MMU_SIZE (0x320000) +#define MMU_BLOCK50_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE) +#elif CONFIG_IDF_TARGET_ESP32S2BETA +/* Use first 63 blocks in MMU for bootloader_mmap, + 63th block for bootloader_flash_read +*/ +#define MMU_BLOCK0_VADDR SOC_DROM_LOW +#define MMU_SIZE (0x3f0000) +#define MMU_BLOCK63_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE) +#endif static bool mapped; @@ -103,25 +124,41 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) ESP_LOGE(TAG, "tried to bootloader_mmap twice"); return NULL; /* can't map twice */ } - if (size > 0x320000) { - /* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads) */ + if (size > MMU_SIZE) { ESP_LOGE(TAG, "bootloader_mmap excess size %x", size); return NULL; } uint32_t src_addr_aligned = src_addr & MMU_FLASH_MASK; uint32_t count = bootloader_cache_pages_to_map(size, src_addr); +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Disable(0); Cache_Flush(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t autoload = Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); +#endif ESP_LOGD(TAG, "mmu set paddr=%08x count=%d size=%x src_addr=%x src_addr_aligned=%x", - src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned ); + src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned ); +#if CONFIG_IDF_TARGET_ESP32 int e = cache_flash_mmu_set(0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + int e = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count, 0); +#endif if (e != 0) { ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e); +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Enable(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Resume_ICache(autoload); +#endif return NULL; } +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Enable(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Resume_ICache(autoload); +#endif mapped = true; @@ -131,10 +168,17 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) void bootloader_munmap(const void *mapping) { if (mapped) { +#if CONFIG_IDF_TARGET_ESP32 /* Full MMU reset */ Cache_Read_Disable(0); Cache_Flush(0); mmu_init(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + //TODO, save the autoload value. + Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); + Cache_MMU_Init(); +#endif mapped = false; current_read_mapping = UINT32_MAX; } @@ -142,7 +186,7 @@ void bootloader_munmap(const void *mapping) static esp_err_t spi_to_esp_err(esp_rom_spiflash_result_t r) { - switch(r) { + switch (r) { case ESP_ROM_SPIFLASH_RESULT_OK: return ESP_OK; case ESP_ROM_SPIFLASH_RESULT_ERR: @@ -156,10 +200,18 @@ static esp_err_t spi_to_esp_err(esp_rom_spiflash_result_t r) static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, size_t size) { +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Disable(0); Cache_Flush(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t autoload = Cache_Suspend_ICache(); +#endif esp_rom_spiflash_result_t r = esp_rom_spiflash_read(src_addr, dest, size); +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Enable(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Resume_ICache(autoload); +#endif return spi_to_esp_err(r); } @@ -168,28 +220,46 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest { uint32_t *dest_words = (uint32_t *)dest; - /* Use the 51st MMU mapping to read from flash in 64KB blocks. - (MMU will transparently decrypt if encryption is enabled.) - */ for (int word = 0; word < size / 4; word++) { uint32_t word_src = src_addr + word * 4; /* Read this offset from flash */ uint32_t map_at = word_src & MMU_FLASH_MASK; /* Map this 64KB block from flash */ uint32_t *map_ptr; if (map_at != current_read_mapping) { /* Move the 64KB mmu mapping window to fit map_at */ +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Disable(0); Cache_Flush(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t autoload = Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); +#endif ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping); +#if CONFIG_IDF_TARGET_ESP32 int e = cache_flash_mmu_set(0, 0, MMU_BLOCK50_VADDR, map_at, 64, 1); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + int e = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, MMU_BLOCK63_VADDR, map_at, 64, 1, 0); +#endif if (e != 0) { ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e); +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Enable(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Resume_ICache(autoload); +#endif return ESP_FAIL; } current_read_mapping = map_at; +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Enable(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Resume_ICache(autoload); +#endif } +#if CONFIG_IDF_TARGET_ESP32 map_ptr = (uint32_t *)(MMU_BLOCK50_VADDR + (word_src - map_at)); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + map_ptr = (uint32_t *)(MMU_BLOCK63_VADDR + (word_src - map_at)); +#endif dest_words[word] = *map_ptr; } return ESP_OK; @@ -240,7 +310,12 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool } if (write_encrypted) { +#if CONFIG_IDF_TARGET_ESP32 return spi_to_esp_err(esp_rom_spiflash_write_encrypted(dest_addr, src, size)); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + // TODO: use the same ROM AP here + return spi_to_esp_err(SPI_Encrypt_Write(dest_addr, src, size)); +#endif } else { return spi_to_esp_err(esp_rom_spiflash_write(dest_addr, src, size)); } diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index cae9c57e5..99a6011e7 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -19,6 +19,7 @@ #include "esp_attr.h" #include "esp_log.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/cache.h" #include "esp32/rom/efuse.h" #include "esp32/rom/ets_sys.h" @@ -28,6 +29,19 @@ #include "esp32/rom/uart.h" #include "esp32/rom/gpio.h" #include "esp32/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/cache.h" +#include "esp32s2beta/rom/efuse.h" +#include "esp32s2beta/rom/ets_sys.h" +#include "esp32s2beta/rom/spi_flash.h" +#include "esp32s2beta/rom/crc.h" +#include "esp32s2beta/rom/rtc.h" +#include "esp32s2beta/rom/uart.h" +#include "esp32s2beta/rom/gpio.h" +#include "esp32s2beta/rom/secure_boot.h" +#else +#error "Unsupported IDF_TARGET" +#endif #include "soc/soc.h" #include "soc/cpu.h" @@ -39,6 +53,11 @@ #include "soc/timer_periph.h" #include "soc/rtc_wdt.h" #include "soc/spi_periph.h" +#if CONFIG_IDF_TARGET_ESP32S2BETA +#include "soc/spi_mem_reg.h" +#include "soc/extmem_reg.h" +#include "soc/assist_debug_reg.h" +#endif #include "sdkconfig.h" #include "esp_image_format.h" @@ -48,6 +67,7 @@ #include "bootloader_flash.h" #include "bootloader_random.h" #include "bootloader_config.h" +#include "bootloader_common.h" #include "bootloader_clock.h" #include "bootloader_common.h" @@ -58,12 +78,13 @@ extern int _bss_end; extern int _data_start; extern int _data_end; -static const char* TAG = "boot"; +static const char *TAG = "boot"; static esp_err_t bootloader_main(); -static void print_flash_info(const esp_image_header_t* pfhdr); -static void update_flash_config(const esp_image_header_t* pfhdr); -static void flash_gpio_configure(const esp_image_header_t* pfhdr); +static void print_flash_info(const esp_image_header_t *pfhdr); +static void update_flash_config(const esp_image_header_t *pfhdr); +static void vddsdio_configure(); +static void flash_gpio_configure(const esp_image_header_t *pfhdr); static void uart_console_configure(void); static void wdt_reset_check(void); @@ -79,8 +100,10 @@ esp_err_t bootloader_init() int *sp = get_sp(); assert(&_bss_start <= &_bss_end); assert(&_data_start <= &_data_end); +#if CONFIG_IDF_TARGET_ESP32 assert(sp < &_bss_start); assert(sp < &_data_start); +#endif } #endif @@ -89,14 +112,27 @@ esp_err_t bootloader_init() /* completely reset MMU for both CPUs (in case serial bootloader was running) */ +#if CONFIG_IDF_TARGET_ESP32 Cache_Read_Disable(0); +#if !CONFIG_FREERTOS_UNICORE Cache_Read_Disable(1); +#endif Cache_Flush(0); +#if !CONFIG_FREERTOS_UNICORE Cache_Flush(1); +#endif mmu_init(0); +#if !CONFIG_FREERTOS_UNICORE DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR); mmu_init(1); DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR); +#endif +#elif CONFIG_IDF_TARGET_ESP32S2BETA + //TODO, save the autoload value + Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); + Cache_MMU_Init(); +#endif /* (above steps probably unnecessary for most serial bootloader usage, all that's absolutely needed is that we unmask DROM0 cache on the following two lines - normal ROM boot exits with @@ -107,10 +143,18 @@ esp_err_t bootloader_init() The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are necessary to work around a hardware bug. */ +#if CONFIG_IDF_TARGET_ESP32 DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0); +#if !CONFIG_FREERTOS_UNICORE DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0); - - if(bootloader_main() != ESP_OK){ +#endif +#elif CONFIG_IDF_TARGET_ESP32S2BETA + DPORT_REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_DROM0); +#if !CONFIG_FREERTOS_UNICORE + DPORT_REG_CLR_BIT(DPORT_APP_ICACHE_CTRL1_REG, DPORT_APP_ICACHE_MASK_DROM0); +#endif +#endif + if (bootloader_main() != ESP_OK) { return ESP_FAIL; } return ESP_OK; @@ -127,23 +171,25 @@ static esp_err_t bootloader_main() return ESP_FAIL; } flash_gpio_configure(&fhdr); -#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240) - //Check if ESP32 is rated for a CPU frequency of 160MHz only - if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) && - REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) { - ESP_LOGE(TAG, "Chip CPU frequency rated for 160MHz. Modify CPU frequency in menuconfig"); + + int rated_freq = bootloader_clock_get_rated_freq_mhz(); + if (rated_freq < CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) { + ESP_LOGE(TAG, "Chip CPU frequency rated for %dMHz, configured for %dMHz. Modify CPU frequency in menuconfig", + rated_freq, CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ); return ESP_FAIL; } -#endif + bootloader_clock_configure(); uart_console_configure(); wdt_reset_check(); ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER); ESP_LOGI(TAG, "compile time " __TIME__ ); +#if !CONFIG_FREERTOS_UNICORE ets_set_appcpu_boot_addr(0); +#endif -#ifdef CONFIG_BOOTLOADER_WDT_ENABLE +#if CONFIG_BOOTLOADER_WDT_ENABLE && CONFIG_IDF_TARGET_ESP32 ESP_LOGD(TAG, "Enabling RTCWDT(%d ms)", CONFIG_BOOTLOADER_WDT_TIME_MS); rtc_wdt_protect_off(); rtc_wdt_disable(); @@ -153,7 +199,7 @@ static esp_err_t bootloader_main() rtc_wdt_set_time(RTC_WDT_STAGE0, CONFIG_BOOTLOADER_WDT_TIME_MS); rtc_wdt_enable(); rtc_wdt_protect_on(); -#else +#elif CONFIG_IDF_TARGET_ESP32 /* disable watch dog here */ rtc_wdt_disable(); #endif @@ -162,7 +208,7 @@ static esp_err_t bootloader_main() #ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH const uint32_t spiconfig = ets_efuse_get_spiconfig(); - if(spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) { + if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) { ESP_LOGE(TAG, "SPI flash pins are overridden. \"Enable SPI flash ROM driver patched functions\" must be enabled in menuconfig"); return ESP_FAIL; } @@ -183,38 +229,46 @@ static esp_err_t bootloader_main() return ESP_OK; } -static void update_flash_config(const esp_image_header_t* pfhdr) +static void update_flash_config(const esp_image_header_t *pfhdr) { uint32_t size; - switch(pfhdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - size = 1; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - size = 2; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - size = 4; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - size = 8; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - size = 16; - break; - default: - size = 2; + switch (pfhdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + size = 1; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + size = 2; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + size = 4; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + size = 8; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + size = 16; + break; + default: + size = 2; } - Cache_Read_Disable( 0 ); +#if CONFIG_IDF_TARGET_ESP32 + Cache_Read_Disable(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t autoload = Cache_Suspend_ICache(); +#endif // Set flash chip size esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode // TODO: set frequency +#if CONFIG_IDF_TARGET_ESP32 Cache_Flush(0); - Cache_Read_Enable( 0 ); + Cache_Read_Enable(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Resume_ICache(autoload); +#endif } -static void print_flash_info(const esp_image_header_t* phdr) +static void print_flash_info(const esp_image_header_t *phdr) { #if (BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_NOTICE) @@ -224,7 +278,7 @@ static void print_flash_info(const esp_image_header_t* phdr) ESP_LOGD(TAG, "spi_speed %02x", phdr->spi_speed ); ESP_LOGD(TAG, "spi_size %02x", phdr->spi_size ); - const char* str; + const char *str; switch ( phdr->spi_speed ) { case ESP_IMAGE_SPI_SPEED_40M: str = "40MHz"; @@ -246,6 +300,7 @@ static void print_flash_info(const esp_image_header_t* phdr) /* SPI mode could have been set to QIO during boot already, so test the SPI registers not the flash header */ +#if CONFIG_IDF_TARGET_ESP32 uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0)); if (spi_ctrl & SPI_FREAD_QIO) { str = "QIO"; @@ -260,6 +315,22 @@ static void print_flash_info(const esp_image_header_t* phdr) } else { str = "SLOW READ"; } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0)); + if (spi_ctrl & SPI_MEM_FREAD_QIO) { + str = "QIO"; + } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) { + str = "QOUT"; + } else if (spi_ctrl & SPI_MEM_FREAD_DIO) { + str = "DIO"; + } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) { + str = "DOUT"; + } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) { + str = "FAST READ"; + } else { + str = "SLOW READ"; + } +#endif ESP_LOGI(TAG, "SPI Mode : %s", str ); switch ( phdr->spi_size ) { @@ -286,58 +357,91 @@ static void print_flash_info(const esp_image_header_t* phdr) #endif } +static void vddsdio_configure() +{ +#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V + rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); + if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V + cfg.drefh = 3; + cfg.drefm = 3; + cfg.drefl = 3; + cfg.force = 1; + rtc_vddsdio_set_config(cfg); + ets_delay_us(10); // wait for regulator to become stable + } +#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST +} + +#if CONFIG_IDF_TARGET_ESP32 #define FLASH_CLK_IO 6 #define FLASH_CS_IO 11 #define FLASH_SPIQ_IO 7 #define FLASH_SPID_IO 8 #define FLASH_SPIWP_IO 10 #define FLASH_SPIHD_IO 9 +#endif + +#if CONFIG_IDF_TARGET_ESP32 #define FLASH_IO_MATRIX_DUMMY_40M 1 #define FLASH_IO_MATRIX_DUMMY_80M 2 +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#define FLASH_IO_MATRIX_DUMMY_40M 0 +#define FLASH_IO_MATRIX_DUMMY_80M 0 +#endif #define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3 /* * Bootloader reads SPI configuration from bin header, so that * the burning configuration can be different with compiling configuration. */ -static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr) +static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t *pfhdr) { int spi_cache_dummy = 0; int drv = 2; switch (pfhdr->spi_mode) { - case ESP_IMAGE_SPI_MODE_QIO: - spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; - break; - case ESP_IMAGE_SPI_MODE_DIO: - spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //qio 3 - break; - case ESP_IMAGE_SPI_MODE_QOUT: - case ESP_IMAGE_SPI_MODE_DOUT: - default: - spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; - break; + case ESP_IMAGE_SPI_MODE_QIO: + spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; + break; + case ESP_IMAGE_SPI_MODE_DIO: + spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //qio 3 + break; + case ESP_IMAGE_SPI_MODE_QOUT: + case ESP_IMAGE_SPI_MODE_DOUT: + default: + spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; + break; } /* dummy_len_plus values defined in ROM for SPI flash configuration */ extern uint8_t g_rom_spiflash_dummy_len_plus[]; switch (pfhdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_80M: - g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M; - g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M; - SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M, - SPI_USR_DUMMY_CYCLELEN_S); //DUMMY - drv = 3; - break; - case ESP_IMAGE_SPI_SPEED_40M: - g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M; - g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M; - SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M, - SPI_USR_DUMMY_CYCLELEN_S); //DUMMY - break; - default: - break; + case ESP_IMAGE_SPI_SPEED_80M: + g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M; + g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M; +#if CONFIG_IDF_TARGET_ESP32 + SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M, + SPI_USR_DUMMY_CYCLELEN_S); //DUMMY +#elif CONFIG_IDF_TARGET_ESP32S2BETA + SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M, + SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY +#endif + drv = 3; + break; + case ESP_IMAGE_SPI_SPEED_40M: + g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M; + g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M; +#if CONFIG_IDF_TARGET_ESP32 + SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M, + SPI_USR_DUMMY_CYCLELEN_S); //DUMMY +#elif CONFIG_IDF_TARGET_ESP32S2BETA + SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M, + SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY +#endif + break; + default: + break; } - +#if CONFIG_IDF_TARGET_ESP32 uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); uint32_t pkg_ver = chip_ver & 0x7; @@ -379,7 +483,7 @@ static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr) PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); - #if CONFIG_SPIRAM_TYPE_ESPPSRAM32 +#if CONFIG_SPIRAM_TYPE_ESPPSRAM32 uint32_t flash_id = g_rom_flashchip.device_id; if (flash_id == FLASH_ID_GD25LQ32C) { // Set drive ability for 1.8v flash in 80Mhz. @@ -390,9 +494,12 @@ static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr) SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S); SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S); } - #endif +#endif } } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + bootloader_configure_spi_pins(drv); +#endif } static void uart_console_configure(void) @@ -450,9 +557,16 @@ static void uart_console_configure(void) static void wdt_reset_cpu0_info_enable(void) { +#if CONFIG_IDF_TARGET_ESP32 //We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1. DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE); DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG); + DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG); + REG_WRITE(ASSIST_DEBUG_PRO_PDEBUGENABLE, 1); + REG_WRITE(ASSIST_DEBUG_PRO_RCD_RECORDING, 1); +#endif } static void wdt_reset_info_dump(int cpu) @@ -461,6 +575,7 @@ static void wdt_reset_info_dump(int cpu) lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0; const char *cpu_name = cpu ? "APP" : "PRO"; +#if CONFIG_IDF_TARGET_ESP32 if (cpu == 0) { stat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_STATUS_REG); pid = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PID_REG); @@ -473,6 +588,7 @@ static void wdt_reset_info_dump(int cpu) lsdata = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0DATA_REG); } else { +#if !CONFIG_FREERTOS_UNICORE stat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_STATUS_REG); pid = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PID_REG); inst = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGINST_REG); @@ -482,9 +598,25 @@ static void wdt_reset_info_dump(int cpu) lsstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0STAT_REG); lsaddr = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0ADDR_REG); lsdata = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0DATA_REG); +#else + ESP_LOGE(TAG, "WDT reset info: &s CPU not support!\n", cpu_name); + return; +#endif } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + stat = 0xdeadbeef; + pid = 0; + inst = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGINST); + dstat = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGSTATUS); + data = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGDATA); + pc = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGPC); + lsstat = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0STAT); + lsaddr = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0ADDR); + lsdata = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0DATA); +#endif + if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 && - DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) { + DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) { ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x (waiti mode)", cpu_name, pc); } else { ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x", cpu_name, pc); @@ -506,21 +638,31 @@ static void wdt_reset_check(void) RESET_REASON rst_reas[2]; rst_reas[0] = rtc_get_reset_reason(0); +#if CONFIG_IDF_TARGET_ESP32 rst_reas[1] = rtc_get_reset_reason(1); if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET || - rst_reas[0] == TGWDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) { + rst_reas[0] == TGWDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) { ESP_LOGW(TAG, "PRO CPU has been reset by WDT."); wdt_rst = 1; } if (rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET || rst_reas[1] == TG1WDT_SYS_RESET || - rst_reas[1] == TGWDT_CPU_RESET || rst_reas[1] == RTCWDT_CPU_RESET) { + rst_reas[1] == TGWDT_CPU_RESET || rst_reas[1] == RTCWDT_CPU_RESET) { ESP_LOGW(TAG, "APP CPU has been reset by WDT."); wdt_rst = 1; } +#elif CONFIG_IDF_TARGET_ESP32S2BETA + if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET || + rst_reas[0] == TG0WDT_CPU_RESET || rst_reas[0] == TG1WDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) { + ESP_LOGW(TAG, "PRO CPU has been reset by WDT."); + wdt_rst = 1; + } +#endif if (wdt_rst) { // if reset by WDT dump info from trace port wdt_reset_info_dump(0); +#if CONFIG_IDF_TARGET_ESP32 wdt_reset_info_dump(1); +#endif } wdt_reset_cpu0_info_enable(); } @@ -528,7 +670,7 @@ static void wdt_reset_check(void) void __assert_func(const char *file, int line, const char *func, const char *expr) { ESP_LOGE(TAG, "Assert failed in %s, %s:%d (%s)", func, file, line, expr); - while(1) {} + while (1) {} } void abort() @@ -539,5 +681,5 @@ void abort() if (esp_cpu_in_ocd_debug_mode()) { __asm__ ("break 0,0"); } - while(1) {} + while (1) {} } diff --git a/components/bootloader_support/src/bootloader_random.c b/components/bootloader_support/src/bootloader_random.c index 4ea86df52..3282afec8 100644 --- a/components/bootloader_support/src/bootloader_random.c +++ b/components/bootloader_support/src/bootloader_random.c @@ -47,14 +47,18 @@ void bootloader_fill_random(void *buffer, size_t length) as-is, we repeatedly read the RNG register and XOR all values. */ +#if CONFIG_IDF_TARGET_ESP32 random = REG_READ(WDEV_RND_REG); RSR(CCOUNT, start); do { random ^= REG_READ(WDEV_RND_REG); RSR(CCOUNT, now); - } while(now - start < 80*32*2); /* extra factor of 2 is precautionary */ + } while (now - start < 80 * 32 * 2); /* extra factor of 2 is precautionary */ +#elif CONFIG_IDF_TARGET_ESP32S2BETA + // ToDo: Get random from register + random = 12345678; +#endif } - buffer_bytes[i] = random >> ((i % 4) * 8); } } @@ -92,18 +96,22 @@ void bootloader_random_enable(void) SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S); SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE); SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE); +#if CONFIG_IDF_TARGET_ESP32 SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX); +#endif SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_CLK_DIV, 4, SYSCON_SARADC_SAR_CLK_DIV_S); SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_RSTB_WAIT, 8, SYSCON_SARADC_RSTB_WAIT_S); /* was 1 */ +#if CONFIG_IDF_TARGET_ESP32 SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 10, SYSCON_SARADC_START_WAIT_S); +#endif SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_WORK_MODE, 0, SYSCON_SARADC_WORK_MODE_S); SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL); CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_SAR_SEL); SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 20, I2S_RX_BCK_DIV_NUM_S); - SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG,SYSCON_SARADC_DATA_TO_I2S); + SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_TO_I2S); CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_CAMERA_EN); SET_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_LCD_EN); @@ -132,10 +140,16 @@ void bootloader_random_disable(void) /* Restore SAR ADC mode */ CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST); +#if CONFIG_IDF_TARGET_ESP32 CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX | SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S); +#endif SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); +#if CONFIG_IDF_TARGET_ESP32 SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 8, SYSCON_SARADC_START_WAIT_S); +#endif /* Reset i2s peripheral */ DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index 3f9d9fe8a..46486e500 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -19,6 +19,7 @@ #include "esp_attr.h" #include "esp_log.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/cache.h" #include "esp32/rom/efuse.h" #include "esp32/rom/ets_sys.h" @@ -28,6 +29,19 @@ #include "esp32/rom/uart.h" #include "esp32/rom/gpio.h" #include "esp32/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/cache.h" +#include "esp32s2beta/rom/efuse.h" +#include "esp32s2beta/rom/ets_sys.h" +#include "esp32s2beta/rom/spi_flash.h" +#include "esp32s2beta/rom/crc.h" +#include "esp32s2beta/rom/rtc.h" +#include "esp32s2beta/rom/uart.h" +#include "esp32s2beta/rom/gpio.h" +#include "esp32s2beta/rom/secure_boot.h" +#else +#error "Unsupported IDF_TARGET" +#endif #include "soc/soc.h" #include "soc/cpu.h" @@ -49,24 +63,27 @@ #include "bootloader_common.h" #include "bootloader_utility.h" #include "bootloader_sha.h" -#include "esp_efuse.h" -static const char* TAG = "boot"; +#ifndef BOOTLOADER_BUILD // TODO: efuse component on esp32s2beta +#include "esp_efuse.h" +#endif + +static const char *TAG = "boot"; /* Reduce literal size for some generic string literals */ #define MAP_ERR_MSG "Image contains multiple %s segments. Only the last one will be mapped." static bool ota_has_initial_contents; -static void load_image(const esp_image_metadata_t* image_data); +static void load_image(const esp_image_metadata_t *image_data); static void unpack_load_app(const esp_image_metadata_t *data); static void set_cache_and_start_app(uint32_t drom_addr, - uint32_t drom_load_addr, - uint32_t drom_size, - uint32_t irom_addr, - uint32_t irom_load_addr, - uint32_t irom_size, - uint32_t entry_addr); + uint32_t drom_load_addr, + uint32_t drom_size, + uint32_t irom_addr, + uint32_t irom_load_addr, + uint32_t irom_size, + uint32_t entry_addr); // Read ota_info partition and fill array from two otadata structures. static esp_err_t read_otadata(const esp_partition_pos_t *ota_info, esp_ota_select_entry_t *two_otadata) @@ -96,7 +113,7 @@ static esp_err_t read_otadata(const esp_partition_pos_t *ota_info, esp_ota_selec return ESP_OK; } -bool bootloader_utility_load_partition_table(bootloader_state_t* bs) +bool bootloader_utility_load_partition_table(bootloader_state_t *bs) { const esp_partition_info_t *partitions; const char *partition_usage; @@ -119,16 +136,16 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs) ESP_LOGI(TAG, "Partition Table:"); ESP_LOGI(TAG, "## Label Usage Type ST Offset Length"); - for(int i = 0; i < num_partitions; i++) { + for (int i = 0; i < num_partitions; i++) { const esp_partition_info_t *partition = &partitions[i]; ESP_LOGD(TAG, "load partition table entry 0x%x", (intptr_t)partition); ESP_LOGD(TAG, "type=%x subtype=%x", partition->type, partition->subtype); partition_usage = "unknown"; /* valid partition table */ - switch(partition->type) { + switch (partition->type) { case PART_TYPE_APP: /* app partition */ - switch(partition->subtype) { + switch (partition->subtype) { case PART_SUBTYPE_FACTORY: /* factory binary */ bs->factory = partition->pos; partition_usage = "factory app"; @@ -143,15 +160,14 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs) bs->ota[partition->subtype & PART_SUBTYPE_OTA_MASK] = partition->pos; ++bs->app_count; partition_usage = "OTA app"; - } - else { + } else { partition_usage = "Unknown app"; } break; } break; /* PART_TYPE_APP */ case PART_TYPE_DATA: /* data partition */ - switch(partition->subtype) { + switch (partition->subtype) { case PART_SUBTYPE_DATA_OTA: /* ota data */ bs->ota_info = partition->pos; partition_usage = "OTA data"; @@ -188,7 +204,7 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs) bootloader_munmap(partitions); - ESP_LOGI(TAG,"End of partition table"); + ESP_LOGI(TAG, "End of partition table"); return true; } @@ -214,7 +230,7 @@ static esp_partition_pos_t index_to_partition(const bootloader_state_t *bs, int static void log_invalid_app_partition(int index) { const char *not_bootable = " is not bootable"; /* save a few string literal bytes */ - switch(index) { + switch (index) { case FACTORY_INDEX: ESP_LOGE(TAG, "Factory app partition%s", not_bootable); break; @@ -317,8 +333,8 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs) #ifndef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK if ((bootloader_common_ota_select_invalid(&otadata[0]) && - bootloader_common_ota_select_invalid(&otadata[1])) || - bs->app_count == 0) { + bootloader_common_ota_select_invalid(&otadata[1])) || + bs->app_count == 0) { ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF) or partition table does not have bootable ota_apps (app_count=%d)", bs->app_count); if (bs->factory.offset != 0) { ESP_LOGI(TAG, "Defaulting to factory image"); @@ -328,7 +344,7 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs) boot_index = 0; // Try to boot from ota_0. if ((otadata[0].ota_seq == UINT32_MAX || otadata[0].crc != bootloader_common_ota_select_crc(&otadata[0])) && - (otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) { + (otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) { // Factory is not found and both otadata are initial(0xFFFFFFFF) or incorrect crc. // will set correct ota_seq. ota_has_initial_contents = true; @@ -341,7 +357,7 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs) ESP_LOGI(TAG, "Secure version (from eFuse) = %d", esp_efuse_read_secure_version()); // When CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK is enabled factory partition should not be in partition table, only two ota_app are there. if ((otadata[0].ota_seq == UINT32_MAX || otadata[0].crc != bootloader_common_ota_select_crc(&otadata[0])) && - (otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) { + (otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) { ESP_LOGI(TAG, "otadata[0..1] in initial state"); // both otadata are initial(0xFFFFFFFF) or incorrect crc. // will set correct ota_seq. @@ -426,7 +442,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_ esp_partition_pos_t part; esp_image_metadata_t image_data; - if(start_index == TEST_APP_INDEX) { + if (start_index == TEST_APP_INDEX) { if (try_load_partition(&bs->test, &image_data)) { load_image(&image_data); } else { @@ -436,7 +452,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_ } /* work backwards from start_index, down to the factory app */ - for(index = start_index; index >= FACTORY_INDEX; index--) { + for (index = start_index; index >= FACTORY_INDEX; index--) { part = index_to_partition(bs, index); if (part.size == 0) { continue; @@ -450,7 +466,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_ } /* failing that work forwards from start_index, try valid OTA slots */ - for(index = start_index + 1; index < bs->app_count; index++) { + for (index = start_index + 1; index < bs->app_count; index++) { part = index_to_partition(bs, index); if (part.size == 0) { continue; @@ -474,7 +490,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_ } // Copy loaded segments to RAM, set up caches for mapped segments, and start application. -static void load_image(const esp_image_metadata_t* image_data) +static void load_image(const esp_image_metadata_t *image_data) { /** * Rough steps for a first boot, when encryption and secure boot are both disabled: @@ -571,6 +587,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..."); + uart_tx_wait_idle(0); bootloader_reset(); } #endif @@ -582,7 +599,7 @@ static void load_image(const esp_image_metadata_t* image_data) unpack_load_app(image_data); } -static void unpack_load_app(const esp_image_metadata_t* data) +static void unpack_load_app(const esp_image_metadata_t *data) { uint32_t drom_addr = 0; uint32_t drom_load_addr = 0; @@ -618,12 +635,12 @@ static void unpack_load_app(const esp_image_metadata_t* data) ESP_LOGD(TAG, "calling set_cache_and_start_app"); set_cache_and_start_app(drom_addr, - drom_load_addr, - drom_size, - irom_addr, - irom_load_addr, - irom_size, - data->image.entry_addr); + drom_load_addr, + drom_size, + irom_addr, + irom_load_addr, + irom_size, + data->image.entry_addr); } static void set_cache_and_start_app( @@ -637,8 +654,13 @@ static void set_cache_and_start_app( { int rc; ESP_LOGD(TAG, "configure drom and irom and start"); - Cache_Read_Disable( 0 ); - Cache_Flush( 0 ); +#if CONFIG_IDF_TARGET_ESP32 + Cache_Read_Disable(0); + Cache_Flush(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t autoload = Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); +#endif /* Clear the MMU entries that are already set up, so the new app only has the mappings it creates. @@ -650,33 +672,73 @@ static void set_cache_and_start_app( uint32_t drom_load_addr_aligned = drom_load_addr & MMU_FLASH_MASK; uint32_t drom_page_count = bootloader_cache_pages_to_map(drom_size, drom_load_addr); ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d", - drom_addr & MMU_FLASH_MASK, drom_load_addr_aligned, drom_size, drom_page_count); + drom_addr & MMU_FLASH_MASK, drom_load_addr_aligned, drom_size, drom_page_count); +#if CONFIG_IDF_TARGET_ESP32 rc = cache_flash_mmu_set(0, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, + 64, drom_page_count, 0); +#endif ESP_LOGV(TAG, "rc=%d", rc); +#if !CONFIG_FREERTOS_UNICORE rc = cache_flash_mmu_set(1, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count); ESP_LOGV(TAG, "rc=%d", rc); - +#endif uint32_t irom_load_addr_aligned = irom_load_addr & MMU_FLASH_MASK; uint32_t irom_page_count = bootloader_cache_pages_to_map(irom_size, irom_load_addr); ESP_LOGV(TAG, "i mmu set paddr=%08x vaddr=%08x size=%d n=%d", - irom_addr & MMU_FLASH_MASK, irom_load_addr_aligned, irom_size, irom_page_count); + irom_addr & MMU_FLASH_MASK, irom_load_addr_aligned, irom_size, irom_page_count); +#if CONFIG_IDF_TARGET_ESP32 rc = cache_flash_mmu_set(0, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count); ESP_LOGV(TAG, "rc=%d", rc); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + uint32_t iram1_used = 0, irom0_used = 0; + if (irom_load_addr + irom_size > IRAM1_ADDRESS_LOW) { + iram1_used = 1; + } + if (irom_load_addr + irom_size > IROM0_ADDRESS_LOW) { + irom0_used = 1; + } + if (iram1_used || irom0_used) { + rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IRAM0_ADDRESS_LOW, 0, 64, 64, 1); + rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IRAM1_ADDRESS_LOW, 0, 64, 64, 1); + REG_SET_BIT(DPORT_CACHE_SOURCE_1_REG, DPORT_PRO_CACHE_I_SOURCE_PRO_IRAM1); + REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_IRAM1); + if (irom0_used) { + rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IROM0_ADDRESS_LOW, 0, 64, 64, 1); + REG_SET_BIT(DPORT_CACHE_SOURCE_1_REG, DPORT_PRO_CACHE_I_SOURCE_PRO_IROM0); + REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_IROM0); + } + } + rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count, 0); +#endif + ESP_LOGV(TAG, "rc=%d", rc); +#if !CONFIG_FREERTOS_UNICORE rc = cache_flash_mmu_set(1, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count); ESP_LOGV(TAG, "rc=%d", rc); - +#endif +#if CONFIG_IDF_TARGET_ESP32 DPORT_REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG, - (DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) | - (DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 | - DPORT_PRO_CACHE_MASK_DRAM1 ); - + (DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) | + (DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 | + DPORT_PRO_CACHE_MASK_DRAM1 ); +#if !CONFIG_FREERTOS_UNICORE DPORT_REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG, - (DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) | - (DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 | - DPORT_APP_CACHE_MASK_DRAM1 ); - - Cache_Read_Enable( 0 ); - + (DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) | + (DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 | + DPORT_APP_CACHE_MASK_DRAM1 ); +#endif +#elif CONFIG_IDF_TARGET_ESP32S2BETA + DPORT_REG_CLR_BIT( DPORT_PRO_ICACHE_CTRL1_REG, (DPORT_PRO_ICACHE_MASK_IRAM0) | (DPORT_PRO_ICACHE_MASK_IRAM1 & 0) | (DPORT_PRO_ICACHE_MASK_IROM0 & 0) | DPORT_PRO_ICACHE_MASK_DROM0 ); +#if !CONFIG_FREERTOS_UNICORE + DPORT_REG_CLR_BIT( DPORT_APP_ICACHE_CTRL1_REG, (DPORT_APP_ICACHE_MASK_IRAM0) | (DPORT_APP_ICACHE_MASK_IRAM1 & 0) | (DPORT_APP_ICACHE_MASK_IROM0 & 0) | DPORT_APP_ICACHE_MASK_DROM0 ); +#endif +#endif +#if CONFIG_IDF_TARGET_ESP32 + Cache_Read_Enable(0); +#elif CONFIG_IDF_TARGET_ESP32S2BETA + Cache_Resume_ICache(autoload); +#endif // Application will need to do Cache_Flush(1) and Cache_Read_Enable(1) ESP_LOGD(TAG, "start: 0x%08x", entry_addr); @@ -688,7 +750,6 @@ static void set_cache_and_start_app( (*entry)(); } - void bootloader_reset(void) { #ifdef BOOTLOADER_BUILD @@ -719,3 +780,24 @@ esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_he } return ESP_OK; } + +void bootloader_debug_buffer(const void *buffer, size_t length, const char *label) +{ +#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG + assert(length <= 128); // Avoid unbounded VLA size + const uint8_t *bytes = (const uint8_t *)buffer; + char hexbuf[length * 2 + 1]; + hexbuf[length * 2] = 0; + for (int i = 0; i < length; i++) { + for (int shift = 0; shift < 2; shift++) { + uint8_t nibble = (bytes[i] >> (shift ? 0 : 4)) & 0x0F; + if (nibble < 10) { + hexbuf[i * 2 + shift] = '0' + nibble; + } else { + hexbuf[i * 2 + shift] = 'a' + nibble - 10; + } + } + } + ESP_LOGD(TAG, "%s: %s", label, hexbuf); +#endif +} diff --git a/components/bootloader_support/src/esp32/bootloader_clock_esp32.c b/components/bootloader_support/src/esp32/bootloader_clock_esp32.c new file mode 100644 index 000000000..fb69d84b3 --- /dev/null +++ b/components/bootloader_support/src/esp32/bootloader_clock_esp32.c @@ -0,0 +1,13 @@ +#include "soc/efuse_reg.h" +#include "bootloader_clock.h" + +int bootloader_clock_get_rated_freq_mhz() +{ + //Check if ESP32 is rated for a CPU frequency of 160MHz only + if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) && + REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) { + return 160; + } + return 240; +} + diff --git a/components/bootloader_support/src/esp32/bootloader_esp32.c b/components/bootloader_support/src/esp32/bootloader_esp32.c new file mode 100644 index 000000000..a6a170516 --- /dev/null +++ b/components/bootloader_support/src/esp32/bootloader_esp32.c @@ -0,0 +1,74 @@ +#include "bootloader_common.h" +#include "sdkconfig.h" +#include "soc/efuse_reg.h" +#include "soc/gpio_sig_map.h" +#include "soc/io_mux_reg.h" +#include "esp32/rom/efuse.h" +#include "esp32/rom/gpio.h" +#include "esp32/rom/spi_flash.h" + +#define FLASH_CLK_IO SPI_CLK_GPIO_NUM +#define FLASH_CS_IO SPI_CS0_GPIO_NUM +#define FLASH_SPIQ_IO SPI_Q_GPIO_NUM +#define FLASH_SPID_IO SPI_D_GPIO_NUM +#define FLASH_SPIWP_IO SPI_WP_GPIO_NUM +#define FLASH_SPIHD_IO SPI_HD_GPIO_NUM + +void bootloader_configure_spi_pins(int drv) +{ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); + uint32_t pkg_ver = chip_ver & 0x7; + + if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) { + // For ESP32D2WD the SPI pins are already configured + // flash clock signal should come from IO MUX. + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) { + // For ESP32PICOD2 the SPI pins are already configured + // flash clock signal should come from IO MUX. + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) { + // For ESP32PICOD4 the SPI pins are already configured + // flash clock signal should come from IO MUX. + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); + } else { + const uint32_t spiconfig = ets_efuse_get_spiconfig(); + if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) { + gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0); + gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0); + gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0); + gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0); + gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0); + gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0); + gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0); + gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0); + gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0); + //select pin function gpio + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO); + // flash clock signal should come from IO MUX. + // set drive ability for clock + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); + + #if CONFIG_SPIRAM_TYPE_ESPPSRAM32 || CONFIG_SPIRAM_TYPE_ESPPSRAM64 + uint32_t flash_id = g_rom_flashchip.device_id; + if (flash_id == FLASH_ID_GD25LQ32C) { + // Set drive ability for 1.8v flash in 80Mhz. + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S); + } + #endif + } + } +} diff --git a/components/bootloader_support/src/esp32/bootloader_sha.c b/components/bootloader_support/src/esp32/bootloader_sha.c index f42c8b663..99074598c 100644 --- a/components/bootloader_support/src/esp32/bootloader_sha.c +++ b/components/bootloader_support/src/esp32/bootloader_sha.c @@ -16,9 +16,10 @@ #include #include #include + #include "esp32/rom/sha.h" +#include "soc/dport_reg.h" #include "soc/hwcrypto_periph.h" -#include "esp32/rom/ets_sys.h" // TO REMOVE static uint32_t words_hashed; diff --git a/components/bootloader_support/src/esp32/flash_encrypt.c b/components/bootloader_support/src/esp32/flash_encrypt.c index 54f82327b..78c40ddf9 100644 --- a/components/bootloader_support/src/esp32/flash_encrypt.c +++ b/components/bootloader_support/src/esp32/flash_encrypt.c @@ -162,7 +162,7 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry /* If the last flash_crypt_cnt bit is burned or write-disabled, the device can't re-encrypt itself. */ - if (flash_crypt_wr_dis) { + if (flash_crypt_wr_dis || flash_crypt_cnt == 0xFF) { ESP_LOGE(TAG, "Cannot re-encrypt data (FLASH_CRYPT_CNT 0x%02x write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis); return ESP_FAIL; } diff --git a/components/bootloader_support/src/esp32s2beta/bootloader_clock_esp32s2beta.c b/components/bootloader_support/src/esp32s2beta/bootloader_clock_esp32s2beta.c new file mode 100644 index 000000000..67253e3e3 --- /dev/null +++ b/components/bootloader_support/src/esp32s2beta/bootloader_clock_esp32s2beta.c @@ -0,0 +1,12 @@ +#include "sdkconfig.h" +#include "bootloader_clock.h" + +int bootloader_clock_get_rated_freq_mhz() +{ +#ifndef CONFIG_HARDWARE_IS_FPGA + #warning "FIXME this needs to be filled in for real hardware" +#endif + return 999; +} + + diff --git a/components/bootloader_support/src/esp32s2beta/bootloader_esp32s2beta.c b/components/bootloader_support/src/esp32s2beta/bootloader_esp32s2beta.c new file mode 100644 index 000000000..5f925ca20 --- /dev/null +++ b/components/bootloader_support/src/esp32s2beta/bootloader_esp32s2beta.c @@ -0,0 +1,54 @@ +#include "bootloader_common.h" +#include "sdkconfig.h" +#include "soc/efuse_reg.h" +#include "soc/gpio_sig_map.h" +#include "soc/io_mux_reg.h" +#include "esp32s2beta/rom/efuse.h" +#include "esp32s2beta/rom/gpio.h" +#include "esp32s2beta/rom/spi_flash.h" + +#define FLASH_CLK_IO SPI_CLK_GPIO_NUM +#define FLASH_CS_IO SPI_CS0_GPIO_NUM +#define FLASH_SPIQ_IO SPI_Q_GPIO_NUM +#define FLASH_SPID_IO SPI_D_GPIO_NUM +#define FLASH_SPIWP_IO SPI_WP_GPIO_NUM +#define FLASH_SPIHD_IO SPI_HD_GPIO_NUM + +void bootloader_configure_spi_pins(int drv) +{ + const uint32_t spiconfig = ets_efuse_get_spiconfig(); + if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) { + gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0); + gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0); + gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0); + gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0); + gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0); + gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0); + gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0); + gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0); + gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0); + //select pin function gpio + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIHD_U, PIN_FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIWP_U, PIN_FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICS0_U, PIN_FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIQ_U, PIN_FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPID_U, PIN_FUNC_GPIO); + // flash clock signal should come from IO MUX. + // set drive ability for clock + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICLK_U, FUNC_SPICLK_SPICLK); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICLK_U, FUN_DRV, drv, FUN_DRV_S); + +#if CONFIG_SPIRAM_TYPE_ESPPSRAM32 || CONFIG_SPIRAM_TYPE_ESPPSRAM64 + uint32_t flash_id = g_rom_flashchip.device_id; + if (flash_id == FLASH_ID_GD25LQ32C) { + // Set drive ability for 1.8v flash in 80Mhz. + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIHD_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIWP_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICS0_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICLK_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIQ_U, FUN_DRV, 3, FUN_DRV_S); + SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPID_U, FUN_DRV, 3, FUN_DRV_S); + } +#endif + } +} diff --git a/components/bootloader_support/src/esp32s2beta/bootloader_sha.c b/components/bootloader_support/src/esp32s2beta/bootloader_sha.c new file mode 100644 index 000000000..bb6b97396 --- /dev/null +++ b/components/bootloader_support/src/esp32s2beta/bootloader_sha.c @@ -0,0 +1,53 @@ +// Copyright 2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "bootloader_sha.h" +#include +#include +#include +#include + +#include "esp32s2beta/rom/sha.h" + +static SHA_CTX ctx; + +// Words per SHA256 block +// static const size_t BLOCK_WORDS = (64/sizeof(uint32_t)); +// Words in final SHA256 digest +// static const size_t DIGEST_WORDS = (32/sizeof(uint32_t)); + +bootloader_sha256_handle_t bootloader_sha256_start() +{ + // Enable SHA hardware + ets_sha_enable(); + ets_sha_init(&ctx, SHA2_256); + return &ctx; // Meaningless non-NULL value +} + +void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len) +{ + assert(handle != NULL); + assert(data_len % 4 == 0); + ets_sha_update(&ctx, data, data_len, false); +} + +void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest) +{ + assert(handle != NULL); + + if (digest == NULL) { + bzero(&ctx, sizeof(ctx)); + return; + } + ets_sha_finish(&ctx, digest); +} diff --git a/components/bootloader_support/src/esp32s2beta/flash_encrypt.c b/components/bootloader_support/src/esp32s2beta/flash_encrypt.c new file mode 100644 index 000000000..0c68a0f5e --- /dev/null +++ b/components/bootloader_support/src/esp32s2beta/flash_encrypt.c @@ -0,0 +1,303 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "bootloader_flash.h" +#include "bootloader_random.h" +#include "bootloader_utility.h" +#include "esp_image_format.h" +#include "esp_flash_encrypt.h" +#include "esp_flash_partitions.h" +#include "esp_secure_boot.h" +#include "esp_log.h" +#include "esp32s2beta/rom/secure_boot.h" +#include "esp32s2beta/rom/cache.h" +#include "esp32s2beta/rom/efuse.h" + +static const char *TAG = "flash_encrypt"; + +/* Static functions for stages of flash encryption */ +static esp_err_t initialise_flash_encryption(void); +static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis); +static esp_err_t encrypt_bootloader(); +static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions); +static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition); + +esp_err_t esp_flash_encrypt_check_and_update(void) +{ + // TODO: not clear why this is read from DATA1 and written to PGM_DATA2 + uint32_t cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_SPI_BOOT_CRYPT_CNT); + ESP_LOGV(TAG, "SPI_BOOT_CRYPT_CNT 0x%x", cnt); + + bool flash_crypt_wr_dis = false; // TODO: check if CRYPT_CNT is write disabled + + _Static_assert(EFUSE_SPI_BOOT_CRYPT_CNT == 0x7, "assuming CRYPT_CNT is only 3 bits wide"); + + if (cnt == 1 || cnt == 3 || cnt == 7) { + /* Flash is already encrypted */ + int left; + if (cnt == 7 /* || disabled */) { + left = 0; + } else if (cnt == 3) { + left = 1; + } else { + left = 2; + } + ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left); + return ESP_OK; + } + else { + /* Flash is not encrypted, so encrypt it! */ + return encrypt_flash_contents(cnt, flash_crypt_wr_dis); + } +} + +static esp_err_t initialise_flash_encryption(void) +{ + /* Before first flash encryption pass, need to initialise key & crypto config */ + + /* Find out if a key is already set */ + bool has_aes128 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL); + bool has_aes256_1 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1, NULL); + bool has_aes256_2 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2, NULL); + + bool has_key = has_aes128 || (has_aes256_1 && has_aes256_2); + + if (!has_key && (has_aes256_1 || has_aes256_2)) { + ESP_LOGE(TAG, "Invalid efuse key blocks: Both AES-256 key blocks must be set."); + return ESP_ERR_INVALID_STATE; + } + + if (has_key) { + ESP_LOGI(TAG, "Using pre-existing key in efuse"); + + ESP_LOGE(TAG, "TODO: Check key is read & write protected"); // TODO + } else { + ESP_LOGI(TAG, "Generating new flash encryption key..."); +#ifdef CONFIG_FLASH_ENCRYPTION_AES256 + const unsigned BLOCKS_NEEDED = 2; + const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1; + const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2; +#else + const unsigned BLOCKS_NEEDED = 1; + const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY; + const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY; +#endif + + if (ets_efuse_count_unused_key_blocks() < BLOCKS_NEEDED) { + ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED); + return ESP_ERR_INVALID_STATE; + } + + for(ets_efuse_purpose_t purpose = PURPOSE_START; purpose <= PURPOSE_END; purpose++) { + uint32_t buf[8]; + bootloader_fill_random(buf, sizeof(buf)); + ets_efuse_block_t block = ets_efuse_find_unused_key_block(); + ESP_LOGD(TAG, "Writing ETS_EFUSE_BLOCK_KEY%d with purpose %d", + block - ETS_EFUSE_BLOCK_KEY0, purpose); + bootloader_debug_buffer(buf, sizeof(buf), "Key content"); + int r = ets_efuse_write_key(block, purpose, buf, sizeof(buf)); + bzero(buf, sizeof(buf)); + if (r != 0) { + ESP_LOGE(TAG, "Failed to write efuse block %d with purpose %d. Can't continue."); + return ESP_FAIL; + } + } + + ESP_LOGD(TAG, "Key generation complete"); + } + + ESP_LOGE(TAG, "TODO: burn remaining security protection bits"); // TODO + + return ESP_OK; +} + +/* Encrypt all flash data that should be encrypted */ +static esp_err_t encrypt_flash_contents(uint32_t spi_boot_crypt_cnt, bool flash_crypt_wr_dis) +{ + esp_err_t err; + esp_partition_info_t partition_table[ESP_PARTITION_TABLE_MAX_ENTRIES]; + int num_partitions; + + /* If the last spi_boot_crypt_cnt bit is burned or write-disabled, the + device can't re-encrypt itself. */ + if (flash_crypt_wr_dis || spi_boot_crypt_cnt == EFUSE_SPI_BOOT_CRYPT_CNT) { + ESP_LOGE(TAG, "Cannot re-encrypt data (SPI_BOOT_CRYPT_CNT 0x%02x write disabled %d", spi_boot_crypt_cnt, flash_crypt_wr_dis); + return ESP_FAIL; + } + + if (spi_boot_crypt_cnt == 0) { + /* Very first flash of encrypted data: generate keys, etc. */ + err = initialise_flash_encryption(); + if (err != ESP_OK) { + return err; + } + } + + err = encrypt_bootloader(); + if (err != ESP_OK) { + return err; + } + + err = encrypt_and_load_partition_table(partition_table, &num_partitions); + if (err != ESP_OK) { + return err; + } + + /* Now iterate the just-loaded partition table, looking for entries to encrypt + */ + + /* Go through each partition and encrypt if necessary */ + for (int i = 0; i < num_partitions; i++) { + err = encrypt_partition(i, &partition_table[i]); + if (err != ESP_OK) { + return err; + } + } + + ESP_LOGD(TAG, "All flash regions checked for encryption pass"); + + /* Set least significant 0-bit in spi_boot_crypt_cnt */ + int ffs_inv = __builtin_ffs((~spi_boot_crypt_cnt) & 0x7); + /* ffs_inv shouldn't be zero, as zero implies spi_boot_crypt_cnt == 0xFF */ + uint32_t new_spi_boot_crypt_cnt = spi_boot_crypt_cnt + (1 << (ffs_inv - 1)); + ESP_LOGD(TAG, "SPI_BOOT_CRYPT_CNT 0x%x -> 0x%x", spi_boot_crypt_cnt, new_spi_boot_crypt_cnt); + + ets_efuse_clear_program_registers(); + REG_SET_FIELD(EFUSE_PGM_DATA2_REG, EFUSE_SPI_BOOT_CRYPT_CNT, new_spi_boot_crypt_cnt); + ets_efuse_program(ETS_EFUSE_BLOCK0); + + ESP_LOGI(TAG, "Flash encryption completed"); + + return ESP_OK; +} + +static esp_err_t encrypt_bootloader() +{ + esp_err_t err; + uint32_t image_length; + /* Check for plaintext bootloader (verification will fail if it's already encrypted) */ + if (esp_image_verify_bootloader(&image_length) == ESP_OK) { + ESP_LOGD(TAG, "bootloader is plaintext. Encrypting..."); + err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, image_length); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err); + return err; + } + + if (esp_secure_boot_enabled()) { + // TODO: anything different for secure boot? + } + } + else { + ESP_LOGW(TAG, "no valid bootloader was found"); + } + + return ESP_OK; +} + +static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions) +{ + esp_err_t err; + /* Check for plaintext partition table */ + err = bootloader_flash_read(ESP_PARTITION_TABLE_OFFSET, partition_table, ESP_PARTITION_TABLE_MAX_LEN, false); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to read partition table data"); + return err; + } + if (esp_partition_table_basic_verify(partition_table, false, num_partitions) == ESP_OK) { + ESP_LOGD(TAG, "partition table is plaintext. Encrypting..."); + esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET, + FLASH_SECTOR_SIZE); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to encrypt partition table in place. %x", err); + return err; + } + } + else { + ESP_LOGE(TAG, "Failed to read partition table data - not plaintext?"); + return ESP_ERR_INVALID_STATE; + } + + /* Valid partition table loded */ + return ESP_OK; +} + + +static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition) +{ + esp_err_t err; + bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED); + + if (partition->type == PART_TYPE_APP) { + /* check if the partition holds a valid unencrypted app */ + esp_image_metadata_t data_ignored; + err = esp_image_load(ESP_IMAGE_VERIFY, + &partition->pos, + &data_ignored); + should_encrypt = (err == ESP_OK); + } else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) { + /* check if we have ota data partition and the partition should be encrypted unconditionally */ + should_encrypt = true; + } + + if (!should_encrypt) { + return ESP_OK; + } + else { + /* should_encrypt */ + ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, partition->pos.size); + + err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size); + ESP_LOGI(TAG, "Done encrypting"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to encrypt partition %d", index); + } + return err; + } +} + + +esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length) +{ + esp_err_t err; + uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)]; + + if (src_addr % FLASH_SECTOR_SIZE != 0) { + ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x",src_addr); + return ESP_FAIL; + } + + for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) { + uint32_t sec_start = i + src_addr; + err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, false); + if (err != ESP_OK) { + goto flash_failed; + } + err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE); + if (err != ESP_OK) { + goto flash_failed; + } + err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true); + if (err != ESP_OK) { + goto flash_failed; + } + } + return ESP_OK; + + flash_failed: + ESP_LOGE(TAG, "flash operation failed: 0x%x", err); + return err; +} diff --git a/components/bootloader_support/src/esp32s2beta/secure_boot.c b/components/bootloader_support/src/esp32s2beta/secure_boot.c new file mode 100644 index 000000000..aac9405a0 --- /dev/null +++ b/components/bootloader_support/src/esp32s2beta/secure_boot.c @@ -0,0 +1,45 @@ +// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "esp_secure_boot.h" +#include "esp_log.h" +#include "esp32s2beta/rom/secure_boot.h" + +#define TAG "secure_boot" + +esp_err_t esp_secure_boot_permanently_enable(void) +{ + uint8_t hash[32]; + + if (ets_efuse_secure_boot_enabled()) + { + ESP_LOGI(TAG, "secure boot is already enabled, continuing.."); + return ESP_OK; + } + + ESP_LOGI(TAG, "Verifying bootloader signature...\n"); + int r = ets_secure_boot_verify_bootloader(hash, false); + if (r != ESP_OK) { + ESP_LOGE(TAG, "Failed to verify bootloader signature"); + return r; + } + + ets_efuse_clear_program_registers(); + REG_SET_BIT(EFUSE_PGM_DATA3_REG, EFUSE_SECURE_BOOT_EN); + ets_efuse_program(ETS_EFUSE_BLOCK0); + + assert(ets_efuse_secure_boot_enabled()); + ESP_LOGI(TAG, "Secure boot permanently enabled"); + + return ESP_OK; +} diff --git a/components/bootloader_support/src/esp32s2beta/secure_boot_signatures.c b/components/bootloader_support/src/esp32s2beta/secure_boot_signatures.c new file mode 100644 index 000000000..d553c1ee6 --- /dev/null +++ b/components/bootloader_support/src/esp32s2beta/secure_boot_signatures.c @@ -0,0 +1,92 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "sdkconfig.h" + +#include "bootloader_flash.h" +#include "bootloader_sha.h" +#include "esp_log.h" +#include "esp_image_format.h" +#include "esp32s2beta/rom/secure_boot.h" + +static const char* TAG = "secure_boot"; + +#define DIGEST_LEN 32 + +esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) +{ + ets_secure_boot_key_digests_t trusted_keys = { 0 }; + uint8_t digest[DIGEST_LEN]; + const uint8_t *data; + + ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length); + + if ((src_addr + length) % 4096 != 0) { + ESP_LOGE(TAG, "addr 0x%x length 0x%x doesn't end on a sector boundary", src_addr, length); + return ESP_ERR_INVALID_ARG; + } + + data = bootloader_mmap(src_addr, length + sizeof(struct ets_secure_boot_sig_block)); + if(data == NULL) { + ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(ets_secure_boot_signature_t)); + return ESP_FAIL; + } + + // Calculate digest of main image +#ifdef BOOTLOADER_BUILD + bootloader_sha256_handle_t handle = bootloader_sha256_start(); + bootloader_sha256_data(handle, data, length); + bootloader_sha256_finish(handle, digest); +#else + /* Use thread-safe esp-idf SHA function */ + esp_sha(SHA2_256, data, length, digest); +#endif + + int r = ets_secure_boot_read_key_digests(&trusted_keys); + + if (r == ETS_OK) { + const ets_secure_boot_signature_t *sig = (const ets_secure_boot_signature_t *)(data + length); + // TODO: calling this function in IDF app context is unsafe + r = ets_secure_boot_verify_signature(sig, digest, &trusted_keys); + } + bootloader_munmap(data); + + return (r == ETS_OK) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_secure_boot_verify_signature_block(uint32_t sig_block_flash_offs, const uint8_t *image_digest) +{ + ets_secure_boot_key_digests_t trusted_keys; + + assert(sig_block_flash_offs % 4096 == 0); // TODO: enforce this in a better way + + const ets_secure_boot_signature_t *sig = bootloader_mmap(sig_block_flash_offs, sizeof(ets_secure_boot_signature_t)); + + if (sig == NULL) { + ESP_LOGE(TAG, "Failed to mmap data at offset 0x%x", sig_block_flash_offs); + return ESP_FAIL; + } + + int r = ets_secure_boot_read_key_digests(&trusted_keys); + if (r != 0) { + ESP_LOGE(TAG, "No trusted key digests were found in efuse!"); + } else { + ESP_LOGD(TAG, "Verifying with RSA-PSS..."); + // TODO: calling this function in IDF app context is unsafe + r = ets_secure_boot_verify_signature(sig, image_digest, &trusted_keys); + } + + bootloader_munmap(sig); + + return (r == 0) ? ESP_OK : ESP_ERR_IMAGE_INVALID; +} diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 77af08c3c..5079e7680 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -13,8 +13,6 @@ // limitations under the License. #include #include - -#include #include #include #include @@ -24,6 +22,14 @@ #include #include #include "bootloader_util.h" +#include "bootloader_utility.h" +#if CONFIG_IDF_TARGET_ESP32 +#include +#include +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include +#include +#endif /* Checking signatures as part of verifying images is necessary: - Always if secure boot is enabled @@ -156,7 +162,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_ } uint32_t next_addr = data->start_addr + sizeof(esp_image_header_t); - for(int i = 0; i < data->image.segment_count; i++) { + for (int i = 0; i < data->image.segment_count; i++) { esp_image_segment_header_t *header = &data->segments[i]; ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr); err = process_segment(i, next_addr, header, silent, do_load, sha_handle, &checksum_word); @@ -186,13 +192,19 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_ FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size); } - bool is_bootloader = (data->start_addr == ESP_BOOTLOADER_OFFSET); /* For secure boot, we don't verify signature on bootloaders. For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because esptool.py may have rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead. */ - if (!is_bootloader) { + bool should_verify; +#if defined(CONFIG_SECURE_BOOT_ENABLED) && defined(CONFIG_IDF_TARGET_ESP32S2BETA) + should_verify = true; +#else // ESP32, or ESP32S2 without secure boot enabled + should_verify = (data->start_addr != ESP_BOOTLOADER_OFFSET); +#endif + + if (should_verify) { #ifdef SECURE_BOOT_CHECK_SIGNATURE // secure boot images have a signature appended err = verify_secure_boot_signature(sha_handle, data); @@ -202,7 +214,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_ err = verify_simple_hash(sha_handle, data); } #endif // SECURE_BOOT_CHECK_SIGNATURE - } else { // is_bootloader + } else { // bootloader may still have a sha256 digest handle open if (sha_handle != NULL) { bootloader_sha256_finish(sha_handle, NULL); @@ -230,7 +242,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_ uint32_t load_addr = data->segments[i].load_addr; if (should_load(load_addr)) { uint32_t *loaded = (uint32_t *)load_addr; - for (int j = 0; j < data->segments[i].data_len/sizeof(uint32_t); j++) { + for (int j = 0; j < data->segments[i].data_len / sizeof(uint32_t); j++) { loaded[j] ^= (j & 1) ? ram_obfs_value[0] : ram_obfs_value[1]; } } @@ -241,9 +253,9 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_ // Success! return ESP_OK; - err: +err: if (err == ESP_OK) { - err = ESP_ERR_IMAGE_INVALID; + err = ESP_ERR_IMAGE_INVALID; } if (sha_handle != NULL) { // Need to finish the hash process to free the handle @@ -330,7 +342,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme ESP_LOGI(TAG, "segment %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", index, data_addr, load_addr, data_len, data_len, - (do_load)?"load":(is_mapping)?"map":""); + (do_load) ? "load" : (is_mapping) ? "map" : ""); } @@ -359,7 +371,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme const intptr_t loader_iram_end = (intptr_t) &_loader_text_end; if (bootloader_util_regions_overlap(loader_iram_start, loader_iram_end, - load_addr, load_end)) { + load_addr, load_end)) { ESP_LOGE(TAG, "Segment %d (0x%08x-0x%08x) overlaps bootloader IRAM (0x%08x-0x%08x)", index, load_addr, load_end, loader_iram_start, loader_iram_end); return ESP_ERR_IMAGE_INVALID; @@ -370,10 +382,10 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme #ifndef BOOTLOADER_BUILD uint32_t free_page_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA); - ESP_LOGD(TAG, "free data page_count 0x%08x",free_page_count); + ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count); uint32_t offset_page = 0; while (data_len >= free_page_count * SPI_FLASH_MMU_PAGE_SIZE) { - offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0)?1:0; + offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0; err = process_segment_data(load_addr, data_addr, (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE, do_load, sha_handle, checksum); if (err != ESP_OK) { return err; @@ -399,7 +411,7 @@ err: static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum) { const uint32_t *data = (const uint32_t *)bootloader_mmap(data_addr, data_len); - if(!data) { + if (!data) { ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", data_addr, data_len); return ESP_FAIL; @@ -416,7 +428,7 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui const uint32_t *src = data; for (int i = 0; i < data_len; i += 4) { - int w_i = i/4; // Word index + int w_i = i / 4; // Word index uint32_t w = src[w_i]; *checksum ^= w; #ifdef BOOTLOADER_BUILD @@ -443,7 +455,7 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent) { if ((segment->data_len & 3) != 0 - || segment->data_len >= SIXTEEN_MB) { + || segment->data_len >= SIXTEEN_MB) { if (!silent) { ESP_LOGE(TAG, "invalid segment length 0x%x", segment->data_len); } @@ -459,7 +471,7 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%x load_addr 0x%x", index, map_segment, segment_data_offs, load_addr); if (map_segment - && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) { + && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) { if (!silent) { ESP_LOGE(TAG, "Segment %d load address 0x%08x, doesn't match data 0x%08x", index, load_addr, segment_data_offs); @@ -473,7 +485,7 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header static bool should_map(uint32_t load_addr) { return (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH) - || (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH); + || (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH); } static bool should_load(uint32_t load_addr) @@ -532,8 +544,8 @@ esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data) .size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET, }; return esp_image_verify(ESP_IMAGE_VERIFY, - &bootloader_part, - data); + &bootloader_part, + data); } @@ -548,9 +560,9 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t esp_err_t err = bootloader_flash_read(data->start_addr + unpadded_length, buf, length - unpadded_length, true); uint8_t calc = buf[length - unpadded_length - 1]; uint8_t checksum = (checksum_word >> 24) - ^ (checksum_word >> 16) - ^ (checksum_word >> 8) - ^ (checksum_word >> 0); + ^ (checksum_word >> 16) + ^ (checksum_word >> 8) + ^ (checksum_word >> 0); if (err != ESP_OK || checksum != calc) { ESP_LOGE(TAG, "Checksum failed. Calculated 0x%x read 0x%x", checksum, calc); return ESP_ERR_IMAGE_INVALID; @@ -568,26 +580,36 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t return ESP_OK; } -static void debug_log_hash(const uint8_t *image_hash, const char *caption); - static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data) { uint8_t image_hash[HASH_LEN] = { 0 }; + uint32_t end = data->start_addr + data->image_len; ESP_LOGI(TAG, "Verifying image signature..."); // For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash // appended to the image for corruption detection if (data->image.hash_appended) { - const void *simple_hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN); + const void *simple_hash = bootloader_mmap(end - HASH_LEN, HASH_LEN); bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN); bootloader_munmap(simple_hash); } +#ifdef CONFIG_IDF_TARGET_ESP32S2BETA + // Pad to 4096 byte sector boundary + if (end % FLASH_SECTOR_SIZE != 0) { + uint32_t pad_len = FLASH_SECTOR_SIZE - (end % FLASH_SECTOR_SIZE); + const void *padding = bootloader_mmap(end, pad_len); + bootloader_sha256_data(sha_handle, padding, pad_len); + bootloader_munmap(padding); + end += pad_len; + } +#endif + bootloader_sha256_finish(sha_handle, image_hash); // Log the hash for debugging - debug_log_hash(image_hash, "Calculated secure boot hash"); + bootloader_debug_buffer(image_hash, HASH_LEN, "Calculated secure boot hash"); // Use hash to verify signature block const esp_secure_boot_sig_block_t *sig_block = bootloader_mmap(data->start_addr + data->image_len, sizeof(esp_secure_boot_sig_block_t)); @@ -612,6 +634,11 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han return ESP_ERR_IMAGE_INVALID; } +#if CONFIG_IDF_TARGET_ESP32S2BETA + // Adjust image length result to include the appended signature + data->image_len = end - data->start_addr + sizeof(ets_secure_boot_signature_t); +#endif + return ESP_OK; } @@ -621,13 +648,13 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i bootloader_sha256_finish(sha_handle, image_hash); // Log the hash for debugging - debug_log_hash(image_hash, "Calculated hash"); + bootloader_debug_buffer(image_hash, HASH_LEN, "Calculated hash"); // Simple hash for verification only const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN); if (memcmp(hash, image_hash, HASH_LEN) != 0) { ESP_LOGE(TAG, "Image hash failed - image is corrupt"); - debug_log_hash(hash, "Expected hash"); + bootloader_debug_buffer(hash, HASH_LEN, "Expected hash"); bootloader_munmap(hash); return ESP_ERR_IMAGE_INVALID; } @@ -635,14 +662,3 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i bootloader_munmap(hash); return ESP_OK; } - -// Log a hash as a hex string -static void debug_log_hash(const uint8_t *image_hash, const char *label) -{ -#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG - char hash_print[HASH_LEN * 2 + 1]; - hash_print[HASH_LEN * 2] = 0; - bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN); - ESP_LOGD(TAG, "%s: %s", label, hash_print); -#endif -} diff --git a/components/bootloader_support/src/flash_qio_mode.c b/components/bootloader_support/src/flash_qio_mode.c index db486c73e..3c94318d7 100644 --- a/components/bootloader_support/src/flash_qio_mode.c +++ b/components/bootloader_support/src/flash_qio_mode.c @@ -16,14 +16,28 @@ #include "flash_qio_mode.h" #include "esp_log.h" #include "esp_err.h" +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/spi_flash.h" #include "esp32/rom/efuse.h" -#include "soc/spi_periph.h" +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#include "esp32s2beta/rom/spi_flash.h" +#include "esp32s2beta/rom/efuse.h" +#endif +#include "soc/spi_struct.h" +#include "soc/spi_reg.h" +#if CONFIG_IDF_TARGET_ESP32S2BETA +#include "soc/spi_mem_struct.h" +#endif #include "soc/efuse_periph.h" +#include "soc/io_mux_reg.h" #include "sdkconfig.h" /* SPI flash controller */ +#if CONFIG_IDF_TARGET_ESP32 #define SPIFLASH SPI1 +#elif CONFIG_IDF_TARGET_ESP32S2BETA +#define SPIFLASH SPIMEM1 +#endif /* SPI commands (actual on-wire commands not SPI controller bitmasks) Suitable for use with the execute_flash_command static function. @@ -42,7 +56,8 @@ static const char *TAG = "qio_mode"; typedef unsigned (*read_status_fn_t)(); typedef void (*write_status_fn_t)(unsigned); -typedef struct __attribute__((packed)) { +typedef struct __attribute__((packed)) +{ const char *manufacturer; uint8_t mfg_id; /* 8-bit JEDEC manufacturer ID */ uint16_t flash_id; /* 16-bit JEDEC flash chip ID */ @@ -90,7 +105,7 @@ static void write_status_8b_xmc25qu64a(unsigned new_status); Searching of this table stops when the first match is found. */ const static qio_info_t chip_data[] = { -/* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */ + /* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */ { "MXIC", 0xC2, 0x2000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, { "ISSI", 0x9D, 0x4000, 0xCF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, /* IDs 0x40xx, 0x70xx */ { "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 }, @@ -109,8 +124,8 @@ const static qio_info_t chip_data[] = { #define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t)) static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn, - write_status_fn_t write_status_fn, - uint8_t status_qio_bit); + write_status_fn_t write_status_fn, + uint8_t status_qio_bit); /* Generic function to use the "user command" SPI controller functionality to send commands to the SPI flash and read the respopnse. @@ -128,6 +143,46 @@ uint32_t bootloader_read_flash_id() return id; } +#if CONFIG_IDF_TARGET_ESP32S2BETA +#define FLASH_WRAP_CMD 0x77 +typedef enum { + FLASH_WRAP_MODE_8B = 0, + FLASH_WRAP_MODE_16B = 2, + FLASH_WRAP_MODE_32B = 4, + FLASH_WRAP_MODE_64B = 6, + FLASH_WRAP_MODE_DISABLE = 1 +} spi_flash_wrap_mode_t; +static esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) +{ + uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val; + uint32_t reg_bkp_usr = SPIFLASH.user.val; + SPIFLASH.user.fwrite_dio = 0; + SPIFLASH.user.fwrite_dual = 0; + SPIFLASH.user.fwrite_qio = 1; + SPIFLASH.user.fwrite_quad = 0; + SPIFLASH.ctrl.fcmd_dual = 0; + SPIFLASH.ctrl.fcmd_quad = 0; + SPIFLASH.user.usr_dummy = 0; + SPIFLASH.user.usr_addr = 1; + SPIFLASH.user.usr_command = 1; + SPIFLASH.user2.usr_command_bitlen = 7; + SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD; + SPIFLASH.user1.usr_addr_bitlen = 23; + SPIFLASH.addr = 0; + SPIFLASH.user.usr_miso = 0; + SPIFLASH.user.usr_mosi = 1; + SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7; + SPIFLASH.data_buf[0] = (uint32_t) mode << 4;; + SPIFLASH.cmd.usr = 1; + while (SPIFLASH.cmd.usr != 0) { + } + + SPIFLASH.ctrl.val = reg_bkp_ctrl; + SPIFLASH.user.val = reg_bkp_usr; + return ESP_OK; +} +#endif + void bootloader_enable_qio_mode(void) { uint32_t raw_flash_id; @@ -145,7 +200,7 @@ void bootloader_enable_qio_mode(void) flash_id = raw_flash_id & 0xFFFF; ESP_LOGD(TAG, "Manufacturer ID 0x%02x chip ID 0x%04x", mfg_id, flash_id); - for (i = 0; i < NUM_CHIPS-1; i++) { + for (i = 0; i < NUM_CHIPS - 1; i++) { const qio_info_t *chip = &chip_data[i]; if (mfg_id == chip->mfg_id && (flash_id & chip->id_mask) == (chip->flash_id & chip->id_mask)) { ESP_LOGI(TAG, "Enabling QIO for flash chip %s", chip_data[i].manufacturer); @@ -156,19 +211,22 @@ void bootloader_enable_qio_mode(void) if (i == NUM_CHIPS - 1) { ESP_LOGI(TAG, "Enabling default flash chip QIO"); } - +#if CONFIG_IDF_TARGET_ESP32S2BETA + spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); +#endif enable_qio_mode(chip_data[i].read_status_fn, chip_data[i].write_status_fn, chip_data[i].status_qio_bit); } static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn, - write_status_fn_t write_status_fn, - uint8_t status_qio_bit) + write_status_fn_t write_status_fn, + uint8_t status_qio_bit) { uint32_t status; const uint32_t spiconfig = ets_efuse_get_spiconfig(); +#if CONFIG_IDF_TARGET_ESP32 if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) { // spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP, // which is compiled into the bootloader instead. @@ -178,27 +236,28 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn, //assignment from that chip's WP pin. uint32_t pkg_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); if (CONFIG_BOOTLOADER_SPI_WP_PIN != ESP32_D2WD_WP_GPIO && - (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 || - pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 || - pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) { + (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 || + pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 || + pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) { ESP_LOGW(TAG, "Chip is ESP32-D2WD/ESP32-PICOD4 but flash WP pin is different value to internal flash"); } } +#endif esp_rom_spiflash_wait_idle(&g_rom_flashchip); status = read_status_fn(); ESP_LOGD(TAG, "Initial flash chip status 0x%x", status); - if ((status & (1< 0; +#if CONFIG_IDF_TARGET_ESP32 SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + SPIFLASH.miso_dlen.usr_miso_bit_len = miso_len ? (miso_len - 1) : 0; +#endif SPIFLASH.user.usr_mosi = mosi_len > 0; +#if CONFIG_IDF_TARGET_ESP32 SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0; +#elif CONFIG_IDF_TARGET_ESP32S2BETA + SPIFLASH.mosi_dlen.usr_mosi_bit_len = mosi_len ? (mosi_len - 1) : 0; +#endif SPIFLASH.data_buf[0] = mosi_data; if (g_rom_spiflash_dummy_len_plus[1]) { @@ -299,8 +377,8 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8 } SPIFLASH.cmd.usr = 1; - while(SPIFLASH.cmd.usr != 0) - { } + while (SPIFLASH.cmd.usr != 0) { + } SPIFLASH.ctrl.val = old_ctrl_reg; return SPIFLASH.data_buf[0]; diff --git a/components/efuse/CMakeLists.txt b/components/efuse/CMakeLists.txt index f649a242f..4cdb84635 100644 --- a/components/efuse/CMakeLists.txt +++ b/components/efuse/CMakeLists.txt @@ -1,5 +1,10 @@ idf_build_get_property(soc_name IDF_TARGET) +# TODO: add esp32sbeta support for efuse component +if(NOT CONFIG_IDF_TARGET_ESP32) + return() +endif() + if(EXISTS "${COMPONENT_DIR}/${soc_name}") include(${COMPONENT_DIR}/${soc_name}/sources.cmake) spaces2list(EFUSE_SOC_SRCS) @@ -7,6 +12,7 @@ if(EXISTS "${COMPONENT_DIR}/${soc_name}") set(COMPONENT_ADD_INCLUDEDIRS include ${soc_name}/include) endif() +list(APPEND COMPONENT_ADD_INCLUDEDIRS include) list(APPEND COMPONENT_SRCS "src/esp_efuse_api.c" "src/esp_efuse_fields.c" "src/esp_efuse_utility.c") diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 3620f4379..8c25a3f38 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -1,11 +1,11 @@ -require_idf_targets(esp32) +# require_idf_targets(esp32) -if(BOOTLOADER_BUILD) +if(BOOTLOADER_BUILD AND CONFIG_IDF_TARGET_ESP32) # For bootloader, all we need from esp32 is headers set(COMPONENT_ADD_INCLUDEDIRS include) register_component() target_linker_script(${COMPONENT_LIB} "ld/esp32.peripherals.ld") -else() +elseif(CONFIG_IDF_TARGET_ESP32) # Regular app build set(COMPONENT_SRCS "brownout.c" diff --git a/components/esp32s2beta/CMakeLists.txt b/components/esp32s2beta/CMakeLists.txt index d4eed8a23..34da19b4e 100644 --- a/components/esp32s2beta/CMakeLists.txt +++ b/components/esp32s2beta/CMakeLists.txt @@ -4,6 +4,9 @@ if(BOOTLOADER_BUILD AND CONFIG_IDF_TARGET_ESP32S2BETA) set(COMPONENT_REQUIRES ${IDF_COMPONENTS} soc) #unfortunately rom/uart uses SOC registers directly set(COMPONENT_SRCS ) register_component() + idf_build_get_property(target IDF_TARGET) + set(scripts "ld/esp32s2beta.peripherals.ld") + target_linker_script(${COMPONENT_LIB} "${scripts}") elseif(CONFIG_IDF_TARGET_ESP32S2BETA) # Regular app build diff --git a/components/esp32s2beta/dport_access.c b/components/esp32s2beta/dport_access.c index b7e7c82d9..7ec8dc8a2 100644 --- a/components/esp32s2beta/dport_access.c +++ b/components/esp32s2beta/dport_access.c @@ -116,7 +116,6 @@ void IRAM_ATTR esp_dport_access_stall_other_cpu_end(void) { #ifndef CONFIG_FREERTOS_UNICORE int cpu_id = xPortGetCoreID(); - if (dport_core_state[0] == DPORT_CORE_STATE_IDLE || dport_core_state[1] == DPORT_CORE_STATE_IDLE) { return; diff --git a/components/esp32s2beta/intr_alloc.c b/components/esp32s2beta/intr_alloc.c index e6f4f10fe..415a296d7 100644 --- a/components/esp32s2beta/intr_alloc.c +++ b/components/esp32s2beta/intr_alloc.c @@ -340,7 +340,6 @@ static bool is_vect_desc_usable(vector_desc_t *vd, int flags, int cpu, int force ALCHLOG("....Unusable: reserved at runtime."); return false; } - //Ints can't be both shared and non-shared. assert(!((vd->flags&VECDESC_FL_SHARED)&&(vd->flags&VECDESC_FL_NONSHARED))); //check if interrupt already is in use by a non-shared interrupt @@ -368,7 +367,6 @@ static bool is_vect_desc_usable(vector_desc_t *vd, int flags, int cpu, int force ALCHLOG("....Unusable: already allocated"); return false; } - return true; } @@ -385,7 +383,6 @@ static int get_available_int(int flags, int cpu, int force, int source) vector_desc_t empty_vect_desc; memset(&empty_vect_desc, 0, sizeof(vector_desc_t)); - //Level defaults to any low/med interrupt if (!(flags&ESP_INTR_FLAG_LEVELMASK)) flags|=ESP_INTR_FLAG_LOWMED; @@ -433,12 +430,10 @@ static int get_available_int(int flags, int cpu, int force, int source) ALCHLOG("Int %d reserved %d level %d %s hasIsr %d", x, int_desc[x].cpuflags[cpu]==INTDESC_RESVD, int_desc[x].level, int_desc[x].type==INTTP_LEVEL?"LEVEL":"EDGE", int_has_handler(x, cpu)); - if ( !is_vect_desc_usable(vd, flags, cpu, force) ) continue; if (flags&ESP_INTR_FLAG_SHARED) { //We're allocating a shared int. - //See if int already is used as a shared interrupt. if (vd->flags&VECDESC_FL_SHARED) { //We can use this already-marked-as-shared interrupt. Count the already attached isrs in order to see diff --git a/components/esp32s2beta/ld/esp32s2beta.project.ld.in b/components/esp32s2beta/ld/esp32s2beta.project.ld.in new file mode 100644 index 000000000..6b10c8694 --- /dev/null +++ b/components/esp32s2beta/ld/esp32s2beta.project.ld.in @@ -0,0 +1,332 @@ +/* Default entry point: */ +ENTRY(call_start_cpu0); + +SECTIONS +{ + /* RTC fast memory holds RTC wake stub code, + including from any source file named rtc_wake_stub*.c + */ + .rtc.text : + { + . = ALIGN(4); + + mapping[rtc_text] + + *rtc_wake_stub*.*(.literal .text .literal.* .text.*) + _rtc_text_end = ABSOLUTE(.); + } > rtc_iram_seg + + /* + This section is required to skip rtc.text area because rtc_iram_seg and + rtc_data_seg are reflect the same address space on different buses. + */ + .rtc.dummy : + { + _rtc_dummy_start = ABSOLUTE(.); + _rtc_fast_start = ABSOLUTE(.); + . = SIZEOF(.rtc.text); + _rtc_dummy_end = ABSOLUTE(.); + } > rtc_data_seg + + /* This section located in RTC FAST Memory area. + It holds data marked with RTC_FAST_ATTR attribute. + See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + . = ALIGN(4); + _rtc_force_fast_start = ABSOLUTE(.); + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4) ; + _rtc_force_fast_end = ABSOLUTE(.); + } > rtc_data_seg + + /* RTC data section holds RTC wake stub + data/rodata, including from any source file + named rtc_wake_stub*.c and the data marked with + RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + The memory location of the data is dependent on + CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. + */ + .rtc.data : + { + _rtc_data_start = ABSOLUTE(.); + + mapping[rtc_data] + + *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*) + _rtc_data_end = ABSOLUTE(.); + } > rtc_data_location + + /* RTC bss, from any source file named rtc_wake_stub*.c */ + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + *rtc_wake_stub*.*(.bss .bss.*) + *rtc_wake_stub*.*(COMMON) + + mapping[rtc_bss] + + _rtc_bss_end = ABSOLUTE(.); + } > rtc_data_location + + /* This section holds data that should not be initialized at power up + and will be retained during deep sleep. + User data marked with RTC_NOINIT_ATTR will be placed + into this section. See the file "esp_attr.h" for more information. + The memory location of the data is dependent on + CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. + */ + .rtc_noinit (NOLOAD): + { + . = ALIGN(4); + _rtc_noinit_start = ABSOLUTE(.); + *(.rtc_noinit .rtc_noinit.*) + . = ALIGN(4) ; + _rtc_noinit_end = ABSOLUTE(.); + } > rtc_data_location + + /* This section located in RTC SLOW Memory area. + It holds data marked with RTC_SLOW_ATTR attribute. + See the file "esp_attr.h" for more information. + */ + .rtc.force_slow : + { + . = ALIGN(4); + _rtc_force_slow_start = ABSOLUTE(.); + *(.rtc.force_slow .rtc.force_slow.*) + . = ALIGN(4) ; + _rtc_force_slow_end = ABSOLUTE(.); + } > rtc_slow_seg + + /* Get size of rtc slow data based on rtc_data_location alias */ + _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_slow_end - _rtc_data_start) + : (_rtc_force_slow_end - _rtc_force_slow_start); + + _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_fast_end - _rtc_fast_start) + : (_rtc_noinit_end - _rtc_fast_start); + + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), + "RTC_SLOW segment data does not fit.") + + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), + "RTC_FAST segment data does not fit.") + + /* Send .iram0 code to iram */ + .iram0.vectors : + { + _iram_start = ABSOLUTE(.); + /* Vectors go to IRAM */ + _init_start = ABSOLUTE(.); + /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ + . = 0x0; + KEEP(*(.WindowVectors.text)); + . = 0x180; + KEEP(*(.Level2InterruptVector.text)); + . = 0x1c0; + KEEP(*(.Level3InterruptVector.text)); + . = 0x200; + KEEP(*(.Level4InterruptVector.text)); + . = 0x240; + KEEP(*(.Level5InterruptVector.text)); + . = 0x280; + KEEP(*(.DebugExceptionVector.text)); + . = 0x2c0; + KEEP(*(.NMIExceptionVector.text)); + . = 0x300; + KEEP(*(.KernelExceptionVector.text)); + . = 0x340; + KEEP(*(.UserExceptionVector.text)); + . = 0x3C0; + KEEP(*(.DoubleExceptionVector.text)); + . = 0x400; + *(.*Vector.literal) + + *(.UserEnter.literal); + *(.UserEnter.text); + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + _init_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.text : + { + /* Code marked as runnning out of IRAM */ + _iram_text_start = ABSOLUTE(.); + + mapping[iram0_text] + + _iram_text_end = ABSOLUTE(.); + _iram_end = ABSOLUTE(.); + } > iram0_0_seg + + ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") + + .dram0.data : + { + _data_start = ABSOLUTE(.); + _bt_data_start = ABSOLUTE(.); + *libbt.a:(.data .data.*) + . = ALIGN (4); + _bt_data_end = ABSOLUTE(.); + _btdm_data_start = ABSOLUTE(.); + *libbtdm_app.a:(.data .data.*) + . = ALIGN (4); + _btdm_data_end = ABSOLUTE(.); + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + + mapping[dram0_data] + + _data_end = ABSOLUTE(.); + . = ALIGN(4); + } > dram0_0_seg + + /*This section holds data that should not be initialized at power up. + The section located in Internal SRAM memory region. The macro _NOINIT + can be used as attribute to place data into this section. + See the esp_attr.h file for more information. + */ + .noinit (NOLOAD): + { + . = ALIGN(4); + _noinit_start = ABSOLUTE(.); + *(.noinit .noinit.*) + . = ALIGN(4) ; + _noinit_end = ABSOLUTE(.); + } > dram0_0_seg + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.ext_ram.bss*) + _bt_bss_start = ABSOLUTE(.); + *libbt.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _bt_bss_end = ABSOLUTE(.); + _btdm_bss_start = ABSOLUTE(.); + *libbtdm_app.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _btdm_bss_end = ABSOLUTE(.); + + mapping[dram0_bss] + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.share.mem) + *(.gnu.linkonce.b.*) + + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + /* The heap starts right after end of this section */ + _heap_start = ABSOLUTE(.); + } > dram0_0_seg + + ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.") + + .flash.rodata : + { + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ + *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ + + mapping[flash_rodata] + + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 3) & ~ 3; + __eh_frame = ABSOLUTE(.); + KEEP(*(.eh_frame)) + . = (. + 7) & ~ 3; + /* C++ constructor and destructor tables, properly ordered: */ + __init_array_start = ABSOLUTE(.); + KEEP (*crtbegin.*(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __init_array_end = ABSOLUTE(.); + KEEP (*crtbegin.*(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + /* Addresses of memory regions reserved via + SOC_RESERVE_MEMORY_REGION() */ + soc_reserved_memory_region_start = ABSOLUTE(.); + KEEP (*(.reserved_memory_address)) + soc_reserved_memory_region_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _thread_local_start = ABSOLUTE(.); + *(.tdata) + *(.tdata.*) + *(.tbss) + *(.tbss.*) + _thread_local_end = ABSOLUTE(.); + . = ALIGN(4); + } >drom0_0_seg + + .flash.text : + { + _stext = .; + _text_start = ABSOLUTE(.); + + mapping[flash_text] + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + resolved by addr2line in preference to the first symbol in + the flash.text segment. + */ + _flash_cache_start = ABSOLUTE(0); + } >iram0_2_seg +} diff --git a/components/esp32s2beta/ld/esp32s2beta_fragments.lf b/components/esp32s2beta/ld/esp32s2beta_fragments.lf new file mode 100644 index 000000000..932197caf --- /dev/null +++ b/components/esp32s2beta/ld/esp32s2beta_fragments.lf @@ -0,0 +1,89 @@ +[sections:text] +entries: + .text+ + .literal+ + +[sections:data] +entries: + .data+ + +[sections:bss] +entries: + .bss+ + +[sections:common] +entries: + COMMON + +[sections:rodata] +entries: + .rodata+ + +[sections:rtc_text] +entries: + .rtc.text+ + .rtc.literal + +[sections:rtc_data] +entries: + .rtc.data+ + +[sections:rtc_rodata] +entries: + .rtc.rodata+ + +[sections:rtc_bss] +entries: + .rtc.bss + +[sections:iram] +entries: + .iram1+ + +[sections:dram] +entries: + .dram1+ + +[sections:wifi_iram] +entries: + .wifi0iram+ + +[scheme:default] +entries: + text -> flash_text + rodata -> flash_rodata + data -> dram0_data + bss -> dram0_bss + common -> dram0_bss + iram -> iram0_text + dram -> dram0_data + rtc_text -> rtc_text + rtc_data -> rtc_data + rtc_rodata -> rtc_data + rtc_bss -> rtc_bss + wifi_iram -> flash_text + +[scheme:rtc] +entries: + text -> rtc_text + data -> rtc_data + rodata -> rtc_data + bss -> rtc_bss + common -> rtc_bss + +[scheme:noflash] +entries: + text -> iram0_text + rodata -> dram0_data + +[scheme:noflash_data] +entries: + rodata -> dram0_data + +[scheme:noflash_text] +entries: + text -> iram0_text + +[scheme:wifi_iram] +entries: + wifi_iram -> iram0_text diff --git a/components/esp32s2beta/system_api.c b/components/esp32s2beta/system_api.c index dae8126e8..18af5e02f 100644 --- a/components/esp32s2beta/system_api.c +++ b/components/esp32s2beta/system_api.c @@ -200,7 +200,6 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type) ESP_LOGW(TAG, "incorrect mac type"); break; } - return ESP_OK; } @@ -366,4 +365,3 @@ void esp_chip_info(esp_chip_info_t* out_info) out_info->features = CHIP_FEATURE_WIFI_BGN; // FIXME: other features? -} diff --git a/components/esp_event/CMakeLists.txt b/components/esp_event/CMakeLists.txt index 53aff6b0a..d6d58eb77 100644 --- a/components/esp_event/CMakeLists.txt +++ b/components/esp_event/CMakeLists.txt @@ -8,8 +8,9 @@ set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_PRIV_INCLUDEDIRS "private_include") set(COMPONENT_REQUIRES log tcpip_adapter) -set(COMPONENT_PRIV_REQUIRES ethernet) -set(COMPONENT_REQUIRES log tcpip_adapter ethernet) +if(CONFIG_IDF_TARGET_ESP32) + set(COMPONENT_PRIV_REQUIRES ethernet) +endif() set(COMPONENT_ADD_LDFRAGMENTS linker.lf) diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 88a230c6a..283aba6a9 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -4,11 +4,17 @@ if(BOOTLOADER_BUILD) set(COMPONENT_REQUIRES ${IDF_COMPONENTS}) set(COMPONENT_SRCS) register_component() - set(scripts - "esp32/ld/esp32.rom.ld" - "esp32/ld/esp32.rom.newlib-funcs.ld" - "esp32/ld/esp32.rom.libgcc.ld" - ) + idf_build_get_property(target IDF_TARGET) + set(scripts "${target}/ld/${target}.rom.ld") + if(target STREQUAL "esp32") + list(APPEND scripts + "${target}/ld/${target}.rom.newlib-funcs.ld" + "${target}/ld/${target}.rom.libgcc.ld") + elseif(target STREQUAL "esp32s2beta") + list(APPEND scripts + "${target}/ld/${target}.rom.spiflash.ld" + "${target}/ld/${target}.rom.spiram_incompatible_fns.ld") + endif() target_linker_script(${COMPONENT_LIB} "${scripts}") else() # Regular app build @@ -17,27 +23,39 @@ else() register_component() - set(scripts - "esp32/ld/esp32.rom.ld" - "esp32/ld/esp32.rom.libgcc.ld" - "esp32/ld/esp32.rom.syscalls.ld" - "esp32/ld/esp32.rom.newlib-data.ld" - ) - target_linker_script(${COMPONENT_LIB} "${scripts}") + if (CONFIG_IDF_TARGET_ESP32) + set(scripts + "esp32/ld/esp32.rom.ld" + "esp32/ld/esp32.rom.libgcc.ld" + "esp32/ld/esp32.rom.syscalls.ld" + "esp32/ld/esp32.rom.newlib-data.ld" + ) + target_linker_script(${COMPONENT_LIB} "${scripts}") - if(NOT CONFIG_SPIRAM_CACHE_WORKAROUND) - target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-funcs.ld") + if(NOT CONFIG_SPIRAM_CACHE_WORKAROUND) + target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-funcs.ld") + endif() + + if(CONFIG_NEWLIB_NANO_FORMAT) + target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-nano.ld") + endif() + + if(NOT GCC_NOT_5_2_0) + target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-locale.ld") + endif() + + if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH) + target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.spiflash.ld") + endif() + + elseif(CONFIG_IDF_TARGET_ESP32S2BETA) + target_linker_script(${COMPONENT_LIB} + "esp32s2beta/ld/esp32s2beta.rom.ld" + "esp32s2beta/ld/esp32s2beta.rom.nanofmt.ld" + "esp32s2beta/ld/esp32s2beta.rom.spiflash.ld" + "esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld" + "esp32s2beta/ld/esp32s2beta.spiram.rom-functions-dram.ld" + "esp32s2beta/ld/esp32s2beta.spiram.rom-functions-iram.ld") endif() - if(CONFIG_NEWLIB_NANO_FORMAT) - target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-nano.ld") - endif() - - if(NOT GCC_NOT_5_2_0) - target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-locale.ld") - endif() - - if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH) - target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.spiflash.ld") - endif() endif() diff --git a/components/esp_rom/esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld b/components/esp_rom/esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld index a773811f3..9c2e2419f 100644 --- a/components/esp_rom/esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld +++ b/components/esp_rom/esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld @@ -7,10 +7,14 @@ PROVIDE ( g_ticks_per_us_pro = g_ticks_per_us ); PROVIDE ( g_rom_flashchip = SPI_flashchip_data ); PROVIDE ( g_rom_spiflash_chip = SPI_flashchip_data ); PROVIDE ( esp_rom_spiflash_config_param = SPIParamCfg ); +PROVIDE ( esp_rom_spiflash_read = SPIRead ); PROVIDE ( esp_rom_spiflash_read_status = SPI_read_status ); PROVIDE ( esp_rom_spiflash_read_statushigh = SPI_read_status_high ); PROVIDE ( esp_rom_spiflash_read_user_cmd = SPI_user_command_read ); -PROVIDE ( esp_rom_spiflash_write_encrypted_disable = SPI_Write_Encrypt_Disable); +PROVIDE ( esp_rom_spiflash_write = SPIWrite ); +PROVIDE ( esp_rom_spiflash_write_encrypted_disable = SPI_Write_Encrypt_Disable ); PROVIDE ( esp_rom_spiflash_write_encrypted_enable = SPI_Write_Encrypt_Enable ); -PROVIDE ( esp_rom_spiflash_config_clk = SPIClkConfig); -PROVIDE ( esp_rom_spiflash_select_qio_pins = SelectSpiQIO); +PROVIDE ( esp_rom_spiflash_config_clk = SPIClkConfig ); +PROVIDE ( esp_rom_spiflash_select_qio_pins = SelectSpiQIO ); +PROVIDE ( esp_rom_spiflash_unlock = SPIUnlock ); +PROVIDE ( esp_rom_spiflash_erase_sector = SPIEraseSector ); diff --git a/components/esp_rom/include/esp32s2beta/rom/cache.h b/components/esp_rom/include/esp32s2beta/rom/cache.h index 61473eb07..234ec3d08 100644 --- a/components/esp_rom/include/esp32s2beta/rom/cache.h +++ b/components/esp_rom/include/esp32s2beta/rom/cache.h @@ -15,6 +15,7 @@ #ifndef _ROM_CACHE_H_ #define _ROM_CACHE_H_ +#include "esp_bit_defs.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_rom/include/esp32s2beta/rom/lldesc.h b/components/esp_rom/include/esp32s2beta/rom/lldesc.h index d027362a5..ae5b4160b 100644 --- a/components/esp_rom/include/esp32s2beta/rom/lldesc.h +++ b/components/esp_rom/include/esp32s2beta/rom/lldesc.h @@ -17,7 +17,7 @@ #include -#include "queue.h" +#include "sys/queue.h" #ifdef __cplusplus extern "C" { @@ -53,8 +53,8 @@ extern "C" { #endif /* !ESP_MAC_5 */ /* * SLC2 DMA Desc struct, aka lldesc_t - * - * -------------------------------------------------------------- + * + * -------------------------------------------------------------- * | own | EoF | sub_sof | 5'b0 | length [11:0] | size [11:0] | * -------------------------------------------------------------- * | buf_ptr [31:0] | @@ -139,12 +139,12 @@ static inline uint32_t lldesc_get_chain_length(lldesc_t *head) { lldesc_t *ds = head; uint32_t len = 0; - + while (ds) { len += ds->length; ds = STAILQ_NEXT(ds, qe); } - + return len; } diff --git a/components/esp_rom/include/esp32s2beta/rom/rsa_pss.h b/components/esp_rom/include/esp32s2beta/rom/rsa_pss.h index 51e2c867c..cd6218f7f 100644 --- a/components/esp_rom/include/esp32s2beta/rom/rsa_pss.h +++ b/components/esp_rom/include/esp32s2beta/rom/rsa_pss.h @@ -16,7 +16,6 @@ #define _ROM_RSA_PSS_H_ #include -#include "rom/rsa_pss.h" #define ETS_SIG_LEN 384 /* Bytes */ #define ETS_DIGEST_LEN 32 /* SHA-256, bytes */ diff --git a/components/esp_rom/include/esp32s2beta/rom/secure_boot.h b/components/esp_rom/include/esp32s2beta/rom/secure_boot.h index 521c795f3..6ee9574bc 100644 --- a/components/esp_rom/include/esp32s2beta/rom/secure_boot.h +++ b/components/esp_rom/include/esp32s2beta/rom/secure_boot.h @@ -16,7 +16,7 @@ #define _ROM_SECURE_BOOT_H_ #include -#include "rom/rsa_pss.h" +#include "rsa_pss.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_rom/include/esp32s2beta/rom/sha.h b/components/esp_rom/include/esp32s2beta/rom/sha.h index 8b031d92a..f04e9aec5 100644 --- a/components/esp_rom/include/esp32s2beta/rom/sha.h +++ b/components/esp_rom/include/esp32s2beta/rom/sha.h @@ -24,7 +24,7 @@ #include #include -#include "rom/ets_sys.h" +#include "ets_sys.h" #ifdef __cplusplus extern "C" { diff --git a/components/ethernet/CMakeLists.txt b/components/ethernet/CMakeLists.txt index db4e8f672..704d21a7d 100644 --- a/components/ethernet/CMakeLists.txt +++ b/components/ethernet/CMakeLists.txt @@ -1,5 +1,3 @@ -require_idf_targets(esp32) - set(COMPONENT_SRCS "emac_dev.c" "emac_main.c" "eth_phy/phy_common.c" diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index 9aaebdae5..2fdd3cc55 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -3,6 +3,7 @@ menu "FreeRTOS" # This is actually also handled in the ESP32 startup code, not only in FreeRTOS. config FREERTOS_UNICORE bool "Run FreeRTOS only on first core" + default y if IDF_TARGET_ESP32S2BETA default n help This version of FreeRTOS normally takes control of all cores of @@ -13,6 +14,7 @@ menu "FreeRTOS" # This invisible config value sets the value of tskNO_AFFINITY in task.h. # Intended to be used as a constant from other Kconfig files. # Value is (32-bit) INT_MAX. + config FREERTOS_NO_AFFINITY hex default 0x7FFFFFFF diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index ca028b99f..7d401d06c 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -126,8 +126,8 @@ if(CONFIG_LWIP_PPP_SUPPORT) "lwip/src/netif/ppp/polarssl/sha1.c") endif() -set(COMPONENT_REQUIRES vfs esp_wifi) -set(COMPONENT_PRIV_REQUIRES ethernet tcpip_adapter nvs_flash) +set(COMPONENT_REQUIRES vfs esp_wifi ethernet) +set(COMPONENT_PRIV_REQUIRES tcpip_adapter nvs_flash) set(COMPONENT_ADD_LDFRAGMENTS linker.lf) diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index 3b5d84ebc..bae7e2fbd 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -9,16 +9,14 @@ if(EXISTS "${COMPONENT_DIR}/${soc_name}") endif() list(APPEND COMPONENT_ADD_INCLUDEDIRS include) -list(APPEND COMPONENT_SRCS "src/memory_layout_utils.c" - "src/lldesc.c" - "src/hal/spi_hal.c" - "src/hal/spi_hal_iram.c" - "src/hal/spi_slave_hal.c" - "src/hal/spi_slave_hal_iram.c" - "src/soc_include_legacy_warn.c" - ) +if(NOT BOOTLOADER_BUILD) + list(APPEND COMPONENT_SRCS "src/memory_layout_utils.c" + "src/lldesc.c src/hal/spi_hal.c" + "src/hal/spi_hal_iram.c" + "src/soc_include_legacy_warn.c") -set(COMPONENT_ADD_LDFRAGMENTS linker.lf) + set(COMPONENT_ADD_LDFRAGMENTS linker.lf) +endif() set(COMPONENT_REQUIRES) diff --git a/components/soc/esp32s2beta/include/soc/cpu.h b/components/soc/esp32s2beta/include/soc/cpu.h index 05ec91776..e88170085 100644 --- a/components/soc/esp32s2beta/include/soc/cpu.h +++ b/components/soc/esp32s2beta/include/soc/cpu.h @@ -51,6 +51,13 @@ static inline void cpu_write_itlb(unsigned vpn, unsigned attr) asm volatile ("witlb %1, %0; isync\n" :: "r" (vpn), "r" (attr)); } +static inline void cpu_init_memctl() +{ +#if XCHAL_ERRATUM_572 +#error "Shouldn't have this errata or need this call on esp32s2beta" +#endif +} + /** * @brief Configure memory region protection * diff --git a/components/soc/esp32s2beta/include/soc/dport_access.h b/components/soc/esp32s2beta/include/soc/dport_access.h index bee3da39e..eee914e32 100644 --- a/components/soc/esp32s2beta/include/soc/dport_access.h +++ b/components/soc/esp32s2beta/include/soc/dport_access.h @@ -17,7 +17,7 @@ #include #include "esp_attr.h" -#include "esp_dport_access.h" +#include "esp32s2beta/dport_access.h" #include "soc.h" #include "uart_reg.h" #include "xtensa/xtruntime.h" diff --git a/components/soc/esp32s2beta/include/soc/gpio_pins.h b/components/soc/esp32s2beta/include/soc/gpio_pins.h new file mode 100644 index 000000000..da8cd2ebe --- /dev/null +++ b/components/soc/esp32s2beta/include/soc/gpio_pins.h @@ -0,0 +1,28 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _GPIO_PINS_H +#define _GPIO_PINS_H +#ifdef __cplusplus +extern "C" +{ +#endif + +#define GPIO_PIN_COUNT 48 + +#ifdef __cplusplus +} +#endif + +#endif // _GPIO_PINS_H diff --git a/components/soc/esp32s2beta/include/soc/soc.h b/components/soc/esp32s2beta/include/soc/soc.h index d00ae1c47..d349e863b 100644 --- a/components/soc/esp32s2beta/include/soc/soc.h +++ b/components/soc/esp32s2beta/include/soc/soc.h @@ -279,6 +279,8 @@ #define SOC_IROM_HIGH 0x40c00000 #define SOC_IRAM_LOW 0x40020000 #define SOC_IRAM_HIGH 0x40070000 +#define SOC_DRAM_LOW 0x3FFD0000 +#define SOC_DRAM_HIGH 0x3FF80000 // TODO: check RAM ranges #define SOC_RTC_IRAM_LOW 0x40070000 #define SOC_RTC_IRAM_HIGH 0x40072000 #define SOC_RTC_DRAM_LOW 0x3ff9e000 diff --git a/components/soc/esp32s2beta/rtc_clk.c b/components/soc/esp32s2beta/rtc_clk.c index e14bcc158..6de4c8547 100644 --- a/components/soc/esp32s2beta/rtc_clk.c +++ b/components/soc/esp32s2beta/rtc_clk.c @@ -16,10 +16,10 @@ #include #include #include -#include "rom/ets_sys.h" -#include "rom/rtc.h" -#include "rom/uart.h" -#include "rom/gpio.h" +#include "esp32s2beta/rom/ets_sys.h" +#include "esp32s2beta/rom/rtc.h" +#include "esp32s2beta/rom/uart.h" +#include "esp32s2beta/rom/gpio.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" #include "soc/rtc_io_reg.h" @@ -201,8 +201,8 @@ void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en) SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M); REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT); } - /* d256 should be independent configured with 8M - * Maybe we can split this function into 8m and dmd256 + /* d256 should be independent configured with 8M + * Maybe we can split this function into 8m and dmd256 */ if (d256_en) { CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV); @@ -226,7 +226,7 @@ void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1); REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0); - /* BIAS I2C not exist any more, but not sure how to get the same effect yet... + /* BIAS I2C not exist any more, but not sure how to get the same effect yet... * if (!enable && * REG_GET_FIELD(SYSCON_SYSCLK_CONF_REG, SYSCON_SOC_CLK_SEL) != SYSCON_SOC_CLK_SEL_PLL) { * REG_SET_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD); @@ -236,7 +236,7 @@ void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm */ if (enable) { - /* no need to differentiate ECO chip any more + /* no need to differentiate ECO chip any more uint8_t sdm_stop_val_2 = APLL_SDM_STOP_VAL_2_REV1; uint32_t is_rev0 = (GET_PERI_REG_BITS2(EFUSE_BLK0_RDATA3_REG, 1, 15) == 0); if (is_rev0) { @@ -427,7 +427,7 @@ void rtc_clk_bbpll_set(rtc_xtal_freq_t xtal_freq, rtc_pll_t pll_freq) ets_delay_us(1); } */ - ets_delay_us(50000); + ets_delay_us(50000); } /** @@ -458,9 +458,9 @@ static void rtc_clk_cpu_freq_to_pll(rtc_cpu_freq_t cpu_freq) { int freq = 0; if ((s_cur_pll == RTC_PLL_NONE) || ((s_cur_pll == RTC_PLL_320M) && (cpu_freq == RTC_CPU_FREQ_240M))) { - /* + /* * if switch from non-pll or switch from PLL 320M to 480M - * need to switch PLLs, fall back to full implementation + * need to switch PLLs, fall back to full implementation */ rtc_clk_cpu_freq_set(cpu_freq); return; @@ -528,7 +528,6 @@ void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq) /* may need equivalent function uint32_t apll_fpd = REG_GET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD); - * if (apll_fpd) { * SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD); * } @@ -556,16 +555,16 @@ void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq) rtc_clk_bbpll_set(xtal_freq, RTC_PLL_480M); s_cur_pll = RTC_PLL_480M; } - + if ((cpu_freq == RTC_CPU_FREQ_80M) || (cpu_freq == RTC_CPU_320M_80M)) { DPORT_REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 0); - ets_update_cpu_frequency(80); + ets_update_cpu_frequency(80); } else if ((cpu_freq == RTC_CPU_FREQ_160M) || (cpu_freq == RTC_CPU_320M_160M)) { DPORT_REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 1); ets_update_cpu_frequency(160); } else if (cpu_freq == RTC_CPU_FREQ_240M) { DPORT_REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 2); - ets_update_cpu_frequency(240); + ets_update_cpu_frequency(240); } REG_SET_FIELD(SYSCON_SYSCLK_CONF_REG, SYSCON_SOC_CLK_SEL, SYSCON_SOC_CLK_SEL_PLL); //rtc_clk_wait_for_slow_cycle(); @@ -752,7 +751,6 @@ void rtc_clk_8m_divider_set(uint32_t div) void rtc_clk_init(rtc_clk_config_t cfg) { rtc_cpu_freq_t cpu_source_before = rtc_clk_cpu_freq_get(); - /* If we get a TG WDT system reset while running at 240MHz, * DPORT_CPUPERIOD_SEL register will be reset to 0 resulting in 120MHz * APB and CPU frequencies after reset. This will cause issues with XTAL @@ -816,8 +814,8 @@ void rtc_clk_init(rtc_clk_config_t cfg) rtc_clk_apb_freq_update(xtal_freq * MHZ); /* Set CPU frequency */ rtc_clk_cpu_freq_set(cfg.cpu_freq); - - /* Re-calculate the ccount to make time calculation correct. */ + + /* Re-calculate the ccount to make time calculation correct. */ uint32_t freq_before = rtc_clk_cpu_freq_value(cpu_source_before) / MHZ; uint32_t freq_after = rtc_clk_cpu_freq_value(cfg.cpu_freq) / MHZ; XTHAL_SET_CCOUNT( XTHAL_GET_CCOUNT() * freq_after / freq_before ); diff --git a/components/soc/esp32s2beta/rtc_sleep.c b/components/soc/esp32s2beta/rtc_sleep.c index bef529005..ff8dff1c2 100644 --- a/components/soc/esp32s2beta/rtc_sleep.c +++ b/components/soc/esp32s2beta/rtc_sleep.c @@ -25,7 +25,7 @@ #include "soc/nrx_reg.h" #include "soc/fe_reg.h" #include "soc/rtc.h" -#include "rom/ets_sys.h" +#include "esp32s2beta/rom/ets_sys.h" #define MHZ (1000000) @@ -55,7 +55,7 @@ void rtc_sleep_pd(rtc_sleep_pd_config_t cfg) void rtc_sleep_init(rtc_sleep_config_t cfg) { - /* Already defined in rtc init + /* Already defined in rtc init // set 5 PWC state machine times to fit in main state machine time REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP); REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, RTC_CNTL_XTL_BUF_WAIT_SLP); @@ -68,7 +68,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) rtc_sleep_pd(pd_cfg); } - /* This option seems to be unneccessary + /* This option seems to be unneccessary if (cfg.rtc_mem_inf_fpu) { SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_PU); } else { @@ -120,10 +120,10 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) /* redundant ? People may not want to touch such registers after init CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_ISO | RTC_CNTL_DG_PAD_FORCE_NOISO); - + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_FORCE_PU | RTC_CNTL_DG_WRAP_FORCE_PD); - + #ifdef CONFIG_CHIP_IS_ESP32 CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_FORCE_NOSLEEP); #endif diff --git a/components/soc/esp32s2beta/rtc_time.c b/components/soc/esp32s2beta/rtc_time.c index 8011611a4..e276341f2 100644 --- a/components/soc/esp32s2beta/rtc_time.c +++ b/components/soc/esp32s2beta/rtc_time.c @@ -13,7 +13,7 @@ // limitations under the License. #include -#include "rom/ets_sys.h" +#include "esp32s2beta/rom/ets_sys.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" #include "soc/timer_group_reg.h" @@ -68,7 +68,6 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) expected_freq = 150000; } uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); - /* Start calibration */ CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); diff --git a/components/soc/esp32s2beta/sources.cmake b/components/soc/esp32s2beta/sources.cmake index 35eb8810c..46acf7eb5 100644 --- a/components/soc/esp32s2beta/sources.cmake +++ b/components/soc/esp32s2beta/sources.cmake @@ -1,4 +1,5 @@ -set(SOC_SRCS "rtc_clk.c" +set(SOC_SRCS "cpu_util.c" + "rtc_clk.c" "rtc_init.c" "rtc_pm.c" "rtc_sleep.c" diff --git a/components/soc/include/soc/soc_memory_layout.h b/components/soc/include/soc/soc_memory_layout.h index 86c5e0f72..f9240848a 100644 --- a/components/soc/include/soc/soc_memory_layout.h +++ b/components/soc/include/soc/soc_memory_layout.h @@ -164,7 +164,7 @@ inline static bool IRAM_ATTR esp_ptr_byte_accessible(const void *p) bool r; r = (ip >= SOC_BYTE_ACCESSIBLE_LOW && ip < SOC_BYTE_ACCESSIBLE_HIGH); #if CONFIG_ESP32_SPIRAM_SUPPORT && CONFIG_SPIRAM_SIZE -// ToDo: Use SOC_EXTRAM_DATA_HIGH if CONFIG_SPIRAM_SIZE is -1 (ie max possible SPIRAM size) + // ToDo: Use SOC_EXTRAM_DATA_HIGH if CONFIG_SPIRAM_SIZE is -1 (ie max possible SPIRAM size) r |= (ip >= SOC_EXTRAM_DATA_LOW && ip < (SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE)); #endif return r; @@ -183,7 +183,7 @@ inline static bool IRAM_ATTR esp_ptr_external_ram(const void *p) { } inline static bool IRAM_ATTR esp_ptr_in_iram(const void *p) { -#ifndef CONFIG_FREERTOS_UNICORE +#if !CONFIG_FREERTOS_UNICORE || CONFIG_IDF_TARGET_ESP32S2BETA return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH); #else return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH); diff --git a/components/soc/include/soc/spi_periph.h b/components/soc/include/soc/spi_periph.h index 88bc64353..1a4104f52 100644 --- a/components/soc/include/soc/spi_periph.h +++ b/components/soc/include/soc/spi_periph.h @@ -16,12 +16,14 @@ #include #include "soc/soc.h" #include "soc/periph_defs.h" -//include soc related (generated) definitions #include "soc/spi_pins.h" #include "soc/spi_reg.h" #include "soc/spi_struct.h" #include "soc/gpio_sig_map.h" #include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32S2BETA +#include "soc/spi_mem_struct.h" +#endif #ifdef __cplusplus extern "C" diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index db8fceee0..43bf49003 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -1,9 +1,11 @@ if(BOOTLOADER_BUILD) - # Bootloader needs SPIUnlock from this file, but doesn't - # need other parts of this component - set(COMPONENT_SRCS "spi_flash_rom_patch.c") - set(COMPONENT_PRIV_REQUIRES bootloader_support soc) -else() + if (CONFIG_IDF_TARGET_ESP32) + # ESP32 Bootloader needs SPIUnlock from this file, but doesn't + # need other parts of this component + set(COMPONENT_SRCS "spi_flash_rom_patch.c") + set(COMPONENT_PRIV_REQUIRES bootloader_support soc) + endif() +else() # not BOOTLOADER_BUILD set(COMPONENT_SRCS "cache_utils.c" "flash_mmap.c" "flash_ops.c" diff --git a/components/xtensa/CMakeLists.txt b/components/xtensa/CMakeLists.txt index 9044f14ae..31cbb2703 100644 --- a/components/xtensa/CMakeLists.txt +++ b/components/xtensa/CMakeLists.txt @@ -1,4 +1,6 @@ -set(COMPONENT_SRCS "eri.c" "trax.c") +if(NOT BOOTLOADER_BUILD) + set(COMPONENT_SRCS "eri.c" "trax.c") +endif() set(COMPONENT_ADD_INCLUDEDIRS "include" "${IDF_TARGET}/include") @@ -7,4 +9,6 @@ set(COMPONENT_PRIV_REQUIRES soc) register_component() -target_link_libraries(${COMPONENT_LIB} "${CMAKE_CURRENT_SOURCE_DIR}/${IDF_TARGET}/libhal.a") +if (NOT BOOTLOADER_BUILD) + target_link_libraries(${COMPONENT_LIB} "${CMAKE_CURRENT_SOURCE_DIR}/${IDF_TARGET}/libhal.a") +endif() diff --git a/components/esp32/include/esp_attr.h b/components/xtensa/include/esp_attr.h similarity index 100% rename from components/esp32/include/esp_attr.h rename to components/xtensa/include/esp_attr.h diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index 4e64c1620..8a020dc1b 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -130,6 +130,9 @@ endfunction() # Automatically adds a -L search path for the containing directory (if found), # and then adds -T with the filename only. This allows INCLUDE directives to be # used to include other linker scripts in the same directory. +# +# TODO: currently multiple linker scripts must be supplied as a single list for "scriptfiles" +# arg, cannot be supplied as list of args function(target_linker_script target scriptfiles) cmake_parse_arguments(_ "PROCESS" "" "" ${ARGN}) foreach(scriptfile ${scriptfiles})