This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 800678ca789eb96b1fe07f06e44130cbeda4dca2 Author: Gustavo Henrique Nihei <gustavo.ni...@espressif.com> AuthorDate: Mon Sep 13 13:56:55 2021 -0300 xtensa/esp32s2: Enable booting from MCUboot bootloader Signed-off-by: Gustavo Henrique Nihei <gustavo.ni...@espressif.com> --- arch/xtensa/src/esp32s2/Kconfig | 132 +++++++++- arch/xtensa/src/esp32s2/esp32s2_start.c | 265 ++++++++++++++++++--- .../src/esp32s2/hardware/esp32s2_cache_memory.h | 153 ++++++++++++ arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h | 69 ++++++ .../esp32s2/esp32s2-saola-1/scripts/Make.defs | 10 +- .../esp32s2-saola-1/scripts/esp32s2.template.ld | 73 +++++- .../esp32s2-saola-1/scripts/esp32s2_flash.ld | 2 +- .../{esp32s2_flash.ld => esp32s2_mcuboot.ld} | 241 +++++++++++++------ .../esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld | 8 +- tools/esp32s2/Config.mk | 108 +++++++-- 10 files changed, 911 insertions(+), 150 deletions(-) diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig index c529b52..09bc35e 100644 --- a/arch/xtensa/src/esp32s2/Kconfig +++ b/arch/xtensa/src/esp32s2/Kconfig @@ -176,14 +176,6 @@ config ESP32S2_RT_TIMER select ESP32S2_TIMER default n -config ESP32S2_PARTITION - bool "ESP32S2 Partition" - default n - select ESP32S2_SPIFLASH - ---help--- - Decode esp-idf's partition file and initialize - partition by nuttx MTD. - config ESP32S2_RUN_IRAM bool "Run from IRAM" default n @@ -620,9 +612,50 @@ endmenu # ESP32S2_SPI menu "SPI Flash configuration" depends on ESP32S2_SPIFLASH +if ESP32S2_HAVE_OTA_PARTITION + +comment "Application Image OTA Update support" + +config ESP32S2_OTA_PRIMARY_SLOT_OFFSET + hex "Application image primary slot offset" + default "0x10000" + +config ESP32S2_OTA_PRIMARY_SLOT_DEVPATH + string "Application image primary slot device path" + default "/dev/ota0" + +config ESP32S2_OTA_SECONDARY_SLOT_OFFSET + hex "Application image secondary slot offset" + default "0x110000" + +config ESP32S2_OTA_SECONDARY_SLOT_DEVPATH + string "Application image secondary slot device path" + default "/dev/ota1" + +config ESP32S2_OTA_SLOT_SIZE + hex "Application image slot size (in bytes)" + default "0x100000" + +config ESP32S2_OTA_SCRATCH_OFFSET + hex "Scratch partition offset" + default "0x210000" + +config ESP32S2_OTA_SCRATCH_SIZE + hex "Scratch partition size" + default "0x40000" + +config ESP32S2_OTA_SCRATCH_DEVPATH + string "Scratch partition device path" + default "/dev/otascratch" + +endif + +comment "General MTD configuration" + config ESP32S2_MTD_OFFSET hex "MTD base address in SPI Flash" - default 0x180000 + default 0x180000 if !ESP32S2_HAVE_OTA_PARTITION + default 0x250000 if ESP32S2_HAVE_OTA_PARTITION ---help--- MTD base address in SPI Flash. @@ -640,7 +673,7 @@ config ESP32S2_SPIFLASH_DEBUG Enable this option, read and write of SPI Flash will show input arguments and result. -endmenu # ESP32S2_SPIFLASH +endmenu # SPI Flash configuration menu "SPI RAM Config" depends on ESP32S2_SPIRAM @@ -866,6 +899,81 @@ config ESP32S2_FREERUN endmenu # Timer/counter Configuration endif # ESP32S2_TIMER +config ESP32S2_HAVE_OTA_PARTITION + bool + default n + +menu "Application Image Configuration" + +choice + prompt "Application Image Format" + default ESP32S2_APP_FORMAT_LEGACY + ---help--- + Depending on the chosen 2nd stage bootloader, the application may + be required to be perform a specific startup routine. Furthermore, + the image binary must be formatted according to the definition from + the 2nd stage bootloader. + +config ESP32S2_APP_FORMAT_LEGACY + bool "Legacy format" + ---help--- + This is the legacy application image format, as supported by the ESP-IDF + 2nd stage bootloader. + +config ESP32S2_APP_FORMAT_MCUBOOT + bool "MCUboot-bootable format" + select ESP32S2_HAVE_OTA_PARTITION + depends on EXPERIMENTAL + ---help--- + The Espressif port of MCUboot supports the loading of unsegmented firmware + images. + +comment "MCUboot support depends on CONFIG_EXPERIMENTAL" + depends on !EXPERIMENTAL + +endchoice # Application Image Format + +choice + prompt "Target slot for image flashing" + default ESP32S2_ESPTOOL_TARGET_PRIMARY + depends on ESP32S2_HAVE_OTA_PARTITION + ---help--- + Slot to which ESPTOOL will flash the generated binary image. + +config ESP32S2_ESPTOOL_TARGET_PRIMARY + bool "Application image primary slot" + ---help--- + This assumes that the generated image is already pre-validated. + This is the recommended option for the initial stages of the + application firmware image development. + +config ESP32S2_ESPTOOL_TARGET_SECONDARY + bool "Application image secondary slot" + ---help--- + The application needs to confirm the generated image as valid, + otherwise the bootloader may consider it invalid and perform the + rollback of the update after a reset. + This is the choice most suitable for the development and verification + of a secure firmware update workflow. + +endchoice + +config ESP32S2_APP_MCUBOOT_HEADER_SIZE + int "Application image header size (in bytes)" + default 32 + depends on ESP32S2_APP_FORMAT_MCUBOOT + +endmenu # Application Image Configuration + +if ESP32S2_APP_FORMAT_LEGACY + +config ESP32S2_PARTITION + bool "ESP32-S2 Partition" + default n + select ESP32S2_SPIFLASH + ---help--- + Decode partition file and initialize partition as MTD. + menu "Partition Configuration" depends on ESP32S2_PARTITION @@ -877,7 +985,9 @@ config ESP32S2_PARTITION_MOUNT string "Partition mount point" default "/dev/esp/partition/" -endmenu # ESP32S2_PARTITION +endmenu # Partition Configuration + +endif menu "AES accelerate" depends on ESP32S2_AES_ACCELERATOR diff --git a/arch/xtensa/src/esp32s2/esp32s2_start.c b/arch/xtensa/src/esp32s2/esp32s2_start.c index a6a883a..18dfe34 100644 --- a/arch/xtensa/src/esp32s2/esp32s2_start.c +++ b/arch/xtensa/src/esp32s2/esp32s2_start.c @@ -33,7 +33,8 @@ #include "xtensa.h" #include "xtensa_attr.h" -#include "hardware/esp32s2_rtccntl.h" +#include "hardware/esp32s2_cache_memory.h" +#include "hardware/esp32s2_extmem.h" #include "esp32s2_clockconfig.h" #include "esp32s2_region.h" #include "esp32s2_start.h" @@ -50,6 +51,67 @@ # define showprogress(c) #endif +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT + +#define PRIMARY_SLOT_OFFSET CONFIG_ESP32S2_OTA_PRIMARY_SLOT_OFFSET + +#define HDR_ATTR __attribute__((section(".entry_addr"))) \ + __attribute__((used)) + +/* Cache MMU block size */ + +#define MMU_BLOCK_SIZE 0x00010000 /* 64 KB */ + +/* Cache MMU address mask (MMU tables ignore bits which are zero) */ + +#define MMU_FLASH_MASK (~(MMU_BLOCK_SIZE - 1)) + +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT +extern uint32_t _image_irom_vma; +extern uint32_t _image_irom_lma; +extern uint32_t _image_irom_size; + +extern uint32_t _image_drom_vma; +extern uint32_t _image_drom_lma; +extern uint32_t _image_drom_size; +#endif + +/**************************************************************************** + * ROM Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT +extern int ets_printf(const char *fmt, ...); +extern uint32_t cache_suspend_icache(void); +extern void cache_resume_icache(uint32_t val); +extern void cache_invalidate_icache_all(void); +extern int cache_ibus_mmu_set(uint32_t ext_ram, uint32_t vaddr, + uint32_t paddr, uint32_t psize, uint32_t num, + uint32_t fixed); +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT +noreturn_function void __start(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT +HDR_ATTR static void (*_entry_point)(void) = &__start; +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -60,29 +122,28 @@ uint32_t g_idlestack[IDLETHREAD_STACKWORDS] aligned_data(16) locate_data(".noinit"); /**************************************************************************** - * Public Functions + * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: __start + * Name: __esp32s2_start * * Description: - * We arrive here after the bootloader finished loading the program from - * flash. The hardware is mostly uninitialized, and the app CPU is in - * reset. We do have a stack, so we can do the initialization in C. + * Perform base configuration of the chip for code execution. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. * ****************************************************************************/ -void IRAM_ATTR __start(void) +void IRAM_ATTR __esp32s2_start(void) { - uint32_t *dest; uint32_t regval; uint32_t sp; - /* Disable any wdt enabled by bootloader */ - - esp32s2_wdt_early_deinit(); - regval = getreg32(DR_REG_BB_BASE + 0x48); /* DR_REG_BB_BASE+48 */ regval &= ~(1 << 14); putreg32(regval, DR_REG_BB_BASE + 0x48); @@ -95,18 +156,6 @@ void IRAM_ATTR __start(void) up_irq_disable(); - /* Set CPU frequency configured in board.h */ - - esp32s2_clockconfig(); - - esp32s2_lowsetup(); - -#ifdef USE_EARLYSERIALINIT - /* Perform early serial initialization */ - - xtensa_earlyserialinit(); -#endif - /* Move the stack to a known location. Although we were given a stack * pointer at start-up, we don't know where that stack pointer is * positioned with respect to our memory map. The only safe option is to @@ -124,29 +173,187 @@ void IRAM_ATTR __start(void) __asm__ __volatile__ ("wsr %0, vecbase\n"::"r" (&_init_start)); - showprogress('A'); - /* Set .bss to zero */ /* Clear .bss. We'll do this inline (vs. calling memset) just to be * certain that there are no issues with the state of global variables. */ - for (dest = &_sbss; dest < &_ebss; dest++) + for (uint32_t *dest = &_sbss; dest < &_ebss; dest++) { *dest = 0; } - showprogress('B'); + /* The 2nd stage bootloader enables RTC WDT to check on startup sequence + * related issues in application. Hence disable that as we are about to + * start the NuttX environment. + */ + + esp32s2_wdt_early_deinit(); + + /* Set CPU frequency configured in board.h */ + + esp32s2_clockconfig(); + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + /* Configure the UART so we can get debug output */ + + esp32s2_lowsetup(); +#endif + +#ifdef USE_EARLYSERIALINIT + /* Perform early serial initialization */ + + xtensa_earlyserialinit(); +#endif + + showprogress('A'); /* Initialize onboard resources */ esp32s2_board_initialize(); - showprogress('C'); + showprogress('B'); /* Bring up NuttX */ nx_start(); for (; ; ); /* Should not return */ } + +/**************************************************************************** + * Name: calc_mmu_pages + * + * Description: + * Calculate the number of cache pages to map. + * + * Input Parameters: + * size - Size of data to map + * vaddr - Virtual address where data will be mapped + * + * Returned Value: + * Number of cache MMU pages required to do the mapping. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT +static inline uint32_t calc_mmu_pages(uint32_t size, uint32_t vaddr) +{ + return (size + (vaddr - (vaddr & MMU_FLASH_MASK)) + MMU_BLOCK_SIZE - 1) / + MMU_BLOCK_SIZE; +} +#endif + +/**************************************************************************** + * Name: map_rom_segments + * + * Description: + * Configure the MMU and Cache peripherals for accessing ROM code and data. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT +static int map_rom_segments(void) +{ + uint32_t rc = 0; + uint32_t regval; + uint32_t drom_lma_aligned; + uint32_t drom_vma_aligned; + uint32_t drom_page_count; + uint32_t irom_lma_aligned; + uint32_t irom_vma_aligned; + uint32_t irom_page_count; + + size_t partition_offset = PRIMARY_SLOT_OFFSET; + uint32_t app_irom_lma = partition_offset + (uint32_t)&_image_irom_lma; + uint32_t app_irom_size = (uint32_t)&_image_irom_size; + uint32_t app_irom_vma = (uint32_t)&_image_irom_vma; + uint32_t app_drom_lma = partition_offset + (uint32_t)&_image_drom_lma; + uint32_t app_drom_size = (uint32_t)&_image_drom_size; + uint32_t app_drom_vma = (uint32_t)&_image_drom_vma; + + uint32_t autoload = cache_suspend_icache(); + cache_invalidate_icache_all(); + + /* Clear the MMU entries that are already set up, so the new app only has + * the mappings it creates. + */ + + for (size_t i = 0; i < FLASH_MMU_TABLE_SIZE; i++) + { + FLASH_MMU_TABLE[i] = MMU_TABLE_INVALID_VAL; + } + + drom_lma_aligned = app_drom_lma & MMU_FLASH_MASK; + drom_vma_aligned = app_drom_vma & MMU_FLASH_MASK; + drom_page_count = calc_mmu_pages(app_drom_size, app_drom_vma); + rc = cache_ibus_mmu_set(MMU_ACCESS_FLASH, drom_vma_aligned, + drom_lma_aligned, 64, (int)drom_page_count, 0); + + irom_lma_aligned = app_irom_lma & MMU_FLASH_MASK; + irom_vma_aligned = app_irom_vma & MMU_FLASH_MASK; + irom_page_count = calc_mmu_pages(app_irom_size, app_irom_vma); + + if (app_irom_lma + app_irom_size > IRAM1_ADDRESS_LOW) + { + rc |= cache_ibus_mmu_set(MMU_ACCESS_FLASH, IRAM0_ADDRESS_LOW, 0, 64, + 64, 1); + rc |= cache_ibus_mmu_set(MMU_ACCESS_FLASH, IRAM1_ADDRESS_LOW, 0, 64, + 64, 1); + + regval = getreg32(EXTMEM_PRO_ICACHE_CTRL1_REG); + regval &= ~(EXTMEM_PRO_ICACHE_MASK_IRAM1); + putreg32(regval, EXTMEM_PRO_ICACHE_CTRL1_REG); + } + + rc |= cache_ibus_mmu_set(MMU_ACCESS_FLASH, irom_vma_aligned, + irom_lma_aligned, 64, (int)irom_page_count, 0); + + regval = getreg32(EXTMEM_PRO_ICACHE_CTRL1_REG); + regval &= ~(EXTMEM_PRO_ICACHE_MASK_IRAM0 | + EXTMEM_PRO_ICACHE_MASK_DROM0); + putreg32(regval, EXTMEM_PRO_ICACHE_CTRL1_REG); + + cache_resume_icache(autoload); + + return (int)rc; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __start + * + * Description: + * We arrive here after the bootloader finished loading the program from + * flash. The hardware is mostly uninitialized, and the app CPU is in + * reset. We do have a stack, so we can do the initialization in C. + * + * The app CPU will remain in reset unless CONFIG_SMP is selected and + * up_cpu_start() is called later in the bring-up sequence. + * + ****************************************************************************/ + +void __start(void) +{ +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT + if (map_rom_segments() != 0) + { + ets_printf("Failed to setup XIP, aborting\n"); + while (true); + } + +#endif + __esp32s2_start(); + + while (true); /* Should not return */ +} diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h new file mode 100644 index 0000000..2812646 --- /dev/null +++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h @@ -0,0 +1,153 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h + * + * 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 __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_CACHE_MEMORY_H_ +#define __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_CACHE_MEMORY_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdint.h> + +#include "esp32s2_soc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRAM0 is connected with Cache IBUS0 */ + +#define IRAM0_ADDRESS_LOW 0x40000000 +#define IRAM0_ADDRESS_HIGH 0x40400000 +#define IRAM0_CACHE_ADDRESS_LOW 0x40080000 +#define IRAM0_CACHE_ADDRESS_HIGH 0x40400000 + +/* IRAM1 is connected with Cache IBUS1 */ + +#define IRAM1_ADDRESS_LOW 0x40400000 +#define IRAM1_ADDRESS_HIGH 0x40800000 + +/* DROM0 is connected with Cache IBUS2 */ + +#define DROM0_ADDRESS_LOW 0x3f000000 +#define DROM0_ADDRESS_HIGH 0x3f400000 + +/* DRAM0 is connected with Cache DBUS0 */ + +#define DRAM0_ADDRESS_LOW 0x3fc00000 +#define DRAM0_ADDRESS_HIGH 0x40000000 +#define DRAM0_CACHE_ADDRESS_LOW 0x3fc00000 +#define DRAM0_CACHE_ADDRESS_HIGH 0x3ff80000 + +/* DRAM1 is connected with Cache DBUS1 */ + +#define DRAM1_ADDRESS_LOW 0x3f800000 +#define DRAM1_ADDRESS_HIGH 0x3fc00000 + +/* DPORT is connected with Cache DBUS2 */ + +#define DPORT_ADDRESS_LOW 0x3f400000 +#define DPORT_ADDRESS_HIGH 0x3f800000 +#define DPORT_CACHE_ADDRESS_LOW 0x3f500000 +#define DPORT_CACHE_ADDRESS_HIGH 0x3f800000 + +#define BUS_SIZE(bus_name) (bus_name##_ADDRESS_HIGH - \ + bus_name##_ADDRESS_LOW) +#define ADDRESS_IN_BUS(bus_name, vaddr) ((vaddr) >= bus_name##_ADDRESS_LOW \ + && (vaddr) < \ + bus_name##_ADDRESS_HIGH) + +#define ADDRESS_IN_IRAM0(vaddr) ADDRESS_IN_BUS(IRAM0, vaddr) +#define ADDRESS_IN_IRAM0_CACHE(vaddr) ADDRESS_IN_BUS(IRAM0_CACHE, vaddr) +#define ADDRESS_IN_IRAM1(vaddr) ADDRESS_IN_BUS(IRAM1, vaddr) +#define ADDRESS_IN_DROM0(vaddr) ADDRESS_IN_BUS(DROM0, vaddr) +#define ADDRESS_IN_DRAM0(vaddr) ADDRESS_IN_BUS(DRAM0, vaddr) +#define ADDRESS_IN_DRAM0_CACHE(vaddr) ADDRESS_IN_BUS(DRAM0_CACHE, vaddr) +#define ADDRESS_IN_DRAM1(vaddr) ADDRESS_IN_BUS(DRAM1, vaddr) +#define ADDRESS_IN_DPORT(vaddr) ADDRESS_IN_BUS(DPORT, vaddr) +#define ADDRESS_IN_DPORT_CACHE(vaddr) ADDRESS_IN_BUS(DPORT_CACHE, vaddr) + +#define BUS_IRAM0_CACHE_SIZE BUS_SIZE(IRAM0_CACHE) +#define BUS_IRAM1_CACHE_SIZE BUS_SIZE(IRAM1) +#define BUS_IROM0_CACHE_SIZE BUS_SIZE(IROM0) +#define BUS_DROM0_CACHE_SIZE BUS_SIZE(DROM0) +#define BUS_DRAM0_CACHE_SIZE BUS_SIZE(DRAM0_CACHE) +#define BUS_DRAM1_CACHE_SIZE BUS_SIZE(DRAM1) +#define BUS_DPORT_CACHE_SIZE BUS_SIZE(DPORT) + +#define PRO_CACHE_IBUS0 0 +#define PRO_CACHE_IBUS0_MMU_START 0 +#define PRO_CACHE_IBUS0_MMU_END 0x100 + +#define PRO_CACHE_IBUS1 1 +#define PRO_CACHE_IBUS1_MMU_START 0x100 +#define PRO_CACHE_IBUS1_MMU_END 0x200 + +#define PRO_CACHE_IBUS2 2 +#define PRO_CACHE_IBUS2_MMU_START 0x200 +#define PRO_CACHE_IBUS2_MMU_END 0x300 + +#define PRO_CACHE_DBUS0 3 +#define PRO_CACHE_DBUS0_MMU_START 0x300 +#define PRO_CACHE_DBUS0_MMU_END 0x400 + +#define PRO_CACHE_DBUS1 4 +#define PRO_CACHE_DBUS1_MMU_START 0x400 +#define PRO_CACHE_DBUS1_MMU_END 0x500 + +#define PRO_CACHE_DBUS2 5 +#define PRO_CACHE_DBUS2_MMU_START 0x500 +#define PRO_CACHE_DBUS2_MMU_END 0x600 + +#define ICACHE_MMU_SIZE 0x300 +#define DCACHE_MMU_SIZE 0x300 + +#define MMU_BUS_START(i) ((i) * 0x100) +#define MMU_BUS_SIZE 0x100 + +#define MMU_INVALID BIT(14) +#define MMU_ACCESS_FLASH BIT(15) +#define MMU_ACCESS_SPIRAM BIT(16) + +#define FLASH_MMU_TABLE ((volatile uint32_t *)DR_REG_MMU_TABLE) +#define FLASH_MMU_TABLE_SIZE (ICACHE_MMU_SIZE / sizeof(uint32_t)) + +#define MMU_TABLE_INVALID_VAL 0x4000 +#define FLASH_MMU_TABLE_INVALID_VAL DPORT_MMU_TABLE_INVALID_VAL +#define MMU_ADDRESS_MASK 0x3fff +#define MMU_PAGE_SIZE 0x10000 + +#define BUS_ADDR_SIZE 0x400000 +#define BUS_ADDR_MASK (BUS_ADDR_SIZE - 1) +#define BUS_NUM_MASK 0x3 + +#define CACHE_MEMORY_BANK_SIZE 8192 +#define CACHE_MEMORY_BANK_NUM 4 +#define CACHE_MEMORY_BANK_NUM_MASK 0x3 +#define CACHE_MEMORY_LAYOUT_SHIFT 4 +#define CACHE_MEMORY_LAYOUT_SHIFT0 0 +#define CACHE_MEMORY_LAYOUT_SHIFT1 4 +#define CACHE_MEMORY_LAYOUT_SHIFT2 8 +#define CACHE_MEMORY_LAYOUT_SHIFT3 12 +#define CACHE_MEMORY_LAYOUT_MASK 0xf +#define CACHE_MEMORY_BANK0_ADDR 0x3ffb0000 +#define CACHE_MEMORY_BANK1_ADDR 0x3ffb2000 +#define CACHE_MEMORY_BANK2_ADDR 0x3ffb4000 +#define CACHE_MEMORY_BANK3_ADDR 0x3ffb6000 + +#endif /* __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_CACHE_MEMORY_H_ */ diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h new file mode 100644 index 0000000..5fdd8e2 --- /dev/null +++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h @@ -0,0 +1,69 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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 __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_EXTMEM_H_ +#define __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_EXTMEM_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "esp32s2_soc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define EXTMEM_PRO_ICACHE_CTRL1_REG (DR_REG_EXTMEM_BASE + 0x044) + +/* EXTMEM_PRO_ICACHE_MASK_BUS2 : R/W ;bitpos:[2] ;default: 1'b1 ; + * description: The bit is used to disable ibus2 + * 0: enable 1: disable + */ + +#define EXTMEM_PRO_ICACHE_MASK_BUS2 (BIT(2)) +#define EXTMEM_PRO_ICACHE_MASK_BUS2_M (BIT(2)) +#define EXTMEM_PRO_ICACHE_MASK_BUS2_V 0x1 +#define EXTMEM_PRO_ICACHE_MASK_BUS2_S 2 + +/* EXTMEM_PRO_ICACHE_MASK_BUS1 : R/W ;bitpos:[1] ;default: 1'b1 ; + * description: The bit is used to disable ibus1 + * 0: enable 1: disable + */ + +#define EXTMEM_PRO_ICACHE_MASK_BUS1 (BIT(1)) +#define EXTMEM_PRO_ICACHE_MASK_BUS1_M (BIT(1)) +#define EXTMEM_PRO_ICACHE_MASK_BUS1_V 0x1 +#define EXTMEM_PRO_ICACHE_MASK_BUS1_S 1 + +/* EXTMEM_PRO_ICACHE_MASK_BUS0 : R/W ;bitpos:[0] ;default: 1'b1 ; + * description: The bit is used to disable ibus0 + * 0: enable 1: disable + */ + +#define EXTMEM_PRO_ICACHE_MASK_BUS0 (BIT(0)) +#define EXTMEM_PRO_ICACHE_MASK_BUS0_M (BIT(0)) +#define EXTMEM_PRO_ICACHE_MASK_BUS0_V 0x1 +#define EXTMEM_PRO_ICACHE_MASK_BUS0_S 0 +#define EXTMEM_PRO_ICACHE_MASK_IRAM0 EXTMEM_PRO_ICACHE_MASK_BUS0 +#define EXTMEM_PRO_ICACHE_MASK_IRAM1 EXTMEM_PRO_ICACHE_MASK_BUS1 +#define EXTMEM_PRO_ICACHE_MASK_DROM0 EXTMEM_PRO_ICACHE_MASK_BUS2 + +#endif /* __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_EXTMEM_H_ */ diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/Make.defs b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/Make.defs index addad88..b757289 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/Make.defs +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/Make.defs @@ -27,10 +27,14 @@ LDSCRIPT1 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_out.ld LDSCRIPT3 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_rom.ld LDSCRIPT4 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_peripherals.ld -ifeq ($(CONFIG_ESP32S2_RUN_IRAM),y) - LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_iram.ld +ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y) + LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_mcuboot.ld else - LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_flash.ld + ifeq ($(CONFIG_ESP32S2_RUN_IRAM),y) + LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_iram.ld + else + LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_flash.ld + endif endif ifeq ($(CONFIG_CYGWIN_WINTOOL),y) diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2.template.ld b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2.template.ld index 3617280..f4811bb 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2.template.ld +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2.template.ld @@ -46,9 +46,34 @@ #define I_D_RAM_SIZE DATA_RAM_END - DRAM_ORG +#ifdef CONFIG_ESP32S2_FLASH_2M +# define FLASH_SIZE 0x200000 +#elif defined (CONFIG_ESP32S2_FLASH_4M) +# define FLASH_SIZE 0x400000 +#elif defined (CONFIG_ESP32S2_FLASH_8M) +# define FLASH_SIZE 0x800000 +#elif defined (CONFIG_ESP32S2_FLASH_16M) +# define FLASH_SIZE 0x1000000 +#endif + MEMORY { - /* All these values assume the flash cache is on, and have the blocks this +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT + /* The origin values for "metadata" and "ROM" memory regions are the actual + * load addresses. + * + * NOTE: The memory region starting from 0x0 with length represented by + * CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE is reserved for the MCUboot header, + * which will be prepended to the binary file by the "imgtool" during the + * signing of firmware image. + */ + + metadata (RX) : org = CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE, len = 0x20 + ROM (RX) : org = CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE + 0x20, + len = FLASH_SIZE - (CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE + 0x20) +#endif + + /* Below values assume the flash cache is on, and have the blocks this * uses subtracted from the length of the various regions. The 'data access * port' dram/drom regions map to the same iram/irom regions but are * connected to the data port of the CPU and eg allow bytewise access. @@ -58,26 +83,57 @@ MEMORY iram0_0_seg (RX) : org = IRAM_ORG, len = I_D_RAM_SIZE - /* Even though the segment name is iram, it is actually mapped to flash */ + /* Flash mapped instruction data. */ - iram0_2_seg (RX) : org = 0x40080020, len = 0x780000-0x20 - - /* (0x20 offset above is a convenience for the app binary image generation. +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT + irom0_0_seg (RX) : org = 0x40080020, len = FLASH_SIZE +#else + /* The 0x20 offset is a convenience for the app binary image generation. * Flash cache has 64KB pages. The .bin file which is flashed to the chip * has a 0x18 byte file header, and each segment has a 0x08 byte segment * header. Setting this offset makes it simple to meet the flash cache MMU's - * constraint that (paddr % 64KB == vaddr % 64KB).) + * constraint that (paddr % 64KB == vaddr % 64KB). */ + irom0_0_seg (RX) : org = 0x40080020, len = FLASH_SIZE - 0x20 +#endif + /* Shared data RAM, excluding memory reserved for bootloader and ROM * bss/data/stack. */ dram0_0_seg (RW) : org = DRAM_ORG, len = I_D_RAM_SIZE + + /* Flash mapped constant data */ - drom0_0_seg (R) : org = 0x3f000020, len = 0x3f0000-0x20 +#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT + /* The DROM segment origin is offset by 0x40 for mirroring the actual ROM + * image layout: + * 0x0 - 0x1F : MCUboot header + * 0x20 - 0x3F : Application image metadata section + * 0x40 onwards: ROM code and data + * This is required to meet the following constraint from the external + * flash MMU: + * VMA % 64KB == LMA % 64KB + * i.e. the lower 16 bits of both the virtual address (address seen by the + * CPU) and the load address (physical address of the external flash) must + * be equal. + */ + + drom0_0_seg (R) : org = 0x3f000000 + (CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE + 0x20), + len = FLASH_SIZE - (CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE + 0x20) +#else + /* The 0x20 offset is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB). + */ + + drom0_0_seg (R) : org = 0x3f000020, len = FLASH_SIZE - 0x20 +#endif /* RTC fast memory (executable). Persists over deep sleep. */ @@ -90,5 +146,8 @@ MEMORY rtc_slow_seg(RW) : org = 0x50000000 + CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM, len = 0x2000 - CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM + + /* RTC fast memory (same block as above), viewed from data bus */ + rtc_data_seg(RW) : org = 0x3ff9e000, len = 0x2000 } diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld index 74acf2f..fa4823e 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld @@ -198,7 +198,7 @@ SECTIONS . += 16; _etext = .; - } >iram0_2_seg + } >irom0_0_seg .rtc.text : { diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld similarity index 50% copy from boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld copy to boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld index 74acf2f..a459692 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld @@ -1,5 +1,21 @@ /**************************************************************************** - * boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld + * boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * ****************************************************************************/ /* Default entry point: */ @@ -8,6 +24,95 @@ ENTRY(__start); SECTIONS { + .metadata : + { + /* Magic for load header */ + + LONG(0xace637d3) + + /* Application entry point address */ + + KEEP(*(.entry_addr)) + + /* IRAM metadata: + * - Destination address (VMA) for IRAM region + * - Flash offset (LMA) for start of IRAM region + * - Size of IRAM region + */ + + LONG(ADDR(.iram0.vectors)) + LONG(LOADADDR(.iram0.vectors)) + LONG(LOADADDR(.iram0.text) + SIZEOF(.iram0.text) - LOADADDR(.iram0.vectors)) + + /* DRAM metadata: + * - Destination address (VMA) for DRAM region + * - Flash offset (LMA) for start of DRAM region + * - Size of DRAM region + */ + + LONG(ADDR(.dram0.data)) + LONG(LOADADDR(.dram0.data)) + LONG(SIZEOF(.dram0.data)) + } >metadata + + _image_drom_vma = ADDR(.flash.rodata); + _image_drom_lma = LOADADDR(.flash.rodata); + _image_drom_size = LOADADDR(.flash.rodata) + SIZEOF(.flash.rodata) - _image_drom_lma; + + .flash.rodata : + { + _srodata = ABSOLUTE(.); + *(EXCLUDE_FILE (esp32s2_start.*) .rodata) + *(EXCLUDE_FILE (esp32s2_start.*) .rodata.*) + + *(.srodata.*) + + *(.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) + KEEP(*(.eh_frame)) + . = (. + 3) & ~ 3; + + /* C++ constructor and destructor tables, properly ordered: */ + + _sinit = ABSOLUTE(.); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + _einit = ABSOLUTE(.); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .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) + . = ALIGN(4); /* This table MUST be 4-byte aligned */ + _erodata = ABSOLUTE(.); + + /* Literals are also RO data. */ + + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + } >drom0_0_seg AT>ROM + /* Send .iram0 code to iram */ .iram0.vectors : @@ -47,24 +152,30 @@ SECTIONS *(.entry.text) *(.init.literal) *(.init) - } > iram0_0_seg + _init_end = ABSOLUTE(.); + } >iram0_0_seg AT>ROM .iram0.text : { /* Code marked as running out of IRAM */ *(.iram1 .iram1.*) + esp32s2_start.*(.literal .text .literal.* .text.*) /* align + add 16B for CPU dummy speculative instr. fetch */ . = ALIGN(4) + 16; _iram_text = ABSOLUTE(.); - } > iram0_0_seg + } >iram0_0_seg AT>ROM - .dram0_reserved_for_iram (NOLOAD): + .dram0.dummy (NOLOAD): { - . = ORIGIN(dram0_0_seg) + _iram_text - _iram_start; - } > dram0_0_seg + /* This section is required to skip .iram0.text area because iram0_0_seg + * and dram0_0_seg reflect the same address space on different buses. + */ + + . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; + } >dram0_0_seg /* Shared RAM */ @@ -100,6 +211,7 @@ SECTIONS . = ALIGN(4); *(.noinit) + *(.noinit.*) . = ALIGN(4); } >dram0_0_seg @@ -120,95 +232,86 @@ SECTIONS KEEP (*(.gnu.linkonce.s2.*)) KEEP (*(.jcr)) *(.dram1 .dram1.*) - . = ALIGN(4); + esp32s2_start.*(.rodata .rodata.*) _edata = ABSOLUTE(.); + . = ALIGN(4); /* Heap starts at the end of .data */ _sheap = ABSOLUTE(.); - } >dram0_0_seg - - .flash.rodata : - { - _srodata = ABSOLUTE(.); - *(.rodata) - *(.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) - *(.eh_frame) + } >dram0_0_seg AT>ROM - . = (. + 3) & ~ 3; + /* Marks the end of IRAM code segment */ - /* C++ constructor and destructor tables, properly ordered: */ - - _sinit = ABSOLUTE(.); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - _einit = ABSOLUTE(.); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .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) - _erodata = ABSOLUTE(.); - - /* Literals are also RO data. */ + .iram0.text_end (NOLOAD) : + { + . = ALIGN (4); + _iram_end = ABSOLUTE(.); + } >iram0_0_seg + + _image_irom_vma = ADDR(.flash.text); + _image_irom_lma = LOADADDR(.flash.text); + _image_irom_size = LOADADDR(.flash.text) + SIZEOF(.flash.text) - _image_irom_lma; + + /* The alignment of the ".flash.text" output section is forced to + * 0x0000FFFF (64KB) to ensure that it will be allocated at the beginning + * of the next available Flash block. + * This is required to meet the following constraint from the external + * flash MMU: + * VMA % 64KB == LMA % 64KB + * i.e. the lower 16 bits of both the virtual address (address seen by the + * CPU) and the load address (physical address of the external flash) must + * be equal. + */ + + .flash_text_dummy (NOLOAD) : ALIGN(0x0000FFFF) + { + /* This section is required to skip .flash.rodata area because irom0_0_seg + * and drom0_0_seg reflect the same address space on different buses. + */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - } >drom0_0_seg + . = SIZEOF(.flash.rodata); + } >irom0_0_seg - .flash.text : + .flash.text : ALIGN(0x0000FFFF) { _stext = .; + *(.literal .text .literal.* .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) - - /* CPU will try to prefetch up to 16 bytes of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - - . += 16; + . = ALIGN(4); _etext = .; - } >iram0_2_seg + } >irom0_0_seg AT>ROM .rtc.text : { . = ALIGN(4); *(.rtc.literal .rtc.text) - } >rtc_iram_seg + } >rtc_iram_seg AT>ROM + + .rtc.dummy (NOLOAD) : + { + /* This section is required to skip .rtc.text area because the text and + * data segments reflect the same address space on different buses. + */ + + . = SIZEOF(.rtc.text); + } >rtc_data_seg + + /* RTC BSS section. */ + + .rtc.bss (NOLOAD) : + { + *(.rtc.bss) + } >rtc_data_seg .rtc.data : { *(.rtc.data) *(.rtc.rodata) - } > rtc_slow_seg + } >rtc_data_seg AT>ROM } diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld index d6d6e1b..61d252a 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld @@ -43,12 +43,12 @@ PROVIDE ( Cache_Get_Memory_BaseAddr = 0x40019244 ); PROVIDE ( Cache_Get_Memory_value = 0x400192d8 ); PROVIDE ( Cache_Get_Mode = 0x40017ff0 ); PROVIDE ( Cache_Get_Virtual_Addr = 0x40019210 ); -PROVIDE ( Cache_Ibus_MMU_Set = 0x40018df4 ); +PROVIDE ( cache_ibus_mmu_set = 0x40018df4 ); PROVIDE ( Cache_ICache_Preload_Done = 0x4001859c ); PROVIDE ( Cache_Invalidate_Addr = 0x400182e4 ); PROVIDE ( Cache_Invalidate_DCache_All = 0x4001842c ); PROVIDE ( Cache_Invalidate_DCache_Items = 0x40018208 ); -PROVIDE ( Cache_Invalidate_ICache_All = 0x40018420 ); +PROVIDE ( cache_invalidate_icache_all = 0x40018420 ); PROVIDE ( Cache_Invalidate_ICache_Items = 0x400181b8 ); PROVIDE ( Cache_Lock_Addr = 0x40018b10 ); PROVIDE ( Cache_Lock_DCache_Items = 0x40018a80 ); @@ -58,7 +58,7 @@ PROVIDE ( cache_memory_baseaddrs = 0x3ffaf020 ); PROVIDE ( Cache_MMU_Init = 0x40018dd8 ); PROVIDE ( Cache_Resume_DCache = 0x40018d3c ); PROVIDE ( Cache_Resume_DCache_Autoload = 0x4001850c ); -PROVIDE ( Cache_Resume_ICache = 0x40018cdc ); +PROVIDE ( cache_resume_icache = 0x40018cdc ); PROVIDE ( Cache_Resume_ICache_Autoload = 0x400184c4 ); PROVIDE ( Cache_Set_DCache_Mode = 0x40018074 ); PROVIDE ( Cache_Set_Default_Mode = 0x4001810c ); @@ -67,7 +67,7 @@ PROVIDE ( Cache_Start_DCache_Preload = 0x400185c4 ); PROVIDE ( Cache_Start_ICache_Preload = 0x40018530 ); PROVIDE ( Cache_Suspend_DCache = 0x40018d04 ); PROVIDE ( Cache_Suspend_DCache_Autoload = 0x400184e0 ); -PROVIDE ( Cache_Suspend_ICache = 0x40018ca4 ); +PROVIDE ( cache_suspend_icache = 0x40018ca4 ); PROVIDE ( Cache_Suspend_ICache_Autoload = 0x40018498 ); PROVIDE ( Cache_Travel_Tag_Memory = 0x4001908c ); PROVIDE ( Cache_Unlock_Addr = 0x40018b9c ); diff --git a/tools/esp32s2/Config.mk b/tools/esp32s2/Config.mk index 51d38f2..9e39b88 100644 --- a/tools/esp32s2/Config.mk +++ b/tools/esp32s2/Config.mk @@ -60,36 +60,43 @@ endif ESPTOOL_FLASH_OPTS := -fs $(FLASH_SIZE) -fm $(FLASH_MODE) -ff $(FLASH_FREQ) +# Configure the variables according to build environment + ifdef ESPTOOL_BINDIR - BL_OFFSET := 0x1000 - PT_OFFSET := 0x8000 - BOOTLOADER := $(ESPTOOL_BINDIR)/bootloader-esp32s2.bin - PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-esp32s2.bin - FLASH_BL := $(BL_OFFSET) $(BOOTLOADER) - FLASH_PT := $(PT_OFFSET) $(PARTITION_TABLE) - ESPTOOL_BINS := $(FLASH_BL) $(FLASH_PT) + ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y) + BL_OFFSET := 0x1000 + PT_OFFSET := 0x8000 + BOOTLOADER := $(ESPTOOL_BINDIR)/bootloader-esp32s2.bin + PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-esp32s2.bin + FLASH_BL := $(BL_OFFSET) $(BOOTLOADER) + FLASH_PT := $(PT_OFFSET) $(PARTITION_TABLE) + ESPTOOL_BINS := $(FLASH_BL) $(FLASH_PT) + else ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y) + BL_OFFSET := 0x1000 + BOOTLOADER := $(ESPTOOL_BINDIR)/mcuboot-esp32s2.bin + FLASH_BL := $(BL_OFFSET) $(BOOTLOADER) + ESPTOOL_BINS := $(FLASH_BL) + endif endif -ESPTOOL_BINS += 0x10000 nuttx.bin +ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y) + APP_OFFSET := 0x10000 + APP_IMAGE := nuttx.bin + FLASH_APP := $(APP_OFFSET) $(APP_IMAGE) +else ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y) + ifeq ($(CONFIG_ESP32S2_ESPTOOL_TARGET_PRIMARY),y) + VERIFIED := --confirm + APP_OFFSET := $(CONFIG_ESP32S2_OTA_PRIMARY_SLOT_OFFSET) + else ifeq ($(CONFIG_ESP32S2_ESPTOOL_TARGET_SECONDARY),y) + VERIFIED := + APP_OFFSET := $(CONFIG_ESP32S2_OTA_SECONDARY_SLOT_OFFSET) + endif + + APP_IMAGE := nuttx.signed.bin + FLASH_APP := $(APP_OFFSET) $(APP_IMAGE) +endif -# ELF2IMAGE -- Convert an ELF file into a binary file in Espressif application image format - -define ELF2IMAGE - $(Q) echo "MKIMAGE: ESP32-S2 binary" - $(Q) if ! esptool.py version 1>/dev/null 2>&1; then \ - echo ""; \ - echo "esptool.py not found. Please run: \"pip install esptool\""; \ - echo ""; \ - echo "Run make again to create the nuttx.bin image."; \ - exit 1; \ - fi - $(Q) if [ -z $(FLASH_SIZE) ]; then \ - echo "Missing Flash memory size configuration for the ESP32-S2 chip."; \ - exit 1; \ - fi - esptool.py -c esp32s2 elf2image $(ESPTOOL_FLASH_OPTS) -o nuttx.bin nuttx - $(Q) echo "Generated: nuttx.bin (ESP32-S2 compatible)" -endef +ESPTOOL_BINS += $(FLASH_APP) # MERGEBIN -- Merge raw binary files into a single file @@ -114,12 +121,61 @@ define MERGEBIN endef endif +# SIGNBIN -- Sign the binary image file + +ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y) +define SIGNBIN + $(Q) echo "MKIMAGE: ESP32-S2 binary" + $(Q) if ! imgtool version 1>/dev/null 2>&1; then \ + echo ""; \ + echo "imgtool not found. Please run: \"pip install imgtool\""; \ + echo ""; \ + echo "Run make again to create the nuttx.signed.bin image."; \ + exit 1; \ + fi + imgtool sign --pad --pad-sig $(VERIFIED) --align 4 -v 0 \ + -H $(CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE) --pad-header \ + -S $(CONFIG_ESP32S2_OTA_SLOT_SIZE) \ + nuttx.bin nuttx.signed.bin + $(Q) echo nuttx.signed.bin >> nuttx.manifest + $(Q) echo "Generated: nuttx.signed.bin (MCUboot compatible)" +endef +endif + +# ELF2IMAGE -- Convert an ELF file into a binary file in Espressif application image format + +ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y) +define ELF2IMAGE + $(Q) echo "MKIMAGE: ESP32-S2 binary" + $(Q) if ! esptool.py version 1>/dev/null 2>&1; then \ + echo ""; \ + echo "esptool.py not found. Please run: \"pip install esptool\""; \ + echo ""; \ + echo "Run make again to create the nuttx.bin image."; \ + exit 1; \ + fi + $(Q) if [ -z $(FLASH_SIZE) ]; then \ + echo "Missing Flash memory size configuration for the ESP32-S2 chip."; \ + exit 1; \ + fi + esptool.py -c esp32s2 elf2image $(ESPTOOL_FLASH_OPTS) -o nuttx.bin nuttx + $(Q) echo "Generated: nuttx.bin (ESP32-S2 compatible)" +endef +endif + # POSTBUILD -- Perform post build operations +ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y) +define POSTBUILD + $(call SIGNBIN) + $(call MERGEBIN) +endef +else ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y) define POSTBUILD $(call ELF2IMAGE) $(call MERGEBIN) endef +endif # ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py