xtensa/esp32: Build patched IDFBoot for Protected Mode support

Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
This commit is contained in:
Gustavo Henrique Nihei 2022-07-06 15:46:25 -03:00 committed by Xiang Xiao
parent 60b7479f12
commit 68c722c051
5 changed files with 131 additions and 7 deletions

View file

@ -1,3 +1,2 @@
/esp-wireless-drivers-3rdparty
/esp-nuttx-bootloader
/*.zip

View file

@ -18,18 +18,18 @@
#
############################################################################
.PHONY: bootloader clean_bootloader
ifeq ($(CONFIG_ESP32_BOOTLOADER_BUILD_FROM_SOURCE),y)
CHIPDIR = $(TOPDIR)/arch/xtensa/src/chip
BOOTLOADER_SRCDIR = $(CHIPDIR)/esp-nuttx-bootloader
BOOTLOADER_DIR = $(CHIPDIR)/bootloader
BOOTLOADER_SRCDIR = $(BOOTLOADER_DIR)/esp-nuttx-bootloader
BOOTLOADER_VERSION = main
BOOTLOADER_URL = https://github.com/espressif/esp-nuttx-bootloader
BOOTLOADER_OUTDIR = out
BOOTLOADER_CONFIG = $(CHIPDIR)/bootloader.conf
$(BOOTLOADER_SRCDIR):
$(Q) git clone $(BOOTLOADER_URL) $(BOOTLOADER_SRCDIR) -b $(BOOTLOADER_VERSION)
BOOTLOADER_CONFIG = $(BOOTLOADER_DIR)/bootloader.conf
# Helpers for creating the configuration file
@ -108,6 +108,9 @@ ifeq ($(CONFIG_ESP32_APP_FORMAT_MCUBOOT),y)
BOOTLOADER_BIN = $(TOPDIR)/mcuboot-esp32.bin
BOOTLOADER_SIGNED_BIN = $(TOPDIR)/mcuboot-esp32.signed.bin
$(BOOTLOADER_SRCDIR):
$(Q) git clone $(BOOTLOADER_URL) $(BOOTLOADER_SRCDIR) -b $(BOOTLOADER_VERSION)
$(BOOTLOADER_BIN): $(BOOTLOADER_CONFIG)
$(Q) echo "Building Bootloader"
$(Q) $(BOOTLOADER_SRCDIR)/build_mcuboot.sh -c esp32 -s -f $(BOOTLOADER_CONFIG)
@ -145,9 +148,16 @@ clean_bootloader:
else ifeq ($(CONFIG_ESP32_APP_FORMAT_LEGACY),y)
$(BOOTLOADER_SRCDIR):
$(Q) git clone $(BOOTLOADER_URL) $(BOOTLOADER_SRCDIR) -b $(BOOTLOADER_VERSION)
$(Q) git -C $(BOOTLOADER_SRCDIR) submodule update --init esp-idf
ifeq ($(CONFIG_BUILD_PROTECTED),y)
$(Q) git -C $(BOOTLOADER_SRCDIR)/esp-idf apply -v $(BOOTLOADER_DIR)/0001-esp32-Connect-Xtensa-Instruction-RAM1-to-Cache.patch
endif
bootloader: $(BOOTLOADER_SRCDIR) $(BOOTLOADER_CONFIG)
$(Q) echo "Building Bootloader binaries"
$(Q) $(BOOTLOADER_SRCDIR)/build_idfboot.sh -c esp32 -s -f $(BOOTLOADER_CONFIG)
$(Q) $(BOOTLOADER_SRCDIR)/build_idfboot.sh -c esp32 -f $(BOOTLOADER_CONFIG)
$(call COPYFILE,$(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/bootloader-esp32.bin,$(TOPDIR))
$(call COPYFILE,$(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/partition-table-esp32.bin,$(TOPDIR))

View file

@ -0,0 +1,2 @@
/esp-nuttx-bootloader
/bootloader.conf

View file

@ -0,0 +1,112 @@
From 3ee21d64a48018b33c1db485b5fbfb08145e4f67 Mon Sep 17 00:00:00 2001
From: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
Date: Wed, 6 Jul 2022 10:03:09 -0300
Subject: [PATCH] esp32: Connect Xtensa Instruction RAM1 to Cache
User application image is executed with PID 5, so it accesses the
External Flash via virtual address starting from 0x40400000 (Vaddr2).
See:
https://github.com/espressif/esp-idf/blob/v4.4.1/components/xtensa/esp32/include/xtensa/config/core-isa.h#L301-L305
Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
---
.../bootloader_support/src/bootloader_utility.c | 17 ++++++++++++++---
components/soc/esp32/include/soc/mmu.h | 1 +
components/spi_flash/cache_utils.c | 2 ++
components/spi_flash/flash_mmap.c | 8 ++++++++
4 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c
index ad56335253..7e343a551b 100644
--- a/components/bootloader_support/src/bootloader_utility.c
+++ b/components/bootloader_support/src/bootloader_utility.c
@@ -737,6 +737,14 @@ static void set_cache_and_start_app(
for (int i = 0; i < DPORT_FLASH_MMU_TABLE_SIZE; i++) {
DPORT_PRO_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL;
}
+
+ /* Xtensa CPU does speculative load/store on VAddr1/2/3 when connected to cache.
+ * Hence it requires all the pages of VAddr2/3 to be set valid to any physical page.
+ * Marking any page invalid would stall the CPU
+ */
+ for (int i = 64; i < 256; i++) {
+ DPORT_PRO_FLASH_MMU_TABLE[i] = 0;
+ }
#else
for (size_t i = 0; i < FLASH_MMU_TABLE_SIZE; i++) {
FLASH_MMU_TABLE[i] = MMU_TABLE_INVALID_VAL;
@@ -793,11 +801,11 @@ static void set_cache_and_start_app(
rc = cache_flash_mmu_set(1, 0, irom_load_addr_aligned, irom_addr_aligned, 64, irom_page_count);
ESP_LOGV(TAG, "rc=%d", rc);
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) |
(DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 |
DPORT_PRO_CACHE_MASK_DRAM1 );
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) |
(DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 |
DPORT_APP_CACHE_MASK_DRAM1 );
#elif CONFIG_IDF_TARGET_ESP32S2
@@ -815,7 +823,10 @@ static void set_cache_and_start_app(
REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_DBUS);
#endif
#if CONFIG_IDF_TARGET_ESP32
- Cache_Read_Enable(0);
+ DPORT_REG_SET_BIT(0x3ff43050, 1);
+ DPORT_REG_SET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE);
+
+ asm("memw");
#elif CONFIG_IDF_TARGET_ESP32S2
Cache_Resume_ICache(autoload);
#elif CONFIG_IDF_TARGET_ESP32S3
diff --git a/components/soc/esp32/include/soc/mmu.h b/components/soc/esp32/include/soc/mmu.h
index bde6995516..9fff17ddba 100644
--- a/components/soc/esp32/include/soc/mmu.h
+++ b/components/soc/esp32/include/soc/mmu.h
@@ -32,6 +32,7 @@ extern "C" {
#define SOC_MMU_ADDR_MASK DPORT_MMU_ADDRESS_MASK
#define SOC_MMU_PAGE_IN_FLASH(page) (page)
#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE ((volatile uint32_t*) 0x3FF10000)
+#define SOC_MMU_DPORT_APP_FLASH_MMU_TABLE ((volatile uint32_t*) 0x3FF12000)
#define SOC_MMU_VADDR1_START_ADDR SOC_IROM_MASK_LOW
#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE ((SOC_MMU_VADDR1_FIRST_USABLE_ADDR - SOC_MMU_VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + SOC_MMU_IROM0_PAGES_START)
#define SOC_MMU_VADDR0_START_ADDR SOC_DROM_LOW
diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c
index 7715900055..b29aed2953 100644
--- a/components/spi_flash/cache_utils.c
+++ b/components/spi_flash/cache_utils.c
@@ -308,6 +308,8 @@ static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_st
while (DPORT_GET_PERI_REG_BITS2(DPORT_PRO_DCACHE_DBUG0_REG, DPORT_PRO_CACHE_STATE, DPORT_PRO_CACHE_STATE_S) != 1) {
;
}
+ /* Disconnect from cache */
+ DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, 0xff);
DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 0, DPORT_PRO_CACHE_ENABLE_S);
}
#if !CONFIG_FREERTOS_UNICORE
diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c
index 9523bc7959..c17a9903ef 100644
--- a/components/spi_flash/flash_mmap.c
+++ b/components/spi_flash/flash_mmap.c
@@ -108,7 +108,15 @@ static void IRAM_ATTR spi_flash_mmap_init(void)
if ((entry_pro & SOC_MMU_INVALID_ENTRY_VAL) == 0 && (i == SOC_MMU_DROM0_PAGES_START || i == SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) {
s_mmap_page_refcnt[i] = 1;
} else {
+#if CONFIG_IDF_TARGET_ESP32
+ /* Due to Xtensa speculative load/store, pages need to be marked valid if VAddr2/VAddr3
+ * are connected to cache. If marked invalid, CPU will halt
+ */
+ SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = 0x00;
+ SOC_MMU_DPORT_APP_FLASH_MMU_TABLE[i] = 0x00;
+#else
SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL;
+#endif
#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32
DPORT_APP_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL;
#endif
--
2.34.1

View file

@ -29,6 +29,7 @@ CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEBUG_WARN=y
CONFIG_ESP32_BOOTLOADER_BUILD_FROM_SOURCE=y
CONFIG_ESP32_PID=y
CONFIG_ESP32_UART0=y
CONFIG_EXPERIMENTAL=y