diff --git a/Kconfig b/Kconfig index 09cc488f4d..7036d12324 100644 --- a/Kconfig +++ b/Kconfig @@ -141,13 +141,15 @@ mainmenu "Espressif IoT Development Framework Configuration" Another option, useful for only very small and limited applications, is to only link the .elf file of the application, such that it can be loaded directly into RAM over - JTAG. Note that since IRAM and DRAM sizes are very limited, it is not possible to - build any complex application this way. However for kinds of testing and debugging, + JTAG or UART. Note that since IRAM and DRAM sizes are very limited, it is not possible + to build any complex application this way. However for some kinds of testing and debugging, this option may provide faster iterations, since the application does not need to be written into flash. - Note that at the moment, ESP-IDF does not contain all the startup code required to - initialize the CPUs and ROM memory (data/bss). Therefore it is necessary to execute - a bit of ROM code prior to executing the application. A gdbinit file may look as follows (for ESP32): + + Note: when APP_BUILD_TYPE_RAM is selected and loaded with JTAG, ESP-IDF does not contain + all the startup code required to initialize the CPUs and ROM memory (data/bss). + Therefore it is necessary to execute a bit of ROM code prior to executing the application. + A gdbinit file may look as follows (for ESP32): # Connect to a running instance of OpenOCD target remote :3333 @@ -169,11 +171,18 @@ mainmenu "Espressif IoT Development Framework Configuration" Example gdbinit files for other targets can be found in tools/test_apps/system/gdb_loadable_elf/ + When loading the BIN with UART, the ROM will jump to ram and run the app after finishing the ROM + startup code, so there's no additional startup initialization required. You can use the + `load_ram` in esptool.py to load the generated .bin file into ram and execute. + + Example: + esptool.py --chip {chip} -p {port} -b {baud} --no-stub load_ram {app.bin} + Recommended sdkconfig.defaults for building loadable ELF files is as follows. - CONFIG_APP_BUILD_TYPE_ELF_RAM is required, other options help reduce application + CONFIG_APP_BUILD_TYPE_RAM is required, other options help reduce application memory footprint. - CONFIG_APP_BUILD_TYPE_ELF_RAM=y + CONFIG_APP_BUILD_TYPE_RAM=y CONFIG_VFS_SUPPORT_TERMIOS= CONFIG_NEWLIB_NANO_FORMAT=y CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y @@ -189,9 +198,11 @@ mainmenu "Espressif IoT Development Framework Configuration" select APP_BUILD_BOOTLOADER select APP_BUILD_USE_FLASH_SECTIONS - config APP_BUILD_TYPE_ELF_RAM + config APP_BUILD_TYPE_RAM bool - prompt "ELF file, loadable into RAM (EXPERIMENTAL))" + prompt "Build app runs entirely in RAM (EXPERIMENTAL)" + select APP_BUILD_GENERATE_BINARIES + endchoice # APP_BUILD_TYPE # Hidden options, set according to the choice above @@ -201,6 +212,16 @@ mainmenu "Espressif IoT Development Framework Configuration" config APP_BUILD_BOOTLOADER bool # Whether to build the bootloader + config APP_BUILD_TYPE_PURE_RAM_APP + bool + prompt "Build app without SPI_FLASH/PSRAM support (saves ram)" + depends on APP_BUILD_TYPE_RAM + help + If this option is enabled, external memory and related peripherals, such as Cache, MMU, + Flash and PSRAM, won't be initialized. Corresponding drivers won't be introduced either. + Components that depend on the spi_flash component will also be unavailable, such as + app_update, etc. When this option is enabled, about 26KB of RAM space can be saved. + config APP_BUILD_USE_FLASH_SECTIONS bool # Whether to place code/data into memory-mapped flash sections @@ -258,7 +279,7 @@ mainmenu "Espressif IoT Development Framework Configuration" bool depends on IDF_TARGET_ESP32 default y if APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS - default y if APP_BUILD_TYPE_ELF_RAM + default y if APP_BUILD_TYPE_RAM endmenu # Build type diff --git a/components/bootloader_support/CMakeLists.txt b/components/bootloader_support/CMakeLists.txt index cd2e1eac74..3651258380 100644 --- a/components/bootloader_support/CMakeLists.txt +++ b/components/bootloader_support/CMakeLists.txt @@ -2,21 +2,31 @@ set(srcs "src/bootloader_common.c" "src/bootloader_common_loader.c" "src/bootloader_clock_init.c" - "bootloader_flash/src/bootloader_flash.c" "src/bootloader_mem.c" "src/bootloader_random.c" "src/bootloader_random_${IDF_TARGET}.c" - "src/bootloader_utility.c" - "src/esp_image_format.c" + "src/bootloader_efuse.c" "src/flash_encrypt.c" "src/secure_boot.c" - "src/flash_partitions.c" - "bootloader_flash/src/flash_qio_mode.c" - "bootloader_flash/src/bootloader_flash_config_${IDF_TARGET}.c" - "src/bootloader_efuse.c" ) -if(BOOTLOADER_BUILD) +if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + list(APPEND srcs + "bootloader_flash/src/bootloader_flash.c" + "bootloader_flash/src/flash_qio_mode.c" + "bootloader_flash/src/bootloader_flash_config_${IDF_TARGET}.c" + ) +endif() + +if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) + list(APPEND srcs + "src/bootloader_utility.c" + "src/flash_partitions.c" + "src/esp_image_format.c" + ) +endif() + +if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_RAM) set(include_dirs "include" "bootloader_flash/include" "private_include") set(priv_requires micro-ecc spi_flash efuse esp_app_format) @@ -25,7 +35,6 @@ if(BOOTLOADER_BUILD) "src/bootloader_clock_loader.c" "src/bootloader_console.c" "src/bootloader_console_loader.c" - "src/bootloader_panic.c" "src/${IDF_TARGET}/bootloader_sha.c" "src/${IDF_TARGET}/bootloader_soc.c" "src/${IDF_TARGET}/bootloader_${IDF_TARGET}.c" @@ -41,6 +50,7 @@ else() endif() if(BOOTLOADER_BUILD) + list(APPEND srcs "src/bootloader_panic.c") if(CONFIG_SECURE_FLASH_ENC_ENABLED) list(APPEND srcs "src/flash_encryption/flash_encrypt.c" "src/${IDF_TARGET}/flash_encryption_secure_features.c") diff --git a/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h b/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h new file mode 100644 index 0000000000..4bff3f9dea --- /dev/null +++ b/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize spi_flash in bootloader and print flash info + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t bootloader_init_spi_flash(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index 26994f7291..da0b959e96 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -61,7 +61,7 @@ uint32_t bootloader_mmap_get_free_pages(void) const void *bootloader_mmap(uint32_t src_addr, uint32_t size) { if (map) { - ESP_LOGE(TAG, "tried to bootloader_mmap twice"); + ESP_EARLY_LOGE(TAG, "tried to bootloader_mmap twice"); return NULL; /* existing mapping in use... */ } const void *result = NULL; @@ -69,7 +69,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) 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) { - ESP_LOGE(TAG, "spi_flash_mmap failed: 0x%x", err); + ESP_EARLY_LOGE(TAG, "spi_flash_mmap failed: 0x%x", err); return NULL; } return (void *)((intptr_t)result + (src_addr - src_page)); @@ -334,15 +334,15 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size, bool allow_decrypt) { if (src_addr & 3) { - ESP_LOGE(TAG, "bootloader_flash_read src_addr 0x%x not 4-byte aligned", src_addr); + ESP_EARLY_LOGE(TAG, "bootloader_flash_read src_addr 0x%x not 4-byte aligned", src_addr); return ESP_FAIL; } if (size & 3) { - ESP_LOGE(TAG, "bootloader_flash_read size 0x%x not 4-byte aligned", size); + ESP_EARLY_LOGE(TAG, "bootloader_flash_read size 0x%x not 4-byte aligned", size); return ESP_FAIL; } if ((intptr_t)dest & 3) { - ESP_LOGE(TAG, "bootloader_flash_read dest 0x%x not 4-byte aligned", (intptr_t)dest); + ESP_EARLY_LOGE(TAG, "bootloader_flash_read dest 0x%x not 4-byte aligned", (intptr_t)dest); return ESP_FAIL; } @@ -358,15 +358,15 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool esp_err_t err; size_t alignment = write_encrypted ? 32 : 4; if ((dest_addr % alignment) != 0) { - ESP_LOGE(TAG, "bootloader_flash_write dest_addr 0x%x not %d-byte aligned", dest_addr, alignment); + ESP_EARLY_LOGE(TAG, "bootloader_flash_write dest_addr 0x%x not %d-byte aligned", dest_addr, alignment); return ESP_FAIL; } if ((size % alignment) != 0) { - ESP_LOGE(TAG, "bootloader_flash_write size 0x%x not %d-byte aligned", size, alignment); + ESP_EARLY_LOGE(TAG, "bootloader_flash_write size 0x%x not %d-byte aligned", size, alignment); return ESP_FAIL; } if (((intptr_t)src % 4) != 0) { - ESP_LOGE(TAG, "bootloader_flash_write src 0x%x not 4 byte aligned", (intptr_t)src); + ESP_EARLY_LOGE(TAG, "bootloader_flash_write src 0x%x not 4 byte aligned", (intptr_t)src); return ESP_FAIL; } @@ -650,7 +650,7 @@ esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode) #define XMC_VENDOR_ID 0x20 #if BOOTLOADER_BUILD -#define BOOTLOADER_FLASH_LOG(level, ...) ESP_LOG##level(TAG, ##__VA_ARGS__) +#define BOOTLOADER_FLASH_LOG(level, ...) ESP_EARLY_LOG##level(TAG, ##__VA_ARGS__) #else static DRAM_ATTR char bootloader_flash_tag[] = "bootloader_flash"; #define BOOTLOADER_FLASH_LOG(level, ...) ESP_DRAM_LOG##level(bootloader_flash_tag, ##__VA_ARGS__) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c index 9bda18434d..405d5c4582 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c @@ -12,6 +12,7 @@ #include "esp_rom_gpio.h" #include "esp_rom_efuse.h" #include "esp32/rom/spi_flash.h" +#include "esp32/rom/cache.h" #include "soc/gpio_periph.h" #include "soc/efuse_reg.h" #include "soc/spi_reg.h" @@ -23,6 +24,15 @@ #include "flash_qio_mode.h" #include "bootloader_common.h" #include "bootloader_flash_config.h" +#include "bootloader_flash_priv.h" +#include "bootloader_init.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_flash_update_id(void) { @@ -183,3 +193,187 @@ int bootloader_flash_get_wp_pin(void) } #endif } + +static const char *TAG = "boot.esp32"; + +void bootloader_configure_spi_pins(int drv) +{ + uint32_t pkg_ver = bootloader_common_get_chip_ver_pkg(); + + if (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_ESP32PICOV302) { + // For ESP32D2WD or ESP32-PICO series,the SPI pins are already configured + // flash clock signal should come from IO MUX. + gpio_hal_iomux_func_sel(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 = esp_rom_efuse_get_flash_gpio_info(); + if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) { + esp_rom_gpio_connect_out_signal(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0); + esp_rom_gpio_connect_out_signal(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0); + esp_rom_gpio_connect_in_signal(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0); + esp_rom_gpio_connect_in_signal(FLASH_SPID_IO, SPID_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0); + esp_rom_gpio_connect_in_signal(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0); + esp_rom_gpio_connect_in_signal(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0); + //select pin function gpio + gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO); + // flash clock signal should come from IO MUX. + // set drive ability for clock + gpio_hal_iomux_func_sel(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 + } + } +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->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); + // 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 + Cache_Flush(0); + Cache_Read_Enable(0); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0)); + if (spi_ctrl & SPI_FREAD_QIO) { + str = "QIO"; + } else if (spi_ctrl & SPI_FREAD_QUAD) { + str = "QOUT"; + } else if (spi_ctrl & SPI_FREAD_DIO) { + str = "DIO"; + } else if (spi_ctrl & SPI_FREAD_DUAL) { + str = "DOUT"; + } else if (spi_ctrl & SPI_FASTRD_MODE) { + str = "FAST READ"; + } else { + str = "SLOW READ"; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_flash_gpio_config(&bootloader_image_hdr); + bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_flash_cs_timing_config(); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); +#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { + ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); + return ESP_FAIL; + } +#endif + + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c index 809ab48e09..a18ccbd519 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c @@ -9,6 +9,7 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_rom_gpio.h" #include "esp32c2/rom/gpio.h" #include "esp32c2/rom/spi_flash.h" #include "esp32c2/rom/efuse.h" @@ -20,6 +21,11 @@ #include "flash_qio_mode.h" #include "bootloader_flash_config.h" #include "bootloader_common.h" +#include "bootloader_flash_priv.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" +#include "hal/mmu_ll.h" #define FLASH_IO_MATRIX_DUMMY_40M 0 #define FLASH_IO_MATRIX_DUMMY_80M 0 @@ -70,3 +76,168 @@ void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) bootloader_configure_spi_pins(1); bootloader_flash_set_dummy_out(); } + +static const char *TAG = "boot.esp32c2"; + + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + // IDF-4066 + const uint32_t spiconfig = 0; + uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; + uint8_t q_gpio_num = SPI_Q_GPIO_NUM; + uint8_t d_gpio_num = SPI_D_GPIO_NUM; + uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; + uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; + uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; + if (spiconfig == 0) { + + } + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + } + if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); + } +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); + // Set flash chip size + esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode + cache_hal_enable(CACHE_TYPE_ALL); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "30MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "15MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "60MHz"; + break; + default: + str = "15MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + 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"; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void bootloader_print_mmu_page_size(void) +{ + mmu_page_size_t page_size = mmu_ll_get_page_size(0); + int size = (page_size == MMU_PAGE_16KB ? 16 : + page_size == MMU_PAGE_32KB ? 32 : + page_size == MMU_PAGE_64KB ? 64 : 0); + ESP_EARLY_LOGI(TAG, "MMU Page Size : %dK", size); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_flash_cs_timing_config(); +} + +static void bootloader_spi_flash_resume(void) +{ + bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); + esp_rom_spiflash_wait_idle(&g_rom_flashchip); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + bootloader_print_mmu_page_size(); + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c index 52aecec883..b89eaa4a86 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c @@ -9,6 +9,8 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" #include "esp32c3/rom/gpio.h" #include "esp32c3/rom/spi_flash.h" #include "esp32c3/rom/efuse.h" @@ -20,6 +22,11 @@ #include "flash_qio_mode.h" #include "bootloader_flash_config.h" #include "bootloader_common.h" +#include "bootloader_flash_priv.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" +#include "hal/mmu_ll.h" #define FLASH_IO_MATRIX_DUMMY_40M 0 #define FLASH_IO_MATRIX_DUMMY_80M 0 @@ -73,3 +80,172 @@ void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) bootloader_configure_spi_pins(1); bootloader_flash_set_dummy_out(); } + +static const char *TAG = "boot.esp32c3"; + + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio(); + uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; + uint8_t q_gpio_num = SPI_Q_GPIO_NUM; + uint8_t d_gpio_num = SPI_D_GPIO_NUM; + uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; + uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; + uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; + if (spiconfig == 0) { + + } else { + clk_gpio_num = spiconfig & 0x3f; + q_gpio_num = (spiconfig >> 6) & 0x3f; + d_gpio_num = (spiconfig >> 12) & 0x3f; + cs0_gpio_num = (spiconfig >> 18) & 0x3f; + hd_gpio_num = (spiconfig >> 24) & 0x3f; + wp_gpio_num = wp_pin; + } + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + } + if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); + } +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); + // Set flash chip size + esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode + cache_hal_enable(CACHE_TYPE_ALL); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + 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"; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_flash_cs_timing_config(); +} + +static void bootloader_spi_flash_resume(void) +{ + bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); + esp_rom_spiflash_wait_idle(&g_rom_flashchip); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); +#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { + ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); + return ESP_FAIL; + } +#endif + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c index 8fc1806ccd..a3bfb4607d 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,8 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" #include "esp32c6/rom/gpio.h" #include "esp32c6/rom/spi_flash.h" #include "esp32c6/rom/efuse.h" @@ -20,6 +22,11 @@ #include "flash_qio_mode.h" #include "bootloader_flash_config.h" #include "bootloader_common.h" +#include "bootloader_flash_priv.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" +#include "hal/mmu_ll.h" void bootloader_flash_update_id() { @@ -55,3 +62,147 @@ void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr) } esp_rom_spiflash_config_clk(spi_clk_div, 0); } + +static const char *TAG = "boot.esp32c6"; + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; + uint8_t q_gpio_num = SPI_Q_GPIO_NUM; + uint8_t d_gpio_num = SPI_D_GPIO_NUM; + uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; + uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; + uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); + // Set flash chip size + esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode + cache_hal_enable(CACHE_TYPE_ALL); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + 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"; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_configure_spi_pins(1); + bootloader_flash_cs_timing_config(); +} + +static void bootloader_spi_flash_resume(void) +{ + bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); + esp_rom_spiflash_wait_idle(&g_rom_flashchip); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c index ae5e8a96cd..147be37990 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,8 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" #include "esp32h2/rom/gpio.h" #include "esp32h2/rom/spi_flash.h" #include "esp32h2/rom/efuse.h" @@ -20,6 +22,11 @@ #include "flash_qio_mode.h" #include "bootloader_flash_config.h" #include "bootloader_common.h" +#include "bootloader_flash_priv.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" +#include "hal/mmu_ll.h" void bootloader_flash_update_id() { @@ -55,3 +62,147 @@ void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr) } esp_rom_spiflash_config_clk(spi_clk_div, 0); } + +static const char *TAG = "boot.esp32h2"; + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; + uint8_t q_gpio_num = SPI_Q_GPIO_NUM; + uint8_t d_gpio_num = SPI_D_GPIO_NUM; + uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; + uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; + uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); + // Set flash chip size + esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode + cache_hal_enable(CACHE_TYPE_ALL); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + 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"; + } + ESP_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + default: + str = "2MB"; + break; + } + ESP_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_configure_spi_pins(1); + bootloader_flash_cs_timing_config(); +} + +static void bootloader_spi_flash_resume(void) +{ + bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); + esp_rom_spiflash_wait_idle(&g_rom_flashchip); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h4.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h4.c index 1beecfe2d9..8281f42682 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h4.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h4.c @@ -9,6 +9,8 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" #include "esp32h4/rom/gpio.h" #include "esp32h4/rom/spi_flash.h" #include "esp32h4/rom/efuse.h" @@ -20,6 +22,11 @@ #include "flash_qio_mode.h" #include "bootloader_flash_config.h" #include "bootloader_common.h" +#include "bootloader_flash_priv.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" +#include "hal/mmu_ll.h" #define FLASH_IO_MATRIX_DUMMY_40M 0 #define FLASH_IO_MATRIX_DUMMY_80M 0 @@ -73,3 +80,171 @@ void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) bootloader_configure_spi_pins(1); bootloader_flash_set_dummy_out(); } + +static const char *TAG = "boot.esp32h4"; + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio(); + uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; + uint8_t q_gpio_num = SPI_Q_GPIO_NUM; + uint8_t d_gpio_num = SPI_D_GPIO_NUM; + uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; + uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; + uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; + if (spiconfig == 0) { + + } else { + clk_gpio_num = spiconfig & 0x3f; + q_gpio_num = (spiconfig >> 6) & 0x3f; + d_gpio_num = (spiconfig >> 12) & 0x3f; + cs0_gpio_num = (spiconfig >> 18) & 0x3f; + hd_gpio_num = (spiconfig >> 24) & 0x3f; + wp_gpio_num = wp_pin; + } + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + } + if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); + } +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); + // Set flash chip size + esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode + cache_hal_enable(CACHE_TYPE_ALL); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "24MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "16MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "12MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "48MHz"; + break; + default: + str = "12MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + 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"; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_flash_cs_timing_config(); +} + +static void bootloader_spi_flash_resume(void) +{ + bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); + esp_rom_spiflash_wait_idle(&g_rom_flashchip); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); +#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { + ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); + return ESP_FAIL; + } +#endif + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c index da0c4b1684..94d8a4fd88 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c @@ -9,14 +9,21 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" #include "esp32s2/rom/spi_flash.h" #include "soc/efuse_reg.h" +#include "soc/io_mux_reg.h" #include "soc/spi_reg.h" #include "soc/spi_mem_reg.h" #include "soc/soc_caps.h" #include "flash_qio_mode.h" #include "bootloader_flash_config.h" +#include "bootloader_flash_priv.h" #include "bootloader_common.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" #define FLASH_IO_MATRIX_DUMMY_40M 0 #define FLASH_IO_MATRIX_DUMMY_80M 0 @@ -77,3 +84,184 @@ void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr) bootloader_configure_spi_pins(1); bootloader_flash_set_dummy_out(); } + +static const char *TAG = "boot.esp32s2"; + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio(); + uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; + uint8_t q_gpio_num = SPI_Q_GPIO_NUM; + uint8_t d_gpio_num = SPI_D_GPIO_NUM; + uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; + uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; + uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; + if (spiconfig == 0) { + + } else { + clk_gpio_num = spiconfig & 0x3f; + q_gpio_num = (spiconfig >> 6) & 0x3f; + d_gpio_num = (spiconfig >> 12) & 0x3f; + cs0_gpio_num = (spiconfig >> 18) & 0x3f; + hd_gpio_num = (spiconfig >> 24) & 0x3f; + wp_gpio_num = wp_pin; + } + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + } + if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); + } +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->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; + case ESP_IMAGE_FLASH_SIZE_32MB: + size = 32; + break; + case ESP_IMAGE_FLASH_SIZE_64MB: + size = 64; + break; + case ESP_IMAGE_FLASH_SIZE_128MB: + size = 128; + break; + default: + size = 2; + } + cache_hal_disable(CACHE_TYPE_ALL); + // 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 + cache_hal_enable(CACHE_TYPE_ALL); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + 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"; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + case ESP_IMAGE_FLASH_SIZE_32MB: + str = "32MB"; + break; + case ESP_IMAGE_FLASH_SIZE_64MB: + str = "64MB"; + break; + case ESP_IMAGE_FLASH_SIZE_128MB: + str = "128MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_flash_cs_timing_config(); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); +#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { + ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); + return ESP_FAIL; + } +#endif + + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c index 9146ef5431..151e469f3b 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c @@ -9,15 +9,22 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" #include "esp32s3/rom/spi_flash.h" #include "soc/efuse_reg.h" +#include "soc/io_mux_reg.h" #include "soc/spi_reg.h" #include "soc/spi_mem_reg.h" #include "soc/soc_caps.h" #include "flash_qio_mode.h" #include "bootloader_flash_config.h" +#include "bootloader_flash_priv.h" #include "bootloader_common.h" #include "bootloader_flash.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" #define FLASH_IO_MATRIX_DUMMY_40M 0 #define FLASH_IO_MATRIX_DUMMY_80M 0 @@ -83,3 +90,192 @@ void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) bootloader_configure_spi_pins(1); bootloader_flash_set_dummy_out(); } + +static const char *TAG = "boot.esp32s3"; + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio(); + uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; + uint8_t q_gpio_num = SPI_Q_GPIO_NUM; + uint8_t d_gpio_num = SPI_D_GPIO_NUM; + uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; + uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; + uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; + if (spiconfig == 0) { + + } else { + clk_gpio_num = spiconfig & 0x3f; + q_gpio_num = (spiconfig >> 6) & 0x3f; + d_gpio_num = (spiconfig >> 12) & 0x3f; + cs0_gpio_num = (spiconfig >> 18) & 0x3f; + hd_gpio_num = (spiconfig >> 24) & 0x3f; + wp_gpio_num = wp_pin; + } + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + } + if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); + } +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->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; + case ESP_IMAGE_FLASH_SIZE_32MB: + size = 32; + break; + case ESP_IMAGE_FLASH_SIZE_64MB: + size = 64; + break; + case ESP_IMAGE_FLASH_SIZE_128MB: + size = 128; + break; + default: + size = 2; + } + + cache_hal_disable(CACHE_TYPE_ALL); + // 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 + cache_hal_enable(CACHE_TYPE_ALL); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "Boot SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + 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"; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + case ESP_IMAGE_FLASH_SIZE_32MB: + str = "32MB"; + break; + case ESP_IMAGE_FLASH_SIZE_64MB: + str = "64MB"; + break; + case ESP_IMAGE_FLASH_SIZE_128MB: + str = "128MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_flash_cs_timing_config(); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); +#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { + ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); + return ESP_FAIL; + } +#endif + +#if CONFIG_SPI_FLASH_HPM_ENABLE + // Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot. + bootloader_spi_flash_reset(); +#endif + + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + if (!bootloader_flash_is_octal_mode_enabled()) { + bootloader_enable_qio_mode(); + } +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 5b568eccb2..a03a1544f4 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -33,7 +33,7 @@ esp_err_t bootloader_read_bootloader_header(void) { /* load bootloader image header */ if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) { - ESP_LOGE(TAG, "failed to load bootloader image header!"); + ESP_EARLY_LOGE(TAG, "failed to load bootloader image header!"); return ESP_FAIL; } return ESP_OK; @@ -44,7 +44,7 @@ esp_err_t bootloader_check_bootloader_validity(void) unsigned int revision = efuse_hal_chip_revision(); unsigned int major = revision / 100; unsigned int minor = revision % 100; - ESP_LOGI(TAG, "chip revision: v%d.%d", major, minor); + ESP_EARLY_LOGI(TAG, "chip revision: v%d.%d", major, minor); /* compare with the one set in bootloader image header */ if (bootloader_common_check_chip_validity(&bootloader_image_hdr, ESP_IMAGE_BOOTLOADER) != ESP_OK) { return ESP_FAIL; @@ -72,7 +72,7 @@ void bootloader_config_wdt(void) #ifdef CONFIG_BOOTLOADER_WDT_ENABLE //Initialize and start RWDT to protect the for bootloader if configured to do so - ESP_LOGD(TAG, "Enabling RTCWDT(%d ms)", CONFIG_BOOTLOADER_WDT_TIME_MS); + ESP_EARLY_LOGD(TAG, "Enabling RTCWDT(%d ms)", CONFIG_BOOTLOADER_WDT_TIME_MS); wdt_hal_init(&rwdt_ctx, WDT_RWDT, 0, false); uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000); wdt_hal_write_protect_disable(&rwdt_ctx); @@ -90,14 +90,14 @@ void bootloader_config_wdt(void) void bootloader_enable_random(void) { - ESP_LOGI(TAG, "Enabling RNG early entropy source..."); + ESP_EARLY_LOGI(TAG, "Enabling RNG early entropy source..."); bootloader_random_enable(); } void bootloader_print_banner(void) { - ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER); + ESP_EARLY_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER); #ifndef CONFIG_APP_REPRODUCIBLE_BUILD - ESP_LOGI(TAG, "compile time " __DATE__ " " __TIME__); + ESP_EARLY_LOGI(TAG, "compile time " __DATE__ " " __TIME__); #endif } diff --git a/components/bootloader_support/src/esp32/bootloader_esp32.c b/components/bootloader_support/src/esp32/bootloader_esp32.c index d3ec3497ce..c2313b9f6e 100644 --- a/components/bootloader_support/src/esp32/bootloader_esp32.c +++ b/components/bootloader_support/src/esp32/bootloader_esp32.c @@ -17,7 +17,7 @@ #include "bootloader_mem.h" #include "bootloader_console.h" #include "bootloader_flash_priv.h" - +#include "esp_private/bootloader_flash_internal.h" #include "esp_cpu.h" #include "soc/dport_reg.h" #include "soc/efuse_reg.h" @@ -39,64 +39,7 @@ static const char *TAG = "boot.esp32"; -#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 pkg_ver = bootloader_common_get_chip_ver_pkg(); - - if (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_ESP32PICOV302) { - // For ESP32D2WD or ESP32-PICO series,the SPI pins are already configured - // flash clock signal should come from IO MUX. - gpio_hal_iomux_func_sel(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 = esp_rom_efuse_get_flash_gpio_info(); - if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) { - esp_rom_gpio_connect_out_signal(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0); - esp_rom_gpio_connect_out_signal(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0); - esp_rom_gpio_connect_out_signal(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(FLASH_SPID_IO, SPID_IN_IDX, 0); - esp_rom_gpio_connect_out_signal(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0); - esp_rom_gpio_connect_out_signal(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0); - //select pin function gpio - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO); - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO); - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO); - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO); - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO); - // flash clock signal should come from IO MUX. - // set drive ability for clock - gpio_hal_iomux_func_sel(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 - } - } -} - +#if !CONFIG_APP_BUILD_TYPE_RAM static void bootloader_reset_mmu(void) { /* completely reset MMU in case serial bootloader was running */ @@ -124,6 +67,7 @@ static void bootloader_reset_mmu(void) DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0); #endif } +#endif //!CONFIG_APP_BUILD_TYPE_RAM static esp_err_t bootloader_check_rated_cpu_clock(void) { @@ -136,137 +80,6 @@ static esp_err_t bootloader_check_rated_cpu_clock(void) return ESP_OK; } -static void update_flash_config(const esp_image_header_t *bootloader_hdr) -{ - uint32_t size; - switch (bootloader_hdr->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); - // 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 - Cache_Flush(0); - Cache_Read_Enable(0); -} - -static void print_flash_info(const esp_image_header_t *bootloader_hdr) -{ - ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic); - ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); - ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); - ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); - ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); - - const char *str; - switch (bootloader_hdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_DIV_2: - str = "40MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_3: - str = "26.7MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_4: - str = "20MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_1: - str = "80MHz"; - break; - default: - str = "20MHz"; - break; - } - ESP_LOGI(TAG, "SPI Speed : %s", str); - - /* SPI mode could have been set to QIO during boot already, - so test the SPI registers not the flash header */ - uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0)); - if (spi_ctrl & SPI_FREAD_QIO) { - str = "QIO"; - } else if (spi_ctrl & SPI_FREAD_QUAD) { - str = "QOUT"; - } else if (spi_ctrl & SPI_FREAD_DIO) { - str = "DIO"; - } else if (spi_ctrl & SPI_FREAD_DUAL) { - str = "DOUT"; - } else if (spi_ctrl & SPI_FASTRD_MODE) { - str = "FAST READ"; - } else { - str = "SLOW READ"; - } - ESP_LOGI(TAG, "SPI Mode : %s", str); - - switch (bootloader_hdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - str = "1MB"; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - str = "2MB"; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - str = "4MB"; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - str = "8MB"; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - str = "16MB"; - break; - default: - str = "2MB"; - break; - } - ESP_LOGI(TAG, "SPI Flash Size : %s", str); -} - -static void IRAM_ATTR bootloader_init_flash_configure(void) -{ - bootloader_flash_gpio_config(&bootloader_image_hdr); - bootloader_flash_dummy_config(&bootloader_image_hdr); - bootloader_flash_cs_timing_config(); -} - -static esp_err_t bootloader_init_spi_flash(void) -{ - bootloader_init_flash_configure(); -#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { - ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); - return ESP_FAIL; - } -#endif - - bootloader_flash_unlock(); - -#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - bootloader_enable_qio_mode(); -#endif - - print_flash_info(&bootloader_image_hdr); - update_flash_config(&bootloader_image_hdr); - //ensure the flash is write-protected - bootloader_enable_wp(); - return ESP_OK; -} - static void wdt_reset_cpu0_info_enable(void) { //We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1. @@ -357,6 +170,8 @@ esp_err_t bootloader_init(void) WSR(MEMCTL, memctl); #endif // XCHAL_ERRATUM_572 +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM bootloader_init_mem(); // check that static RAM is after the stack @@ -371,6 +186,8 @@ esp_err_t bootloader_init(void) #endif // clear bss section bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // init eFuse virtual mode (read eFuses to RAM) #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); @@ -380,11 +197,9 @@ esp_err_t bootloader_init(void) #endif // bootst up vddsdio bootloader_common_vddsdio_configure(); - // reset MMU - bootloader_reset_mmu(); // check rated CPU clock if ((ret = bootloader_check_rated_cpu_clock()) != ESP_OK) { - goto err; + return ret; } // config clock bootloader_clock_configure(); @@ -392,31 +207,36 @@ esp_err_t bootloader_init(void) bootloader_console_init(); /* print 2nd bootloader banner */ bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + // reset MMU + bootloader_reset_mmu(); // update flash ID bootloader_flash_update_id(); // Check and run XMC startup flow if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); - goto err; + return ret; } // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { - goto err; + return ret; } // read chip revision and check if it's compatible to bootloader if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { - goto err; + return ret; } // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { - goto err; + return ret; } +#endif // #if !CONFIG_APP_BUILD_TYPE_RAM + // check whether a WDT reset happend bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); // enable RNG early entropy source bootloader_enable_random(); -err: return ret; } diff --git a/components/bootloader_support/src/esp32/bootloader_sha.c b/components/bootloader_support/src/esp32/bootloader_sha.c index 8d81d165a1..d69ad064b6 100644 --- a/components/bootloader_support/src/esp32/bootloader_sha.c +++ b/components/bootloader_support/src/esp32/bootloader_sha.c @@ -44,7 +44,7 @@ void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, copy_words = MIN(word_len, copy_words); // Wait for SHA engine idle - while (REG_READ(SHA_256_BUSY_REG) != 0) { } + while (_DPORT_REG_READ(SHA_256_BUSY_REG) != 0) { } // Copy to memory block for (size_t i = 0; i < copy_words; i++) { @@ -61,9 +61,9 @@ void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, // If we loaded a full block, run the SHA engine if (block_count == BLOCK_WORDS) { if (words_hashed == BLOCK_WORDS) { - REG_WRITE(SHA_256_START_REG, 1); + _DPORT_REG_WRITE(SHA_256_START_REG, 1); } else { - REG_WRITE(SHA_256_CONTINUE_REG, 1); + _DPORT_REG_WRITE(SHA_256_CONTINUE_REG, 1); } block_count = 0; } @@ -103,9 +103,9 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest assert(words_hashed % BLOCK_WORDS == 0); - while (REG_READ(SHA_256_BUSY_REG) == 1) { } - REG_WRITE(SHA_256_LOAD_REG, 1); - while (REG_READ(SHA_256_BUSY_REG) == 1) { } + while (_DPORT_REG_READ(SHA_256_BUSY_REG) == 1) { } + _DPORT_REG_WRITE(SHA_256_LOAD_REG, 1); + while (_DPORT_REG_READ(SHA_256_BUSY_REG) == 1) { } uint32_t *digest_words = (uint32_t *)digest; uint32_t *sha_text_reg = (uint32_t *)(SHA_TEXT_BASE); diff --git a/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c b/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c index 0b6b67f781..bac2b8bc10 100644 --- a/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c +++ b/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c @@ -34,6 +34,7 @@ #include "bootloader_mem.h" #include "bootloader_console.h" #include "bootloader_flash_priv.h" +#include "esp_private/bootloader_flash_internal.h" #include "esp_efuse.h" #include "hal/mmu_hal.h" #include "hal/cache_hal.h" @@ -41,168 +42,6 @@ static const char *TAG = "boot.esp32c2"; -void IRAM_ATTR bootloader_configure_spi_pins(int drv) -{ - // IDF-4066 - const uint32_t spiconfig = 0; - uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; - uint8_t q_gpio_num = SPI_Q_GPIO_NUM; - uint8_t d_gpio_num = SPI_D_GPIO_NUM; - uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; - uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; - uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; - if (spiconfig == 0) { - - } - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - } - if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); - } -} - -static void update_flash_config(const esp_image_header_t *bootloader_hdr) -{ - uint32_t size; - switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); - // Set flash chip size - esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_TYPE_ALL); -} - -static void print_flash_info(const esp_image_header_t *bootloader_hdr) -{ - ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic); - ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); - ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); - ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); - ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); - - const char *str; - switch (bootloader_hdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_DIV_2: - str = "30MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_3: - str = "20MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_4: - str = "15MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_1: - str = "60MHz"; - break; - default: - str = "15MHz"; - break; - } - ESP_LOGI(TAG, "SPI Speed : %s", str); - - /* SPI mode could have been set to QIO during boot already, - so test the SPI registers not the flash header */ - 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"; - } - ESP_LOGI(TAG, "SPI Mode : %s", str); - - switch (bootloader_hdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - str = "1MB"; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - str = "2MB"; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - str = "4MB"; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - str = "8MB"; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - str = "16MB"; - break; - default: - str = "2MB"; - break; - } - ESP_LOGI(TAG, "SPI Flash Size : %s", str); -} - -static void bootloader_print_mmu_page_size(void) -{ - mmu_page_size_t page_size = mmu_ll_get_page_size(0); - int size = (page_size == MMU_PAGE_16KB ? 16 : - page_size == MMU_PAGE_32KB ? 32 : - page_size == MMU_PAGE_64KB ? 64 : 0); - ESP_LOGI(TAG, "MMU Page Size : %dK", size); -} - -static void IRAM_ATTR bootloader_init_flash_configure(void) -{ - bootloader_flash_dummy_config(&bootloader_image_hdr); - bootloader_flash_cs_timing_config(); -} - -static void bootloader_spi_flash_resume(void) -{ - bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); -} - -static esp_err_t bootloader_init_spi_flash(void) -{ - bootloader_init_flash_configure(); - - bootloader_spi_flash_resume(); - bootloader_flash_unlock(); - -#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - bootloader_enable_qio_mode(); -#endif - - bootloader_print_mmu_page_size(); - print_flash_info(&bootloader_image_hdr); - update_flash_config(&bootloader_image_hdr); - //ensure the flash is write-protected - bootloader_enable_wp(); - return ESP_OK; -} - static void wdt_reset_cpu0_info_enable(void) { REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG); @@ -245,6 +84,9 @@ esp_err_t bootloader_init(void) esp_err_t ret = ESP_OK; bootloader_super_wdt_auto_feed(); + +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM // protect memory region bootloader_init_mem(); /* check that static RAM is after the stack */ @@ -252,6 +94,8 @@ esp_err_t bootloader_init(void) assert(&_data_start <= &_data_end); // clear bss section bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // init eFuse virtual mode (read eFuses to RAM) #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); @@ -259,38 +103,41 @@ esp_err_t bootloader_init(void) esp_efuse_init_virtual_mode_in_ram(); #endif #endif - //init cache hal - cache_hal_init(); - //reset mmu - mmu_hal_init(); - // config mmu page size - mmu_ll_set_page_size(0, SPI_FLASH_MMU_PAGE_SIZE); // config clock bootloader_clock_configure(); // initialize console, from now on, we can use esp_log bootloader_console_init(); /* print 2nd bootloader banner */ bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + //init cache hal + cache_hal_init(); + //reset mmu + mmu_hal_init(); + // config mmu page size + mmu_ll_set_page_size(0, SPI_FLASH_MMU_PAGE_SIZE); // update flash ID bootloader_flash_update_id(); // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { - goto err; + return ret; } // read chip revision and check if it's compatible to bootloader if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { - goto err; + return ret; } // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { - goto err; + return ret; } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // check whether a WDT reset happend bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); // enable RNG early entropy source bootloader_enable_random(); -err: return ret; } diff --git a/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c b/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c index c67c9aefe3..1a7a8097b1 100644 --- a/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c +++ b/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c @@ -38,6 +38,7 @@ #include "soc/regi2c_bias.h" #include "bootloader_console.h" #include "bootloader_flash_priv.h" +#include "esp_private/bootloader_flash_internal.h" #include "bootloader_soc.h" #include "esp_efuse.h" #include "hal/mmu_hal.h" @@ -46,172 +47,6 @@ static const char *TAG = "boot.esp32c3"; -void IRAM_ATTR bootloader_configure_spi_pins(int drv) -{ - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio(); - uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; - uint8_t q_gpio_num = SPI_Q_GPIO_NUM; - uint8_t d_gpio_num = SPI_D_GPIO_NUM; - uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; - uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; - uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; - if (spiconfig == 0) { - - } else { - clk_gpio_num = spiconfig & 0x3f; - q_gpio_num = (spiconfig >> 6) & 0x3f; - d_gpio_num = (spiconfig >> 12) & 0x3f; - cs0_gpio_num = (spiconfig >> 18) & 0x3f; - hd_gpio_num = (spiconfig >> 24) & 0x3f; - wp_gpio_num = wp_pin; - } - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - } - if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); - } -} - -static void update_flash_config(const esp_image_header_t *bootloader_hdr) -{ - uint32_t size; - switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); - // Set flash chip size - esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_TYPE_ALL); -} - -static void print_flash_info(const esp_image_header_t *bootloader_hdr) -{ - ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic); - ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); - ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); - ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); - ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); - - const char *str; - switch (bootloader_hdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_DIV_2: - str = "40MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_3: - str = "26.7MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_4: - str = "20MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_1: - str = "80MHz"; - break; - default: - str = "20MHz"; - break; - } - ESP_LOGI(TAG, "SPI Speed : %s", str); - - /* SPI mode could have been set to QIO during boot already, - so test the SPI registers not the flash header */ - 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"; - } - ESP_LOGI(TAG, "SPI Mode : %s", str); - - switch (bootloader_hdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - str = "1MB"; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - str = "2MB"; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - str = "4MB"; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - str = "8MB"; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - str = "16MB"; - break; - default: - str = "2MB"; - break; - } - ESP_LOGI(TAG, "SPI Flash Size : %s", str); -} - -static void IRAM_ATTR bootloader_init_flash_configure(void) -{ - bootloader_flash_dummy_config(&bootloader_image_hdr); - bootloader_flash_cs_timing_config(); -} - -static void bootloader_spi_flash_resume(void) -{ - bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); -} - -static esp_err_t bootloader_init_spi_flash(void) -{ - bootloader_init_flash_configure(); -#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { - ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); - return ESP_FAIL; - } -#endif - - bootloader_spi_flash_resume(); - bootloader_flash_unlock(); - -#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - bootloader_enable_qio_mode(); -#endif - - print_flash_info(&bootloader_image_hdr); - update_flash_config(&bootloader_image_hdr); - //ensure the flash is write-protected - bootloader_enable_wp(); - return ESP_OK; -} - static void wdt_reset_cpu0_info_enable(void) { REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG); @@ -297,6 +132,9 @@ esp_err_t bootloader_init(void) bootloader_hardware_init(); bootloader_ana_reset_config(); bootloader_super_wdt_auto_feed(); + +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM // protect memory region bootloader_init_mem(); /* check that static RAM is after the stack */ @@ -304,6 +142,8 @@ esp_err_t bootloader_init(void) assert(&_data_start <= &_data_end); // clear bss section bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // init eFuse virtual mode (read eFuses to RAM) #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); @@ -311,41 +151,45 @@ esp_err_t bootloader_init(void) esp_efuse_init_virtual_mode_in_ram(); #endif #endif - //init cache hal - cache_hal_init(); - //reset mmu - mmu_hal_init(); // config clock bootloader_clock_configure(); // initialize console, from now on, we can use esp_log bootloader_console_init(); /* print 2nd bootloader banner */ bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + //init cache hal + cache_hal_init(); + //reset mmu + mmu_hal_init(); // update flash ID bootloader_flash_update_id(); // Check and run XMC startup flow if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); - goto err; + return ret; } // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { - goto err; + return ret; } // read chip revision and check if it's compatible to bootloader if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { - goto err; + return ret; } // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { - goto err; + return ret; } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // check whether a WDT reset happend bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); // enable RNG early entropy source bootloader_enable_random(); -err: + return ret; } diff --git a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c index 105438bae6..fc2ecc3863 100644 --- a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c +++ b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c @@ -37,6 +37,7 @@ #include "bootloader_console.h" #include "bootloader_flash_priv.h" #include "bootloader_soc.h" +#include "esp_private/bootloader_flash_internal.h" #include "esp_efuse.h" #include "hal/mmu_hal.h" #include "hal/cache_hal.h" @@ -47,148 +48,6 @@ static const char *TAG = "boot.esp32c6"; -void IRAM_ATTR bootloader_configure_spi_pins(int drv) -{ - uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; - uint8_t q_gpio_num = SPI_Q_GPIO_NUM; - uint8_t d_gpio_num = SPI_D_GPIO_NUM; - uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; - uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; - uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); -} - -static void update_flash_config(const esp_image_header_t *bootloader_hdr) -{ - uint32_t size; - switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); - // Set flash chip size - esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_TYPE_ALL); -} - -static void print_flash_info(const esp_image_header_t *bootloader_hdr) -{ - ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic); - ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); - ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); - ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); - ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); - - const char *str; - switch (bootloader_hdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_DIV_2: - str = "40MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_3: - str = "26.7MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_4: - str = "20MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_1: - str = "80MHz"; - break; - default: - str = "20MHz"; - break; - } - ESP_LOGI(TAG, "SPI Speed : %s", str); - - /* SPI mode could have been set to QIO during boot already, - so test the SPI registers not the flash header */ - 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"; - } - ESP_LOGI(TAG, "SPI Mode : %s", str); - - switch (bootloader_hdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - str = "1MB"; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - str = "2MB"; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - str = "4MB"; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - str = "8MB"; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - str = "16MB"; - break; - default: - str = "2MB"; - break; - } - ESP_LOGI(TAG, "SPI Flash Size : %s", str); -} - -static void IRAM_ATTR bootloader_init_flash_configure(void) -{ - bootloader_configure_spi_pins(1); - bootloader_flash_cs_timing_config(); -} - -static void bootloader_spi_flash_resume(void) -{ - bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); -} - -static esp_err_t bootloader_init_spi_flash(void) -{ - bootloader_init_flash_configure(); - bootloader_spi_flash_resume(); - bootloader_flash_unlock(); - -#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - bootloader_enable_qio_mode(); -#endif - - print_flash_info(&bootloader_image_hdr); - update_flash_config(&bootloader_image_hdr); - //ensure the flash is write-protected - bootloader_enable_wp(); - return ESP_OK; -} - static void wdt_reset_cpu0_info_enable(void) { REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN); @@ -229,7 +88,7 @@ static void bootloader_super_wdt_auto_feed(void) static inline void bootloader_hardware_init(void) { // In 80MHz flash mode, ROM sets the mspi module clk divider to 2, fix it here -#if CONFIG_ESPTOOLPY_FLASHFREQ_80M +#if CONFIG_ESPTOOLPY_FLASHFREQ_80M && !CONFIG_APP_BUILD_TYPE_RAM clk_ll_mspi_fast_set_hs_divider(6); esp_rom_spiflash_config_clk(1, 0); esp_rom_spiflash_config_clk(1, 1); @@ -280,6 +139,9 @@ esp_err_t bootloader_init(void) bootloader_hardware_init(); bootloader_ana_reset_config(); bootloader_super_wdt_auto_feed(); + +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM // protect memory region bootloader_init_mem(); /* check that static RAM is after the stack */ @@ -287,6 +149,8 @@ esp_err_t bootloader_init(void) assert(&_data_start <= &_data_end); // clear bss section bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // init eFuse virtual mode (read eFuses to RAM) #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); @@ -294,41 +158,45 @@ esp_err_t bootloader_init(void) esp_efuse_init_virtual_mode_in_ram(); #endif #endif - //init cache hal - cache_hal_init(); - //reset mmu - mmu_hal_init(); // config clock bootloader_clock_configure(); // initialize console, from now on, we can use esp_log bootloader_console_init(); /* print 2nd bootloader banner */ bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + //init cache hal + cache_hal_init(); + //reset mmu + mmu_hal_init(); // update flash ID bootloader_flash_update_id(); // Check and run XMC startup flow if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); - goto err; + return ret; } // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { - goto err; + return ret; } // read chip revision and check if it's compatible to bootloader if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { - goto err; + return ret; } // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { - goto err; + return ret; } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // check whether a WDT reset happend bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); // enable RNG early entropy source bootloader_enable_random(); -err: + return ret; } diff --git a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c index e4043e49d3..ba06e9609e 100644 --- a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c +++ b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -36,6 +36,7 @@ #include "bootloader_console.h" #include "bootloader_flash_priv.h" #include "bootloader_soc.h" +#include "esp_private/bootloader_flash_internal.h" #include "esp_efuse.h" #include "hal/mmu_hal.h" #include "hal/cache_hal.h" @@ -45,148 +46,6 @@ static const char *TAG = "boot.esp32h2"; -void IRAM_ATTR bootloader_configure_spi_pins(int drv) -{ - uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; - uint8_t q_gpio_num = SPI_Q_GPIO_NUM; - uint8_t d_gpio_num = SPI_D_GPIO_NUM; - uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; - uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; - uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); -} - -static void update_flash_config(const esp_image_header_t *bootloader_hdr) -{ - uint32_t size; - switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); - // Set flash chip size - esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_TYPE_ALL); -} - -static void print_flash_info(const esp_image_header_t *bootloader_hdr) -{ - ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); - ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); - ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); - ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); - ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); - - const char *str; - switch (bootloader_hdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_DIV_2: - str = "40MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_3: - str = "26.7MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_4: - str = "20MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_1: - str = "80MHz"; - break; - default: - str = "20MHz"; - break; - } - ESP_LOGI(TAG, "SPI Speed : %s", str); - - /* SPI mode could have been set to QIO during boot already, - so test the SPI registers not the flash header */ - 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"; - } - ESP_LOGI(TAG, "SPI Mode : %s", str); - - switch (bootloader_hdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - str = "1MB"; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - str = "2MB"; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - str = "4MB"; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - str = "8MB"; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - str = "16MB"; - break; - default: - str = "2MB"; - break; - } - ESP_LOGI(TAG, "SPI Flash Size : %s", str); -} - -static void IRAM_ATTR bootloader_init_flash_configure(void) -{ - bootloader_configure_spi_pins(1); - bootloader_flash_cs_timing_config(); -} - -static void bootloader_spi_flash_resume(void) -{ - bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); -} - -static esp_err_t bootloader_init_spi_flash(void) -{ - bootloader_init_flash_configure(); - bootloader_spi_flash_resume(); - bootloader_flash_unlock(); - -#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - bootloader_enable_qio_mode(); -#endif - - print_flash_info(&bootloader_image_hdr); - update_flash_config(&bootloader_image_hdr); - //ensure the flash is write-protected - bootloader_enable_wp(); - return ESP_OK; -} - static void wdt_reset_cpu0_info_enable(void) { REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN); @@ -267,6 +126,9 @@ esp_err_t bootloader_init(void) bootloader_hardware_init(); bootloader_ana_reset_config(); bootloader_super_wdt_auto_feed(); + +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM // protect memory region bootloader_init_mem(); /* check that static RAM is after the stack */ @@ -274,6 +136,8 @@ esp_err_t bootloader_init(void) assert(&_data_start <= &_data_end); // clear bss section bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // init eFuse virtual mode (read eFuses to RAM) #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); @@ -281,41 +145,46 @@ esp_err_t bootloader_init(void) esp_efuse_init_virtual_mode_in_ram(); #endif #endif - //init cache hal - cache_hal_init(); - //reset mmu - mmu_hal_init(); // config clock bootloader_clock_configure(); // initialize console, from now on, we can use esp_log bootloader_console_init(); /* print 2nd bootloader banner */ bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + //init cache hal + cache_hal_init(); + //reset mmu + mmu_hal_init(); + // update flash ID bootloader_flash_update_id(); // Check and run XMC startup flow if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); - goto err; + return ret; } // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { - goto err; + return ret; } // read chip revision and check if it's compatible to bootloader if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { - goto err; + return ret; } // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { - goto err; + return ret; } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // check whether a WDT reset happend bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); // enable RNG early entropy source bootloader_enable_random(); -err: + return ret; } diff --git a/components/bootloader_support/src/esp32h4/bootloader_esp32h4.c b/components/bootloader_support/src/esp32h4/bootloader_esp32h4.c index 9e4589383e..ef7cf34687 100644 --- a/components/bootloader_support/src/esp32h4/bootloader_esp32h4.c +++ b/components/bootloader_support/src/esp32h4/bootloader_esp32h4.c @@ -35,177 +35,12 @@ #include "bootloader_console.h" #include "bootloader_flash_priv.h" #include "bootloader_soc.h" +#include "esp_private/bootloader_flash_internal.h" #include "hal/mmu_hal.h" #include "hal/cache_hal.h" static const char *TAG = "boot.esp32h4"; -void IRAM_ATTR bootloader_configure_spi_pins(int drv) -{ - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio(); - uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; - uint8_t q_gpio_num = SPI_Q_GPIO_NUM; - uint8_t d_gpio_num = SPI_D_GPIO_NUM; - uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; - uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; - uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; - if (spiconfig == 0) { - - } else { - clk_gpio_num = spiconfig & 0x3f; - q_gpio_num = (spiconfig >> 6) & 0x3f; - d_gpio_num = (spiconfig >> 12) & 0x3f; - cs0_gpio_num = (spiconfig >> 18) & 0x3f; - hd_gpio_num = (spiconfig >> 24) & 0x3f; - wp_gpio_num = wp_pin; - } - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - } - if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); - } -} - -static void update_flash_config(const esp_image_header_t *bootloader_hdr) -{ - uint32_t size; - switch (bootloader_hdr->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_hal_disable(CACHE_TYPE_ALL); - // Set flash chip size - esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_TYPE_ALL); -} - -static void print_flash_info(const esp_image_header_t *bootloader_hdr) -{ - ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic); - ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); - ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); - ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); - ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); - - const char *str; - switch (bootloader_hdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_DIV_2: - str = "24MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_3: - str = "16MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_4: - str = "12MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_1: - str = "48MHz"; - break; - default: - str = "12MHz"; - break; - } - ESP_LOGI(TAG, "SPI Speed : %s", str); - - /* SPI mode could have been set to QIO during boot already, - so test the SPI registers not the flash header */ - 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"; - } - ESP_LOGI(TAG, "SPI Mode : %s", str); - - switch (bootloader_hdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - str = "1MB"; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - str = "2MB"; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - str = "4MB"; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - str = "8MB"; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - str = "16MB"; - break; - default: - str = "2MB"; - break; - } - ESP_LOGI(TAG, "SPI Flash Size : %s", str); -} - -static void IRAM_ATTR bootloader_init_flash_configure(void) -{ - bootloader_flash_dummy_config(&bootloader_image_hdr); - bootloader_flash_cs_timing_config(); -} - -static void bootloader_spi_flash_resume(void) -{ - bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); -} - -static esp_err_t bootloader_init_spi_flash(void) -{ - bootloader_init_flash_configure(); -#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { - ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); - return ESP_FAIL; - } -#endif - - bootloader_spi_flash_resume(); - bootloader_flash_unlock(); - -#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - bootloader_enable_qio_mode(); -#endif - - print_flash_info(&bootloader_image_hdr); - update_flash_config(&bootloader_image_hdr); - //ensure the flash is write-protected - bootloader_enable_wp(); - return ESP_OK; -} - static void wdt_reset_cpu0_info_enable(void) { REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG); @@ -263,6 +98,9 @@ esp_err_t bootloader_init(void) bootloader_hardware_init(); bootloader_ana_reset_config(); bootloader_super_wdt_auto_feed(); + +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM // protect memory region bootloader_init_mem(); /* check that static RAM is after the stack */ @@ -270,41 +108,46 @@ esp_err_t bootloader_init(void) assert(&_data_start <= &_data_end); // clear bss section bootloader_clear_bss_section(); - //init cache hal - cache_hal_init(); //TODO IDF-4649 - //reset mmu - mmu_hal_init(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // config clock bootloader_clock_configure(); // initialize console, from now on, we can use esp_log bootloader_console_init(); /* print 2nd bootloader banner */ bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + //init cache hal + cache_hal_init(); //TODO IDF-4649 + //reset mmu + mmu_hal_init(); // update flash ID bootloader_flash_update_id(); // Check and run XMC startup flow if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); - goto err; + return ret; } // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { - goto err; + return ret; } // read chip revision and check if it's compatible to bootloader if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { - goto err; + return ret; } // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { - goto err; + return ret; } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // check whether a WDT reset happend bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); // enable RNG early entropy source bootloader_enable_random(); -err: return ret; } diff --git a/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c b/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c index 7a280e8805..c3a25ef54e 100644 --- a/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c +++ b/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c @@ -18,7 +18,7 @@ #include "bootloader_mem.h" #include "bootloader_console.h" #include "bootloader_flash_priv.h" - +#include "esp_private/bootloader_flash_internal.h" #include "esp_rom_gpio.h" #include "esp_rom_efuse.h" #include "esp_rom_sys.h" @@ -40,184 +40,6 @@ #include "hal/cache_hal.h" static const char *TAG = "boot.esp32s2"; -void IRAM_ATTR bootloader_configure_spi_pins(int drv) -{ - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio(); - uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; - uint8_t q_gpio_num = SPI_Q_GPIO_NUM; - uint8_t d_gpio_num = SPI_D_GPIO_NUM; - uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; - uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; - uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; - if (spiconfig == 0) { - - } else { - clk_gpio_num = spiconfig & 0x3f; - q_gpio_num = (spiconfig >> 6) & 0x3f; - d_gpio_num = (spiconfig >> 12) & 0x3f; - cs0_gpio_num = (spiconfig >> 18) & 0x3f; - hd_gpio_num = (spiconfig >> 24) & 0x3f; - wp_gpio_num = wp_pin; - } - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - } - if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); - } -} - -static void update_flash_config(const esp_image_header_t *bootloader_hdr) -{ - uint32_t size; - switch (bootloader_hdr->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; - case ESP_IMAGE_FLASH_SIZE_32MB: - size = 32; - break; - case ESP_IMAGE_FLASH_SIZE_64MB: - size = 64; - break; - case ESP_IMAGE_FLASH_SIZE_128MB: - size = 128; - break; - default: - size = 2; - } - cache_hal_disable(CACHE_TYPE_ALL); - // 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 - cache_hal_enable(CACHE_TYPE_ALL); -} - -static void print_flash_info(const esp_image_header_t *bootloader_hdr) -{ - ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic); - ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); - ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); - ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); - ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); - - const char *str; - switch (bootloader_hdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_DIV_2: - str = "40MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_3: - str = "26.7MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_4: - str = "20MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_1: - str = "80MHz"; - break; - default: - str = "20MHz"; - break; - } - ESP_LOGI(TAG, "SPI Speed : %s", str); - - /* SPI mode could have been set to QIO during boot already, - so test the SPI registers not the flash header */ - 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"; - } - ESP_LOGI(TAG, "SPI Mode : %s", str); - - switch (bootloader_hdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - str = "1MB"; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - str = "2MB"; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - str = "4MB"; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - str = "8MB"; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - str = "16MB"; - break; - case ESP_IMAGE_FLASH_SIZE_32MB: - str = "32MB"; - break; - case ESP_IMAGE_FLASH_SIZE_64MB: - str = "64MB"; - break; - case ESP_IMAGE_FLASH_SIZE_128MB: - str = "128MB"; - break; - default: - str = "2MB"; - break; - } - ESP_LOGI(TAG, "SPI Flash Size : %s", str); -} - -static void IRAM_ATTR bootloader_init_flash_configure(void) -{ - bootloader_flash_dummy_config(&bootloader_image_hdr); - bootloader_flash_cs_timing_config(); -} - -static esp_err_t bootloader_init_spi_flash(void) -{ - bootloader_init_flash_configure(); -#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { - ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); - return ESP_FAIL; - } -#endif - - bootloader_flash_unlock(); - -#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - bootloader_enable_qio_mode(); -#endif - - print_flash_info(&bootloader_image_hdr); - update_flash_config(&bootloader_image_hdr); - //ensure the flash is write-protected - bootloader_enable_wp(); - return ESP_OK; -} static void wdt_reset_cpu0_info_enable(void) { @@ -287,6 +109,8 @@ esp_err_t bootloader_init(void) bootloader_super_wdt_auto_feed(); // protect memory region +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM bootloader_init_mem(); /* check that static RAM is after the stack */ @@ -298,6 +122,8 @@ esp_err_t bootloader_init(void) #endif // clear bss section bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // init eFuse virtual mode (read eFuses to RAM) #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); @@ -305,43 +131,48 @@ esp_err_t bootloader_init(void) esp_efuse_init_virtual_mode_in_ram(); #endif #endif - // init cache hal - cache_hal_init(); - // reset mmu - mmu_hal_init(); - // Workaround: normal ROM bootloader exits with DROM0 cache unmasked, but 2nd bootloader exits with it masked. - REG_CLR_BIT(EXTMEM_PRO_ICACHE_CTRL1_REG, EXTMEM_PRO_ICACHE_MASK_DROM0); + // config clock bootloader_clock_configure(); // initialize console, from now on, we can use esp_log bootloader_console_init(); /* print 2nd bootloader banner */ bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + // init cache hal + cache_hal_init(); + // reset mmu + mmu_hal_init(); + // Workaround: normal ROM bootloader exits with DROM0 cache unmasked, but 2nd bootloader exits with it masked. + REG_CLR_BIT(EXTMEM_PRO_ICACHE_CTRL1_REG, EXTMEM_PRO_ICACHE_MASK_DROM0); // update flash ID bootloader_flash_update_id(); // Check and run XMC startup flow if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); - goto err; + return ret; } // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { - goto err; + return ret; } // read chip revision and check if it's compatible to bootloader if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { - goto err; + return ret; } // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { - goto err; + return ret; } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // check whether a WDT reset happend bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); // enable RNG early entropy source bootloader_enable_random(); -err: + return ret; } diff --git a/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c b/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c index 53a426a6c0..31a36b8098 100644 --- a/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c +++ b/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c @@ -34,6 +34,7 @@ #include "bootloader_console.h" #include "bootloader_flash_priv.h" #include "bootloader_soc.h" +#include "esp_private/bootloader_flash_internal.h" #include "esp_efuse.h" #include "hal/mmu_hal.h" #include "hal/cache_hal.h" @@ -43,193 +44,6 @@ static const char *TAG = "boot.esp32s3"; -void IRAM_ATTR bootloader_configure_spi_pins(int drv) -{ - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio(); - uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM; - uint8_t q_gpio_num = SPI_Q_GPIO_NUM; - uint8_t d_gpio_num = SPI_D_GPIO_NUM; - uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM; - uint8_t hd_gpio_num = SPI_HD_GPIO_NUM; - uint8_t wp_gpio_num = SPI_WP_GPIO_NUM; - if (spiconfig == 0) { - - } else { - clk_gpio_num = spiconfig & 0x3f; - q_gpio_num = (spiconfig >> 6) & 0x3f; - d_gpio_num = (spiconfig >> 12) & 0x3f; - cs0_gpio_num = (spiconfig >> 18) & 0x3f; - hd_gpio_num = (spiconfig >> 24) & 0x3f; - wp_gpio_num = wp_pin; - } - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - if (hd_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - } - if (wp_gpio_num <= MAX_PAD_GPIO_NUM) { - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); - } -} - -static void update_flash_config(const esp_image_header_t *bootloader_hdr) -{ - uint32_t size; - switch (bootloader_hdr->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; - case ESP_IMAGE_FLASH_SIZE_32MB: - size = 32; - break; - case ESP_IMAGE_FLASH_SIZE_64MB: - size = 64; - break; - case ESP_IMAGE_FLASH_SIZE_128MB: - size = 128; - break; - default: - size = 2; - } - - cache_hal_disable(CACHE_TYPE_ALL); - // 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 - cache_hal_enable(CACHE_TYPE_ALL); -} - -static void print_flash_info(const esp_image_header_t *bootloader_hdr) -{ - ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic); - ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); - ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); - ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); - ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); - - const char *str; - switch (bootloader_hdr->spi_speed) { - case ESP_IMAGE_SPI_SPEED_DIV_2: - str = "40MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_3: - str = "26.7MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_4: - str = "20MHz"; - break; - case ESP_IMAGE_SPI_SPEED_DIV_1: - str = "80MHz"; - break; - default: - str = "20MHz"; - break; - } - ESP_LOGI(TAG, "Boot SPI Speed : %s", str); - - /* SPI mode could have been set to QIO during boot already, - so test the SPI registers not the flash header */ - 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"; - } - ESP_LOGI(TAG, "SPI Mode : %s", str); - - switch (bootloader_hdr->spi_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - str = "1MB"; - break; - case ESP_IMAGE_FLASH_SIZE_2MB: - str = "2MB"; - break; - case ESP_IMAGE_FLASH_SIZE_4MB: - str = "4MB"; - break; - case ESP_IMAGE_FLASH_SIZE_8MB: - str = "8MB"; - break; - case ESP_IMAGE_FLASH_SIZE_16MB: - str = "16MB"; - break; - case ESP_IMAGE_FLASH_SIZE_32MB: - str = "32MB"; - break; - case ESP_IMAGE_FLASH_SIZE_64MB: - str = "64MB"; - break; - case ESP_IMAGE_FLASH_SIZE_128MB: - str = "128MB"; - break; - default: - str = "2MB"; - break; - } - ESP_LOGI(TAG, "SPI Flash Size : %s", str); -} - -static void IRAM_ATTR bootloader_init_flash_configure(void) -{ - bootloader_flash_dummy_config(&bootloader_image_hdr); - bootloader_flash_cs_timing_config(); -} - -static esp_err_t bootloader_init_spi_flash(void) -{ - bootloader_init_flash_configure(); -#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH - const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); - if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { - ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig"); - return ESP_FAIL; - } -#endif - -#if CONFIG_SPI_FLASH_HPM_ENABLE - // Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot. - bootloader_spi_flash_reset(); -#endif - - bootloader_flash_unlock(); - -#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - if (!bootloader_flash_is_octal_mode_enabled()) { - bootloader_enable_qio_mode(); - } -#endif - - print_flash_info(&bootloader_image_hdr); - update_flash_config(&bootloader_image_hdr); - //ensure the flash is write-protected - bootloader_enable_wp(); - return ESP_OK; -} - static void wdt_reset_cpu0_info_enable(void) { REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG); @@ -333,6 +147,9 @@ esp_err_t bootloader_init(void) bootloader_ana_reset_config(); bootloader_super_wdt_auto_feed(); + +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM // protect memory region bootloader_init_mem(); /* check that static RAM is after the stack */ @@ -344,6 +161,8 @@ esp_err_t bootloader_init(void) #endif // clear bss section bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // init eFuse virtual mode (read eFuses to RAM) #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); @@ -351,41 +170,44 @@ esp_err_t bootloader_init(void) esp_efuse_init_virtual_mode_in_ram(); #endif #endif - //init cache hal - cache_hal_init(); - //reset mmu - mmu_hal_init(); // config clock bootloader_clock_configure(); // initialize console, from now on, we can use esp_log bootloader_console_init(); /* print 2nd bootloader banner */ bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + //init cache hal + cache_hal_init(); + //reset mmu + mmu_hal_init(); // update flash ID bootloader_flash_update_id(); // Check and run XMC startup flow if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); - goto err; + return ret; } // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { - goto err; + return ret; } // read chip revision and check if it's compatible to bootloader if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { - goto err; + return ret; } // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { - goto err; + return ret; } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + // check whether a WDT reset happend bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); // enable RNG early entropy source bootloader_enable_random(); -err: return ret; } diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 93224e6e97..3bd8928347 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -96,6 +96,7 @@ menu "Hardware Settings" config ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND bool "Flash leakage current workaround in light sleep" + depends on !APP_BUILD_TYPE_PURE_RAM_APP default y help When the CS pin of Flash is not pulled up, the sleep current will diff --git a/components/esp_hw_support/port/esp32s3/rtc_init.c b/components/esp_hw_support/port/esp32s3/rtc_init.c index 18b7abd5a5..3a3600440c 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_init.c +++ b/components/esp_hw_support/port/esp32s3/rtc_init.c @@ -252,7 +252,7 @@ static void set_ocode_by_efuse(int calib_version) */ static void calibrate_ocode(void) { -#ifndef BOOTLOADER_BUILD +#if !defined(BOOTLOADER_BUILD) && !defined(CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) /** * Background: * 1. Following code will switch the system clock to XTAL first, to self-calibrate the OCode. @@ -262,7 +262,7 @@ static void calibrate_ocode(void) * When CPU clock switches down, the delay should be cleared. Therefore here we call this function to remove the delays. */ mspi_timing_change_speed_mode_cache_safe(true); -#endif +#endif // #if !defined(BOOTLOADER_BUILD) && !defined(CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) /* Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL). Method: @@ -308,10 +308,10 @@ static void calibrate_ocode(void) } } rtc_clk_cpu_freq_set_config(&old_config); -#ifndef BOOTLOADER_BUILD +#if !defined(BOOTLOADER_BUILD) && !defined(CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) //System clock is switched back to PLL. Here we switch to the MSPI high speed mode, add the delays back mspi_timing_change_speed_mode_cache_safe(false); -#endif +#endif // #if !defined(BOOTLOADER_BUILD) && !defined(CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) } static uint32_t get_dig_dbias_by_efuse(uint8_t pvt_scheme_ver) diff --git a/components/esp_psram/Kconfig b/components/esp_psram/Kconfig index 44bcc1534d..891fa9826f 100644 --- a/components/esp_psram/Kconfig +++ b/components/esp_psram/Kconfig @@ -1,5 +1,5 @@ menu "ESP PSRAM" - + depends on !APP_BUILD_TYPE_PURE_RAM_APP # Will be refactored after !18050 to merge target-specific items orsource "./$IDF_TARGET/Kconfig.spiram" diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.api.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.api.ld index 04f47bdde3..bbb4093565 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.api.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.api.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -45,6 +45,7 @@ PROVIDE ( esp_rom_get_reset_reason = rtc_get_reset_reason ); PROVIDE ( esp_rom_route_intr_matrix = intr_matrix_set ); PROVIDE ( esp_rom_get_cpu_ticks_per_us = ets_get_cpu_frequency ); +PROVIDE ( esp_rom_spiflash_attach = spi_flash_attach ); PROVIDE ( esp_rom_spiflash_clear_bp = esp_rom_spiflash_unlock ); PROVIDE ( esp_rom_spiflash_write_enable = SPI_write_enable ); PROVIDE ( esp_rom_spiflash_erase_area = SPIEraseArea ); diff --git a/components/esp_rom/esp32h2/ld/esp32h2.rom.api.ld b/components/esp_rom/esp32h2/ld/esp32h2.rom.api.ld index f6c327d758..486dd3944c 100644 --- a/components/esp_rom/esp32h2/ld/esp32h2.rom.api.ld +++ b/components/esp_rom/esp32h2/ld/esp32h2.rom.api.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,6 +46,7 @@ PROVIDE ( esp_rom_get_reset_reason = rtc_get_reset_reason ); PROVIDE ( esp_rom_route_intr_matrix = intr_matrix_set ); PROVIDE ( esp_rom_get_cpu_ticks_per_us = ets_get_cpu_frequency ); +PROVIDE ( esp_rom_spiflash_attach = spi_flash_attach ); PROVIDE ( esp_rom_spiflash_clear_bp = esp_rom_spiflash_unlock ); PROVIDE ( esp_rom_spiflash_write_enable = SPI_write_enable ); PROVIDE ( esp_rom_spiflash_erase_area = SPIEraseArea ); diff --git a/components/esp_rom/esp32h4/ld/rev1/esp32h4.rom.api.ld b/components/esp_rom/esp32h4/ld/rev1/esp32h4.rom.api.ld index a12e1c2c5a..a108eb5b36 100644 --- a/components/esp_rom/esp32h4/ld/rev1/esp32h4.rom.api.ld +++ b/components/esp_rom/esp32h4/ld/rev1/esp32h4.rom.api.ld @@ -47,6 +47,7 @@ PROVIDE ( esp_rom_get_reset_reason = rtc_get_reset_reason ); PROVIDE ( esp_rom_route_intr_matrix = intr_matrix_set ); PROVIDE ( esp_rom_get_cpu_ticks_per_us = ets_get_cpu_frequency ); +PROVIDE ( esp_rom_spiflash_attach = spi_flash_attach ); PROVIDE ( esp_rom_spiflash_clear_bp = esp_rom_spiflash_unlock ); PROVIDE ( esp_rom_spiflash_write_enable = SPI_write_enable); PROVIDE ( esp_rom_spiflash_erase_area = SPIEraseArea ); diff --git a/components/esp_system/esp_err.c b/components/esp_system/esp_err.c index 7fbaf9dcaa..ecc3de99bb 100644 --- a/components/esp_system/esp_err.c +++ b/components/esp_system/esp_err.c @@ -31,7 +31,10 @@ static void esp_error_check_failed_print(const char *msg, esp_err_t rc, const ch esp_rom_printf(" (%s)", esp_err_to_name(rc)); #endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP esp_rom_printf(" at 0x%08x\n", esp_cpu_get_call_addr(addr)); - if (spi_flash_cache_enabled()) { // strings may be in flash cache +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + if (spi_flash_cache_enabled()) // strings may be in flash cache +#endif + { esp_rom_printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression); } } diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in index ac7ab6cfb8..bb2ed2f14c 100644 --- a/components/esp_system/ld/esp32c3/sections.ld.in +++ b/components/esp_system/ld/esp32c3/sections.ld.in @@ -250,7 +250,7 @@ SECTIONS . = . + SIZEOF(.flash.text); /* Prepare the alignment of the section above. Few bytes (0x20) must be * added for the mapping header. */ - . = ALIGN(0x10000) + 0x20; + . = ALIGN(_esp_mmu_block_size) + 0x20; _rodata_reserved_start = .; } > default_rodata_seg diff --git a/components/esp_system/ld/esp32c6/sections.ld.in b/components/esp_system/ld/esp32c6/sections.ld.in index 7a17be374e..d8e72f755a 100644 --- a/components/esp_system/ld/esp32c6/sections.ld.in +++ b/components/esp_system/ld/esp32c6/sections.ld.in @@ -283,7 +283,7 @@ SECTIONS . = . + SIZEOF(.flash.text); /* Prepare the alignment of the section above. Few bytes (0x20) must be * added for the mapping header. */ - . = ALIGN(0x10000) + 0x20; + . = ALIGN(_esp_mmu_block_size) + 0x20; _rodata_reserved_start = .; } > default_rodata_seg diff --git a/components/esp_system/ld/esp32h2/sections.ld.in b/components/esp_system/ld/esp32h2/sections.ld.in index 68508de11b..096e63d27d 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -283,7 +283,7 @@ SECTIONS . = . + SIZEOF(.flash.text); /* Prepare the alignment of the section above. Few bytes (0x20) must be * added for the mapping header. */ - . = ALIGN(0x10000) + 0x20; + . = ALIGN(_esp_mmu_block_size) + 0x20; _rodata_reserved_start = .; } > default_rodata_seg diff --git a/components/esp_system/ld/esp32h4/sections.ld.in b/components/esp_system/ld/esp32h4/sections.ld.in index ec03a82fb2..84726e7414 100644 --- a/components/esp_system/ld/esp32h4/sections.ld.in +++ b/components/esp_system/ld/esp32h4/sections.ld.in @@ -253,7 +253,7 @@ SECTIONS . = . + SIZEOF(.flash.text); /* Prepare the alignment of the section above. Few bytes (0x20) must be * added for the mapping header. */ - . = ALIGN(0x10000) + 0x20; + . = ALIGN(_esp_mmu_block_size) + 0x20; _rodata_reserved_start = .; } > default_rodata_seg diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index 1ea6eaa606..575e1e289e 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -188,7 +188,6 @@ SECTIONS /* iram_end_test section exists for use by memprot unit tests only */ *(.iram_end_test) _iram_text_end = ABSOLUTE(.); - _iram_end = ABSOLUTE(.); } > iram0_0_seg .dram0_reserved_for_iram (NOLOAD): diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index efe69736e9..afd83defa1 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -287,7 +287,7 @@ SECTIONS . = . + SIZEOF(.flash.text); /* Prepare the alignment of the section above. Few bytes (0x20) must be * added for the mapping header. */ - . = ALIGN(0x10000) + 0x20; + . = ALIGN(_esp_mmu_block_size) + 0x20; _rodata_reserved_start = .; /* This is a symbol marking the flash.rodata start, this can be used for mmu driver to maintain virtual address */ } > default_rodata_seg diff --git a/components/esp_system/ld/ld.common b/components/esp_system/ld/ld.common index 26607f9263..46f61c554b 100644 --- a/components/esp_system/ld/ld.common +++ b/components/esp_system/ld/ld.common @@ -23,4 +23,8 @@ _esp_memprot_align_size = CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE; _esp_memprot_align_size = 0; #endif +#if CONFIG_APP_BUILD_TYPE_RAM +_esp_mmu_block_size = 0; +#else _esp_mmu_block_size = (CONFIG_MMU_PAGE_SIZE); +#endif diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index ca11a60508..6c1ef92d1c 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -95,9 +95,10 @@ #include "bootloader_mem.h" -#if CONFIG_APP_BUILD_TYPE_ELF_RAM +#if CONFIG_APP_BUILD_TYPE_RAM #include "esp_rom_spiflash.h" -#endif // CONFIG_APP_BUILD_TYPE_ELF_RAM +#include "bootloader_init.h" +#endif // CONFIG_APP_BUILD_TYPE_RAM //This dependency will be removed in the future #include "soc/ext_mem_defs.h" @@ -176,9 +177,11 @@ void IRAM_ATTR call_start_cpu1(void) // Clear interrupt matrix for APP CPU core core_intr_matrix_clear(); +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP //Take care putting stuff here: if asked, FreeRTOS will happily tell you the scheduler //has started, but it isn't active *on this CPU* yet. esp_cache_err_int_init(); +#endif #if (CONFIG_IDF_TARGET_ESP32 && CONFIG_ESP32_TRAX_TWOBANKS) || \ (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_ESP32S3_TRAX_TWOBANKS) @@ -209,10 +212,10 @@ static void start_other_core(void) ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1); -#if CONFIG_IDF_TARGET_ESP32 +#if CONFIG_IDF_TARGET_ESP32 && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP Cache_Flush(1); Cache_Read_Enable(1); -#endif +#endif // #if CONFIG_IDF_TARGET_ESP32 && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP esp_cpu_unstall(1); @@ -288,6 +291,27 @@ void IRAM_ATTR call_start_cpu0(void) rst_reas[1] = esp_rom_get_reset_reason(1); #endif + //Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this. + memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start)); + +#if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY) + // Clear IRAM BSS + memset(&_iram_bss_start, 0, (&_iram_bss_end - &_iram_bss_start) * sizeof(_iram_bss_start)); +#endif + +#if SOC_RTC_FAST_MEM_SUPPORTED || SOC_RTC_SLOW_MEM_SUPPORTED + /* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */ + if (rst_reas[0] != RESET_REASON_CORE_DEEP_SLEEP) { + memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start)); + } +#endif + + // When the APP is loaded into ram for execution, some hardware initialization behaviors + // in the bootloader are still necessary +#if CONFIG_APP_BUILD_TYPE_RAM + bootloader_init(); +#endif + #ifndef CONFIG_BOOTLOADER_WDT_ENABLE // from panic handler we can be reset by RWDT or TG0WDT if (rst_reas[0] == RESET_REASON_CORE_RTC_WDT || rst_reas[0] == RESET_REASON_CORE_MWDT0 @@ -306,21 +330,7 @@ void IRAM_ATTR call_start_cpu0(void) } #endif - //Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this. - memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start)); - -#if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY) - // Clear IRAM BSS - memset(&_iram_bss_start, 0, (&_iram_bss_end - &_iram_bss_start) * sizeof(_iram_bss_start)); -#endif - -#if SOC_RTC_FAST_MEM_SUPPORTED || SOC_RTC_SLOW_MEM_SUPPORTED - /* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */ - if (rst_reas[0] != RESET_REASON_CORE_DEEP_SLEEP) { - memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start)); - } -#endif - +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if CONFIG_IDF_TARGET_ESP32S2 /* Configure the mode of instruction cache : cache size, cache associated ways, cache line size. */ extern void esp_config_instruction_cache_mode(void); @@ -391,7 +401,6 @@ void IRAM_ATTR call_start_cpu0(void) mspi_timing_flash_tuning(); #endif - bootloader_init_mem(); #if CONFIG_SPIRAM_BOOT_INIT if (esp_psram_init() != ESP_OK) { #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY @@ -407,6 +416,9 @@ void IRAM_ATTR call_start_cpu0(void) #endif } #endif +#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + + bootloader_init_mem(); #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE s_cpu_up[0] = true; @@ -443,6 +455,7 @@ void IRAM_ATTR call_start_cpu0(void) } #endif //CONFIG_SPIRAM_MEMTEST +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP //TODO: IDF-5023, replace with MMU driver #if CONFIG_IDF_TARGET_ESP32S3 int s_instr_flash2spiram_off = 0; @@ -490,6 +503,7 @@ void IRAM_ATTR call_start_cpu0(void) esp_enable_cache_wrap(1); #endif #endif +#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY memset(&_ext_ram_bss_start, 0, (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start)); @@ -535,7 +549,9 @@ void IRAM_ATTR call_start_cpu0(void) esp_deep_sleep_wakeup_io_reset(); } +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP esp_cache_err_int_init(); +#endif #if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE && !CONFIG_ESP_SYSTEM_MEMPROT_TEST // Memprot cannot be locked during OS startup as the lock-on prevents any PMS changes until a next reboot @@ -575,26 +591,26 @@ void IRAM_ATTR call_start_cpu0(void) // Read the application binary image header. This will also decrypt the header if the image is encrypted. __attribute__((unused)) esp_image_header_t fhdr = {0}; -#ifdef CONFIG_APP_BUILD_TYPE_ELF_RAM +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP fhdr.spi_mode = ESP_IMAGE_SPI_MODE_DIO; fhdr.spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2; fhdr.spi_size = ESP_IMAGE_FLASH_SIZE_4MB; extern void esp_rom_spiflash_attach(uint32_t, bool); -#if !CONFIG_IDF_TARGET_ESP32C2 +#if SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); #else - // ESP32C2 cannot get flash_gpio_info from efuse esp_rom_spiflash_attach(0, false); -#endif // CONFIG_IDF_TARGET_ESP32C2 +#endif bootloader_flash_unlock(); #else // This assumes that DROM is the first segment in the application binary, i.e. that we can read // the binary header through cache by accessing SOC_DROM_LOW address. hal_memcpy(&fhdr, (void *) SOC_DROM_LOW, sizeof(fhdr)); -#endif // CONFIG_APP_BUILD_TYPE_ELF_RAM +#endif // CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if CONFIG_IDF_TARGET_ESP32 #if !CONFIG_SPIRAM_BOOT_INIT // If psram is uninitialized, we need to improve some flash configuration. @@ -613,6 +629,7 @@ void IRAM_ATTR call_start_cpu0(void) } bootloader_flash_update_size(app_flash_size); #endif //CONFIG_SPI_FLASH_SIZE_OVERRIDE +#endif //!CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE s_cpu_inited[0] = true; diff --git a/components/esp_system/port/panic_handler.c b/components/esp_system/port/panic_handler.c index 3acf88a236..013c77a7e5 100644 --- a/components/esp_system/port/panic_handler.c +++ b/components/esp_system/port/panic_handler.c @@ -196,20 +196,22 @@ static void panic_handler(void *frame, bool pseudo_excause) * This function must always be in IRAM as it is required to * re-enable the flash cache. */ +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP static void IRAM_ATTR panic_enable_cache(void) { int core_id = esp_cpu_get_core_id(); - if (!spi_flash_cache_enabled()) { esp_ipc_isr_stall_abort(); spi_flash_enable_cache(core_id); } } +#endif void IRAM_ATTR panicHandler(void *frame) { - +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP panic_enable_cache(); +#endif // This panic handler gets called for when the double exception vector, // kernel exception vector gets used; as well as handling interrupt-based // faults cache error, wdt expiry. EXCAUSE register gets written with @@ -219,7 +221,9 @@ void IRAM_ATTR panicHandler(void *frame) void IRAM_ATTR xt_unhandled_exception(void *frame) { +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP panic_enable_cache(); +#endif panic_handler(frame, false); } diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index 2a361cbc03..73b390fca1 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -331,6 +331,7 @@ static void do_core_init(void) err = esp_pthread_init(); assert(err == ESP_OK && "Failed to init pthread module!"); +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if CONFIG_SPI_FLASH_ROM_IMPL spi_flash_rom_impl_init(); #endif @@ -342,6 +343,7 @@ static void do_core_init(void) #if CONFIG_SPI_FLASH_BROWNOUT_RESET spi_flash_needs_reset_check(); #endif // CONFIG_SPI_FLASH_BROWNOUT_RESET +#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); diff --git a/components/esptool_py/CMakeLists.txt b/components/esptool_py/CMakeLists.txt index 094da4d240..1497be79f5 100644 --- a/components/esptool_py/CMakeLists.txt +++ b/components/esptool_py/CMakeLists.txt @@ -48,13 +48,14 @@ consist of two ota app without factory or test partitions.") CONTENT "${flasher_args_content}") file_generate("${CMAKE_BINARY_DIR}/flasher_args.json" INPUT "${CMAKE_CURRENT_BINARY_DIR}/flasher_args.json.in") - - # Generate app_check_size_command target to check the app size against the partition table parameters - partition_table_add_check_size_target(app_check_size - DEPENDS gen_project_binary - BINARY_PATH "${build_dir}/${PROJECT_BIN}" - PARTITION_TYPE app) - add_dependencies(app app_check_size) + if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) + # Generate app_check_size_command target to check the app size against the partition table parameters + partition_table_add_check_size_target(app_check_size + DEPENDS gen_project_binary + BINARY_PATH "${build_dir}/${PROJECT_BIN}" + PARTITION_TYPE app) + add_dependencies(app app_check_size) + endif() endif() endif() # NOT BOOTLOADER_BUILD diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 3b74136093..b091de1ebe 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -1,4 +1,5 @@ menu "Serial flasher config" + depends on !APP_BUILD_TYPE_PURE_RAM_APP config ESPTOOLPY_NO_STUB bool "Disable download stub" diff --git a/components/esptool_py/project_include.cmake b/components/esptool_py/project_include.cmake index 709c007960..0e52d0c9c4 100644 --- a/components/esptool_py/project_include.cmake +++ b/components/esptool_py/project_include.cmake @@ -19,58 +19,75 @@ set(ESPTOOLPY ${python} "$ENV{ESPTOOL_WRAPPER}" "${CMAKE_CURRENT_LIST_DIR}/espto set(ESPSECUREPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espsecure.py") set(ESPEFUSEPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espefuse.py") set(ESPMONITOR ${python} "${idf_path}/tools/idf_monitor.py") - -if(CONFIG_SPI_FLASH_HPM_ENABLE) -# When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode -# because on some flash chips, 120M will modify the status register, -# which will make ROM won't work. -# This change intends to be for esptool only and the bootloader should keep use -# ``DOUT`` mode. - set(ESPFLASHMODE "dout") - message("Note: HPM is enabled for the flash, force the ROM bootloader into DOUT mode for stable boot on") -else() - set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE}) -endif() -set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ}) -set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE}) - set(ESPTOOLPY_CHIP "${chip_model}") -set(esptool_elf2image_args - --flash_mode ${ESPFLASHMODE} - --flash_freq ${ESPFLASHFREQ} - --flash_size ${ESPFLASHSIZE} - ) - -if(BOOTLOADER_BUILD AND CONFIG_SECURE_BOOT_V2_ENABLED) - # The bootloader binary needs to be 4KB aligned in order to append a secure boot V2 signature block. - # If CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES is NOT set, the bootloader - # image generated is not 4KB aligned for external HSM to sign it readily. - # Following esptool option --pad-to-size 4KB generates a 4K aligned bootloader image. - # In case of signing during build, espsecure.py "sign_data" operation handles the 4K alignment of the image. - if(NOT CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES) - list(APPEND esptool_elf2image_args --pad-to-size 4KB) +if(NOT CONFIG_APP_BUILD_TYPE_RAM AND CONFIG_APP_BUILD_GENERATE_BINARIES) + if(CONFIG_SPI_FLASH_HPM_ENABLE) + # When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode + # because on some flash chips, 120M will modify the status register, + # which will make ROM won't work. + # This change intends to be for esptool only and the bootloader should keep use + # ``DOUT`` mode. + set(ESPFLASHMODE "dout") + message("Note: HPM is enabled for the flash, force the ROM bootloader into DOUT mode for stable boot on") + else() + set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE}) endif() -endif() + set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ}) + set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE}) -set(MMU_PAGE_SIZE ${CONFIG_MMU_PAGE_MODE}) -if(NOT BOOTLOADER_BUILD) - list(APPEND esptool_elf2image_args --elf-sha256-offset 0xb0) - # For chips that support configurable MMU page size feature - # If page size is configured to values other than the default "64KB" in menuconfig, - # then we need to pass the actual size to flash-mmu-page-size arg - if(NOT MMU_PAGE_SIZE STREQUAL "64KB") - list(APPEND esptool_elf2image_args --flash-mmu-page-size ${MMU_PAGE_SIZE}) + set(esptool_elf2image_args + --flash_mode ${ESPFLASHMODE} + --flash_freq ${ESPFLASHFREQ} + --flash_size ${ESPFLASHSIZE} + ) + + if(BOOTLOADER_BUILD AND CONFIG_SECURE_BOOT_V2_ENABLED) + # The bootloader binary needs to be 4KB aligned in order to append a secure boot V2 signature block. + # If CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES is NOT set, the bootloader + # image generated is not 4KB aligned for external HSM to sign it readily. + # Following esptool option --pad-to-size 4KB generates a 4K aligned bootloader image. + # In case of signing during build, espsecure.py "sign_data" operation handles the 4K alignment of the image. + if(NOT CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES) + list(APPEND esptool_elf2image_args --pad-to-size 4KB) + endif() endif() -endif() -if(NOT CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION AND - NOT BOOTLOADER_BUILD) - if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) - list(APPEND esptool_elf2image_args --secure-pad) - elseif(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) - list(APPEND esptool_elf2image_args --secure-pad-v2) + set(MMU_PAGE_SIZE ${CONFIG_MMU_PAGE_MODE}) + + if(NOT BOOTLOADER_BUILD) + list(APPEND esptool_elf2image_args --elf-sha256-offset 0xb0) + # For chips that support configurable MMU page size feature + # If page size is configured to values other than the default "64KB" in menuconfig, + # then we need to pass the actual size to flash-mmu-page-size arg + if(NOT MMU_PAGE_SIZE STREQUAL "64KB") + list(APPEND esptool_elf2image_args --flash-mmu-page-size ${MMU_PAGE_SIZE}) + endif() + endif() + + if(NOT CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION AND + NOT BOOTLOADER_BUILD) + if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) + list(APPEND esptool_elf2image_args --secure-pad) + elseif(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) + list(APPEND esptool_elf2image_args --secure-pad-v2) + endif() + endif() + + if(CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE) + # Set ESPFLASHSIZE to 'detect' *after* esptool_elf2image_args are generated, + # as elf2image can't have 'detect' as an option... + set(ESPFLASHSIZE detect) + + # Flash size detection updates the image header which would invalidate the appended + # SHA256 digest. Therefore, a digest is not appended in that case. + # This argument requires esptool>=4.1. + list(APPEND esptool_elf2image_args --dont-append-digest) + endif() + + if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME) + set(ESPFLASHSIZE keep) endif() endif() @@ -482,7 +499,11 @@ function(esptool_py_custom_target target_name flasher_filename dependencies) endfunction() if(NOT BOOTLOADER_BUILD) - set(flash_deps "partition_table_bin") + set(flash_deps "") + + if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) + list(APPEND flash_deps "partition_table_bin") + endif() if(CONFIG_APP_BUILD_GENERATE_BINARIES) list(APPEND flash_deps "app") diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index da8ae89434..33eb859c3e 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -8,8 +8,8 @@ endif() set(srcs "mpu_hal.c" "efuse_hal.c" - "${target}/efuse_hal.c" - "mmu_hal.c") + "${target}/efuse_hal.c") + set(includes "${target}/include" "include" "platform_port/include") @@ -17,7 +17,11 @@ if(NOT CONFIG_HAL_WDT_USE_ROM_IMPL) list(APPEND srcs "wdt_hal_iram.c") endif() -if(NOT ${target} STREQUAL "esp32") +if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + list(APPEND srcs "mmu_hal.c") +endif() + +if(NOT ${target} STREQUAL "esp32" AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) list(APPEND srcs "cache_hal.c") endif() @@ -35,13 +39,18 @@ if(NOT BOOTLOADER_BUILD) "gpio_hal.c" "uart_hal.c" "uart_hal_iram.c" - "spi_flash_hal.c" - "spi_flash_hal_iram.c" - "spi_flash_encrypt_hal_iram.c" "adc_hal_common.c" "adc_oneshot_hal.c" "${target}/clk_tree_hal.c") + if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + list(APPEND srcs + "spi_flash_hal.c" + "spi_flash_hal_iram.c" + "spi_flash_encrypt_hal_iram.c" + ) + endif() + if(CONFIG_SOC_SYSTIMER_SUPPORTED AND NOT CONFIG_HAL_SYSTIMER_USE_ROM_IMPL) list(APPEND srcs "systimer_hal.c") endif() diff --git a/components/hal/linker.lf b/components/hal/linker.lf index 42aec03118..fe94161376 100644 --- a/components/hal/linker.lf +++ b/components/hal/linker.lf @@ -1,8 +1,11 @@ [mapping:hal] archive: libhal.a entries: - mmu_hal (noflash) - if IDF_TARGET_ESP32 = n: + if APP_BUILD_TYPE_PURE_RAM_APP = n: + mmu_hal (noflash) + spi_flash_hal_iram (noflash) + spi_flash_encrypt_hal_iram (noflash) + if IDF_TARGET_ESP32 = n && APP_BUILD_TYPE_PURE_RAM_APP = n: cache_hal (noflash) if SOC_GPSPI_SUPPORTED = y: spi_hal_iram (noflash) @@ -11,8 +14,6 @@ entries: uart_hal_iram (noflash) else: uart_hal_iram (default) - spi_flash_hal_iram (noflash) - spi_flash_encrypt_hal_iram (noflash) if SOC_LEDC_SUPPORTED = y: ledc_hal_iram (noflash) if SOC_I2C_SUPPORTED = y: diff --git a/components/newlib/assert.c b/components/newlib/assert.c index bb8449339a..5b0d80736f 100644 --- a/components/newlib/assert.c +++ b/components/newlib/assert.c @@ -47,7 +47,10 @@ void __attribute__((noreturn)) __assert_func(const char *file, int line, const c itoa(line, lbuf, 10); - if (!spi_flash_cache_enabled()) { +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + if (!spi_flash_cache_enabled()) +#endif + { if (esp_ptr_in_drom(file)) { file = CACHE_DISABLED_STR; } diff --git a/components/openthread/CMakeLists.txt b/components/openthread/CMakeLists.txt index 732d7a51ad..73569f24ff 100644 --- a/components/openthread/CMakeLists.txt +++ b/components/openthread/CMakeLists.txt @@ -1,4 +1,6 @@ if(CONFIG_OPENTHREAD_ENABLED) + idf_build_get_property(idf_target IDF_TARGET) + set(public_include_dirs "include" "openthread/include") diff --git a/components/partition_table/CMakeLists.txt b/components/partition_table/CMakeLists.txt index f386028612..5eaec4d312 100644 --- a/components/partition_table/CMakeLists.txt +++ b/components/partition_table/CMakeLists.txt @@ -144,7 +144,7 @@ endif() idf_component_get_property(main_args esptool_py FLASH_ARGS) idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS) -if(CONFIG_APP_BUILD_GENERATE_BINARIES) +if(CONFIG_APP_BUILD_GENERATE_BINARIES AND CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) esptool_py_flash_target(partition-table-flash "${main_args}" "${sub_args}") esptool_py_flash_target_image(partition-table-flash partition-table "${PARTITION_TABLE_OFFSET}" "${build_dir}/partition_table/${final_partition_bin}") diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 08129892d3..c3b32e2bed 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -3,17 +3,10 @@ if(${target} STREQUAL "linux") return() endif() -if(BOOTLOADER_BUILD) +if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) set(cache_srcs "") set(priv_requires bootloader_support soc) else() - set(cache_srcs - "cache_utils.c" - "flash_mmap.c" - "flash_ops.c" - "${target}/flash_ops_${target}.c" - ) - set(srcs "flash_brownout_hook.c") if(CONFIG_SOC_SPI_MEM_SUPPORT_OPI_MODE) @@ -38,6 +31,13 @@ else() "spi_flash_chip_th.c" "memspi_host_driver.c") + set(cache_srcs + "cache_utils.c" + "flash_mmap.c" + "flash_ops.c" + "${target}/flash_ops_${target}.c" + ) + list(APPEND cache_srcs "esp_flash_api.c" "esp_flash_spi_init.c" @@ -63,7 +63,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU") " -fno-inline-small-functions -fno-inline-functions-called-once") endif() -if(NOT BOOTLOADER_BUILD) +if(NOT BOOTLOADER_BUILD AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) if(CONFIG_SPIRAM) # [refactor-todo]: requires "esp_psram" for few MMU usages in `flash_mmap.c` # will be replaced with MMU requirements diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 209d6e1cd4..cf73c13af1 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -1,4 +1,5 @@ menu "SPI Flash driver" + depends on !APP_BUILD_TYPE_PURE_RAM_APP config SPI_FLASH_VERIFY_WRITE bool "Verify SPI flash writes" diff --git a/components/spi_flash/linker.lf b/components/spi_flash/linker.lf index 62130ab71a..1d9a112655 100644 --- a/components/spi_flash/linker.lf +++ b/components/spi_flash/linker.lf @@ -1,19 +1,20 @@ [mapping:spi_flash] archive: libspi_flash.a entries: - spi_flash_chip_generic (noflash) - spi_flash_chip_issi (noflash) - spi_flash_chip_mxic (noflash) - spi_flash_chip_gd (noflash) - spi_flash_chip_winbond (noflash) - spi_flash_chip_boya (noflash) - spi_flash_chip_th (noflash) - memspi_host_driver (noflash) - flash_brownout_hook (noflash) + if APP_BUILD_TYPE_PURE_RAM_APP = n: + spi_flash_chip_generic (noflash) + spi_flash_chip_issi (noflash) + spi_flash_chip_mxic (noflash) + spi_flash_chip_gd (noflash) + spi_flash_chip_winbond (noflash) + spi_flash_chip_boya (noflash) + spi_flash_chip_th (noflash) + memspi_host_driver (noflash) + flash_brownout_hook (noflash) - if IDF_TARGET_ESP32S3 = y: - spi_flash_chip_mxic_opi (noflash) - spi_flash_hpm_enable (noflash) + if IDF_TARGET_ESP32S3 = y: + spi_flash_chip_mxic_opi (noflash) + spi_flash_hpm_enable (noflash) - if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y: - spi_flash_oct_flash_init (noflash) + if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y: + spi_flash_oct_flash_init (noflash) diff --git a/sdkconfig.rename b/sdkconfig.rename index 1b3c415ddf..e0b4d367c9 100644 --- a/sdkconfig.rename +++ b/sdkconfig.rename @@ -23,3 +23,4 @@ CONFIG_WARN_WRITE_STRINGS CONFIG_COMPILER_WARN_WRITE_STRINGS CONFIG_NO_BLOBS CONFIG_APP_NO_BLOBS CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS +CONFIG_APP_BUILD_TYPE_ELF_RAM CONFIG_APP_BUILD_TYPE_RAM diff --git a/tools/ci/test_build_system_cmake.sh b/tools/ci/test_build_system_cmake.sh index cbc800c3cc..4b8701f60c 100755 --- a/tools/ci/test_build_system_cmake.sh +++ b/tools/ci/test_build_system_cmake.sh @@ -885,7 +885,7 @@ endmenu\n" >> ${IDF_PATH}/Kconfig rm -rf build sdkconfig print_status "Loadable ELF build works" - echo "CONFIG_APP_BUILD_TYPE_ELF_RAM=y" > sdkconfig + echo "CONFIG_APP_BUILD_TYPE_RAM=y" > sdkconfig # Set recommend configs to reduce memory footprint echo "CONFIG_VFS_SUPPORT_TERMIOS=n" >> sdkconfig @@ -894,7 +894,7 @@ endmenu\n" >> ${IDF_PATH}/Kconfig echo "CONFIG_ESP_ERR_TO_NAME_LOOKUP=n" >> sdkconfig idf.py reconfigure || failure "Couldn't configure for loadable ELF file" - test -f build/flasher_args.json && failure "flasher_args.json should not be generated in a loadable ELF build" + test ! -f build/flasher_args.json && failure "flasher_args.json should be generated in a loadable ELF build" idf.py build || failure "Couldn't build a loadable ELF file" print_status "Defaults set properly for unspecified idf_build_process args" diff --git a/tools/cmake/project.cmake b/tools/cmake/project.cmake index 7b5e8fb7c9..7852fc41e0 100644 --- a/tools/cmake/project.cmake +++ b/tools/cmake/project.cmake @@ -153,6 +153,12 @@ function(__project_info test_components) idf_build_get_property(COMPONENT_KCONFIGS_PROJBUILD KCONFIG_PROJBUILDS) idf_build_get_property(debug_prefix_map_gdbinit DEBUG_PREFIX_MAP_GDBINIT) + if(CONFIG_APP_BUILD_TYPE_RAM) + set(PROJECT_BUILD_TYPE ram_app) + else() + set(PROJECT_BUILD_TYPE flash_app) + endif() + # Write project description JSON file idf_build_get_property(build_dir BUILD_DIR) make_json_list("${build_components};${test_components}" build_components_json) diff --git a/tools/cmake/project_description.json.in b/tools/cmake/project_description.json.in index 330c5190a9..5400ac20e4 100644 --- a/tools/cmake/project_description.json.in +++ b/tools/cmake/project_description.json.in @@ -7,6 +7,7 @@ "bootloader_elf": "${BOOTLOADER_ELF_FILE}", "app_elf": "${PROJECT_EXECUTABLE}", "app_bin": "${PROJECT_BIN}", + "build_type": "${PROJECT_BUILD_TYPE}", "git_revision": "${IDF_VER}", "target": "${CONFIG_IDF_TARGET}", "rev": "${CONFIG_ESP32_REV_MIN}", diff --git a/tools/test_apps/.build-test-rules.yml b/tools/test_apps/.build-test-rules.yml index 7fc8297b8b..11131f809d 100644 --- a/tools/test_apps/.build-test-rules.yml +++ b/tools/test_apps/.build-test-rules.yml @@ -161,6 +161,12 @@ tools/test_apps/system/panic: temporary: true reason: test app not ported to this target yet +tools/test_apps/system/ram_loadable_app: + disable: + - if: IDF_TARGET == "esp32h2" or IDF_TARGET == "esp32h4" + temporary: true + reason: lack of runners + tools/test_apps/system/startup: enable: - if: INCLUDE_DEFAULT == 1 or IDF_TARGET in ["esp32h4", "esp32c6"] # preview targets diff --git a/tools/test_apps/system/gdb_loadable_elf/conftest.py b/tools/test_apps/system/gdb_loadable_elf/conftest.py new file mode 100644 index 0000000000..6cf51977a3 --- /dev/null +++ b/tools/test_apps/system/gdb_loadable_elf/conftest.py @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=W0621 # redefined-outer-name + +import pytest +from _pytest.fixtures import FixtureRequest +from _pytest.monkeypatch import MonkeyPatch +from test_gdb_loadable_elf_util.loadable_app_serial import LoadableAppSerial + + +@pytest.fixture(scope='module') +def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch: + mp = MonkeyPatch() + request.addfinalizer(mp.undo) + return mp + + +@pytest.fixture(scope='module', autouse=True) +def replace_dut_class(monkeypatch_module: MonkeyPatch) -> None: + monkeypatch_module.setattr('pytest_embedded_idf.serial.IdfSerial', LoadableAppSerial) + monkeypatch_module.setattr('pytest_embedded_idf.IdfSerial', LoadableAppSerial) diff --git a/tools/test_apps/system/gdb_loadable_elf/sdkconfig.defaults b/tools/test_apps/system/gdb_loadable_elf/sdkconfig.defaults index 331e8d5ef6..b7b5ad9822 100644 --- a/tools/test_apps/system/gdb_loadable_elf/sdkconfig.defaults +++ b/tools/test_apps/system/gdb_loadable_elf/sdkconfig.defaults @@ -1,4 +1,4 @@ -CONFIG_APP_BUILD_TYPE_ELF_RAM=y +CONFIG_APP_BUILD_TYPE_RAM=y CONFIG_VFS_SUPPORT_TERMIOS=n CONFIG_NEWLIB_NANO_FORMAT=y CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y diff --git a/tools/test_apps/system/gdb_loadable_elf/test_gdb_loadable_elf_util/loadable_app_serial.py b/tools/test_apps/system/gdb_loadable_elf/test_gdb_loadable_elf_util/loadable_app_serial.py new file mode 100644 index 0000000000..2d38453fbe --- /dev/null +++ b/tools/test_apps/system/gdb_loadable_elf/test_gdb_loadable_elf_util/loadable_app_serial.py @@ -0,0 +1,53 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import logging +from typing import Any, Optional + +import esptool +from pytest_embedded_idf.app import IdfApp +from pytest_embedded_serial_esp.serial import EspSerial, EsptoolArgs + + +class LoadableAppSerial(EspSerial): + def __init__( + self, + app: IdfApp, + target: Optional[str] = None, + **kwargs: Any, + ) -> None: + self.app = app + + if not hasattr(self.app, 'target'): + raise ValueError(f'Idf app not parsable. Please check if it\'s valid: {self.app.binary_path}') + + if target and self.app.target and self.app.target != target: + raise ValueError(f'Targets do not match. App target: {self.app.target}, Cmd target: {target}.') + + super().__init__( + target=target or app.target, + **kwargs, + ) + + def _start(self) -> None: + self.load_ram() + + @EspSerial.use_esptool(hard_reset_after=False, no_stub=True) + def load_ram(self) -> None: + if not self.app.bin_file: + logging.error('No image file detected. Skipping load ram...') + return + + f_bin_file = open(self.app.bin_file, 'rb') + + default_kwargs = { + 'filename': f_bin_file, + 'chip': self.esp.CHIP_NAME.lower().replace('-', ''), + } + + load_ram_args = EsptoolArgs(**default_kwargs) + + try: + self.esp.change_baud(460800) + esptool.load_ram(self.esp, load_ram_args) + finally: + f_bin_file.close() diff --git a/tools/test_apps/system/ram_loadable_app/CMakeLists.txt b/tools/test_apps/system/ram_loadable_app/CMakeLists.txt new file mode 100644 index 0000000000..32cc85adf5 --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(ram_loadable_app) diff --git a/tools/test_apps/system/ram_loadable_app/README.md b/tools/test_apps/system/ram_loadable_app/README.md new file mode 100644 index 0000000000..31d42c0c24 --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/README.md @@ -0,0 +1,49 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# RAM loadable app Example + +Starts a FreeRTOS task to print "Hello World". The segments of this application are +fully linked and run in internal RAM. + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +## How to use example + +### Hardware Required + +This example should be able to run on any commonly available ESP32 development board. + +### Configure the project + +``` +idf.py menuconfig +``` + +This step is optional, the default settings in `sdkconfig.defaults` are already set to enable the ram_loadable app feature. + +`CONFIG_APP_BUILD_TYPE_RAM` is enable by default so that all programs and data are linked into internal RAM. For more information about `CONFIG_APP_BUILD_TYPE_RAM` you can refer to the description in menuconfig. + +(Enabling `APP_BUILD_TYPE_PURE_RAM_APP` option IDF will not compile the `spi_flash` related code into bin, which will save a lot of internal ram space. For `esp32` target, limited by its RAM layout, the available RAM space for the app is too small to accommodate this example without this option enabled, so this option is selected by default for esp32 target.) + +### Build and Load to RAM + +Build the project and load it to the chip's internal RAM, then run monitor tool to view serial output: + +``` +idf.py set-target {target name} + +idf.py build + +esptool.py -p PORT --no-stub load_ram build/ram_loadable_app.bin + +idf.py -p PORT monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +(For ram_loadable_app, after the chip is reset, it will start from flash by default, so the program will be executed directly after loading to ram. Therefore, manually open idf.py monitor will lose part of the log at startup because the serial port cannot be opened in time, so it is recommended to use a separate serial converter to monitor the output of the UART TX pin) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. diff --git a/tools/test_apps/system/ram_loadable_app/conftest.py b/tools/test_apps/system/ram_loadable_app/conftest.py new file mode 100644 index 0000000000..5c99c8eb50 --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/conftest.py @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=W0621 # redefined-outer-name + +import pytest +from _pytest.fixtures import FixtureRequest +from _pytest.monkeypatch import MonkeyPatch +from test_ram_loadable_app_util.loadable_app_serial import LoadableAppSerial + + +@pytest.fixture(scope='module') +def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch: + mp = MonkeyPatch() + request.addfinalizer(mp.undo) + return mp + + +@pytest.fixture(scope='module', autouse=True) +def replace_dut_class(monkeypatch_module: MonkeyPatch) -> None: + monkeypatch_module.setattr('pytest_embedded_idf.serial.IdfSerial', LoadableAppSerial) + monkeypatch_module.setattr('pytest_embedded_idf.IdfSerial', LoadableAppSerial) diff --git a/tools/test_apps/system/ram_loadable_app/main/CMakeLists.txt b/tools/test_apps/system/ram_loadable_app/main/CMakeLists.txt new file mode 100644 index 0000000000..a2342d3e36 --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "ram_loadable_app_example_main.c" + INCLUDE_DIRS "") diff --git a/tools/test_apps/system/ram_loadable_app/main/ram_loadable_app_example_main.c b/tools/test_apps/system/ram_loadable_app/main/ram_loadable_app_example_main.c new file mode 100644 index 0000000000..e1090b0ce6 --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/main/ram_loadable_app_example_main.c @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_chip_info.h" + +void app_main(void) +{ + printf("Hello world!\n"); + + /* Print chip information */ + esp_chip_info_t chip_info; + + esp_chip_info(&chip_info); + printf("This is %s chip with %d CPU core(s), WiFi%s%s, ", + CONFIG_IDF_TARGET, + chip_info.cores, + (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); + + printf("silicon revision %d, ", chip_info.revision); + + printf("Minimum free heap size: %"PRIu32" bytes\n", esp_get_minimum_free_heap_size()); + + printf("App is running in RAM !\n"); + uint32_t uptime = 0; + while (1) { + printf("Time since boot: %"PRIu32" seconds...\n", uptime++); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +} diff --git a/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py b/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py new file mode 100644 index 0000000000..8068351016 --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded_idf.dut import IdfDut + + +@pytest.mark.esp32 +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize('config', ['pure_ram',], indirect=True,) +def test_pure_ram_loadable_app(dut: IdfDut) -> None: + dut.expect('app_start: Starting scheduler', timeout=10) + dut.expect('Time since boot: 3 seconds...', timeout=10) + + +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize('config', ['defaults',], indirect=True,) +def test_ram_loadable_app(dut: IdfDut) -> None: + dut.expect('spi_flash: detected chip', timeout=10) + dut.expect('Time since boot: 3 seconds...', timeout=10) diff --git a/tools/test_apps/system/ram_loadable_app/sdkconfig.ci.defaults b/tools/test_apps/system/ram_loadable_app/sdkconfig.ci.defaults new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/test_apps/system/ram_loadable_app/sdkconfig.ci.pure_ram b/tools/test_apps/system/ram_loadable_app/sdkconfig.ci.pure_ram new file mode 100644 index 0000000000..5158a87a8d --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/sdkconfig.ci.pure_ram @@ -0,0 +1 @@ +CONFIG_APP_BUILD_TYPE_PURE_RAM_APP=y diff --git a/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults b/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults new file mode 100644 index 0000000000..6c0ad38fad --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults @@ -0,0 +1,9 @@ +CONFIG_APP_BUILD_TYPE_RAM=y + +# Save size +CONFIG_VFS_SUPPORT_IO=n + +# Reset is meaningless to ram_app +CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y + +CONFIG_APP_BUILD_TYPE_PURE_RAM_APP=n diff --git a/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 b/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 new file mode 100644 index 0000000000..8feb070c3a --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 @@ -0,0 +1,9 @@ +CONFIG_APP_BUILD_TYPE_RAM=y + +# Save size +CONFIG_VFS_SUPPORT_TERMIOS=n + +# Reset is meaningless to ram_app +CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y + +CONFIG_APP_BUILD_TYPE_PURE_RAM_APP=y diff --git a/tools/test_apps/system/ram_loadable_app/test_ram_loadable_app_util/loadable_app_serial.py b/tools/test_apps/system/ram_loadable_app/test_ram_loadable_app_util/loadable_app_serial.py new file mode 100644 index 0000000000..9cb8ca4dfb --- /dev/null +++ b/tools/test_apps/system/ram_loadable_app/test_ram_loadable_app_util/loadable_app_serial.py @@ -0,0 +1,54 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import logging +from typing import Any, Optional + +import esptool +from pytest_embedded_idf.app import IdfApp +from pytest_embedded_serial_esp.serial import EspSerial, EsptoolArgs + + +class LoadableAppSerial(EspSerial): + def __init__( + self, + app: IdfApp, + target: Optional[str] = None, + **kwargs: Any, + ) -> None: + self.app = app + self.app.bin_file = self.app._get_bin_file() + + if not hasattr(self.app, 'target'): + raise ValueError(f'Idf app not parsable. Please check if it\'s valid: {self.app.binary_path}') + + if target and self.app.target and self.app.target != target: + raise ValueError(f'Targets do not match. App target: {self.app.target}, Cmd target: {target}.') + + super().__init__( + target=target or app.target, + **kwargs, + ) + + def _start(self) -> None: + self.load_ram() + + @EspSerial.use_esptool(hard_reset_after=False, no_stub=True) + def load_ram(self) -> None: + if not self.app.bin_file: + logging.error('No image file detected. Skipping load ram...') + return + + f_bin_file = open(self.app.bin_file, 'rb') + + default_kwargs = { + 'filename': f_bin_file, + 'chip': self.esp.CHIP_NAME.lower().replace('-', ''), + } + + load_ram_args = EsptoolArgs(**default_kwargs) + + try: + self.esp.change_baud(460800) + esptool.load_ram(self.esp, load_ram_args) + finally: + f_bin_file.close()