Skip to content

Commit

Permalink
esp32s3: add simple boot support
Browse files Browse the repository at this point in the history
The Simple Boot feature for Espressif chips is a method of booting
that doesn't depend on a 2nd stage bootloader. Its not the
intention to replace a 2nd stage bootloader such as MCUboot and
ESP-IDF bootloader, but to have a minimal and straight-forward way
of booting, and also simplify the building.

This commit also removes deprecated code and makes this bootloader
configuration as default for esp32s3 targets and removes the need
for running 'make bootloader' command for it.

Other related fix, but not directly to Simple Boot:
- Instrumentation is required to run from IRAM to support it during
initialization. `is_eco0` function also needs to run from IRAM.
- `rtc.data` section placement was fixed.
- Provide arch-defined interfaces for efuses, in order to decouple
board config level from arch-defined values.

Signed-off-by: Almir Okato <almir.okato@espressif.com>
  • Loading branch information
almir-okato committed Apr 16, 2024
1 parent 24df2cc commit 8734040
Show file tree
Hide file tree
Showing 49 changed files with 1,211 additions and 7,600 deletions.
2 changes: 1 addition & 1 deletion arch/xtensa/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ config ARCH_CHIP_ESP32S3
bool "Espressif ESP32-S3"
select ARCH_FAMILY_LX7
select XTENSA_HAVE_INTERRUPTS
select ARCH_HAVE_BOOTLOADER
select ARCH_HAVE_BOOTLOADER if !ESPRESSIF_SIMPLE_BOOT
select ARCH_HAVE_FPU
select ARCH_HAVE_MPU
select ARCH_HAVE_MULTICPU
Expand Down
6 changes: 6 additions & 0 deletions arch/xtensa/include/esp32s3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/soc.h
/reg_base.h
/esp_attr.h
/esp_assert.h
/esp_bit_defs.h
/sdkconfig.h
24 changes: 7 additions & 17 deletions arch/xtensa/src/esp32s3/Bootloader.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

.PHONY: bootloader clean_bootloader

ifeq ($(CONFIG_ESP32S3_BOOTLOADER_BUILD_FROM_SOURCE),y)
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),)

TOOLSDIR = $(TOPDIR)/tools/espressif
CHIPDIR = $(TOPDIR)/arch/xtensa/src/chip
Expand Down Expand Up @@ -83,8 +83,13 @@ else ifeq ($(CONFIG_ESP32S3_APP_FORMAT_LEGACY),y)
$(call cfg_val,CONFIG_PARTITION_TABLE_OFFSET,$(CONFIG_ESP32S3_PARTITION_TABLE_OFFSET)) \
} >> $(BOOTLOADER_CONFIG)
endif
endif

ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
bootloader:
$(Q) echo "Using direct bootloader to boot NuttX."

else ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)

BOOTLOADER_BIN = $(TOPDIR)/mcuboot-esp32s3.bin

Expand Down Expand Up @@ -126,18 +131,3 @@ clean_bootloader:
$(call DELFILE,$(TOPDIR)/partition-table-esp32s3.bin)

endif

else ifeq ($(CONFIG_ESP32S3_BOOTLOADER_DOWNLOAD_PREBUILT),y)

BOOTLOADER_VERSION = latest
BOOTLOADER_URL = https://github.com/espressif/esp-nuttx-bootloader/releases/download/$(BOOTLOADER_VERSION)

bootloader:
$(call DOWNLOAD,$(BOOTLOADER_URL),bootloader-esp32s3.bin,$(TOPDIR)/bootloader-esp32s3.bin)
$(call DOWNLOAD,$(BOOTLOADER_URL),partition-table-esp32s3.bin,$(TOPDIR)/partition-table-esp32s3.bin)

clean_bootloader:
$(call DELFILE,$(TOPDIR)/bootloader-esp32s3.bin)
$(call DELFILE,$(TOPDIR)/partition-table-esp32s3.bin)

endif
42 changes: 15 additions & 27 deletions arch/xtensa/src/esp32s3/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ config ESPRESSIF_CHIP_SERIES
string
default "esp32s3"

config ESPRESSIF_NUM_CPUS
int
default 2

choice ESP32S3_DEFAULT_CPU_FREQ
prompt "CPU frequency"
default ESP32S3_DEFAULT_CPU_FREQ_240
Expand Down Expand Up @@ -530,6 +534,7 @@ config ESP32S3_WDT

config ESP32S3_EFUSE
bool "EFUSE support"
select EFUSE
default n
---help---
Enable ESP32-S3 efuse support.
Expand Down Expand Up @@ -1887,15 +1892,13 @@ config ESP32S3_SPI_FLASH_SUPPORT_PSRAM_STACK
3. Once operation in step 2 triggers, CPU will trigger exception.
So related SPI flash functions should be sent and run in tasks which use SRAM as task stack.

if ESP32S3_APP_FORMAT_LEGACY

comment "Partition Table configuration"

config ESP32S3_PARTITION_TABLE
bool "Create MTD partitions from Partition Table"
default n
depends on ESP32S3_MTD && ESP32S3_APP_FORMAT_LEGACY
select ESP32S3_BOOTLOADER_BUILD_FROM_SOURCE
depends on ESP32S3_MTD
select ESP32S3_APP_FORMAT_LEGACY
---help---
Decode partition table and initialize partitions as MTD.

Expand All @@ -1904,8 +1907,6 @@ config ESP32S3_PARTITION_MOUNTPT
default "/dev/esp/partition/"
depends on ESP32S3_PARTITION_TABLE

endif # ESP32S3_APP_FORMAT_LEGACY

endif # ESP32S3_SPIFLASH

endmenu # SPI Flash configuration
Expand Down Expand Up @@ -2173,38 +2174,26 @@ endmenu

menu "Bootloader and Image Configuration"

config ESP32S3_APP_FORMAT_LEGACY
config ESPRESSIF_SIMPLE_BOOT
bool
default y if !ESP32S3_APP_FORMAT_MCUBOOT
depends on !ESP32S3_APP_FORMAT_MCUBOOT
---help---
This is the legacy application image format, as supported by the ESP-IDF
2nd stage bootloader.
depends on !ESP32S3_APP_FORMAT_LEGACY
default y

config ESP32S3_APP_FORMAT_MCUBOOT
bool "Enable MCUboot-bootable format"
depends on !MCUBOOT_BOOTLOADER
default n
select ESP32S3_HAVE_OTA_PARTITION
select ESP32S3_BOOTLOADER_BUILD_FROM_SOURCE
---help---
Enables the Espressif port of MCUboot to be used as 2nd stage bootloader.

config ESP32S3_BOOTLOADER_DOWNLOAD_PREBUILT
config ESP32S3_APP_FORMAT_LEGACY
bool
default y if !ESP32S3_BOOTLOADER_BUILD_FROM_SOURCE
depends on !ESP32S3_BOOTLOADER_BUILD_FROM_SOURCE
default y if BUILD_PROTECTED
---help---
The build system will download the prebuilt binaries from
https://github.com/espressif/esp-nuttx-bootloader according to the chosen
Application Image Format (ESP32S3_APP_FORMAT_LEGACY or ESP32S3_APP_FORMAT_MCUBOOT)

config ESP32S3_BOOTLOADER_BUILD_FROM_SOURCE
bool "Build binaries from source"
---help---
The build system will build all the required binaries from source. It will clone
the https://github.com/espressif/esp-nuttx-bootloader repository and build a
custom bootloader according to the chosen Application Image Format
(ESP32S3_APP_FORMAT_LEGACY or ESP32S3_APP_FORMAT_MCUBOOT) and partition information.
This is the legacy application image format, as supported by the ESP-IDF
2nd stage bootloader.

choice
prompt "Target slot for image flashing"
Expand Down Expand Up @@ -2250,7 +2239,6 @@ config ESP32S3_CUSTOM_PARTITION_TABLE_OFFSET
bool "Customize partition table offset"
default n
depends on ESP32S3_APP_FORMAT_LEGACY
select ESP32S3_BOOTLOADER_BUILD_FROM_SOURCE
---help---
Enable to select the offset of the partition table in the flash.

Expand Down
7 changes: 3 additions & 4 deletions arch/xtensa/src/esp32s3/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ endif

ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION
ESP_HAL_3RDPARTY_VERSION = c6a4edccfce95e32ef5e34d9f1119d9c581c5c1c
ESP_HAL_3RDPARTY_VERSION = 7c4fae7ebc5342b19cab03511bfa277176bba377
endif

ifndef ESP_HAL_3RDPARTY_URL
Expand All @@ -212,6 +212,8 @@ chip/$(ESP_HAL_3RDPARTY_REPO):
CFLAGS += -Wno-undef -Wno-unused-variable
CFLAGS += ${DEFINE_PREFIX}_RETARGETABLE_LOCKING

AFLAGS += $(CFLAGS)

# Files that require the HAL recipe

include chip/Bootloader.mk
Expand All @@ -231,9 +233,6 @@ ifeq ($(CONFIG_ESP32S3_WIRELESS),y)
$(Q) cd chip/$(ESP_HAL_3RDPARTY_REPO)/components/mbedtls/mbedtls && git apply ../../../nuttx/patches/components/mbedtls/mbedtls/*.patch
endif

distclean::
$(call DELDIR, chip/$(ESP_HAL_3RDPARTY_REPO))

ifeq ($(CONFIG_ESP32S3_WIRELESS),y)
include chip/Wireless.mk
endif
Expand Down
2 changes: 1 addition & 1 deletion arch/xtensa/src/esp32s3/esp32s3_ble_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
#include "hardware/wdev_reg.h"
#include "rom/esp32s3_spiflash.h"
#include "xtensa.h"
#include "xtensa_attr.h"
#include "esp_attr.h"
#include "esp32s3_irq.h"
#include "esp32s3_rt_timer.h"
#include "esp32s3_rtc.h"
Expand Down
2 changes: 1 addition & 1 deletion arch/xtensa/src/esp32s3/esp32s3_clockconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <sys/param.h>

#include "xtensa.h"
#include "xtensa_attr.h"
#include "esp_attr.h"
#include "hardware/esp32s3_soc.h"
#include "hardware/esp32s3_uart.h"
#include "hardware/esp32s3_system.h"
Expand Down
142 changes: 70 additions & 72 deletions arch/xtensa/src/esp32s3/esp32s3_efuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,51 +440,6 @@ static int esp32s3_efuse_process(const efuse_desc_t *field[], void *ptr,
return err;
}

/****************************************************************************
* Name: esp32s3_efuse_write_reg
*
* Description:
* Write value to efuse register.
*
* Input Parameters:
* blk - Block number of eFuse
* num_reg - The register number in the block
* value - Value to write
*
* Returned Value:
* None.
*
****************************************************************************/

static void esp32s3_efuse_write_reg(uint32_t blk, uint32_t num_reg,
uint32_t value)
{
uint32_t addr_wr_reg;
uint32_t reg_to_write;
uint32_t blk_start = g_start_efuse_wrreg[blk];

DEBUGASSERT(blk >= 0 && blk < EFUSE_BLK_MAX);

DEBUGASSERT(num_reg <= 7);

/* The block 0 and register 7 doesn't exist */

if (blk == 0 && num_reg == 7)
{
merr("Block 0 Register 7 doesn't exist!\n");
return;
}

addr_wr_reg = blk_start + num_reg * 4;
reg_to_write = getreg32(addr_wr_reg) | value;

/* The register can be written in parts so we combine the new value
* with the one already available.
*/

putreg32(reg_to_write, addr_wr_reg);
}

/****************************************************************************
* Name: esp32s3_efuse_write_blob
*
Expand Down Expand Up @@ -518,33 +473,6 @@ static int esp32s3_efuse_write_blob(uint32_t num_reg, int bit_offset,
return OK;
}

/****************************************************************************
* Name: esp32s3_efuse_read_reg
*
* Description:
* Read efuse register.
*
* Input Parameters:
* blk - Block number of eFuse
* num_reg - The register number in the block
*
* Returned Value:
* Return the value in the efuse register.
*
****************************************************************************/

static uint32_t esp32s3_efuse_read_reg(uint32_t blk, uint32_t num_reg)
{
DEBUGASSERT(blk >= 0 && blk < EFUSE_BLK_MAX);
uint32_t value;
uint32_t blk_start = g_start_efuse_rdreg[blk];

DEBUGASSERT(num_reg <= 7);

value = getreg32(blk_start + num_reg * 4);
return value;
}

/****************************************************************************
* Name: esp32s3_efuse_fill_buff
*
Expand Down Expand Up @@ -709,3 +637,73 @@ void esp32s3_efuse_burn_efuses(void)
};
}

/****************************************************************************
* Name: esp32s3_efuse_read_reg
*
* Description:
* Read efuse register.
*
* Input Parameters:
* blk - Block number of eFuse
* num_reg - The register number in the block
*
* Returned Value:
* Return the value in the efuse register.
*
****************************************************************************/

uint32_t esp32s3_efuse_read_reg(uint32_t blk, uint32_t num_reg)
{
DEBUGASSERT(blk >= 0 && blk < EFUSE_BLK_MAX);
uint32_t value;
uint32_t blk_start = g_start_efuse_rdreg[blk];

DEBUGASSERT(num_reg <= 7);

value = getreg32(blk_start + num_reg * 4);
return value;
}

/****************************************************************************
* Name: esp32s3_efuse_write_reg
*
* Description:
* Write value to efuse register.
*
* Input Parameters:
* blk - Block number of eFuse
* num_reg - The register number in the block
* value - Value to write
*
* Returned Value:
* None.
*
****************************************************************************/

void esp32s3_efuse_write_reg(uint32_t blk, uint32_t num_reg, uint32_t value)
{
uint32_t addr_wr_reg;
uint32_t reg_to_write;
uint32_t blk_start = g_start_efuse_wrreg[blk];

DEBUGASSERT(blk >= 0 && blk < EFUSE_BLK_MAX);

DEBUGASSERT(num_reg <= 7);

/* The block 0 and register 7 doesn't exist */

if (blk == 0 && num_reg == 7)
{
merr("Block 0 Register 7 doesn't exist!\n");
return;
}

addr_wr_reg = blk_start + num_reg * 4;
reg_to_write = getreg32(addr_wr_reg) | value;

/* The register can be written in parts so we combine the new value
* with the one already available.
*/

putreg32(reg_to_write, addr_wr_reg);
}
Loading

0 comments on commit 8734040

Please sign in to comment.