mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
make bootloader_support support esp32s2beta
This commit is contained in:
parent
b146104885
commit
61ce868396
@ -1,18 +1,8 @@
|
|||||||
set(COMPONENT_SRCS "bootloader_start.c")
|
idf_component_register(SRCS "bootloader_start.c"
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS "")
|
REQUIRES bootloader bootloader_support)
|
||||||
set(COMPONENT_REQUIRES bootloader bootloader_support)
|
|
||||||
register_component()
|
|
||||||
|
|
||||||
idf_build_get_property(target IDF_TARGET)
|
idf_build_get_property(target IDF_TARGET)
|
||||||
|
set(scripts "ld/${target}/bootloader.ld"
|
||||||
|
"ld/${target}/bootloader.rom.ld")
|
||||||
|
|
||||||
target_linker_script(${COMPONENT_LIB}
|
target_linker_script(${COMPONENT_LIB} "${scripts}")
|
||||||
"ld/${target}/bootloader.ld"
|
|
||||||
"ld/${target}/bootloader.rom.ld"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(scripts
|
|
||||||
"${IDF_PATH}/components/esp_rom/${target}/ld/${target}.rom.ld"
|
|
||||||
"${IDF_PATH}/components/esp_rom/${target}/ld/${target}.rom.newlib-funcs.ld"
|
|
||||||
"${IDF_PATH}/components/${target}/ld/${target}.peripherals.ld")
|
|
||||||
|
|
||||||
target_linker_script(${COMPONENT_LIB} ${scripts})
|
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
PROVIDE ( ets_update_cpu_frequency = 0x4000d954 );
|
PROVIDE ( ets_update_cpu_frequency = 0x4000d954 );
|
||||||
|
|
||||||
/* ToDo: Following address may need modification */
|
/* ToDo: Following address may need modification */
|
||||||
PROVIDE ( MD5Final = 0x4005db1c );
|
PROVIDE ( MD5Final = 0x400056e8 );
|
||||||
PROVIDE ( MD5Init = 0x4005da7c );
|
PROVIDE ( MD5Init = 0x40005648 );
|
||||||
PROVIDE ( MD5Update = 0x4005da9c );
|
PROVIDE ( MD5Update = 0x40005668 );
|
||||||
/* bootloader will use following functions from xtensa hal library */
|
/* bootloader will use following functions from xtensa hal library */
|
||||||
xthal_get_ccount = 0x4000c050;
|
xthal_get_ccount = 0x40015cbc;
|
||||||
xthal_get_ccompare = 0x4000c078;
|
xthal_get_ccompare = 0x40015ce8;
|
||||||
xthal_set_ccompare = 0x4000c058;
|
xthal_set_ccompare = 0x40015cc4;
|
||||||
|
@ -15,7 +15,9 @@ if(BOOTLOADER_BUILD)
|
|||||||
"src/${IDF_TARGET}/bootloader_sha.c"
|
"src/${IDF_TARGET}/bootloader_sha.c"
|
||||||
"src/${IDF_TARGET}/flash_encrypt.c"
|
"src/${IDF_TARGET}/flash_encrypt.c"
|
||||||
"src/${IDF_TARGET}/secure_boot_signatures.c"
|
"src/${IDF_TARGET}/secure_boot_signatures.c"
|
||||||
"src/${IDF_TARGET}/secure_boot.c")
|
"src/${IDF_TARGET}/secure_boot.c"
|
||||||
|
"src/${IDF_TARGET}/bootloader_${IDF_TARGET}.c"
|
||||||
|
"src/${IDF_TARGET}/bootloader_clock_${IDF_TARGET}.c")
|
||||||
|
|
||||||
if(CONFIG_SECURE_SIGNED_APPS)
|
if(CONFIG_SECURE_SIGNED_APPS)
|
||||||
get_filename_component(secure_boot_verification_key
|
get_filename_component(secure_boot_verification_key
|
||||||
|
@ -46,10 +46,10 @@ $(ORIG_SECURE_BOOT_VERIFICATION_KEY):
|
|||||||
$(SECURE_BOOT_VERIFICATION_KEY): $(ORIG_SECURE_BOOT_VERIFICATION_KEY) $(SDKCONFIG_MAKEFILE)
|
$(SECURE_BOOT_VERIFICATION_KEY): $(ORIG_SECURE_BOOT_VERIFICATION_KEY) $(SDKCONFIG_MAKEFILE)
|
||||||
$(summary) CP $< $@
|
$(summary) CP $< $@
|
||||||
cp $< $@
|
cp $< $@
|
||||||
endif
|
endif #CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||||
|
|
||||||
COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY)
|
COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY)
|
||||||
|
|
||||||
COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY)
|
COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY)
|
||||||
|
|
||||||
endif
|
endif #CONFIG_SECURE_SIGNED_APPS
|
||||||
|
@ -19,3 +19,7 @@
|
|||||||
* Called by bootloader, or by the app if the bootloader version is old (pre v2.1).
|
* Called by bootloader, or by the app if the bootloader version is old (pre v2.1).
|
||||||
*/
|
*/
|
||||||
void bootloader_clock_configure(void);
|
void bootloader_clock_configure(void);
|
||||||
|
|
||||||
|
/** @brief Return the rated maximum frequency of this chip
|
||||||
|
*/
|
||||||
|
int bootloader_clock_get_rated_freq_mhz(void);
|
||||||
|
@ -78,6 +78,13 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
|
|||||||
*/
|
*/
|
||||||
bool bootloader_common_label_search(const char *list, char *label);
|
bool bootloader_common_label_search(const char *list, char *label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure default SPI pin modes and drive strengths
|
||||||
|
*
|
||||||
|
* @param drv GPIO drive level (determined by clock frequency)
|
||||||
|
*/
|
||||||
|
void bootloader_configure_spi_pins(int drv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
|
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
|
||||||
*
|
*
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "esp_spi_flash.h"
|
#include "esp_spi_flash.h"
|
||||||
#endif
|
#endif
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file esp_partition.h
|
* @file esp_partition.h
|
||||||
@ -35,8 +36,14 @@
|
|||||||
*
|
*
|
||||||
* @return true if flash encryption is enabled.
|
* @return true if flash encryption is enabled.
|
||||||
*/
|
*/
|
||||||
static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_enabled(void) {
|
static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_enabled(void)
|
||||||
uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT);
|
{
|
||||||
|
uint32_t flash_crypt_cnt;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
flash_crypt_cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_SPI_BOOT_CRYPT_CNT);
|
||||||
|
#endif
|
||||||
/* __builtin_parity is in flash, so we calculate parity inline */
|
/* __builtin_parity is in flash, so we calculate parity inline */
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
while (flash_crypt_cnt) {
|
while (flash_crypt_cnt) {
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include "esp32s2beta/rom/efuse.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||||
#if !defined(CONFIG_SECURE_SIGNED_ON_BOOT) || !defined(CONFIG_SECURE_SIGNED_ON_UPDATE) || !defined(CONFIG_SECURE_SIGNED_APPS)
|
#if !defined(CONFIG_SECURE_SIGNED_ON_BOOT) || !defined(CONFIG_SECURE_SIGNED_ON_UPDATE) || !defined(CONFIG_SECURE_SIGNED_APPS)
|
||||||
@ -36,14 +39,18 @@ extern "C" {
|
|||||||
|
|
||||||
/** @brief Is secure boot currently enabled in hardware?
|
/** @brief Is secure boot currently enabled in hardware?
|
||||||
*
|
*
|
||||||
* Secure boot is enabled if the ABS_DONE_0 efuse is blown. This means
|
* This means that the ROM bootloader code will only boot
|
||||||
* that the ROM bootloader code will only boot a verified secure
|
* a verified secure bootloader from now on.
|
||||||
* bootloader digest from now on.
|
|
||||||
*
|
*
|
||||||
* @return true if secure boot is enabled.
|
* @return true if secure boot is enabled.
|
||||||
*/
|
*/
|
||||||
static inline bool esp_secure_boot_enabled(void) {
|
static inline bool esp_secure_boot_enabled(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0;
|
return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0;
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
return ets_efuse_secure_boot_enabled();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Generate secure digest from bootloader image
|
/** @brief Generate secure digest from bootloader image
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "bootloader_config.h"
|
#include "bootloader_config.h"
|
||||||
#include "esp_image_format.h"
|
#include "esp_image_format.h"
|
||||||
|
#include "bootloader_config.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Load partition table.
|
* @brief Load partition table.
|
||||||
@ -86,3 +87,14 @@ __attribute__((noreturn)) void bootloader_reset(void);
|
|||||||
* ESP_ERR_INVALID_ARG: Error in the passed arguments
|
* ESP_ERR_INVALID_ARG: Error in the passed arguments
|
||||||
*/
|
*/
|
||||||
esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len);
|
esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug log contents of a buffer as hexadecimal
|
||||||
|
*
|
||||||
|
* @note Only works if component log level is DEBUG or higher.
|
||||||
|
*
|
||||||
|
* @param buffer Buffer to log
|
||||||
|
* @param length Length of buffer in bytes. Maximum length 128 bytes.
|
||||||
|
* @param label Label to print at beginning of log line.
|
||||||
|
*/
|
||||||
|
void bootloader_debug_buffer(const void *buffer, size_t length, const char *label);
|
||||||
|
@ -27,23 +27,30 @@ void bootloader_clock_configure()
|
|||||||
// and will be done with the bootloader much earlier than UART FIFO is empty.
|
// and will be done with the bootloader much earlier than UART FIFO is empty.
|
||||||
uart_tx_wait_idle(0);
|
uart_tx_wait_idle(0);
|
||||||
|
|
||||||
/* Set CPU to 80MHz. Keep other clocks unmodified. */
|
|
||||||
int cpu_freq_mhz = 80;
|
|
||||||
|
|
||||||
/* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to
|
/* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to
|
||||||
* 240 MHz may cause the chip to lock up (see section 3.5 of the errata
|
* 240 MHz may cause the chip to lock up (see section 3.5 of the errata
|
||||||
* document). For rev. 0, switch to 240 instead if it has been enabled
|
* document). For rev. 0, switch to 240 instead if it has been enabled
|
||||||
* previously.
|
* previously.
|
||||||
*/
|
*/
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
/* Set CPU to 80MHz. Keep other clocks unmodified. */
|
||||||
|
int cpu_freq_mhz = 80;
|
||||||
|
|
||||||
uint32_t chip_ver_reg = REG_READ(EFUSE_BLK0_RDATA3_REG);
|
uint32_t chip_ver_reg = REG_READ(EFUSE_BLK0_RDATA3_REG);
|
||||||
if ((chip_ver_reg & EFUSE_RD_CHIP_VER_REV1_M) == 0 &&
|
if ((chip_ver_reg & EFUSE_RD_CHIP_VER_REV1_M) == 0 &&
|
||||||
DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL) == DPORT_CPUPERIOD_SEL_240) {
|
DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL) == DPORT_CPUPERIOD_SEL_240) {
|
||||||
cpu_freq_mhz = 240;
|
cpu_freq_mhz = 240;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
|
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
|
||||||
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
||||||
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
|
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
||||||
|
clk_cfg.cpu_freq = RTC_CPU_FREQ_80M;
|
||||||
|
#endif
|
||||||
clk_cfg.slow_freq = rtc_clk_slow_freq_get();
|
clk_cfg.slow_freq = rtc_clk_slow_freq_get();
|
||||||
clk_cfg.fast_freq = rtc_clk_fast_freq_get();
|
clk_cfg.fast_freq = rtc_clk_fast_freq_get();
|
||||||
rtc_clk_init(clk_cfg);
|
rtc_clk_init(clk_cfg);
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp32/rom/crc.h"
|
#include "esp32/rom/crc.h"
|
||||||
#include "esp32/rom/gpio.h"
|
#include "esp32/rom/gpio.h"
|
||||||
#include "esp_secure_boot.h"
|
|
||||||
#include "esp_flash_partitions.h"
|
#include "esp_flash_partitions.h"
|
||||||
#include "bootloader_flash.h"
|
#include "bootloader_flash.h"
|
||||||
#include "bootloader_common.h"
|
#include "bootloader_common.h"
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
#include <esp_spi_flash.h> /* including in bootloader for error values */
|
#include <esp_spi_flash.h> /* including in bootloader for error values */
|
||||||
#include <esp_flash_encrypt.h>
|
#include <esp_flash_encrypt.h>
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include "esp32s2beta/rom/spi_flash.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef BOOTLOADER_BUILD
|
#ifndef BOOTLOADER_BUILD
|
||||||
/* Normal app version maps to esp_spi_flash.h operations...
|
/* Normal app version maps to esp_spi_flash.h operations...
|
||||||
@ -62,7 +65,11 @@ esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size, bool allow_
|
|||||||
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted)
|
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted)
|
||||||
{
|
{
|
||||||
if (write_encrypted) {
|
if (write_encrypted) {
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
return spi_flash_write_encrypted(dest_addr, src, size);
|
return spi_flash_write_encrypted(dest_addr, src, size);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
return SPI_Encrypt_Write(dest_addr, src, size);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
return spi_flash_write(dest_addr, src, size);
|
return spi_flash_write(dest_addr, src, size);
|
||||||
}
|
}
|
||||||
@ -81,16 +88,30 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
|
|||||||
#else
|
#else
|
||||||
/* Bootloader version, uses ROM functions only */
|
/* Bootloader version, uses ROM functions only */
|
||||||
#include <soc/dport_reg.h>
|
#include <soc/dport_reg.h>
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#include <esp32/rom/spi_flash.h>
|
#include <esp32/rom/spi_flash.h>
|
||||||
#include <esp32/rom/cache.h>
|
#include <esp32/rom/cache.h>
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include <esp32s2beta/rom/spi_flash.h>
|
||||||
|
#include <esp32s2beta/rom/cache.h>
|
||||||
|
#endif
|
||||||
static const char *TAG = "bootloader_flash";
|
static const char *TAG = "bootloader_flash";
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
/* Use first 50 blocks in MMU for bootloader_mmap,
|
/* Use first 50 blocks in MMU for bootloader_mmap,
|
||||||
50th block for bootloader_flash_read
|
50th block for bootloader_flash_read
|
||||||
*/
|
*/
|
||||||
#define MMU_BLOCK0_VADDR 0x3f400000
|
#define MMU_BLOCK0_VADDR SOC_DROM_LOW
|
||||||
#define MMU_BLOCK50_VADDR 0x3f720000
|
#define MMU_SIZE (0x320000)
|
||||||
|
#define MMU_BLOCK50_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE)
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
/* Use first 63 blocks in MMU for bootloader_mmap,
|
||||||
|
63th block for bootloader_flash_read
|
||||||
|
*/
|
||||||
|
#define MMU_BLOCK0_VADDR SOC_DROM_LOW
|
||||||
|
#define MMU_SIZE (0x3f0000)
|
||||||
|
#define MMU_BLOCK63_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool mapped;
|
static bool mapped;
|
||||||
|
|
||||||
@ -103,25 +124,41 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
|||||||
ESP_LOGE(TAG, "tried to bootloader_mmap twice");
|
ESP_LOGE(TAG, "tried to bootloader_mmap twice");
|
||||||
return NULL; /* can't map twice */
|
return NULL; /* can't map twice */
|
||||||
}
|
}
|
||||||
if (size > 0x320000) {
|
if (size > MMU_SIZE) {
|
||||||
/* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads) */
|
|
||||||
ESP_LOGE(TAG, "bootloader_mmap excess size %x", size);
|
ESP_LOGE(TAG, "bootloader_mmap excess size %x", size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t src_addr_aligned = src_addr & MMU_FLASH_MASK;
|
uint32_t src_addr_aligned = src_addr & MMU_FLASH_MASK;
|
||||||
uint32_t count = bootloader_cache_pages_to_map(size, src_addr);
|
uint32_t count = bootloader_cache_pages_to_map(size, src_addr);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Disable(0);
|
Cache_Read_Disable(0);
|
||||||
Cache_Flush(0);
|
Cache_Flush(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
uint32_t autoload = Cache_Suspend_ICache();
|
||||||
|
Cache_Invalidate_ICache_All();
|
||||||
|
#endif
|
||||||
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d size=%x src_addr=%x src_addr_aligned=%x",
|
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d size=%x src_addr=%x src_addr_aligned=%x",
|
||||||
src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned );
|
src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned );
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count);
|
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
int e = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count, 0);
|
||||||
|
#endif
|
||||||
if (e != 0) {
|
if (e != 0) {
|
||||||
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Enable(0);
|
Cache_Read_Enable(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
Cache_Resume_ICache(autoload);
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Enable(0);
|
Cache_Read_Enable(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
Cache_Resume_ICache(autoload);
|
||||||
|
#endif
|
||||||
|
|
||||||
mapped = true;
|
mapped = true;
|
||||||
|
|
||||||
@ -131,10 +168,17 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
|||||||
void bootloader_munmap(const void *mapping)
|
void bootloader_munmap(const void *mapping)
|
||||||
{
|
{
|
||||||
if (mapped) {
|
if (mapped) {
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
/* Full MMU reset */
|
/* Full MMU reset */
|
||||||
Cache_Read_Disable(0);
|
Cache_Read_Disable(0);
|
||||||
Cache_Flush(0);
|
Cache_Flush(0);
|
||||||
mmu_init(0);
|
mmu_init(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
//TODO, save the autoload value.
|
||||||
|
Cache_Suspend_ICache();
|
||||||
|
Cache_Invalidate_ICache_All();
|
||||||
|
Cache_MMU_Init();
|
||||||
|
#endif
|
||||||
mapped = false;
|
mapped = false;
|
||||||
current_read_mapping = UINT32_MAX;
|
current_read_mapping = UINT32_MAX;
|
||||||
}
|
}
|
||||||
@ -156,10 +200,18 @@ static esp_err_t spi_to_esp_err(esp_rom_spiflash_result_t r)
|
|||||||
|
|
||||||
static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, size_t size)
|
static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, size_t size)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Disable(0);
|
Cache_Read_Disable(0);
|
||||||
Cache_Flush(0);
|
Cache_Flush(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
uint32_t autoload = Cache_Suspend_ICache();
|
||||||
|
#endif
|
||||||
esp_rom_spiflash_result_t r = esp_rom_spiflash_read(src_addr, dest, size);
|
esp_rom_spiflash_result_t r = esp_rom_spiflash_read(src_addr, dest, size);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Enable(0);
|
Cache_Read_Enable(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
Cache_Resume_ICache(autoload);
|
||||||
|
#endif
|
||||||
|
|
||||||
return spi_to_esp_err(r);
|
return spi_to_esp_err(r);
|
||||||
}
|
}
|
||||||
@ -168,28 +220,46 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest
|
|||||||
{
|
{
|
||||||
uint32_t *dest_words = (uint32_t *)dest;
|
uint32_t *dest_words = (uint32_t *)dest;
|
||||||
|
|
||||||
/* Use the 51st MMU mapping to read from flash in 64KB blocks.
|
|
||||||
(MMU will transparently decrypt if encryption is enabled.)
|
|
||||||
*/
|
|
||||||
for (int word = 0; word < size / 4; word++) {
|
for (int word = 0; word < size / 4; word++) {
|
||||||
uint32_t word_src = src_addr + word * 4; /* Read this offset from flash */
|
uint32_t word_src = src_addr + word * 4; /* Read this offset from flash */
|
||||||
uint32_t map_at = word_src & MMU_FLASH_MASK; /* Map this 64KB block from flash */
|
uint32_t map_at = word_src & MMU_FLASH_MASK; /* Map this 64KB block from flash */
|
||||||
uint32_t *map_ptr;
|
uint32_t *map_ptr;
|
||||||
if (map_at != current_read_mapping) {
|
if (map_at != current_read_mapping) {
|
||||||
/* Move the 64KB mmu mapping window to fit map_at */
|
/* Move the 64KB mmu mapping window to fit map_at */
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Disable(0);
|
Cache_Read_Disable(0);
|
||||||
Cache_Flush(0);
|
Cache_Flush(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
uint32_t autoload = Cache_Suspend_ICache();
|
||||||
|
Cache_Invalidate_ICache_All();
|
||||||
|
#endif
|
||||||
ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping);
|
ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK50_VADDR, map_at, 64, 1);
|
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK50_VADDR, map_at, 64, 1);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
int e = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, MMU_BLOCK63_VADDR, map_at, 64, 1, 0);
|
||||||
|
#endif
|
||||||
if (e != 0) {
|
if (e != 0) {
|
||||||
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Enable(0);
|
Cache_Read_Enable(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
Cache_Resume_ICache(autoload);
|
||||||
|
#endif
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
current_read_mapping = map_at;
|
current_read_mapping = map_at;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Enable(0);
|
Cache_Read_Enable(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
Cache_Resume_ICache(autoload);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
map_ptr = (uint32_t *)(MMU_BLOCK50_VADDR + (word_src - map_at));
|
map_ptr = (uint32_t *)(MMU_BLOCK50_VADDR + (word_src - map_at));
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
map_ptr = (uint32_t *)(MMU_BLOCK63_VADDR + (word_src - map_at));
|
||||||
|
#endif
|
||||||
dest_words[word] = *map_ptr;
|
dest_words[word] = *map_ptr;
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@ -240,7 +310,12 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (write_encrypted) {
|
if (write_encrypted) {
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
return spi_to_esp_err(esp_rom_spiflash_write_encrypted(dest_addr, src, size));
|
return spi_to_esp_err(esp_rom_spiflash_write_encrypted(dest_addr, src, size));
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
// TODO: use the same ROM AP here
|
||||||
|
return spi_to_esp_err(SPI_Encrypt_Write(dest_addr, src, size));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
return spi_to_esp_err(esp_rom_spiflash_write(dest_addr, src, size));
|
return spi_to_esp_err(esp_rom_spiflash_write(dest_addr, src, size));
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#include "esp32/rom/cache.h"
|
#include "esp32/rom/cache.h"
|
||||||
#include "esp32/rom/efuse.h"
|
#include "esp32/rom/efuse.h"
|
||||||
#include "esp32/rom/ets_sys.h"
|
#include "esp32/rom/ets_sys.h"
|
||||||
@ -28,6 +29,19 @@
|
|||||||
#include "esp32/rom/uart.h"
|
#include "esp32/rom/uart.h"
|
||||||
#include "esp32/rom/gpio.h"
|
#include "esp32/rom/gpio.h"
|
||||||
#include "esp32/rom/secure_boot.h"
|
#include "esp32/rom/secure_boot.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include "esp32s2beta/rom/cache.h"
|
||||||
|
#include "esp32s2beta/rom/efuse.h"
|
||||||
|
#include "esp32s2beta/rom/ets_sys.h"
|
||||||
|
#include "esp32s2beta/rom/spi_flash.h"
|
||||||
|
#include "esp32s2beta/rom/crc.h"
|
||||||
|
#include "esp32s2beta/rom/rtc.h"
|
||||||
|
#include "esp32s2beta/rom/uart.h"
|
||||||
|
#include "esp32s2beta/rom/gpio.h"
|
||||||
|
#include "esp32s2beta/rom/secure_boot.h"
|
||||||
|
#else
|
||||||
|
#error "Unsupported IDF_TARGET"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "soc/cpu.h"
|
#include "soc/cpu.h"
|
||||||
@ -39,6 +53,11 @@
|
|||||||
#include "soc/timer_periph.h"
|
#include "soc/timer_periph.h"
|
||||||
#include "soc/rtc_wdt.h"
|
#include "soc/rtc_wdt.h"
|
||||||
#include "soc/spi_periph.h"
|
#include "soc/spi_periph.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include "soc/spi_mem_reg.h"
|
||||||
|
#include "soc/extmem_reg.h"
|
||||||
|
#include "soc/assist_debug_reg.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_image_format.h"
|
#include "esp_image_format.h"
|
||||||
@ -48,6 +67,7 @@
|
|||||||
#include "bootloader_flash.h"
|
#include "bootloader_flash.h"
|
||||||
#include "bootloader_random.h"
|
#include "bootloader_random.h"
|
||||||
#include "bootloader_config.h"
|
#include "bootloader_config.h"
|
||||||
|
#include "bootloader_common.h"
|
||||||
#include "bootloader_clock.h"
|
#include "bootloader_clock.h"
|
||||||
#include "bootloader_common.h"
|
#include "bootloader_common.h"
|
||||||
|
|
||||||
@ -63,6 +83,7 @@ static const char* TAG = "boot";
|
|||||||
static esp_err_t bootloader_main();
|
static esp_err_t bootloader_main();
|
||||||
static void print_flash_info(const esp_image_header_t *pfhdr);
|
static void print_flash_info(const esp_image_header_t *pfhdr);
|
||||||
static void update_flash_config(const esp_image_header_t *pfhdr);
|
static void update_flash_config(const esp_image_header_t *pfhdr);
|
||||||
|
static void vddsdio_configure();
|
||||||
static void flash_gpio_configure(const esp_image_header_t *pfhdr);
|
static void flash_gpio_configure(const esp_image_header_t *pfhdr);
|
||||||
static void uart_console_configure(void);
|
static void uart_console_configure(void);
|
||||||
static void wdt_reset_check(void);
|
static void wdt_reset_check(void);
|
||||||
@ -79,8 +100,10 @@ esp_err_t bootloader_init()
|
|||||||
int *sp = get_sp();
|
int *sp = get_sp();
|
||||||
assert(&_bss_start <= &_bss_end);
|
assert(&_bss_start <= &_bss_end);
|
||||||
assert(&_data_start <= &_data_end);
|
assert(&_data_start <= &_data_end);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
assert(sp < &_bss_start);
|
assert(sp < &_bss_start);
|
||||||
assert(sp < &_data_start);
|
assert(sp < &_data_start);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -89,14 +112,27 @@ esp_err_t bootloader_init()
|
|||||||
|
|
||||||
/* completely reset MMU for both CPUs
|
/* completely reset MMU for both CPUs
|
||||||
(in case serial bootloader was running) */
|
(in case serial bootloader was running) */
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Disable(0);
|
Cache_Read_Disable(0);
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
Cache_Read_Disable(1);
|
Cache_Read_Disable(1);
|
||||||
|
#endif
|
||||||
Cache_Flush(0);
|
Cache_Flush(0);
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
Cache_Flush(1);
|
Cache_Flush(1);
|
||||||
|
#endif
|
||||||
mmu_init(0);
|
mmu_init(0);
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
|
DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
|
||||||
mmu_init(1);
|
mmu_init(1);
|
||||||
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
|
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
|
||||||
|
#endif
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
//TODO, save the autoload value
|
||||||
|
Cache_Suspend_ICache();
|
||||||
|
Cache_Invalidate_ICache_All();
|
||||||
|
Cache_MMU_Init();
|
||||||
|
#endif
|
||||||
/* (above steps probably unnecessary for most serial bootloader
|
/* (above steps probably unnecessary for most serial bootloader
|
||||||
usage, all that's absolutely needed is that we unmask DROM0
|
usage, all that's absolutely needed is that we unmask DROM0
|
||||||
cache on the following two lines - normal ROM boot exits with
|
cache on the following two lines - normal ROM boot exits with
|
||||||
@ -107,9 +143,17 @@ esp_err_t bootloader_init()
|
|||||||
The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
|
The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
|
||||||
necessary to work around a hardware bug.
|
necessary to work around a hardware bug.
|
||||||
*/
|
*/
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
|
DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
|
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
|
||||||
|
#endif
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
DPORT_REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_DROM0);
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
|
DPORT_REG_CLR_BIT(DPORT_APP_ICACHE_CTRL1_REG, DPORT_APP_ICACHE_MASK_DROM0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
if (bootloader_main() != ESP_OK) {
|
if (bootloader_main() != ESP_OK) {
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
@ -127,23 +171,25 @@ static esp_err_t bootloader_main()
|
|||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
flash_gpio_configure(&fhdr);
|
flash_gpio_configure(&fhdr);
|
||||||
#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
|
|
||||||
//Check if ESP32 is rated for a CPU frequency of 160MHz only
|
int rated_freq = bootloader_clock_get_rated_freq_mhz();
|
||||||
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
|
if (rated_freq < CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) {
|
||||||
REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) {
|
ESP_LOGE(TAG, "Chip CPU frequency rated for %dMHz, configured for %dMHz. Modify CPU frequency in menuconfig",
|
||||||
ESP_LOGE(TAG, "Chip CPU frequency rated for 160MHz. Modify CPU frequency in menuconfig");
|
rated_freq, CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ);
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
bootloader_clock_configure();
|
bootloader_clock_configure();
|
||||||
uart_console_configure();
|
uart_console_configure();
|
||||||
wdt_reset_check();
|
wdt_reset_check();
|
||||||
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
|
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "compile time " __TIME__ );
|
ESP_LOGI(TAG, "compile time " __TIME__ );
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
ets_set_appcpu_boot_addr(0);
|
ets_set_appcpu_boot_addr(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
#if CONFIG_BOOTLOADER_WDT_ENABLE && CONFIG_IDF_TARGET_ESP32
|
||||||
ESP_LOGD(TAG, "Enabling RTCWDT(%d ms)", CONFIG_BOOTLOADER_WDT_TIME_MS);
|
ESP_LOGD(TAG, "Enabling RTCWDT(%d ms)", CONFIG_BOOTLOADER_WDT_TIME_MS);
|
||||||
rtc_wdt_protect_off();
|
rtc_wdt_protect_off();
|
||||||
rtc_wdt_disable();
|
rtc_wdt_disable();
|
||||||
@ -153,7 +199,7 @@ static esp_err_t bootloader_main()
|
|||||||
rtc_wdt_set_time(RTC_WDT_STAGE0, CONFIG_BOOTLOADER_WDT_TIME_MS);
|
rtc_wdt_set_time(RTC_WDT_STAGE0, CONFIG_BOOTLOADER_WDT_TIME_MS);
|
||||||
rtc_wdt_enable();
|
rtc_wdt_enable();
|
||||||
rtc_wdt_protect_on();
|
rtc_wdt_protect_on();
|
||||||
#else
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
/* disable watch dog here */
|
/* disable watch dog here */
|
||||||
rtc_wdt_disable();
|
rtc_wdt_disable();
|
||||||
#endif
|
#endif
|
||||||
@ -205,13 +251,21 @@ static void update_flash_config(const esp_image_header_t* pfhdr)
|
|||||||
default:
|
default:
|
||||||
size = 2;
|
size = 2;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Disable(0);
|
Cache_Read_Disable(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
uint32_t autoload = Cache_Suspend_ICache();
|
||||||
|
#endif
|
||||||
// Set flash chip size
|
// Set flash chip size
|
||||||
esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
|
esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
|
||||||
// TODO: set mode
|
// TODO: set mode
|
||||||
// TODO: set frequency
|
// TODO: set frequency
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Flush(0);
|
Cache_Flush(0);
|
||||||
Cache_Read_Enable(0);
|
Cache_Read_Enable(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
Cache_Resume_ICache(autoload);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_flash_info(const esp_image_header_t *phdr)
|
static void print_flash_info(const esp_image_header_t *phdr)
|
||||||
@ -246,6 +300,7 @@ static void print_flash_info(const esp_image_header_t* phdr)
|
|||||||
|
|
||||||
/* SPI mode could have been set to QIO during boot already,
|
/* SPI mode could have been set to QIO during boot already,
|
||||||
so test the SPI registers not the flash header */
|
so test the SPI registers not the flash header */
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
|
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
|
||||||
if (spi_ctrl & SPI_FREAD_QIO) {
|
if (spi_ctrl & SPI_FREAD_QIO) {
|
||||||
str = "QIO";
|
str = "QIO";
|
||||||
@ -260,6 +315,22 @@ static void print_flash_info(const esp_image_header_t* phdr)
|
|||||||
} else {
|
} else {
|
||||||
str = "SLOW READ";
|
str = "SLOW READ";
|
||||||
}
|
}
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
|
||||||
|
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
|
||||||
|
str = "QIO";
|
||||||
|
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
|
||||||
|
str = "QOUT";
|
||||||
|
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
|
||||||
|
str = "DIO";
|
||||||
|
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
|
||||||
|
str = "DOUT";
|
||||||
|
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
|
||||||
|
str = "FAST READ";
|
||||||
|
} else {
|
||||||
|
str = "SLOW READ";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
ESP_LOGI(TAG, "SPI Mode : %s", str );
|
ESP_LOGI(TAG, "SPI Mode : %s", str );
|
||||||
|
|
||||||
switch ( phdr->spi_size ) {
|
switch ( phdr->spi_size ) {
|
||||||
@ -286,14 +357,37 @@ static void print_flash_info(const esp_image_header_t* phdr)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vddsdio_configure()
|
||||||
|
{
|
||||||
|
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||||
|
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
|
||||||
|
if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V
|
||||||
|
cfg.drefh = 3;
|
||||||
|
cfg.drefm = 3;
|
||||||
|
cfg.drefl = 3;
|
||||||
|
cfg.force = 1;
|
||||||
|
rtc_vddsdio_set_config(cfg);
|
||||||
|
ets_delay_us(10); // wait for regulator to become stable
|
||||||
|
}
|
||||||
|
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#define FLASH_CLK_IO 6
|
#define FLASH_CLK_IO 6
|
||||||
#define FLASH_CS_IO 11
|
#define FLASH_CS_IO 11
|
||||||
#define FLASH_SPIQ_IO 7
|
#define FLASH_SPIQ_IO 7
|
||||||
#define FLASH_SPID_IO 8
|
#define FLASH_SPID_IO 8
|
||||||
#define FLASH_SPIWP_IO 10
|
#define FLASH_SPIWP_IO 10
|
||||||
#define FLASH_SPIHD_IO 9
|
#define FLASH_SPIHD_IO 9
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#define FLASH_IO_MATRIX_DUMMY_40M 1
|
#define FLASH_IO_MATRIX_DUMMY_40M 1
|
||||||
#define FLASH_IO_MATRIX_DUMMY_80M 2
|
#define FLASH_IO_MATRIX_DUMMY_80M 2
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#define FLASH_IO_MATRIX_DUMMY_40M 0
|
||||||
|
#define FLASH_IO_MATRIX_DUMMY_80M 0
|
||||||
|
#endif
|
||||||
#define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3
|
#define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -324,20 +418,30 @@ static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr)
|
|||||||
case ESP_IMAGE_SPI_SPEED_80M:
|
case ESP_IMAGE_SPI_SPEED_80M:
|
||||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M;
|
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M;
|
||||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M;
|
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
||||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
||||||
|
SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||||
|
#endif
|
||||||
drv = 3;
|
drv = 3;
|
||||||
break;
|
break;
|
||||||
case ESP_IMAGE_SPI_SPEED_40M:
|
case ESP_IMAGE_SPI_SPEED_40M:
|
||||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M;
|
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M;
|
||||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M;
|
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
|
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
|
||||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
|
||||||
|
SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||||
uint32_t pkg_ver = chip_ver & 0x7;
|
uint32_t pkg_ver = chip_ver & 0x7;
|
||||||
|
|
||||||
@ -393,6 +497,9 @@ static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
bootloader_configure_spi_pins(drv);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_console_configure(void)
|
static void uart_console_configure(void)
|
||||||
@ -450,9 +557,16 @@ static void uart_console_configure(void)
|
|||||||
|
|
||||||
static void wdt_reset_cpu0_info_enable(void)
|
static void wdt_reset_cpu0_info_enable(void)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
//We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
|
//We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
|
||||||
DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE);
|
DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE);
|
||||||
DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE);
|
DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
|
||||||
|
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
|
||||||
|
REG_WRITE(ASSIST_DEBUG_PRO_PDEBUGENABLE, 1);
|
||||||
|
REG_WRITE(ASSIST_DEBUG_PRO_RCD_RECORDING, 1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wdt_reset_info_dump(int cpu)
|
static void wdt_reset_info_dump(int cpu)
|
||||||
@ -461,6 +575,7 @@ static void wdt_reset_info_dump(int cpu)
|
|||||||
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
|
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
|
||||||
const char *cpu_name = cpu ? "APP" : "PRO";
|
const char *cpu_name = cpu ? "APP" : "PRO";
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
if (cpu == 0) {
|
if (cpu == 0) {
|
||||||
stat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_STATUS_REG);
|
stat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_STATUS_REG);
|
||||||
pid = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PID_REG);
|
pid = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PID_REG);
|
||||||
@ -473,6 +588,7 @@ static void wdt_reset_info_dump(int cpu)
|
|||||||
lsdata = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0DATA_REG);
|
lsdata = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0DATA_REG);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
stat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_STATUS_REG);
|
stat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_STATUS_REG);
|
||||||
pid = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PID_REG);
|
pid = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PID_REG);
|
||||||
inst = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGINST_REG);
|
inst = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGINST_REG);
|
||||||
@ -482,7 +598,23 @@ static void wdt_reset_info_dump(int cpu)
|
|||||||
lsstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0STAT_REG);
|
lsstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0STAT_REG);
|
||||||
lsaddr = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0ADDR_REG);
|
lsaddr = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0ADDR_REG);
|
||||||
lsdata = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0DATA_REG);
|
lsdata = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0DATA_REG);
|
||||||
|
#else
|
||||||
|
ESP_LOGE(TAG, "WDT reset info: &s CPU not support!\n", cpu_name);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
stat = 0xdeadbeef;
|
||||||
|
pid = 0;
|
||||||
|
inst = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGINST);
|
||||||
|
dstat = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGSTATUS);
|
||||||
|
data = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGDATA);
|
||||||
|
pc = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGPC);
|
||||||
|
lsstat = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0STAT);
|
||||||
|
lsaddr = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0ADDR);
|
||||||
|
lsdata = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0DATA);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
|
if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
|
||||||
DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
|
DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
|
||||||
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x (waiti mode)", cpu_name, pc);
|
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x (waiti mode)", cpu_name, pc);
|
||||||
@ -506,6 +638,7 @@ static void wdt_reset_check(void)
|
|||||||
RESET_REASON rst_reas[2];
|
RESET_REASON rst_reas[2];
|
||||||
|
|
||||||
rst_reas[0] = rtc_get_reset_reason(0);
|
rst_reas[0] = rtc_get_reset_reason(0);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
rst_reas[1] = rtc_get_reset_reason(1);
|
rst_reas[1] = rtc_get_reset_reason(1);
|
||||||
if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET ||
|
if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET ||
|
||||||
rst_reas[0] == TGWDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) {
|
rst_reas[0] == TGWDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) {
|
||||||
@ -517,10 +650,19 @@ static void wdt_reset_check(void)
|
|||||||
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
|
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
wdt_rst = 1;
|
||||||
}
|
}
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET ||
|
||||||
|
rst_reas[0] == TG0WDT_CPU_RESET || rst_reas[0] == TG1WDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) {
|
||||||
|
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
|
wdt_rst = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (wdt_rst) {
|
if (wdt_rst) {
|
||||||
// if reset by WDT dump info from trace port
|
// if reset by WDT dump info from trace port
|
||||||
wdt_reset_info_dump(0);
|
wdt_reset_info_dump(0);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
wdt_reset_info_dump(1);
|
wdt_reset_info_dump(1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
wdt_reset_cpu0_info_enable();
|
wdt_reset_cpu0_info_enable();
|
||||||
}
|
}
|
||||||
|
@ -47,14 +47,18 @@ void bootloader_fill_random(void *buffer, size_t length)
|
|||||||
as-is, we repeatedly read the RNG register and XOR all
|
as-is, we repeatedly read the RNG register and XOR all
|
||||||
values.
|
values.
|
||||||
*/
|
*/
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
random = REG_READ(WDEV_RND_REG);
|
random = REG_READ(WDEV_RND_REG);
|
||||||
RSR(CCOUNT, start);
|
RSR(CCOUNT, start);
|
||||||
do {
|
do {
|
||||||
random ^= REG_READ(WDEV_RND_REG);
|
random ^= REG_READ(WDEV_RND_REG);
|
||||||
RSR(CCOUNT, now);
|
RSR(CCOUNT, now);
|
||||||
} while (now - start < 80 * 32 * 2); /* extra factor of 2 is precautionary */
|
} while (now - start < 80 * 32 * 2); /* extra factor of 2 is precautionary */
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
// ToDo: Get random from register
|
||||||
|
random = 12345678;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_bytes[i] = random >> ((i % 4) * 8);
|
buffer_bytes[i] = random >> ((i % 4) * 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,11 +96,15 @@ void bootloader_random_enable(void)
|
|||||||
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
|
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
|
||||||
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE);
|
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE);
|
||||||
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE);
|
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX);
|
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX);
|
||||||
|
#endif
|
||||||
SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_CLK_DIV, 4, SYSCON_SARADC_SAR_CLK_DIV_S);
|
SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_CLK_DIV, 4, SYSCON_SARADC_SAR_CLK_DIV_S);
|
||||||
|
|
||||||
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_RSTB_WAIT, 8, SYSCON_SARADC_RSTB_WAIT_S); /* was 1 */
|
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_RSTB_WAIT, 8, SYSCON_SARADC_RSTB_WAIT_S); /* was 1 */
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 10, SYSCON_SARADC_START_WAIT_S);
|
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 10, SYSCON_SARADC_START_WAIT_S);
|
||||||
|
#endif
|
||||||
SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_WORK_MODE, 0, SYSCON_SARADC_WORK_MODE_S);
|
SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_WORK_MODE, 0, SYSCON_SARADC_WORK_MODE_S);
|
||||||
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL);
|
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL);
|
||||||
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_SAR_SEL);
|
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_SAR_SEL);
|
||||||
@ -132,10 +140,16 @@ void bootloader_random_disable(void)
|
|||||||
|
|
||||||
/* Restore SAR ADC mode */
|
/* Restore SAR ADC mode */
|
||||||
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST);
|
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX
|
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX
|
||||||
| SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S);
|
| SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S);
|
||||||
|
#endif
|
||||||
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S);
|
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 8, SYSCON_SARADC_START_WAIT_S);
|
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 8, SYSCON_SARADC_START_WAIT_S);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Reset i2s peripheral */
|
/* Reset i2s peripheral */
|
||||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#include "esp32/rom/cache.h"
|
#include "esp32/rom/cache.h"
|
||||||
#include "esp32/rom/efuse.h"
|
#include "esp32/rom/efuse.h"
|
||||||
#include "esp32/rom/ets_sys.h"
|
#include "esp32/rom/ets_sys.h"
|
||||||
@ -28,6 +29,19 @@
|
|||||||
#include "esp32/rom/uart.h"
|
#include "esp32/rom/uart.h"
|
||||||
#include "esp32/rom/gpio.h"
|
#include "esp32/rom/gpio.h"
|
||||||
#include "esp32/rom/secure_boot.h"
|
#include "esp32/rom/secure_boot.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include "esp32s2beta/rom/cache.h"
|
||||||
|
#include "esp32s2beta/rom/efuse.h"
|
||||||
|
#include "esp32s2beta/rom/ets_sys.h"
|
||||||
|
#include "esp32s2beta/rom/spi_flash.h"
|
||||||
|
#include "esp32s2beta/rom/crc.h"
|
||||||
|
#include "esp32s2beta/rom/rtc.h"
|
||||||
|
#include "esp32s2beta/rom/uart.h"
|
||||||
|
#include "esp32s2beta/rom/gpio.h"
|
||||||
|
#include "esp32s2beta/rom/secure_boot.h"
|
||||||
|
#else
|
||||||
|
#error "Unsupported IDF_TARGET"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "soc/cpu.h"
|
#include "soc/cpu.h"
|
||||||
@ -49,7 +63,10 @@
|
|||||||
#include "bootloader_common.h"
|
#include "bootloader_common.h"
|
||||||
#include "bootloader_utility.h"
|
#include "bootloader_utility.h"
|
||||||
#include "bootloader_sha.h"
|
#include "bootloader_sha.h"
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER_BUILD // TODO: efuse component on esp32s2beta
|
||||||
#include "esp_efuse.h"
|
#include "esp_efuse.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *TAG = "boot";
|
static const char *TAG = "boot";
|
||||||
|
|
||||||
@ -143,8 +160,7 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
|
|||||||
bs->ota[partition->subtype & PART_SUBTYPE_OTA_MASK] = partition->pos;
|
bs->ota[partition->subtype & PART_SUBTYPE_OTA_MASK] = partition->pos;
|
||||||
++bs->app_count;
|
++bs->app_count;
|
||||||
partition_usage = "OTA app";
|
partition_usage = "OTA app";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
partition_usage = "Unknown app";
|
partition_usage = "Unknown app";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -571,6 +587,7 @@ static void load_image(const esp_image_metadata_t* image_data)
|
|||||||
so issue a system reset to ensure flash encryption
|
so issue a system reset to ensure flash encryption
|
||||||
cache resets properly */
|
cache resets properly */
|
||||||
ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
|
ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
|
||||||
|
uart_tx_wait_idle(0);
|
||||||
bootloader_reset();
|
bootloader_reset();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -637,8 +654,13 @@ static void set_cache_and_start_app(
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
ESP_LOGD(TAG, "configure drom and irom and start");
|
ESP_LOGD(TAG, "configure drom and irom and start");
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Disable(0);
|
Cache_Read_Disable(0);
|
||||||
Cache_Flush(0);
|
Cache_Flush(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
uint32_t autoload = Cache_Suspend_ICache();
|
||||||
|
Cache_Invalidate_ICache_All();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Clear the MMU entries that are already set up,
|
/* Clear the MMU entries that are already set up,
|
||||||
so the new app only has the mappings it creates.
|
so the new app only has the mappings it creates.
|
||||||
@ -651,32 +673,72 @@ static void set_cache_and_start_app(
|
|||||||
uint32_t drom_page_count = bootloader_cache_pages_to_map(drom_size, drom_load_addr);
|
uint32_t drom_page_count = bootloader_cache_pages_to_map(drom_size, drom_load_addr);
|
||||||
ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d",
|
ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d",
|
||||||
drom_addr & MMU_FLASH_MASK, drom_load_addr_aligned, drom_size, drom_page_count);
|
drom_addr & MMU_FLASH_MASK, drom_load_addr_aligned, drom_size, drom_page_count);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
rc = cache_flash_mmu_set(0, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
|
rc = cache_flash_mmu_set(0, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000,
|
||||||
|
64, drom_page_count, 0);
|
||||||
|
#endif
|
||||||
ESP_LOGV(TAG, "rc=%d", rc);
|
ESP_LOGV(TAG, "rc=%d", rc);
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
rc = cache_flash_mmu_set(1, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
|
rc = cache_flash_mmu_set(1, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
|
||||||
ESP_LOGV(TAG, "rc=%d", rc);
|
ESP_LOGV(TAG, "rc=%d", rc);
|
||||||
|
#endif
|
||||||
uint32_t irom_load_addr_aligned = irom_load_addr & MMU_FLASH_MASK;
|
uint32_t irom_load_addr_aligned = irom_load_addr & MMU_FLASH_MASK;
|
||||||
uint32_t irom_page_count = bootloader_cache_pages_to_map(irom_size, irom_load_addr);
|
uint32_t irom_page_count = bootloader_cache_pages_to_map(irom_size, irom_load_addr);
|
||||||
ESP_LOGV(TAG, "i mmu set paddr=%08x vaddr=%08x size=%d n=%d",
|
ESP_LOGV(TAG, "i mmu set paddr=%08x vaddr=%08x size=%d n=%d",
|
||||||
irom_addr & MMU_FLASH_MASK, irom_load_addr_aligned, irom_size, irom_page_count);
|
irom_addr & MMU_FLASH_MASK, irom_load_addr_aligned, irom_size, irom_page_count);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
rc = cache_flash_mmu_set(0, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
|
rc = cache_flash_mmu_set(0, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
|
||||||
ESP_LOGV(TAG, "rc=%d", rc);
|
ESP_LOGV(TAG, "rc=%d", rc);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
uint32_t iram1_used = 0, irom0_used = 0;
|
||||||
|
if (irom_load_addr + irom_size > IRAM1_ADDRESS_LOW) {
|
||||||
|
iram1_used = 1;
|
||||||
|
}
|
||||||
|
if (irom_load_addr + irom_size > IROM0_ADDRESS_LOW) {
|
||||||
|
irom0_used = 1;
|
||||||
|
}
|
||||||
|
if (iram1_used || irom0_used) {
|
||||||
|
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IRAM0_ADDRESS_LOW, 0, 64, 64, 1);
|
||||||
|
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IRAM1_ADDRESS_LOW, 0, 64, 64, 1);
|
||||||
|
REG_SET_BIT(DPORT_CACHE_SOURCE_1_REG, DPORT_PRO_CACHE_I_SOURCE_PRO_IRAM1);
|
||||||
|
REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_IRAM1);
|
||||||
|
if (irom0_used) {
|
||||||
|
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IROM0_ADDRESS_LOW, 0, 64, 64, 1);
|
||||||
|
REG_SET_BIT(DPORT_CACHE_SOURCE_1_REG, DPORT_PRO_CACHE_I_SOURCE_PRO_IROM0);
|
||||||
|
REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_IROM0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count, 0);
|
||||||
|
#endif
|
||||||
|
ESP_LOGV(TAG, "rc=%d", rc);
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
rc = cache_flash_mmu_set(1, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
|
rc = cache_flash_mmu_set(1, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
|
||||||
ESP_LOGV(TAG, "rc=%d", rc);
|
ESP_LOGV(TAG, "rc=%d", rc);
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
DPORT_REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG,
|
DPORT_REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG,
|
||||||
(DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) |
|
(DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) |
|
||||||
(DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 |
|
(DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 |
|
||||||
DPORT_PRO_CACHE_MASK_DRAM1 );
|
DPORT_PRO_CACHE_MASK_DRAM1 );
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
DPORT_REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG,
|
DPORT_REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG,
|
||||||
(DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) |
|
(DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) |
|
||||||
(DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 |
|
(DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 |
|
||||||
DPORT_APP_CACHE_MASK_DRAM1 );
|
DPORT_APP_CACHE_MASK_DRAM1 );
|
||||||
|
#endif
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
DPORT_REG_CLR_BIT( DPORT_PRO_ICACHE_CTRL1_REG, (DPORT_PRO_ICACHE_MASK_IRAM0) | (DPORT_PRO_ICACHE_MASK_IRAM1 & 0) | (DPORT_PRO_ICACHE_MASK_IROM0 & 0) | DPORT_PRO_ICACHE_MASK_DROM0 );
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
|
DPORT_REG_CLR_BIT( DPORT_APP_ICACHE_CTRL1_REG, (DPORT_APP_ICACHE_MASK_IRAM0) | (DPORT_APP_ICACHE_MASK_IRAM1 & 0) | (DPORT_APP_ICACHE_MASK_IROM0 & 0) | DPORT_APP_ICACHE_MASK_DROM0 );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
Cache_Read_Enable(0);
|
Cache_Read_Enable(0);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
Cache_Resume_ICache(autoload);
|
||||||
|
#endif
|
||||||
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)
|
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)
|
||||||
|
|
||||||
ESP_LOGD(TAG, "start: 0x%08x", entry_addr);
|
ESP_LOGD(TAG, "start: 0x%08x", entry_addr);
|
||||||
@ -688,7 +750,6 @@ static void set_cache_and_start_app(
|
|||||||
(*entry)();
|
(*entry)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bootloader_reset(void)
|
void bootloader_reset(void)
|
||||||
{
|
{
|
||||||
#ifdef BOOTLOADER_BUILD
|
#ifdef BOOTLOADER_BUILD
|
||||||
@ -719,3 +780,24 @@ esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_he
|
|||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bootloader_debug_buffer(const void *buffer, size_t length, const char *label)
|
||||||
|
{
|
||||||
|
#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
|
||||||
|
assert(length <= 128); // Avoid unbounded VLA size
|
||||||
|
const uint8_t *bytes = (const uint8_t *)buffer;
|
||||||
|
char hexbuf[length * 2 + 1];
|
||||||
|
hexbuf[length * 2] = 0;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
for (int shift = 0; shift < 2; shift++) {
|
||||||
|
uint8_t nibble = (bytes[i] >> (shift ? 0 : 4)) & 0x0F;
|
||||||
|
if (nibble < 10) {
|
||||||
|
hexbuf[i * 2 + shift] = '0' + nibble;
|
||||||
|
} else {
|
||||||
|
hexbuf[i * 2 + shift] = 'a' + nibble - 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "%s: %s", label, hexbuf);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
#include "soc/efuse_reg.h"
|
||||||
|
#include "bootloader_clock.h"
|
||||||
|
|
||||||
|
int bootloader_clock_get_rated_freq_mhz()
|
||||||
|
{
|
||||||
|
//Check if ESP32 is rated for a CPU frequency of 160MHz only
|
||||||
|
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
|
||||||
|
REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) {
|
||||||
|
return 160;
|
||||||
|
}
|
||||||
|
return 240;
|
||||||
|
}
|
||||||
|
|
74
components/bootloader_support/src/esp32/bootloader_esp32.c
Normal file
74
components/bootloader_support/src/esp32/bootloader_esp32.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "bootloader_common.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "soc/efuse_reg.h"
|
||||||
|
#include "soc/gpio_sig_map.h"
|
||||||
|
#include "soc/io_mux_reg.h"
|
||||||
|
#include "esp32/rom/efuse.h"
|
||||||
|
#include "esp32/rom/gpio.h"
|
||||||
|
#include "esp32/rom/spi_flash.h"
|
||||||
|
|
||||||
|
#define FLASH_CLK_IO SPI_CLK_GPIO_NUM
|
||||||
|
#define FLASH_CS_IO SPI_CS0_GPIO_NUM
|
||||||
|
#define FLASH_SPIQ_IO SPI_Q_GPIO_NUM
|
||||||
|
#define FLASH_SPID_IO SPI_D_GPIO_NUM
|
||||||
|
#define FLASH_SPIWP_IO SPI_WP_GPIO_NUM
|
||||||
|
#define FLASH_SPIHD_IO SPI_HD_GPIO_NUM
|
||||||
|
|
||||||
|
void bootloader_configure_spi_pins(int drv)
|
||||||
|
{
|
||||||
|
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||||
|
uint32_t pkg_ver = chip_ver & 0x7;
|
||||||
|
|
||||||
|
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
|
||||||
|
// For ESP32D2WD the SPI pins are already configured
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
|
||||||
|
// For ESP32PICOD2 the SPI pins are already configured
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||||
|
// For ESP32PICOD4 the SPI pins are already configured
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
} else {
|
||||||
|
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||||
|
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
||||||
|
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
|
||||||
|
//select pin function gpio
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
// set drive ability for clock
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
|
||||||
|
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32 || CONFIG_SPIRAM_TYPE_ESPPSRAM64
|
||||||
|
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||||
|
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||||
|
// Set drive ability for 1.8v flash in 80Mhz.
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,9 +16,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include "esp32/rom/sha.h"
|
#include "esp32/rom/sha.h"
|
||||||
|
#include "soc/dport_reg.h"
|
||||||
#include "soc/hwcrypto_periph.h"
|
#include "soc/hwcrypto_periph.h"
|
||||||
#include "esp32/rom/ets_sys.h" // TO REMOVE
|
|
||||||
|
|
||||||
static uint32_t words_hashed;
|
static uint32_t words_hashed;
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
|
|||||||
|
|
||||||
/* If the last flash_crypt_cnt bit is burned or write-disabled, the
|
/* If the last flash_crypt_cnt bit is burned or write-disabled, the
|
||||||
device can't re-encrypt itself. */
|
device can't re-encrypt itself. */
|
||||||
if (flash_crypt_wr_dis) {
|
if (flash_crypt_wr_dis || flash_crypt_cnt == 0xFF) {
|
||||||
ESP_LOGE(TAG, "Cannot re-encrypt data (FLASH_CRYPT_CNT 0x%02x write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
|
ESP_LOGE(TAG, "Cannot re-encrypt data (FLASH_CRYPT_CNT 0x%02x write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "bootloader_clock.h"
|
||||||
|
|
||||||
|
int bootloader_clock_get_rated_freq_mhz()
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_HARDWARE_IS_FPGA
|
||||||
|
#warning "FIXME this needs to be filled in for real hardware"
|
||||||
|
#endif
|
||||||
|
return 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
|||||||
|
#include "bootloader_common.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "soc/efuse_reg.h"
|
||||||
|
#include "soc/gpio_sig_map.h"
|
||||||
|
#include "soc/io_mux_reg.h"
|
||||||
|
#include "esp32s2beta/rom/efuse.h"
|
||||||
|
#include "esp32s2beta/rom/gpio.h"
|
||||||
|
#include "esp32s2beta/rom/spi_flash.h"
|
||||||
|
|
||||||
|
#define FLASH_CLK_IO SPI_CLK_GPIO_NUM
|
||||||
|
#define FLASH_CS_IO SPI_CS0_GPIO_NUM
|
||||||
|
#define FLASH_SPIQ_IO SPI_Q_GPIO_NUM
|
||||||
|
#define FLASH_SPID_IO SPI_D_GPIO_NUM
|
||||||
|
#define FLASH_SPIWP_IO SPI_WP_GPIO_NUM
|
||||||
|
#define FLASH_SPIHD_IO SPI_HD_GPIO_NUM
|
||||||
|
|
||||||
|
void bootloader_configure_spi_pins(int drv)
|
||||||
|
{
|
||||||
|
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||||
|
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
||||||
|
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
|
||||||
|
//select pin function gpio
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIHD_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIWP_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICS0_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIQ_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPID_U, PIN_FUNC_GPIO);
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
// set drive ability for clock
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICLK_U, FUNC_SPICLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
|
||||||
|
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32 || CONFIG_SPIRAM_TYPE_ESPPSRAM64
|
||||||
|
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||||
|
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||||
|
// Set drive ability for 1.8v flash in 80Mhz.
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIHD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIWP_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICS0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIQ_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPID_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#include "bootloader_sha.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include "esp32s2beta/rom/sha.h"
|
||||||
|
|
||||||
|
static SHA_CTX ctx;
|
||||||
|
|
||||||
|
// Words per SHA256 block
|
||||||
|
// static const size_t BLOCK_WORDS = (64/sizeof(uint32_t));
|
||||||
|
// Words in final SHA256 digest
|
||||||
|
// static const size_t DIGEST_WORDS = (32/sizeof(uint32_t));
|
||||||
|
|
||||||
|
bootloader_sha256_handle_t bootloader_sha256_start()
|
||||||
|
{
|
||||||
|
// Enable SHA hardware
|
||||||
|
ets_sha_enable();
|
||||||
|
ets_sha_init(&ctx, SHA2_256);
|
||||||
|
return &ctx; // Meaningless non-NULL value
|
||||||
|
}
|
||||||
|
|
||||||
|
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len)
|
||||||
|
{
|
||||||
|
assert(handle != NULL);
|
||||||
|
assert(data_len % 4 == 0);
|
||||||
|
ets_sha_update(&ctx, data, data_len, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest)
|
||||||
|
{
|
||||||
|
assert(handle != NULL);
|
||||||
|
|
||||||
|
if (digest == NULL) {
|
||||||
|
bzero(&ctx, sizeof(ctx));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ets_sha_finish(&ctx, digest);
|
||||||
|
}
|
303
components/bootloader_support/src/esp32s2beta/flash_encrypt.c
Normal file
303
components/bootloader_support/src/esp32s2beta/flash_encrypt.c
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#include "bootloader_flash.h"
|
||||||
|
#include "bootloader_random.h"
|
||||||
|
#include "bootloader_utility.h"
|
||||||
|
#include "esp_image_format.h"
|
||||||
|
#include "esp_flash_encrypt.h"
|
||||||
|
#include "esp_flash_partitions.h"
|
||||||
|
#include "esp_secure_boot.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp32s2beta/rom/secure_boot.h"
|
||||||
|
#include "esp32s2beta/rom/cache.h"
|
||||||
|
#include "esp32s2beta/rom/efuse.h"
|
||||||
|
|
||||||
|
static const char *TAG = "flash_encrypt";
|
||||||
|
|
||||||
|
/* Static functions for stages of flash encryption */
|
||||||
|
static esp_err_t initialise_flash_encryption(void);
|
||||||
|
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis);
|
||||||
|
static esp_err_t encrypt_bootloader();
|
||||||
|
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions);
|
||||||
|
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition);
|
||||||
|
|
||||||
|
esp_err_t esp_flash_encrypt_check_and_update(void)
|
||||||
|
{
|
||||||
|
// TODO: not clear why this is read from DATA1 and written to PGM_DATA2
|
||||||
|
uint32_t cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_SPI_BOOT_CRYPT_CNT);
|
||||||
|
ESP_LOGV(TAG, "SPI_BOOT_CRYPT_CNT 0x%x", cnt);
|
||||||
|
|
||||||
|
bool flash_crypt_wr_dis = false; // TODO: check if CRYPT_CNT is write disabled
|
||||||
|
|
||||||
|
_Static_assert(EFUSE_SPI_BOOT_CRYPT_CNT == 0x7, "assuming CRYPT_CNT is only 3 bits wide");
|
||||||
|
|
||||||
|
if (cnt == 1 || cnt == 3 || cnt == 7) {
|
||||||
|
/* Flash is already encrypted */
|
||||||
|
int left;
|
||||||
|
if (cnt == 7 /* || disabled */) {
|
||||||
|
left = 0;
|
||||||
|
} else if (cnt == 3) {
|
||||||
|
left = 1;
|
||||||
|
} else {
|
||||||
|
left = 2;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Flash is not encrypted, so encrypt it! */
|
||||||
|
return encrypt_flash_contents(cnt, flash_crypt_wr_dis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t initialise_flash_encryption(void)
|
||||||
|
{
|
||||||
|
/* Before first flash encryption pass, need to initialise key & crypto config */
|
||||||
|
|
||||||
|
/* Find out if a key is already set */
|
||||||
|
bool has_aes128 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL);
|
||||||
|
bool has_aes256_1 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1, NULL);
|
||||||
|
bool has_aes256_2 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2, NULL);
|
||||||
|
|
||||||
|
bool has_key = has_aes128 || (has_aes256_1 && has_aes256_2);
|
||||||
|
|
||||||
|
if (!has_key && (has_aes256_1 || has_aes256_2)) {
|
||||||
|
ESP_LOGE(TAG, "Invalid efuse key blocks: Both AES-256 key blocks must be set.");
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_key) {
|
||||||
|
ESP_LOGI(TAG, "Using pre-existing key in efuse");
|
||||||
|
|
||||||
|
ESP_LOGE(TAG, "TODO: Check key is read & write protected"); // TODO
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "Generating new flash encryption key...");
|
||||||
|
#ifdef CONFIG_FLASH_ENCRYPTION_AES256
|
||||||
|
const unsigned BLOCKS_NEEDED = 2;
|
||||||
|
const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1;
|
||||||
|
const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2;
|
||||||
|
#else
|
||||||
|
const unsigned BLOCKS_NEEDED = 1;
|
||||||
|
const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY;
|
||||||
|
const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ets_efuse_count_unused_key_blocks() < BLOCKS_NEEDED) {
|
||||||
|
ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED);
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(ets_efuse_purpose_t purpose = PURPOSE_START; purpose <= PURPOSE_END; purpose++) {
|
||||||
|
uint32_t buf[8];
|
||||||
|
bootloader_fill_random(buf, sizeof(buf));
|
||||||
|
ets_efuse_block_t block = ets_efuse_find_unused_key_block();
|
||||||
|
ESP_LOGD(TAG, "Writing ETS_EFUSE_BLOCK_KEY%d with purpose %d",
|
||||||
|
block - ETS_EFUSE_BLOCK_KEY0, purpose);
|
||||||
|
bootloader_debug_buffer(buf, sizeof(buf), "Key content");
|
||||||
|
int r = ets_efuse_write_key(block, purpose, buf, sizeof(buf));
|
||||||
|
bzero(buf, sizeof(buf));
|
||||||
|
if (r != 0) {
|
||||||
|
ESP_LOGE(TAG, "Failed to write efuse block %d with purpose %d. Can't continue.");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Key generation complete");
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGE(TAG, "TODO: burn remaining security protection bits"); // TODO
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encrypt all flash data that should be encrypted */
|
||||||
|
static esp_err_t encrypt_flash_contents(uint32_t spi_boot_crypt_cnt, bool flash_crypt_wr_dis)
|
||||||
|
{
|
||||||
|
esp_err_t err;
|
||||||
|
esp_partition_info_t partition_table[ESP_PARTITION_TABLE_MAX_ENTRIES];
|
||||||
|
int num_partitions;
|
||||||
|
|
||||||
|
/* If the last spi_boot_crypt_cnt bit is burned or write-disabled, the
|
||||||
|
device can't re-encrypt itself. */
|
||||||
|
if (flash_crypt_wr_dis || spi_boot_crypt_cnt == EFUSE_SPI_BOOT_CRYPT_CNT) {
|
||||||
|
ESP_LOGE(TAG, "Cannot re-encrypt data (SPI_BOOT_CRYPT_CNT 0x%02x write disabled %d", spi_boot_crypt_cnt, flash_crypt_wr_dis);
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi_boot_crypt_cnt == 0) {
|
||||||
|
/* Very first flash of encrypted data: generate keys, etc. */
|
||||||
|
err = initialise_flash_encryption();
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = encrypt_bootloader();
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = encrypt_and_load_partition_table(partition_table, &num_partitions);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now iterate the just-loaded partition table, looking for entries to encrypt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Go through each partition and encrypt if necessary */
|
||||||
|
for (int i = 0; i < num_partitions; i++) {
|
||||||
|
err = encrypt_partition(i, &partition_table[i]);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "All flash regions checked for encryption pass");
|
||||||
|
|
||||||
|
/* Set least significant 0-bit in spi_boot_crypt_cnt */
|
||||||
|
int ffs_inv = __builtin_ffs((~spi_boot_crypt_cnt) & 0x7);
|
||||||
|
/* ffs_inv shouldn't be zero, as zero implies spi_boot_crypt_cnt == 0xFF */
|
||||||
|
uint32_t new_spi_boot_crypt_cnt = spi_boot_crypt_cnt + (1 << (ffs_inv - 1));
|
||||||
|
ESP_LOGD(TAG, "SPI_BOOT_CRYPT_CNT 0x%x -> 0x%x", spi_boot_crypt_cnt, new_spi_boot_crypt_cnt);
|
||||||
|
|
||||||
|
ets_efuse_clear_program_registers();
|
||||||
|
REG_SET_FIELD(EFUSE_PGM_DATA2_REG, EFUSE_SPI_BOOT_CRYPT_CNT, new_spi_boot_crypt_cnt);
|
||||||
|
ets_efuse_program(ETS_EFUSE_BLOCK0);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Flash encryption completed");
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t encrypt_bootloader()
|
||||||
|
{
|
||||||
|
esp_err_t err;
|
||||||
|
uint32_t image_length;
|
||||||
|
/* Check for plaintext bootloader (verification will fail if it's already encrypted) */
|
||||||
|
if (esp_image_verify_bootloader(&image_length) == ESP_OK) {
|
||||||
|
ESP_LOGD(TAG, "bootloader is plaintext. Encrypting...");
|
||||||
|
err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, image_length);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_secure_boot_enabled()) {
|
||||||
|
// TODO: anything different for secure boot?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGW(TAG, "no valid bootloader was found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions)
|
||||||
|
{
|
||||||
|
esp_err_t err;
|
||||||
|
/* Check for plaintext partition table */
|
||||||
|
err = bootloader_flash_read(ESP_PARTITION_TABLE_OFFSET, partition_table, ESP_PARTITION_TABLE_MAX_LEN, false);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to read partition table data");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (esp_partition_table_basic_verify(partition_table, false, num_partitions) == ESP_OK) {
|
||||||
|
ESP_LOGD(TAG, "partition table is plaintext. Encrypting...");
|
||||||
|
esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET,
|
||||||
|
FLASH_SECTOR_SIZE);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to encrypt partition table in place. %x", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGE(TAG, "Failed to read partition table data - not plaintext?");
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Valid partition table loded */
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition)
|
||||||
|
{
|
||||||
|
esp_err_t err;
|
||||||
|
bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED);
|
||||||
|
|
||||||
|
if (partition->type == PART_TYPE_APP) {
|
||||||
|
/* check if the partition holds a valid unencrypted app */
|
||||||
|
esp_image_metadata_t data_ignored;
|
||||||
|
err = esp_image_load(ESP_IMAGE_VERIFY,
|
||||||
|
&partition->pos,
|
||||||
|
&data_ignored);
|
||||||
|
should_encrypt = (err == ESP_OK);
|
||||||
|
} else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) {
|
||||||
|
/* check if we have ota data partition and the partition should be encrypted unconditionally */
|
||||||
|
should_encrypt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!should_encrypt) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* should_encrypt */
|
||||||
|
ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, partition->pos.size);
|
||||||
|
|
||||||
|
err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size);
|
||||||
|
ESP_LOGI(TAG, "Done encrypting");
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to encrypt partition %d", index);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
|
||||||
|
{
|
||||||
|
esp_err_t err;
|
||||||
|
uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)];
|
||||||
|
|
||||||
|
if (src_addr % FLASH_SECTOR_SIZE != 0) {
|
||||||
|
ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x",src_addr);
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
|
||||||
|
uint32_t sec_start = i + src_addr;
|
||||||
|
err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, false);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
goto flash_failed;
|
||||||
|
}
|
||||||
|
err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
goto flash_failed;
|
||||||
|
}
|
||||||
|
err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
goto flash_failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
|
||||||
|
flash_failed:
|
||||||
|
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
|
||||||
|
return err;
|
||||||
|
}
|
45
components/bootloader_support/src/esp32s2beta/secure_boot.c
Normal file
45
components/bootloader_support/src/esp32s2beta/secure_boot.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#include "esp_secure_boot.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp32s2beta/rom/secure_boot.h"
|
||||||
|
|
||||||
|
#define TAG "secure_boot"
|
||||||
|
|
||||||
|
esp_err_t esp_secure_boot_permanently_enable(void)
|
||||||
|
{
|
||||||
|
uint8_t hash[32];
|
||||||
|
|
||||||
|
if (ets_efuse_secure_boot_enabled())
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "secure boot is already enabled, continuing..");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Verifying bootloader signature...\n");
|
||||||
|
int r = ets_secure_boot_verify_bootloader(hash, false);
|
||||||
|
if (r != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to verify bootloader signature");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
ets_efuse_clear_program_registers();
|
||||||
|
REG_SET_BIT(EFUSE_PGM_DATA3_REG, EFUSE_SECURE_BOOT_EN);
|
||||||
|
ets_efuse_program(ETS_EFUSE_BLOCK0);
|
||||||
|
|
||||||
|
assert(ets_efuse_secure_boot_enabled());
|
||||||
|
ESP_LOGI(TAG, "Secure boot permanently enabled");
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include "bootloader_flash.h"
|
||||||
|
#include "bootloader_sha.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_image_format.h"
|
||||||
|
#include "esp32s2beta/rom/secure_boot.h"
|
||||||
|
|
||||||
|
static const char* TAG = "secure_boot";
|
||||||
|
|
||||||
|
#define DIGEST_LEN 32
|
||||||
|
|
||||||
|
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||||
|
{
|
||||||
|
ets_secure_boot_key_digests_t trusted_keys = { 0 };
|
||||||
|
uint8_t digest[DIGEST_LEN];
|
||||||
|
const uint8_t *data;
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
|
||||||
|
|
||||||
|
if ((src_addr + length) % 4096 != 0) {
|
||||||
|
ESP_LOGE(TAG, "addr 0x%x length 0x%x doesn't end on a sector boundary", src_addr, length);
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = bootloader_mmap(src_addr, length + sizeof(struct ets_secure_boot_sig_block));
|
||||||
|
if(data == NULL) {
|
||||||
|
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(ets_secure_boot_signature_t));
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate digest of main image
|
||||||
|
#ifdef BOOTLOADER_BUILD
|
||||||
|
bootloader_sha256_handle_t handle = bootloader_sha256_start();
|
||||||
|
bootloader_sha256_data(handle, data, length);
|
||||||
|
bootloader_sha256_finish(handle, digest);
|
||||||
|
#else
|
||||||
|
/* Use thread-safe esp-idf SHA function */
|
||||||
|
esp_sha(SHA2_256, data, length, digest);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int r = ets_secure_boot_read_key_digests(&trusted_keys);
|
||||||
|
|
||||||
|
if (r == ETS_OK) {
|
||||||
|
const ets_secure_boot_signature_t *sig = (const ets_secure_boot_signature_t *)(data + length);
|
||||||
|
// TODO: calling this function in IDF app context is unsafe
|
||||||
|
r = ets_secure_boot_verify_signature(sig, digest, &trusted_keys);
|
||||||
|
}
|
||||||
|
bootloader_munmap(data);
|
||||||
|
|
||||||
|
return (r == ETS_OK) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_secure_boot_verify_signature_block(uint32_t sig_block_flash_offs, const uint8_t *image_digest)
|
||||||
|
{
|
||||||
|
ets_secure_boot_key_digests_t trusted_keys;
|
||||||
|
|
||||||
|
assert(sig_block_flash_offs % 4096 == 0); // TODO: enforce this in a better way
|
||||||
|
|
||||||
|
const ets_secure_boot_signature_t *sig = bootloader_mmap(sig_block_flash_offs, sizeof(ets_secure_boot_signature_t));
|
||||||
|
|
||||||
|
if (sig == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Failed to mmap data at offset 0x%x", sig_block_flash_offs);
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int r = ets_secure_boot_read_key_digests(&trusted_keys);
|
||||||
|
if (r != 0) {
|
||||||
|
ESP_LOGE(TAG, "No trusted key digests were found in efuse!");
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "Verifying with RSA-PSS...");
|
||||||
|
// TODO: calling this function in IDF app context is unsafe
|
||||||
|
r = ets_secure_boot_verify_signature(sig, image_digest, &trusted_keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
bootloader_munmap(sig);
|
||||||
|
|
||||||
|
return (r == 0) ? ESP_OK : ESP_ERR_IMAGE_INVALID;
|
||||||
|
}
|
@ -13,8 +13,6 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include <esp32/rom/rtc.h>
|
|
||||||
#include <soc/cpu.h>
|
#include <soc/cpu.h>
|
||||||
#include <bootloader_utility.h>
|
#include <bootloader_utility.h>
|
||||||
#include <esp_secure_boot.h>
|
#include <esp_secure_boot.h>
|
||||||
@ -24,6 +22,14 @@
|
|||||||
#include <bootloader_random.h>
|
#include <bootloader_random.h>
|
||||||
#include <bootloader_sha.h>
|
#include <bootloader_sha.h>
|
||||||
#include "bootloader_util.h"
|
#include "bootloader_util.h"
|
||||||
|
#include "bootloader_utility.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
#include <esp32/rom/rtc.h>
|
||||||
|
#include <esp32/rom/secure_boot.h>
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include <esp32s2beta/rom/rtc.h>
|
||||||
|
#include <esp32s2beta/rom/secure_boot.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Checking signatures as part of verifying images is necessary:
|
/* Checking signatures as part of verifying images is necessary:
|
||||||
- Always if secure boot is enabled
|
- Always if secure boot is enabled
|
||||||
@ -186,13 +192,19 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
|||||||
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
|
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_bootloader = (data->start_addr == ESP_BOOTLOADER_OFFSET);
|
|
||||||
/* For secure boot, we don't verify signature on bootloaders.
|
/* For secure boot, we don't verify signature on bootloaders.
|
||||||
|
|
||||||
For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because esptool.py may have
|
For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because esptool.py may have
|
||||||
rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.
|
rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.
|
||||||
*/
|
*/
|
||||||
if (!is_bootloader) {
|
bool should_verify;
|
||||||
|
#if defined(CONFIG_SECURE_BOOT_ENABLED) && defined(CONFIG_IDF_TARGET_ESP32S2BETA)
|
||||||
|
should_verify = true;
|
||||||
|
#else // ESP32, or ESP32S2 without secure boot enabled
|
||||||
|
should_verify = (data->start_addr != ESP_BOOTLOADER_OFFSET);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (should_verify) {
|
||||||
#ifdef SECURE_BOOT_CHECK_SIGNATURE
|
#ifdef SECURE_BOOT_CHECK_SIGNATURE
|
||||||
// secure boot images have a signature appended
|
// secure boot images have a signature appended
|
||||||
err = verify_secure_boot_signature(sha_handle, data);
|
err = verify_secure_boot_signature(sha_handle, data);
|
||||||
@ -202,7 +214,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
|||||||
err = verify_simple_hash(sha_handle, data);
|
err = verify_simple_hash(sha_handle, data);
|
||||||
}
|
}
|
||||||
#endif // SECURE_BOOT_CHECK_SIGNATURE
|
#endif // SECURE_BOOT_CHECK_SIGNATURE
|
||||||
} else { // is_bootloader
|
} else {
|
||||||
// bootloader may still have a sha256 digest handle open
|
// bootloader may still have a sha256 digest handle open
|
||||||
if (sha_handle != NULL) {
|
if (sha_handle != NULL) {
|
||||||
bootloader_sha256_finish(sha_handle, NULL);
|
bootloader_sha256_finish(sha_handle, NULL);
|
||||||
@ -568,26 +580,36 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void debug_log_hash(const uint8_t *image_hash, const char *caption);
|
|
||||||
|
|
||||||
static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data)
|
static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data)
|
||||||
{
|
{
|
||||||
uint8_t image_hash[HASH_LEN] = { 0 };
|
uint8_t image_hash[HASH_LEN] = { 0 };
|
||||||
|
uint32_t end = data->start_addr + data->image_len;
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Verifying image signature...");
|
ESP_LOGI(TAG, "Verifying image signature...");
|
||||||
|
|
||||||
// For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash
|
// For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash
|
||||||
// appended to the image for corruption detection
|
// appended to the image for corruption detection
|
||||||
if (data->image.hash_appended) {
|
if (data->image.hash_appended) {
|
||||||
const void *simple_hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
|
const void *simple_hash = bootloader_mmap(end - HASH_LEN, HASH_LEN);
|
||||||
bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN);
|
bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN);
|
||||||
bootloader_munmap(simple_hash);
|
bootloader_munmap(simple_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
// Pad to 4096 byte sector boundary
|
||||||
|
if (end % FLASH_SECTOR_SIZE != 0) {
|
||||||
|
uint32_t pad_len = FLASH_SECTOR_SIZE - (end % FLASH_SECTOR_SIZE);
|
||||||
|
const void *padding = bootloader_mmap(end, pad_len);
|
||||||
|
bootloader_sha256_data(sha_handle, padding, pad_len);
|
||||||
|
bootloader_munmap(padding);
|
||||||
|
end += pad_len;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bootloader_sha256_finish(sha_handle, image_hash);
|
bootloader_sha256_finish(sha_handle, image_hash);
|
||||||
|
|
||||||
// Log the hash for debugging
|
// Log the hash for debugging
|
||||||
debug_log_hash(image_hash, "Calculated secure boot hash");
|
bootloader_debug_buffer(image_hash, HASH_LEN, "Calculated secure boot hash");
|
||||||
|
|
||||||
// Use hash to verify signature block
|
// Use hash to verify signature block
|
||||||
const esp_secure_boot_sig_block_t *sig_block = bootloader_mmap(data->start_addr + data->image_len, sizeof(esp_secure_boot_sig_block_t));
|
const esp_secure_boot_sig_block_t *sig_block = bootloader_mmap(data->start_addr + data->image_len, sizeof(esp_secure_boot_sig_block_t));
|
||||||
@ -612,6 +634,11 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han
|
|||||||
return ESP_ERR_IMAGE_INVALID;
|
return ESP_ERR_IMAGE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
// Adjust image length result to include the appended signature
|
||||||
|
data->image_len = end - data->start_addr + sizeof(ets_secure_boot_signature_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,13 +648,13 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i
|
|||||||
bootloader_sha256_finish(sha_handle, image_hash);
|
bootloader_sha256_finish(sha_handle, image_hash);
|
||||||
|
|
||||||
// Log the hash for debugging
|
// Log the hash for debugging
|
||||||
debug_log_hash(image_hash, "Calculated hash");
|
bootloader_debug_buffer(image_hash, HASH_LEN, "Calculated hash");
|
||||||
|
|
||||||
// Simple hash for verification only
|
// Simple hash for verification only
|
||||||
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
|
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
|
||||||
if (memcmp(hash, image_hash, HASH_LEN) != 0) {
|
if (memcmp(hash, image_hash, HASH_LEN) != 0) {
|
||||||
ESP_LOGE(TAG, "Image hash failed - image is corrupt");
|
ESP_LOGE(TAG, "Image hash failed - image is corrupt");
|
||||||
debug_log_hash(hash, "Expected hash");
|
bootloader_debug_buffer(hash, HASH_LEN, "Expected hash");
|
||||||
bootloader_munmap(hash);
|
bootloader_munmap(hash);
|
||||||
return ESP_ERR_IMAGE_INVALID;
|
return ESP_ERR_IMAGE_INVALID;
|
||||||
}
|
}
|
||||||
@ -635,14 +662,3 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i
|
|||||||
bootloader_munmap(hash);
|
bootloader_munmap(hash);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log a hash as a hex string
|
|
||||||
static void debug_log_hash(const uint8_t *image_hash, const char *label)
|
|
||||||
{
|
|
||||||
#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
|
|
||||||
char hash_print[HASH_LEN * 2 + 1];
|
|
||||||
hash_print[HASH_LEN * 2] = 0;
|
|
||||||
bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
|
|
||||||
ESP_LOGD(TAG, "%s: %s", label, hash_print);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
@ -16,14 +16,28 @@
|
|||||||
#include "flash_qio_mode.h"
|
#include "flash_qio_mode.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#include "esp32/rom/spi_flash.h"
|
#include "esp32/rom/spi_flash.h"
|
||||||
#include "esp32/rom/efuse.h"
|
#include "esp32/rom/efuse.h"
|
||||||
#include "soc/spi_periph.h"
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include "esp32s2beta/rom/spi_flash.h"
|
||||||
|
#include "esp32s2beta/rom/efuse.h"
|
||||||
|
#endif
|
||||||
|
#include "soc/spi_struct.h"
|
||||||
|
#include "soc/spi_reg.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include "soc/spi_mem_struct.h"
|
||||||
|
#endif
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
|
#include "soc/io_mux_reg.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
/* SPI flash controller */
|
/* SPI flash controller */
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#define SPIFLASH SPI1
|
#define SPIFLASH SPI1
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#define SPIFLASH SPIMEM1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
|
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
|
||||||
Suitable for use with the execute_flash_command static function.
|
Suitable for use with the execute_flash_command static function.
|
||||||
@ -42,7 +56,8 @@ static const char *TAG = "qio_mode";
|
|||||||
typedef unsigned (*read_status_fn_t)();
|
typedef unsigned (*read_status_fn_t)();
|
||||||
typedef void (*write_status_fn_t)(unsigned);
|
typedef void (*write_status_fn_t)(unsigned);
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
const char *manufacturer;
|
const char *manufacturer;
|
||||||
uint8_t mfg_id; /* 8-bit JEDEC manufacturer ID */
|
uint8_t mfg_id; /* 8-bit JEDEC manufacturer ID */
|
||||||
uint16_t flash_id; /* 16-bit JEDEC flash chip ID */
|
uint16_t flash_id; /* 16-bit JEDEC flash chip ID */
|
||||||
@ -128,6 +143,46 @@ uint32_t bootloader_read_flash_id()
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#define FLASH_WRAP_CMD 0x77
|
||||||
|
typedef enum {
|
||||||
|
FLASH_WRAP_MODE_8B = 0,
|
||||||
|
FLASH_WRAP_MODE_16B = 2,
|
||||||
|
FLASH_WRAP_MODE_32B = 4,
|
||||||
|
FLASH_WRAP_MODE_64B = 6,
|
||||||
|
FLASH_WRAP_MODE_DISABLE = 1
|
||||||
|
} spi_flash_wrap_mode_t;
|
||||||
|
static esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
|
||||||
|
{
|
||||||
|
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
|
||||||
|
uint32_t reg_bkp_usr = SPIFLASH.user.val;
|
||||||
|
SPIFLASH.user.fwrite_dio = 0;
|
||||||
|
SPIFLASH.user.fwrite_dual = 0;
|
||||||
|
SPIFLASH.user.fwrite_qio = 1;
|
||||||
|
SPIFLASH.user.fwrite_quad = 0;
|
||||||
|
SPIFLASH.ctrl.fcmd_dual = 0;
|
||||||
|
SPIFLASH.ctrl.fcmd_quad = 0;
|
||||||
|
SPIFLASH.user.usr_dummy = 0;
|
||||||
|
SPIFLASH.user.usr_addr = 1;
|
||||||
|
SPIFLASH.user.usr_command = 1;
|
||||||
|
SPIFLASH.user2.usr_command_bitlen = 7;
|
||||||
|
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
|
||||||
|
SPIFLASH.user1.usr_addr_bitlen = 23;
|
||||||
|
SPIFLASH.addr = 0;
|
||||||
|
SPIFLASH.user.usr_miso = 0;
|
||||||
|
SPIFLASH.user.usr_mosi = 1;
|
||||||
|
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
|
||||||
|
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
|
||||||
|
SPIFLASH.cmd.usr = 1;
|
||||||
|
while (SPIFLASH.cmd.usr != 0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
SPIFLASH.ctrl.val = reg_bkp_ctrl;
|
||||||
|
SPIFLASH.user.val = reg_bkp_usr;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void bootloader_enable_qio_mode(void)
|
void bootloader_enable_qio_mode(void)
|
||||||
{
|
{
|
||||||
uint32_t raw_flash_id;
|
uint32_t raw_flash_id;
|
||||||
@ -156,7 +211,9 @@ void bootloader_enable_qio_mode(void)
|
|||||||
if (i == NUM_CHIPS - 1) {
|
if (i == NUM_CHIPS - 1) {
|
||||||
ESP_LOGI(TAG, "Enabling default flash chip QIO");
|
ESP_LOGI(TAG, "Enabling default flash chip QIO");
|
||||||
}
|
}
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
|
||||||
|
#endif
|
||||||
enable_qio_mode(chip_data[i].read_status_fn,
|
enable_qio_mode(chip_data[i].read_status_fn,
|
||||||
chip_data[i].write_status_fn,
|
chip_data[i].write_status_fn,
|
||||||
chip_data[i].status_qio_bit);
|
chip_data[i].status_qio_bit);
|
||||||
@ -169,6 +226,7 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
|
|||||||
uint32_t status;
|
uint32_t status;
|
||||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
|
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
|
||||||
// spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP,
|
// spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP,
|
||||||
// which is compiled into the bootloader instead.
|
// which is compiled into the bootloader instead.
|
||||||
@ -184,6 +242,7 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
|
|||||||
ESP_LOGW(TAG, "Chip is ESP32-D2WD/ESP32-PICOD4 but flash WP pin is different value to internal flash");
|
ESP_LOGW(TAG, "Chip is ESP32-D2WD/ESP32-PICOD4 but flash WP pin is different value to internal flash");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||||
|
|
||||||
@ -218,8 +277,15 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
|
|||||||
|
|
||||||
esp_rom_spiflash_config_readmode(mode);
|
esp_rom_spiflash_config_readmode(mode);
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
esp_rom_spiflash_select_qio_pins(CONFIG_BOOTLOADER_SPI_WP_PIN, spiconfig);
|
esp_rom_spiflash_select_qio_pins(CONFIG_BOOTLOADER_SPI_WP_PIN, spiconfig);
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
if (ets_efuse_get_wp_pad() <= MAX_PAD_GPIO_NUM) {
|
||||||
|
esp_rom_spiflash_select_qio_pins(ets_efuse_get_wp_pad(), spiconfig);
|
||||||
|
} else {
|
||||||
|
esp_rom_spiflash_select_qio_pins(CONFIG_BOOTLOADER_SPI_WP_PIN, spiconfig);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +340,11 @@ static void write_status_8b_xmc25qu64a(unsigned new_status)
|
|||||||
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
|
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
|
||||||
{
|
{
|
||||||
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;
|
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
SPIFLASH.ctrl.val = SPI_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
|
SPIFLASH.ctrl.val = SPI_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
SPIFLASH.ctrl.val = SPI_MEM_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
|
||||||
|
#endif
|
||||||
SPIFLASH.user.usr_dummy = 0;
|
SPIFLASH.user.usr_dummy = 0;
|
||||||
SPIFLASH.user.usr_addr = 0;
|
SPIFLASH.user.usr_addr = 0;
|
||||||
SPIFLASH.user.usr_command = 1;
|
SPIFLASH.user.usr_command = 1;
|
||||||
@ -282,9 +352,17 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8
|
|||||||
|
|
||||||
SPIFLASH.user2.usr_command_value = command;
|
SPIFLASH.user2.usr_command_value = command;
|
||||||
SPIFLASH.user.usr_miso = miso_len > 0;
|
SPIFLASH.user.usr_miso = miso_len > 0;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
|
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
SPIFLASH.miso_dlen.usr_miso_bit_len = miso_len ? (miso_len - 1) : 0;
|
||||||
|
#endif
|
||||||
SPIFLASH.user.usr_mosi = mosi_len > 0;
|
SPIFLASH.user.usr_mosi = mosi_len > 0;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0;
|
SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0;
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
SPIFLASH.mosi_dlen.usr_mosi_bit_len = mosi_len ? (mosi_len - 1) : 0;
|
||||||
|
#endif
|
||||||
SPIFLASH.data_buf[0] = mosi_data;
|
SPIFLASH.data_buf[0] = mosi_data;
|
||||||
|
|
||||||
if (g_rom_spiflash_dummy_len_plus[1]) {
|
if (g_rom_spiflash_dummy_len_plus[1]) {
|
||||||
@ -299,8 +377,8 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8
|
|||||||
}
|
}
|
||||||
|
|
||||||
SPIFLASH.cmd.usr = 1;
|
SPIFLASH.cmd.usr = 1;
|
||||||
while(SPIFLASH.cmd.usr != 0)
|
while (SPIFLASH.cmd.usr != 0) {
|
||||||
{ }
|
}
|
||||||
|
|
||||||
SPIFLASH.ctrl.val = old_ctrl_reg;
|
SPIFLASH.ctrl.val = old_ctrl_reg;
|
||||||
return SPIFLASH.data_buf[0];
|
return SPIFLASH.data_buf[0];
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
idf_build_get_property(soc_name IDF_TARGET)
|
idf_build_get_property(soc_name IDF_TARGET)
|
||||||
|
|
||||||
|
# TODO: add esp32sbeta support for efuse component
|
||||||
|
if(NOT CONFIG_IDF_TARGET_ESP32)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(EXISTS "${COMPONENT_DIR}/${soc_name}")
|
if(EXISTS "${COMPONENT_DIR}/${soc_name}")
|
||||||
include(${COMPONENT_DIR}/${soc_name}/sources.cmake)
|
include(${COMPONENT_DIR}/${soc_name}/sources.cmake)
|
||||||
spaces2list(EFUSE_SOC_SRCS)
|
spaces2list(EFUSE_SOC_SRCS)
|
||||||
@ -7,6 +12,7 @@ if(EXISTS "${COMPONENT_DIR}/${soc_name}")
|
|||||||
set(COMPONENT_ADD_INCLUDEDIRS include ${soc_name}/include)
|
set(COMPONENT_ADD_INCLUDEDIRS include ${soc_name}/include)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
list(APPEND COMPONENT_ADD_INCLUDEDIRS include)
|
||||||
list(APPEND COMPONENT_SRCS "src/esp_efuse_api.c"
|
list(APPEND COMPONENT_SRCS "src/esp_efuse_api.c"
|
||||||
"src/esp_efuse_fields.c"
|
"src/esp_efuse_fields.c"
|
||||||
"src/esp_efuse_utility.c")
|
"src/esp_efuse_utility.c")
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
require_idf_targets(esp32)
|
# require_idf_targets(esp32)
|
||||||
|
|
||||||
if(BOOTLOADER_BUILD)
|
if(BOOTLOADER_BUILD AND CONFIG_IDF_TARGET_ESP32)
|
||||||
# For bootloader, all we need from esp32 is headers
|
# For bootloader, all we need from esp32 is headers
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS include)
|
set(COMPONENT_ADD_INCLUDEDIRS include)
|
||||||
register_component()
|
register_component()
|
||||||
target_linker_script(${COMPONENT_LIB} "ld/esp32.peripherals.ld")
|
target_linker_script(${COMPONENT_LIB} "ld/esp32.peripherals.ld")
|
||||||
else()
|
elseif(CONFIG_IDF_TARGET_ESP32)
|
||||||
# Regular app build
|
# Regular app build
|
||||||
|
|
||||||
set(COMPONENT_SRCS "brownout.c"
|
set(COMPONENT_SRCS "brownout.c"
|
||||||
|
@ -4,6 +4,9 @@ if(BOOTLOADER_BUILD AND CONFIG_IDF_TARGET_ESP32S2BETA)
|
|||||||
set(COMPONENT_REQUIRES ${IDF_COMPONENTS} soc) #unfortunately rom/uart uses SOC registers directly
|
set(COMPONENT_REQUIRES ${IDF_COMPONENTS} soc) #unfortunately rom/uart uses SOC registers directly
|
||||||
set(COMPONENT_SRCS )
|
set(COMPONENT_SRCS )
|
||||||
register_component()
|
register_component()
|
||||||
|
idf_build_get_property(target IDF_TARGET)
|
||||||
|
set(scripts "ld/esp32s2beta.peripherals.ld")
|
||||||
|
target_linker_script(${COMPONENT_LIB} "${scripts}")
|
||||||
elseif(CONFIG_IDF_TARGET_ESP32S2BETA)
|
elseif(CONFIG_IDF_TARGET_ESP32S2BETA)
|
||||||
# Regular app build
|
# Regular app build
|
||||||
|
|
||||||
|
@ -116,7 +116,6 @@ void IRAM_ATTR esp_dport_access_stall_other_cpu_end(void)
|
|||||||
{
|
{
|
||||||
#ifndef CONFIG_FREERTOS_UNICORE
|
#ifndef CONFIG_FREERTOS_UNICORE
|
||||||
int cpu_id = xPortGetCoreID();
|
int cpu_id = xPortGetCoreID();
|
||||||
|
|
||||||
if (dport_core_state[0] == DPORT_CORE_STATE_IDLE
|
if (dport_core_state[0] == DPORT_CORE_STATE_IDLE
|
||||||
|| dport_core_state[1] == DPORT_CORE_STATE_IDLE) {
|
|| dport_core_state[1] == DPORT_CORE_STATE_IDLE) {
|
||||||
return;
|
return;
|
||||||
|
@ -340,7 +340,6 @@ static bool is_vect_desc_usable(vector_desc_t *vd, int flags, int cpu, int force
|
|||||||
ALCHLOG("....Unusable: reserved at runtime.");
|
ALCHLOG("....Unusable: reserved at runtime.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ints can't be both shared and non-shared.
|
//Ints can't be both shared and non-shared.
|
||||||
assert(!((vd->flags&VECDESC_FL_SHARED)&&(vd->flags&VECDESC_FL_NONSHARED)));
|
assert(!((vd->flags&VECDESC_FL_SHARED)&&(vd->flags&VECDESC_FL_NONSHARED)));
|
||||||
//check if interrupt already is in use by a non-shared interrupt
|
//check if interrupt already is in use by a non-shared interrupt
|
||||||
@ -368,7 +367,6 @@ static bool is_vect_desc_usable(vector_desc_t *vd, int flags, int cpu, int force
|
|||||||
ALCHLOG("....Unusable: already allocated");
|
ALCHLOG("....Unusable: already allocated");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +383,6 @@ static int get_available_int(int flags, int cpu, int force, int source)
|
|||||||
vector_desc_t empty_vect_desc;
|
vector_desc_t empty_vect_desc;
|
||||||
memset(&empty_vect_desc, 0, sizeof(vector_desc_t));
|
memset(&empty_vect_desc, 0, sizeof(vector_desc_t));
|
||||||
|
|
||||||
|
|
||||||
//Level defaults to any low/med interrupt
|
//Level defaults to any low/med interrupt
|
||||||
if (!(flags&ESP_INTR_FLAG_LEVELMASK)) flags|=ESP_INTR_FLAG_LOWMED;
|
if (!(flags&ESP_INTR_FLAG_LEVELMASK)) flags|=ESP_INTR_FLAG_LOWMED;
|
||||||
|
|
||||||
@ -433,12 +430,10 @@ static int get_available_int(int flags, int cpu, int force, int source)
|
|||||||
ALCHLOG("Int %d reserved %d level %d %s hasIsr %d",
|
ALCHLOG("Int %d reserved %d level %d %s hasIsr %d",
|
||||||
x, int_desc[x].cpuflags[cpu]==INTDESC_RESVD, int_desc[x].level,
|
x, int_desc[x].cpuflags[cpu]==INTDESC_RESVD, int_desc[x].level,
|
||||||
int_desc[x].type==INTTP_LEVEL?"LEVEL":"EDGE", int_has_handler(x, cpu));
|
int_desc[x].type==INTTP_LEVEL?"LEVEL":"EDGE", int_has_handler(x, cpu));
|
||||||
|
|
||||||
if ( !is_vect_desc_usable(vd, flags, cpu, force) ) continue;
|
if ( !is_vect_desc_usable(vd, flags, cpu, force) ) continue;
|
||||||
|
|
||||||
if (flags&ESP_INTR_FLAG_SHARED) {
|
if (flags&ESP_INTR_FLAG_SHARED) {
|
||||||
//We're allocating a shared int.
|
//We're allocating a shared int.
|
||||||
|
|
||||||
//See if int already is used as a shared interrupt.
|
//See if int already is used as a shared interrupt.
|
||||||
if (vd->flags&VECDESC_FL_SHARED) {
|
if (vd->flags&VECDESC_FL_SHARED) {
|
||||||
//We can use this already-marked-as-shared interrupt. Count the already attached isrs in order to see
|
//We can use this already-marked-as-shared interrupt. Count the already attached isrs in order to see
|
||||||
|
332
components/esp32s2beta/ld/esp32s2beta.project.ld.in
Normal file
332
components/esp32s2beta/ld/esp32s2beta.project.ld.in
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/* Default entry point: */
|
||||||
|
ENTRY(call_start_cpu0);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* RTC fast memory holds RTC wake stub code,
|
||||||
|
including from any source file named rtc_wake_stub*.c
|
||||||
|
*/
|
||||||
|
.rtc.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
mapping[rtc_text]
|
||||||
|
|
||||||
|
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
|
||||||
|
_rtc_text_end = ABSOLUTE(.);
|
||||||
|
} > rtc_iram_seg
|
||||||
|
|
||||||
|
/*
|
||||||
|
This section is required to skip rtc.text area because rtc_iram_seg and
|
||||||
|
rtc_data_seg are reflect the same address space on different buses.
|
||||||
|
*/
|
||||||
|
.rtc.dummy :
|
||||||
|
{
|
||||||
|
_rtc_dummy_start = ABSOLUTE(.);
|
||||||
|
_rtc_fast_start = ABSOLUTE(.);
|
||||||
|
. = SIZEOF(.rtc.text);
|
||||||
|
_rtc_dummy_end = ABSOLUTE(.);
|
||||||
|
} > rtc_data_seg
|
||||||
|
|
||||||
|
/* This section located in RTC FAST Memory area.
|
||||||
|
It holds data marked with RTC_FAST_ATTR attribute.
|
||||||
|
See the file "esp_attr.h" for more information.
|
||||||
|
*/
|
||||||
|
.rtc.force_fast :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_rtc_force_fast_start = ABSOLUTE(.);
|
||||||
|
*(.rtc.force_fast .rtc.force_fast.*)
|
||||||
|
. = ALIGN(4) ;
|
||||||
|
_rtc_force_fast_end = ABSOLUTE(.);
|
||||||
|
} > rtc_data_seg
|
||||||
|
|
||||||
|
/* RTC data section holds RTC wake stub
|
||||||
|
data/rodata, including from any source file
|
||||||
|
named rtc_wake_stub*.c and the data marked with
|
||||||
|
RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
|
||||||
|
The memory location of the data is dependent on
|
||||||
|
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
|
||||||
|
*/
|
||||||
|
.rtc.data :
|
||||||
|
{
|
||||||
|
_rtc_data_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
mapping[rtc_data]
|
||||||
|
|
||||||
|
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||||
|
_rtc_data_end = ABSOLUTE(.);
|
||||||
|
} > rtc_data_location
|
||||||
|
|
||||||
|
/* RTC bss, from any source file named rtc_wake_stub*.c */
|
||||||
|
.rtc.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
_rtc_bss_start = ABSOLUTE(.);
|
||||||
|
*rtc_wake_stub*.*(.bss .bss.*)
|
||||||
|
*rtc_wake_stub*.*(COMMON)
|
||||||
|
|
||||||
|
mapping[rtc_bss]
|
||||||
|
|
||||||
|
_rtc_bss_end = ABSOLUTE(.);
|
||||||
|
} > rtc_data_location
|
||||||
|
|
||||||
|
/* This section holds data that should not be initialized at power up
|
||||||
|
and will be retained during deep sleep.
|
||||||
|
User data marked with RTC_NOINIT_ATTR will be placed
|
||||||
|
into this section. See the file "esp_attr.h" for more information.
|
||||||
|
The memory location of the data is dependent on
|
||||||
|
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
|
||||||
|
*/
|
||||||
|
.rtc_noinit (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_rtc_noinit_start = ABSOLUTE(.);
|
||||||
|
*(.rtc_noinit .rtc_noinit.*)
|
||||||
|
. = ALIGN(4) ;
|
||||||
|
_rtc_noinit_end = ABSOLUTE(.);
|
||||||
|
} > rtc_data_location
|
||||||
|
|
||||||
|
/* This section located in RTC SLOW Memory area.
|
||||||
|
It holds data marked with RTC_SLOW_ATTR attribute.
|
||||||
|
See the file "esp_attr.h" for more information.
|
||||||
|
*/
|
||||||
|
.rtc.force_slow :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_rtc_force_slow_start = ABSOLUTE(.);
|
||||||
|
*(.rtc.force_slow .rtc.force_slow.*)
|
||||||
|
. = ALIGN(4) ;
|
||||||
|
_rtc_force_slow_end = ABSOLUTE(.);
|
||||||
|
} > rtc_slow_seg
|
||||||
|
|
||||||
|
/* Get size of rtc slow data based on rtc_data_location alias */
|
||||||
|
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
|
||||||
|
? (_rtc_force_slow_end - _rtc_data_start)
|
||||||
|
: (_rtc_force_slow_end - _rtc_force_slow_start);
|
||||||
|
|
||||||
|
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
|
||||||
|
? (_rtc_force_fast_end - _rtc_fast_start)
|
||||||
|
: (_rtc_noinit_end - _rtc_fast_start);
|
||||||
|
|
||||||
|
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
|
||||||
|
"RTC_SLOW segment data does not fit.")
|
||||||
|
|
||||||
|
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
|
||||||
|
"RTC_FAST segment data does not fit.")
|
||||||
|
|
||||||
|
/* Send .iram0 code to iram */
|
||||||
|
.iram0.vectors :
|
||||||
|
{
|
||||||
|
_iram_start = ABSOLUTE(.);
|
||||||
|
/* Vectors go to IRAM */
|
||||||
|
_init_start = ABSOLUTE(.);
|
||||||
|
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
|
||||||
|
. = 0x0;
|
||||||
|
KEEP(*(.WindowVectors.text));
|
||||||
|
. = 0x180;
|
||||||
|
KEEP(*(.Level2InterruptVector.text));
|
||||||
|
. = 0x1c0;
|
||||||
|
KEEP(*(.Level3InterruptVector.text));
|
||||||
|
. = 0x200;
|
||||||
|
KEEP(*(.Level4InterruptVector.text));
|
||||||
|
. = 0x240;
|
||||||
|
KEEP(*(.Level5InterruptVector.text));
|
||||||
|
. = 0x280;
|
||||||
|
KEEP(*(.DebugExceptionVector.text));
|
||||||
|
. = 0x2c0;
|
||||||
|
KEEP(*(.NMIExceptionVector.text));
|
||||||
|
. = 0x300;
|
||||||
|
KEEP(*(.KernelExceptionVector.text));
|
||||||
|
. = 0x340;
|
||||||
|
KEEP(*(.UserExceptionVector.text));
|
||||||
|
. = 0x3C0;
|
||||||
|
KEEP(*(.DoubleExceptionVector.text));
|
||||||
|
. = 0x400;
|
||||||
|
*(.*Vector.literal)
|
||||||
|
|
||||||
|
*(.UserEnter.literal);
|
||||||
|
*(.UserEnter.text);
|
||||||
|
. = ALIGN (16);
|
||||||
|
*(.entry.text)
|
||||||
|
*(.init.literal)
|
||||||
|
*(.init)
|
||||||
|
_init_end = ABSOLUTE(.);
|
||||||
|
} > iram0_0_seg
|
||||||
|
|
||||||
|
.iram0.text :
|
||||||
|
{
|
||||||
|
/* Code marked as runnning out of IRAM */
|
||||||
|
_iram_text_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
mapping[iram0_text]
|
||||||
|
|
||||||
|
_iram_text_end = ABSOLUTE(.);
|
||||||
|
_iram_end = ABSOLUTE(.);
|
||||||
|
} > iram0_0_seg
|
||||||
|
|
||||||
|
ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
|
||||||
|
"IRAM0 segment data does not fit.")
|
||||||
|
|
||||||
|
.dram0.data :
|
||||||
|
{
|
||||||
|
_data_start = ABSOLUTE(.);
|
||||||
|
_bt_data_start = ABSOLUTE(.);
|
||||||
|
*libbt.a:(.data .data.*)
|
||||||
|
. = ALIGN (4);
|
||||||
|
_bt_data_end = ABSOLUTE(.);
|
||||||
|
_btdm_data_start = ABSOLUTE(.);
|
||||||
|
*libbtdm_app.a:(.data .data.*)
|
||||||
|
. = ALIGN (4);
|
||||||
|
_btdm_data_end = ABSOLUTE(.);
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
*(.data1)
|
||||||
|
*(.sdata)
|
||||||
|
*(.sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
*(.sdata2)
|
||||||
|
*(.sdata2.*)
|
||||||
|
*(.gnu.linkonce.s2.*)
|
||||||
|
*(.jcr)
|
||||||
|
|
||||||
|
mapping[dram0_data]
|
||||||
|
|
||||||
|
_data_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > dram0_0_seg
|
||||||
|
|
||||||
|
/*This section holds data that should not be initialized at power up.
|
||||||
|
The section located in Internal SRAM memory region. The macro _NOINIT
|
||||||
|
can be used as attribute to place data into this section.
|
||||||
|
See the esp_attr.h file for more information.
|
||||||
|
*/
|
||||||
|
.noinit (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_noinit_start = ABSOLUTE(.);
|
||||||
|
*(.noinit .noinit.*)
|
||||||
|
. = ALIGN(4) ;
|
||||||
|
_noinit_end = ABSOLUTE(.);
|
||||||
|
} > dram0_0_seg
|
||||||
|
|
||||||
|
/* Shared RAM */
|
||||||
|
.dram0.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_start = ABSOLUTE(.);
|
||||||
|
*(.ext_ram.bss*)
|
||||||
|
_bt_bss_start = ABSOLUTE(.);
|
||||||
|
*libbt.a:(.bss .bss.* COMMON)
|
||||||
|
. = ALIGN (4);
|
||||||
|
_bt_bss_end = ABSOLUTE(.);
|
||||||
|
_btdm_bss_start = ABSOLUTE(.);
|
||||||
|
*libbtdm_app.a:(.bss .bss.* COMMON)
|
||||||
|
. = ALIGN (4);
|
||||||
|
_btdm_bss_end = ABSOLUTE(.);
|
||||||
|
|
||||||
|
mapping[dram0_bss]
|
||||||
|
|
||||||
|
*(.dynsbss)
|
||||||
|
*(.sbss)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.scommon)
|
||||||
|
*(.sbss2)
|
||||||
|
*(.sbss2.*)
|
||||||
|
*(.gnu.linkonce.sb2.*)
|
||||||
|
*(.dynbss)
|
||||||
|
*(.share.mem)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_end = ABSOLUTE(.);
|
||||||
|
/* The heap starts right after end of this section */
|
||||||
|
_heap_start = ABSOLUTE(.);
|
||||||
|
} > dram0_0_seg
|
||||||
|
|
||||||
|
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
|
||||||
|
"DRAM segment data does not fit.")
|
||||||
|
|
||||||
|
.flash.rodata :
|
||||||
|
{
|
||||||
|
_rodata_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||||
|
*(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||||
|
|
||||||
|
mapping[flash_rodata]
|
||||||
|
|
||||||
|
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.rodata1)
|
||||||
|
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_table)
|
||||||
|
*(.gcc_except_table .gcc_except_table.*)
|
||||||
|
*(.gnu.linkonce.e.*)
|
||||||
|
*(.gnu.version_r)
|
||||||
|
. = (. + 3) & ~ 3;
|
||||||
|
__eh_frame = ABSOLUTE(.);
|
||||||
|
KEEP(*(.eh_frame))
|
||||||
|
. = (. + 7) & ~ 3;
|
||||||
|
/* C++ constructor and destructor tables, properly ordered: */
|
||||||
|
__init_array_start = ABSOLUTE(.);
|
||||||
|
KEEP (*crtbegin.*(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
__init_array_end = ABSOLUTE(.);
|
||||||
|
KEEP (*crtbegin.*(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
/* C++ exception handlers table: */
|
||||||
|
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc)
|
||||||
|
*(.gnu.linkonce.h.*)
|
||||||
|
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc_end)
|
||||||
|
*(.dynamic)
|
||||||
|
*(.gnu.version_d)
|
||||||
|
/* Addresses of memory regions reserved via
|
||||||
|
SOC_RESERVE_MEMORY_REGION() */
|
||||||
|
soc_reserved_memory_region_start = ABSOLUTE(.);
|
||||||
|
KEEP (*(.reserved_memory_address))
|
||||||
|
soc_reserved_memory_region_end = ABSOLUTE(.);
|
||||||
|
_rodata_end = ABSOLUTE(.);
|
||||||
|
/* Literals are also RO data. */
|
||||||
|
_lit4_start = ABSOLUTE(.);
|
||||||
|
*(*.lit4)
|
||||||
|
*(.lit4.*)
|
||||||
|
*(.gnu.linkonce.lit4.*)
|
||||||
|
_lit4_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_thread_local_start = ABSOLUTE(.);
|
||||||
|
*(.tdata)
|
||||||
|
*(.tdata.*)
|
||||||
|
*(.tbss)
|
||||||
|
*(.tbss.*)
|
||||||
|
_thread_local_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >drom0_0_seg
|
||||||
|
|
||||||
|
.flash.text :
|
||||||
|
{
|
||||||
|
_stext = .;
|
||||||
|
_text_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
mapping[flash_text]
|
||||||
|
|
||||||
|
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||||
|
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||||
|
*(.fini.literal)
|
||||||
|
*(.fini)
|
||||||
|
*(.gnu.version)
|
||||||
|
_text_end = ABSOLUTE(.);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
/* Similar to _iram_start, this symbol goes here so it is
|
||||||
|
resolved by addr2line in preference to the first symbol in
|
||||||
|
the flash.text segment.
|
||||||
|
*/
|
||||||
|
_flash_cache_start = ABSOLUTE(0);
|
||||||
|
} >iram0_2_seg
|
||||||
|
}
|
89
components/esp32s2beta/ld/esp32s2beta_fragments.lf
Normal file
89
components/esp32s2beta/ld/esp32s2beta_fragments.lf
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
[sections:text]
|
||||||
|
entries:
|
||||||
|
.text+
|
||||||
|
.literal+
|
||||||
|
|
||||||
|
[sections:data]
|
||||||
|
entries:
|
||||||
|
.data+
|
||||||
|
|
||||||
|
[sections:bss]
|
||||||
|
entries:
|
||||||
|
.bss+
|
||||||
|
|
||||||
|
[sections:common]
|
||||||
|
entries:
|
||||||
|
COMMON
|
||||||
|
|
||||||
|
[sections:rodata]
|
||||||
|
entries:
|
||||||
|
.rodata+
|
||||||
|
|
||||||
|
[sections:rtc_text]
|
||||||
|
entries:
|
||||||
|
.rtc.text+
|
||||||
|
.rtc.literal
|
||||||
|
|
||||||
|
[sections:rtc_data]
|
||||||
|
entries:
|
||||||
|
.rtc.data+
|
||||||
|
|
||||||
|
[sections:rtc_rodata]
|
||||||
|
entries:
|
||||||
|
.rtc.rodata+
|
||||||
|
|
||||||
|
[sections:rtc_bss]
|
||||||
|
entries:
|
||||||
|
.rtc.bss
|
||||||
|
|
||||||
|
[sections:iram]
|
||||||
|
entries:
|
||||||
|
.iram1+
|
||||||
|
|
||||||
|
[sections:dram]
|
||||||
|
entries:
|
||||||
|
.dram1+
|
||||||
|
|
||||||
|
[sections:wifi_iram]
|
||||||
|
entries:
|
||||||
|
.wifi0iram+
|
||||||
|
|
||||||
|
[scheme:default]
|
||||||
|
entries:
|
||||||
|
text -> flash_text
|
||||||
|
rodata -> flash_rodata
|
||||||
|
data -> dram0_data
|
||||||
|
bss -> dram0_bss
|
||||||
|
common -> dram0_bss
|
||||||
|
iram -> iram0_text
|
||||||
|
dram -> dram0_data
|
||||||
|
rtc_text -> rtc_text
|
||||||
|
rtc_data -> rtc_data
|
||||||
|
rtc_rodata -> rtc_data
|
||||||
|
rtc_bss -> rtc_bss
|
||||||
|
wifi_iram -> flash_text
|
||||||
|
|
||||||
|
[scheme:rtc]
|
||||||
|
entries:
|
||||||
|
text -> rtc_text
|
||||||
|
data -> rtc_data
|
||||||
|
rodata -> rtc_data
|
||||||
|
bss -> rtc_bss
|
||||||
|
common -> rtc_bss
|
||||||
|
|
||||||
|
[scheme:noflash]
|
||||||
|
entries:
|
||||||
|
text -> iram0_text
|
||||||
|
rodata -> dram0_data
|
||||||
|
|
||||||
|
[scheme:noflash_data]
|
||||||
|
entries:
|
||||||
|
rodata -> dram0_data
|
||||||
|
|
||||||
|
[scheme:noflash_text]
|
||||||
|
entries:
|
||||||
|
text -> iram0_text
|
||||||
|
|
||||||
|
[scheme:wifi_iram]
|
||||||
|
entries:
|
||||||
|
wifi_iram -> iram0_text
|
@ -200,7 +200,6 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
|
|||||||
ESP_LOGW(TAG, "incorrect mac type");
|
ESP_LOGW(TAG, "incorrect mac type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,4 +365,3 @@ void esp_chip_info(esp_chip_info_t* out_info)
|
|||||||
out_info->features = CHIP_FEATURE_WIFI_BGN;
|
out_info->features = CHIP_FEATURE_WIFI_BGN;
|
||||||
|
|
||||||
// FIXME: other features?
|
// FIXME: other features?
|
||||||
}
|
|
||||||
|
@ -8,8 +8,9 @@ set(COMPONENT_ADD_INCLUDEDIRS "include")
|
|||||||
set(COMPONENT_PRIV_INCLUDEDIRS "private_include")
|
set(COMPONENT_PRIV_INCLUDEDIRS "private_include")
|
||||||
|
|
||||||
set(COMPONENT_REQUIRES log tcpip_adapter)
|
set(COMPONENT_REQUIRES log tcpip_adapter)
|
||||||
|
if(CONFIG_IDF_TARGET_ESP32)
|
||||||
set(COMPONENT_PRIV_REQUIRES ethernet)
|
set(COMPONENT_PRIV_REQUIRES ethernet)
|
||||||
set(COMPONENT_REQUIRES log tcpip_adapter ethernet)
|
endif()
|
||||||
|
|
||||||
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
||||||
|
|
||||||
|
@ -4,11 +4,17 @@ if(BOOTLOADER_BUILD)
|
|||||||
set(COMPONENT_REQUIRES ${IDF_COMPONENTS})
|
set(COMPONENT_REQUIRES ${IDF_COMPONENTS})
|
||||||
set(COMPONENT_SRCS)
|
set(COMPONENT_SRCS)
|
||||||
register_component()
|
register_component()
|
||||||
set(scripts
|
idf_build_get_property(target IDF_TARGET)
|
||||||
"esp32/ld/esp32.rom.ld"
|
set(scripts "${target}/ld/${target}.rom.ld")
|
||||||
"esp32/ld/esp32.rom.newlib-funcs.ld"
|
if(target STREQUAL "esp32")
|
||||||
"esp32/ld/esp32.rom.libgcc.ld"
|
list(APPEND scripts
|
||||||
)
|
"${target}/ld/${target}.rom.newlib-funcs.ld"
|
||||||
|
"${target}/ld/${target}.rom.libgcc.ld")
|
||||||
|
elseif(target STREQUAL "esp32s2beta")
|
||||||
|
list(APPEND scripts
|
||||||
|
"${target}/ld/${target}.rom.spiflash.ld"
|
||||||
|
"${target}/ld/${target}.rom.spiram_incompatible_fns.ld")
|
||||||
|
endif()
|
||||||
target_linker_script(${COMPONENT_LIB} "${scripts}")
|
target_linker_script(${COMPONENT_LIB} "${scripts}")
|
||||||
else()
|
else()
|
||||||
# Regular app build
|
# Regular app build
|
||||||
@ -17,6 +23,7 @@ else()
|
|||||||
|
|
||||||
register_component()
|
register_component()
|
||||||
|
|
||||||
|
if (CONFIG_IDF_TARGET_ESP32)
|
||||||
set(scripts
|
set(scripts
|
||||||
"esp32/ld/esp32.rom.ld"
|
"esp32/ld/esp32.rom.ld"
|
||||||
"esp32/ld/esp32.rom.libgcc.ld"
|
"esp32/ld/esp32.rom.libgcc.ld"
|
||||||
@ -40,4 +47,15 @@ else()
|
|||||||
if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH)
|
if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH)
|
||||||
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.spiflash.ld")
|
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.spiflash.ld")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32S2BETA)
|
||||||
|
target_linker_script(${COMPONENT_LIB}
|
||||||
|
"esp32s2beta/ld/esp32s2beta.rom.ld"
|
||||||
|
"esp32s2beta/ld/esp32s2beta.rom.nanofmt.ld"
|
||||||
|
"esp32s2beta/ld/esp32s2beta.rom.spiflash.ld"
|
||||||
|
"esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld"
|
||||||
|
"esp32s2beta/ld/esp32s2beta.spiram.rom-functions-dram.ld"
|
||||||
|
"esp32s2beta/ld/esp32s2beta.spiram.rom-functions-iram.ld")
|
||||||
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
@ -7,10 +7,14 @@ PROVIDE ( g_ticks_per_us_pro = g_ticks_per_us );
|
|||||||
PROVIDE ( g_rom_flashchip = SPI_flashchip_data );
|
PROVIDE ( g_rom_flashchip = SPI_flashchip_data );
|
||||||
PROVIDE ( g_rom_spiflash_chip = SPI_flashchip_data );
|
PROVIDE ( g_rom_spiflash_chip = SPI_flashchip_data );
|
||||||
PROVIDE ( esp_rom_spiflash_config_param = SPIParamCfg );
|
PROVIDE ( esp_rom_spiflash_config_param = SPIParamCfg );
|
||||||
|
PROVIDE ( esp_rom_spiflash_read = SPIRead );
|
||||||
PROVIDE ( esp_rom_spiflash_read_status = SPI_read_status );
|
PROVIDE ( esp_rom_spiflash_read_status = SPI_read_status );
|
||||||
PROVIDE ( esp_rom_spiflash_read_statushigh = SPI_read_status_high );
|
PROVIDE ( esp_rom_spiflash_read_statushigh = SPI_read_status_high );
|
||||||
PROVIDE ( esp_rom_spiflash_read_user_cmd = SPI_user_command_read );
|
PROVIDE ( esp_rom_spiflash_read_user_cmd = SPI_user_command_read );
|
||||||
|
PROVIDE ( esp_rom_spiflash_write = SPIWrite );
|
||||||
PROVIDE ( esp_rom_spiflash_write_encrypted_disable = SPI_Write_Encrypt_Disable );
|
PROVIDE ( esp_rom_spiflash_write_encrypted_disable = SPI_Write_Encrypt_Disable );
|
||||||
PROVIDE ( esp_rom_spiflash_write_encrypted_enable = SPI_Write_Encrypt_Enable );
|
PROVIDE ( esp_rom_spiflash_write_encrypted_enable = SPI_Write_Encrypt_Enable );
|
||||||
PROVIDE ( esp_rom_spiflash_config_clk = SPIClkConfig );
|
PROVIDE ( esp_rom_spiflash_config_clk = SPIClkConfig );
|
||||||
PROVIDE ( esp_rom_spiflash_select_qio_pins = SelectSpiQIO );
|
PROVIDE ( esp_rom_spiflash_select_qio_pins = SelectSpiQIO );
|
||||||
|
PROVIDE ( esp_rom_spiflash_unlock = SPIUnlock );
|
||||||
|
PROVIDE ( esp_rom_spiflash_erase_sector = SPIEraseSector );
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#ifndef _ROM_CACHE_H_
|
#ifndef _ROM_CACHE_H_
|
||||||
#define _ROM_CACHE_H_
|
#define _ROM_CACHE_H_
|
||||||
|
|
||||||
|
#include "esp_bit_defs.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "queue.h"
|
#include "sys/queue.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#define _ROM_RSA_PSS_H_
|
#define _ROM_RSA_PSS_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "rom/rsa_pss.h"
|
|
||||||
|
|
||||||
#define ETS_SIG_LEN 384 /* Bytes */
|
#define ETS_SIG_LEN 384 /* Bytes */
|
||||||
#define ETS_DIGEST_LEN 32 /* SHA-256, bytes */
|
#define ETS_DIGEST_LEN 32 /* SHA-256, bytes */
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#define _ROM_SECURE_BOOT_H_
|
#define _ROM_SECURE_BOOT_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "rom/rsa_pss.h"
|
#include "rsa_pss.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "rom/ets_sys.h"
|
#include "ets_sys.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
require_idf_targets(esp32)
|
|
||||||
|
|
||||||
set(COMPONENT_SRCS "emac_dev.c"
|
set(COMPONENT_SRCS "emac_dev.c"
|
||||||
"emac_main.c"
|
"emac_main.c"
|
||||||
"eth_phy/phy_common.c"
|
"eth_phy/phy_common.c"
|
||||||
|
@ -3,6 +3,7 @@ menu "FreeRTOS"
|
|||||||
# This is actually also handled in the ESP32 startup code, not only in FreeRTOS.
|
# This is actually also handled in the ESP32 startup code, not only in FreeRTOS.
|
||||||
config FREERTOS_UNICORE
|
config FREERTOS_UNICORE
|
||||||
bool "Run FreeRTOS only on first core"
|
bool "Run FreeRTOS only on first core"
|
||||||
|
default y if IDF_TARGET_ESP32S2BETA
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
This version of FreeRTOS normally takes control of all cores of
|
This version of FreeRTOS normally takes control of all cores of
|
||||||
@ -13,6 +14,7 @@ menu "FreeRTOS"
|
|||||||
# This invisible config value sets the value of tskNO_AFFINITY in task.h.
|
# This invisible config value sets the value of tskNO_AFFINITY in task.h.
|
||||||
# Intended to be used as a constant from other Kconfig files.
|
# Intended to be used as a constant from other Kconfig files.
|
||||||
# Value is (32-bit) INT_MAX.
|
# Value is (32-bit) INT_MAX.
|
||||||
|
|
||||||
config FREERTOS_NO_AFFINITY
|
config FREERTOS_NO_AFFINITY
|
||||||
hex
|
hex
|
||||||
default 0x7FFFFFFF
|
default 0x7FFFFFFF
|
||||||
|
@ -126,8 +126,8 @@ if(CONFIG_LWIP_PPP_SUPPORT)
|
|||||||
"lwip/src/netif/ppp/polarssl/sha1.c")
|
"lwip/src/netif/ppp/polarssl/sha1.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(COMPONENT_REQUIRES vfs esp_wifi)
|
set(COMPONENT_REQUIRES vfs esp_wifi ethernet)
|
||||||
set(COMPONENT_PRIV_REQUIRES ethernet tcpip_adapter nvs_flash)
|
set(COMPONENT_PRIV_REQUIRES tcpip_adapter nvs_flash)
|
||||||
|
|
||||||
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
||||||
|
|
||||||
|
@ -9,16 +9,14 @@ if(EXISTS "${COMPONENT_DIR}/${soc_name}")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS include)
|
list(APPEND COMPONENT_ADD_INCLUDEDIRS include)
|
||||||
|
if(NOT BOOTLOADER_BUILD)
|
||||||
list(APPEND COMPONENT_SRCS "src/memory_layout_utils.c"
|
list(APPEND COMPONENT_SRCS "src/memory_layout_utils.c"
|
||||||
"src/lldesc.c"
|
"src/lldesc.c src/hal/spi_hal.c"
|
||||||
"src/hal/spi_hal.c"
|
|
||||||
"src/hal/spi_hal_iram.c"
|
"src/hal/spi_hal_iram.c"
|
||||||
"src/hal/spi_slave_hal.c"
|
"src/soc_include_legacy_warn.c")
|
||||||
"src/hal/spi_slave_hal_iram.c"
|
|
||||||
"src/soc_include_legacy_warn.c"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(COMPONENT_REQUIRES)
|
set(COMPONENT_REQUIRES)
|
||||||
|
|
||||||
|
@ -51,6 +51,13 @@ static inline void cpu_write_itlb(unsigned vpn, unsigned attr)
|
|||||||
asm volatile ("witlb %1, %0; isync\n" :: "r" (vpn), "r" (attr));
|
asm volatile ("witlb %1, %0; isync\n" :: "r" (vpn), "r" (attr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void cpu_init_memctl()
|
||||||
|
{
|
||||||
|
#if XCHAL_ERRATUM_572
|
||||||
|
#error "Shouldn't have this errata or need this call on esp32s2beta"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configure memory region protection
|
* @brief Configure memory region protection
|
||||||
*
|
*
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "esp_dport_access.h"
|
#include "esp32s2beta/dport_access.h"
|
||||||
#include "soc.h"
|
#include "soc.h"
|
||||||
#include "uart_reg.h"
|
#include "uart_reg.h"
|
||||||
#include "xtensa/xtruntime.h"
|
#include "xtensa/xtruntime.h"
|
||||||
|
28
components/soc/esp32s2beta/include/soc/gpio_pins.h
Normal file
28
components/soc/esp32s2beta/include/soc/gpio_pins.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef _GPIO_PINS_H
|
||||||
|
#define _GPIO_PINS_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GPIO_PIN_COUNT 48
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _GPIO_PINS_H
|
@ -279,6 +279,8 @@
|
|||||||
#define SOC_IROM_HIGH 0x40c00000
|
#define SOC_IROM_HIGH 0x40c00000
|
||||||
#define SOC_IRAM_LOW 0x40020000
|
#define SOC_IRAM_LOW 0x40020000
|
||||||
#define SOC_IRAM_HIGH 0x40070000
|
#define SOC_IRAM_HIGH 0x40070000
|
||||||
|
#define SOC_DRAM_LOW 0x3FFD0000
|
||||||
|
#define SOC_DRAM_HIGH 0x3FF80000 // TODO: check RAM ranges
|
||||||
#define SOC_RTC_IRAM_LOW 0x40070000
|
#define SOC_RTC_IRAM_LOW 0x40070000
|
||||||
#define SOC_RTC_IRAM_HIGH 0x40072000
|
#define SOC_RTC_IRAM_HIGH 0x40072000
|
||||||
#define SOC_RTC_DRAM_LOW 0x3ff9e000
|
#define SOC_RTC_DRAM_LOW 0x3ff9e000
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "rom/ets_sys.h"
|
#include "esp32s2beta/rom/ets_sys.h"
|
||||||
#include "rom/rtc.h"
|
#include "esp32s2beta/rom/rtc.h"
|
||||||
#include "rom/uart.h"
|
#include "esp32s2beta/rom/uart.h"
|
||||||
#include "rom/gpio.h"
|
#include "esp32s2beta/rom/gpio.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
@ -528,7 +528,6 @@ void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq)
|
|||||||
/* may need equivalent function
|
/* may need equivalent function
|
||||||
uint32_t apll_fpd = REG_GET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
uint32_t apll_fpd = REG_GET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
||||||
|
|
||||||
|
|
||||||
* if (apll_fpd) {
|
* if (apll_fpd) {
|
||||||
* SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD);
|
* SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD);
|
||||||
* }
|
* }
|
||||||
@ -752,7 +751,6 @@ void rtc_clk_8m_divider_set(uint32_t div)
|
|||||||
void rtc_clk_init(rtc_clk_config_t cfg)
|
void rtc_clk_init(rtc_clk_config_t cfg)
|
||||||
{
|
{
|
||||||
rtc_cpu_freq_t cpu_source_before = rtc_clk_cpu_freq_get();
|
rtc_cpu_freq_t cpu_source_before = rtc_clk_cpu_freq_get();
|
||||||
|
|
||||||
/* If we get a TG WDT system reset while running at 240MHz,
|
/* If we get a TG WDT system reset while running at 240MHz,
|
||||||
* DPORT_CPUPERIOD_SEL register will be reset to 0 resulting in 120MHz
|
* DPORT_CPUPERIOD_SEL register will be reset to 0 resulting in 120MHz
|
||||||
* APB and CPU frequencies after reset. This will cause issues with XTAL
|
* APB and CPU frequencies after reset. This will cause issues with XTAL
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "soc/nrx_reg.h"
|
#include "soc/nrx_reg.h"
|
||||||
#include "soc/fe_reg.h"
|
#include "soc/fe_reg.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "rom/ets_sys.h"
|
#include "esp32s2beta/rom/ets_sys.h"
|
||||||
|
|
||||||
#define MHZ (1000000)
|
#define MHZ (1000000)
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "rom/ets_sys.h"
|
#include "esp32s2beta/rom/ets_sys.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/timer_group_reg.h"
|
#include "soc/timer_group_reg.h"
|
||||||
@ -68,7 +68,6 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
expected_freq = 150000;
|
expected_freq = 150000;
|
||||||
}
|
}
|
||||||
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
|
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
|
||||||
|
|
||||||
/* Start calibration */
|
/* Start calibration */
|
||||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
set(SOC_SRCS "rtc_clk.c"
|
set(SOC_SRCS "cpu_util.c"
|
||||||
|
"rtc_clk.c"
|
||||||
"rtc_init.c"
|
"rtc_init.c"
|
||||||
"rtc_pm.c"
|
"rtc_pm.c"
|
||||||
"rtc_sleep.c"
|
"rtc_sleep.c"
|
||||||
|
@ -183,7 +183,7 @@ inline static bool IRAM_ATTR esp_ptr_external_ram(const void *p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline static bool IRAM_ATTR esp_ptr_in_iram(const void *p) {
|
inline static bool IRAM_ATTR esp_ptr_in_iram(const void *p) {
|
||||||
#ifndef CONFIG_FREERTOS_UNICORE
|
#if !CONFIG_FREERTOS_UNICORE || CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
|
return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
|
||||||
#else
|
#else
|
||||||
return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH);
|
return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH);
|
||||||
|
@ -16,12 +16,14 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "soc/periph_defs.h"
|
#include "soc/periph_defs.h"
|
||||||
//include soc related (generated) definitions
|
|
||||||
#include "soc/spi_pins.h"
|
#include "soc/spi_pins.h"
|
||||||
#include "soc/spi_reg.h"
|
#include "soc/spi_reg.h"
|
||||||
#include "soc/spi_struct.h"
|
#include "soc/spi_struct.h"
|
||||||
#include "soc/gpio_sig_map.h"
|
#include "soc/gpio_sig_map.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
|
#include "soc/spi_mem_struct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
if(BOOTLOADER_BUILD)
|
if(BOOTLOADER_BUILD)
|
||||||
# Bootloader needs SPIUnlock from this file, but doesn't
|
if (CONFIG_IDF_TARGET_ESP32)
|
||||||
|
# ESP32 Bootloader needs SPIUnlock from this file, but doesn't
|
||||||
# need other parts of this component
|
# need other parts of this component
|
||||||
set(COMPONENT_SRCS "spi_flash_rom_patch.c")
|
set(COMPONENT_SRCS "spi_flash_rom_patch.c")
|
||||||
set(COMPONENT_PRIV_REQUIRES bootloader_support soc)
|
set(COMPONENT_PRIV_REQUIRES bootloader_support soc)
|
||||||
else()
|
endif()
|
||||||
|
else() # not BOOTLOADER_BUILD
|
||||||
set(COMPONENT_SRCS "cache_utils.c"
|
set(COMPONENT_SRCS "cache_utils.c"
|
||||||
"flash_mmap.c"
|
"flash_mmap.c"
|
||||||
"flash_ops.c"
|
"flash_ops.c"
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
if(NOT BOOTLOADER_BUILD)
|
||||||
set(COMPONENT_SRCS "eri.c" "trax.c")
|
set(COMPONENT_SRCS "eri.c" "trax.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS "include" "${IDF_TARGET}/include")
|
set(COMPONENT_ADD_INCLUDEDIRS "include" "${IDF_TARGET}/include")
|
||||||
|
|
||||||
@ -7,4 +9,6 @@ set(COMPONENT_PRIV_REQUIRES soc)
|
|||||||
|
|
||||||
register_component()
|
register_component()
|
||||||
|
|
||||||
|
if (NOT BOOTLOADER_BUILD)
|
||||||
target_link_libraries(${COMPONENT_LIB} "${CMAKE_CURRENT_SOURCE_DIR}/${IDF_TARGET}/libhal.a")
|
target_link_libraries(${COMPONENT_LIB} "${CMAKE_CURRENT_SOURCE_DIR}/${IDF_TARGET}/libhal.a")
|
||||||
|
endif()
|
||||||
|
@ -130,6 +130,9 @@ endfunction()
|
|||||||
# Automatically adds a -L search path for the containing directory (if found),
|
# Automatically adds a -L search path for the containing directory (if found),
|
||||||
# and then adds -T with the filename only. This allows INCLUDE directives to be
|
# and then adds -T with the filename only. This allows INCLUDE directives to be
|
||||||
# used to include other linker scripts in the same directory.
|
# used to include other linker scripts in the same directory.
|
||||||
|
#
|
||||||
|
# TODO: currently multiple linker scripts must be supplied as a single list for "scriptfiles"
|
||||||
|
# arg, cannot be supplied as list of args
|
||||||
function(target_linker_script target scriptfiles)
|
function(target_linker_script target scriptfiles)
|
||||||
cmake_parse_arguments(_ "PROCESS" "" "" ${ARGN})
|
cmake_parse_arguments(_ "PROCESS" "" "" ${ARGN})
|
||||||
foreach(scriptfile ${scriptfiles})
|
foreach(scriptfile ${scriptfiles})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user