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/nuttx.git
commit bfc40c74d077318794906aac7263ef570f64f6e7 Author: Gustavo Henrique Nihei <[email protected]> AuthorDate: Mon Oct 31 11:47:33 2022 -0300 xtensa/esp32s3: Add support for Protected Mode Signed-off-by: Gustavo Henrique Nihei <[email protected]> --- arch/xtensa/Kconfig | 1 + arch/xtensa/src/esp32s3/Kconfig | 10 + arch/xtensa/src/esp32s3/Make.defs | 4 + arch/xtensa/src/esp32s3/chip_macros.h | 10 + arch/xtensa/src/esp32s3/esp32s3_allocateheap.c | 84 ++++- arch/xtensa/src/esp32s3/esp32s3_start.c | 14 + arch/xtensa/src/esp32s3/esp32s3_userspace.c | 347 +++++++++++++++++++++ arch/xtensa/src/esp32s3/esp32s3_userspace.h | 49 +++ boards/xtensa/esp32s3/common/kernel/Makefile | 102 ++++++ .../esp32s3/common/kernel/esp32s3_userspace.c | 100 ++++++ .../xtensa/esp32s3/common/scripts/esp32s3_rom.ld | 4 +- .../scripts/{esp32s3_memory.ld => flat_memory.ld} | 0 .../xtensa/esp32s3/common/scripts/kernel-space.ld | 322 +++++++++++++++++++ .../{esp32s3_memory.ld => protected_memory.ld} | 66 ++-- boards/xtensa/esp32s3/common/scripts/user-space.ld | 231 ++++++++++++++ .../esp32s3/esp32s3-devkit/configs/knsh/defconfig | 55 ++++ .../esp32s3-devkit/include/board_memorymap.h | 116 +++++++ .../esp32s3/esp32s3-devkit/scripts/Make.defs | 12 +- .../xtensa/esp32s3/esp32s3-eye/scripts/Make.defs | 12 +- tools/esp32s3/Config.mk | 4 + 20 files changed, 1485 insertions(+), 58 deletions(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 16d12f639e..e288c01f8f 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -79,6 +79,7 @@ config ARCH_CHIP_ESP32S3 select ARCH_FAMILY_LX7 select XTENSA_HAVE_INTERRUPTS select ARCH_HAVE_FPU + select ARCH_HAVE_MPU select ARCH_HAVE_MULTICPU select ARCH_HAVE_TEXT_HEAP select ARCH_HAVE_SDRAM diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index 9fd728d96a..b604ab9e56 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -906,6 +906,16 @@ config ESP32S3_PARTITION_TABLE_OFFSET default 0x8000 depends on ESP32S3_APP_FORMAT_LEGACY +if BUILD_PROTECTED + +config ESP32S3_USER_IMAGE_OFFSET + hex "User image offset" + default 0x90000 + ---help--- + Offset in SPI Flash for flashing the User application firmware image. + +endif + endmenu # Application Image Configuration endif # ARCH_CHIP_ESP32S3 diff --git a/arch/xtensa/src/esp32s3/Make.defs b/arch/xtensa/src/esp32s3/Make.defs index 14985252c3..e01aed9551 100644 --- a/arch/xtensa/src/esp32s3/Make.defs +++ b/arch/xtensa/src/esp32s3/Make.defs @@ -37,6 +37,10 @@ ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) CHIP_CSRCS += esp32s3_idle.c endif +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += esp32s3_userspace.c +endif + ifeq ($(CONFIG_SMP),y) CHIP_ASRCS = esp32s3_cpuindex.S CHIP_CSRCS += esp32s3_cpuidlestack.c esp32s3_cpustart.c esp32s3_intercpu_interrupt.c diff --git a/arch/xtensa/src/esp32s3/chip_macros.h b/arch/xtensa/src/esp32s3/chip_macros.h index 95ebd91ea0..913f2e8476 100644 --- a/arch/xtensa/src/esp32s3/chip_macros.h +++ b/arch/xtensa/src/esp32s3/chip_macros.h @@ -43,6 +43,16 @@ #define HANDLER_SECTION .iram1 +#if defined(CONFIG_BUILD_PROTECTED) + +#define xtensa_saveprivilege(regs,var) +#define xtensa_restoreprivilege(regs,var) + +#define xtensa_lowerprivilege(regs) +#define xtensa_raiseprivilege(regs) + +#endif + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c b/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c index 2da70fea3e..1ccac0a905 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c +++ b/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c @@ -24,16 +24,19 @@ #include <nuttx/config.h> -#include <sys/types.h> #include <debug.h> +#include <sys/types.h> -#include <nuttx/mm/mm.h> #include <nuttx/arch.h> #include <nuttx/board.h> +#include <nuttx/mm/mm.h> +#include <nuttx/userspace.h> #include <arch/board/board.h> +#ifdef CONFIG_MM_KERNEL_HEAP +#include <arch/board/board_memorymap.h> +#endif #include "xtensa.h" - #include "hardware/esp32s3_rom_layout.h" /**************************************************************************** @@ -50,23 +53,84 @@ * Description: * This function will be called to dynamically set aside the heap region. * - * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and - * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the - * size of the unprotected, user-space heap. + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel and + * userspace heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, userspace heap. * - * If a protected kernel-space heap is provided, the kernel heap must be + * If a protected kernel space heap is provided, the kernel heap must be * allocated (and protected) by an analogous up_allocate_kheap(). * ****************************************************************************/ void up_allocate_heap(void **heap_start, size_t *heap_size) { +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + uintptr_t ubase = USERSPACE->us_dataend; + uintptr_t utop = ets_rom_layout_p->dram0_rtos_reserved_start; + size_t usize = utop - ubase; + + minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n", + ubase, utop, usize); + + board_autoled_on(LED_HEAPALLOCATE); + + /* Return the userspace heap settings */ + + *heap_start = (void *)ubase; + *heap_size = usize; + + /* Allow user-mode access to the user heap memory in PMP + * is already done in esp32s3_userspace(). + */ + +#else + /* These values come from the linker scripts (esp32s3_sections.ld and + * flat_memory.ld). + * Check boards/xtensa/esp32s3. + */ + + board_autoled_on(LED_HEAPALLOCATE); + + *heap_start = _sheap; + *heap_size = ets_rom_layout_p->dram0_rtos_reserved_start - + (uintptr_t)_sheap; +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */ +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel and + * userspace heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) && \ + defined(__KERNEL__) +void up_allocate_kheap(void **heap_start, size_t *heap_size) +{ + /* These values come from the linker scripts (kernel-space.ld and + * protected_memory.ld). + * Check boards/xtensa/esp32s3. + */ + + uintptr_t kbase = (uintptr_t)_sheap; + uintptr_t ktop = KDRAM_END; + size_t ksize = ktop - kbase; + + minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n", + kbase, ktop, ksize); + board_autoled_on(LED_HEAPALLOCATE); - *heap_start = (void *)_sheap; - *heap_size = (size_t)(ets_rom_layout_p->dram0_rtos_reserved_start - - (uintptr_t)_sheap); + *heap_start = (void *)kbase; + *heap_size = ksize; } +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */ /**************************************************************************** * Name: xtensa_add_region diff --git a/arch/xtensa/src/esp32s3/esp32s3_start.c b/arch/xtensa/src/esp32s3/esp32s3_start.c index 910ab96171..fc6091c9ca 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_start.c +++ b/arch/xtensa/src/esp32s3/esp32s3_start.c @@ -39,6 +39,9 @@ #include "esp32s3_region.h" #include "esp32s3_spiram.h" #include "esp32s3_wdt.h" +#ifdef CONFIG_BUILD_PROTECTED +# include "esp32s3_userspace.h" +#endif #include "hardware/esp32s3_cache_memory.h" #include "hardware/esp32s3_system.h" @@ -312,6 +315,17 @@ void noreturn_function IRAM_ATTR __esp32s3_start(void) showprogress('B'); +#ifdef CONFIG_BUILD_PROTECTED + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + + esp32s3_userspace(); + showprogress('C'); +#endif + /* Bring up NuttX */ nx_start(); diff --git a/arch/xtensa/src/esp32s3/esp32s3_userspace.c b/arch/xtensa/src/esp32s3/esp32s3_userspace.c new file mode 100644 index 0000000000..04786a5c6c --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_userspace.c @@ -0,0 +1,347 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_userspace.c + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <assert.h> +#include <debug.h> +#include <stdint.h> +#include <stdlib.h> + +#include <nuttx/userspace.h> + +#include <arch/board/board_memorymap.h> + +#include "chip.h" +#include "xtensa.h" +#include "xtensa_attr.h" +#include "esp32s3_userspace.h" +#include "hardware/esp32s3_cache_memory.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define USER_IMAGE_OFFSET CONFIG_ESP32S3_USER_IMAGE_OFFSET + +#define MMU_BLOCK0_VADDR SOC_DROM_LOW +#define MMU_SIZE 0x3f0000 +#define MMU_BLOCK63_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE) + +/* 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)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct user_image_load_header_s +{ + uintptr_t drom_vma; /* Destination address (VMA) for DROM region */ + uintptr_t drom_lma; /* Flash offset (LMA) for start of DROM region */ + uintptr_t drom_size; /* Size of DROM region */ + uintptr_t irom_vma; /* Destination address (VMA) for IROM region */ + uintptr_t irom_lma; /* Flash offset (LMA) for start of IROM region */ + uintptr_t irom_size; /* Size of IROM region */ +}; + +/**************************************************************************** + * ROM Function Prototypes + ****************************************************************************/ + +extern uint32_t cache_suspend_dcache(void); +extern void cache_resume_dcache(uint32_t val); +extern void cache_invalidate_dcache_all(void); +extern int cache_dbus_mmu_set(uint32_t ext_ram, uint32_t vaddr, + uint32_t paddr, uint32_t psize, uint32_t num, + uint32_t fixed); +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); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct user_image_load_header_s g_header; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: calc_mmu_pages + * + * Description: + * Calculate the required number of MMU pages for mapping a given region + * from External Flash into Internal RAM. + * + * Input Parameters: + * size - Length of the region to map + * vaddr - Starting External Flash offset to map to Internal RAM + * + * Returned Value: + * None. + * + ****************************************************************************/ + +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; +} + +/**************************************************************************** + * Name: configure_flash_mmu + * + * Description: + * Configure the External Flash MMU and Cache for enabling access to code + * and read-only data of the userspace image. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static noinline_function IRAM_ATTR void configure_flash_mmu(void) +{ + 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 = USER_IMAGE_OFFSET; + uint32_t app_drom_lma = partition_offset + g_header.drom_lma; + uint32_t app_drom_size = g_header.drom_size; + uint32_t app_drom_vma = g_header.drom_vma; + uint32_t app_irom_lma = partition_offset + g_header.irom_lma; + uint32_t app_irom_size = g_header.irom_size; + uint32_t app_irom_vma = g_header.irom_vma; + + uint32_t autoload = cache_suspend_dcache(); + cache_invalidate_dcache_all(); + + 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); + ASSERT(cache_dbus_mmu_set(MMU_ACCESS_FLASH, drom_vma_aligned, + drom_lma_aligned, 64, + (int)drom_page_count, 0) == 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); + ASSERT(cache_ibus_mmu_set(MMU_ACCESS_FLASH, irom_vma_aligned, + irom_lma_aligned, 64, + (int)irom_page_count, 0) == 0); + + cache_resume_dcache(autoload); +} + +/**************************************************************************** + * Name: map_flash + * + * Description: + * Map a region of the External Flash memory to Internal RAM. + * + * Input Parameters: + * src_addr - Starting External Flash offset to map to Internal RAM + * size - Length of the region to map + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static noinline_function IRAM_ATTR const void *map_flash(uint32_t src_addr, + uint32_t size) +{ + uint32_t src_addr_aligned; + uint32_t page_count; + + uint32_t autoload = cache_suspend_dcache(); + cache_invalidate_dcache_all(); + + src_addr_aligned = src_addr & MMU_FLASH_MASK; + page_count = calc_mmu_pages(size, src_addr); + + ASSERT(cache_dbus_mmu_set(MMU_ACCESS_FLASH, MMU_BLOCK63_VADDR, + src_addr_aligned, 64, (int)page_count, 0) == 0); + + cache_resume_dcache(autoload); + + return (void *)(MMU_BLOCK63_VADDR + (src_addr - src_addr_aligned)); +} + +/**************************************************************************** + * Name: load_header + * + * Description: + * Load IROM and DROM information from image header to enable the correct + * configuration of the Flash MMU and Cache. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void load_header(void) +{ + size_t length = sizeof(struct user_image_load_header_s); + const uint8_t *data = + (const uint8_t *)map_flash(USER_IMAGE_OFFSET, length); + + DEBUGASSERT(data != NULL); + + memcpy(&g_header, data, length); +} + +/**************************************************************************** + * Name: initialize_data + * + * Description: + * Initialize data sections of the userspace image. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void initialize_data(void) +{ + uint8_t *dest; + uint8_t *end; + size_t length = USERSPACE->us_dataend - USERSPACE->us_datastart; + const uint8_t *src = + (const uint8_t *)map_flash(USER_IMAGE_OFFSET + USERSPACE->us_datasource, + length); + + DEBUGASSERT(src != NULL); + + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } +} + +/**************************************************************************** + * Name: configure_mpu + * + * Description: + * Configure the MPU for kernel/userspace separation. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void configure_mpu(void) +{ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_userspace + * + * Description: + * For the case of the separate user/kernel space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the userspace .data and .bss + * segments. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32s3_userspace(void) +{ + uint8_t *dest; + uint8_t *end; + + /* Load IROM and DROM information from image header */ + + load_header(); + + /* Configure the Flash MMU for enabling access to the userspace image */ + + configure_flash_mmu(); + + /* Clear all of userspace .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of userspace .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + initialize_data(); + + /* Configure MPU to grant access to the userspace */ + + configure_mpu(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/xtensa/src/esp32s3/esp32s3_userspace.h b/arch/xtensa/src/esp32s3/esp32s3_userspace.h new file mode 100644 index 0000000000..2496042ed2 --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_userspace.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_userspace.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_ESP32S3_ESP32S3_USERSPACE_H +#define __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_USERSPACE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void esp32s3_userspace(void); +#endif + +#endif /* __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_USERSPACE_H */ diff --git a/boards/xtensa/esp32s3/common/kernel/Makefile b/boards/xtensa/esp32s3/common/kernel/Makefile new file mode 100644 index 0000000000..5a08434340 --- /dev/null +++ b/boards/xtensa/esp32s3/common/kernel/Makefile @@ -0,0 +1,102 @@ +############################################################################ +# boards/xtensa/esp32s3/esp32s3-devkit/kernel/Makefile +# +# 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. +# +############################################################################ + +include $(TOPDIR)/Make.defs + +# The entry point name (if none is provided in the .config file) + +CONFIG_INIT_ENTRYPOINT ?= user_start +ENTRYPT = $(patsubst "%",%,$(CONFIG_INIT_ENTRYPOINT)) + +# Get the paths to the libraries and the links script path in format that +# is appropriate for the host OS + +USER_LIBPATHS = $(addprefix -L,$(call CONVERT_PATH,$(addprefix $(TOPDIR)$(DELIM),$(dir $(USERLIBS))))) +USER_LDSCRIPT = $(call CONVERT_PATH,$(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)protected_memory.ld) +USER_LDSCRIPT += $(call CONVERT_PATH,$(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)user-space.ld) +USER_LDSCRIPT += $(call CONVERT_PATH,$(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_rom.ld) +USER_HEXFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.hex) +USER_BINFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.bin) + +USER_LDFLAGS = --undefined=$(ENTRYPT) --entry=$(ENTRYPT) $(addprefix -T,$(addsuffix .tmp,$(USER_LDSCRIPT))) + +ifeq ($(CONFIG_DEBUG_LINK_MAP),y) +USER_LDFLAGS += --cref -Map="$(TOPDIR)$(DELIM)User.map" +endif + +USER_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(USERLIBS)))) +USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" + +# Source files + +CSRCS = esp32s3_userspace.c +COBJS = $(CSRCS:.c=$(OBJEXT)) +OBJS = $(COBJS) + +ifeq ($(LD),$(CC)) + LDSTARTGROUP ?= -Wl,--start-group + LDENDGROUP ?= -Wl,--end-group + USER_LDFLAGS := $(addprefix -Xlinker ,$(USER_LDFLAGS)) + USER_LDFLAGS += $(CFLAGS) +else + LDSTARTGROUP ?= --start-group + LDENDGROUP ?= --end-group +endif + +# Targets: + +all: $(TOPDIR)$(DELIM)nuttx_user.elf +.PHONY: nuttx_user.elf depend clean distclean + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE,$<,$@) + +$(addsuffix .tmp,$(USER_LDSCRIPT)): $(USER_LDSCRIPT) + $(call PREPROCESS,$(patsubst %.tmp,%,$@),$@) + +# Create the nuttx_user.elf file containing all of the user-mode code + +nuttx_user.elf: $(OBJS) $(addsuffix .tmp,$(USER_LDSCRIPT)) + $(Q) $(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) $(OBJS) $(LDSTARTGROUP) $(USER_LDLIBS) $(LDENDGROUP) $(USER_LIBGCC) + +$(TOPDIR)$(DELIM)nuttx_user.elf: nuttx_user.elf + $(Q) echo "LD: nuttx_user.elf" + $(Q) cp -a nuttx_user.elf $(TOPDIR)$(DELIM)nuttx_user.elf +ifeq ($(CONFIG_INTELHEX_BINARY),y) + $(Q) echo "CP: nuttx_user.hex" + $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex nuttx_user.elf $(USER_HEXFILE) +endif +ifeq ($(CONFIG_RAW_BINARY),y) + $(Q) echo "CP: nuttx_user.bin" + $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary nuttx_user.elf $(USER_BINFILE) +endif + $(Q) $(call DELFILE,$(addsuffix .tmp,$(USER_LDSCRIPT))) + +.depend: + +depend: .depend + +clean: + $(call DELFILE,nuttx_user.elf) + $(call DELFILE,$(TOPDIR)$(DELIM)nuttx_user.*) + $(call DELFILE,$(TOPDIR)$(DELIM)User.map) + $(call CLEAN) + +distclean: clean diff --git a/boards/xtensa/esp32s3/common/kernel/esp32s3_userspace.c b/boards/xtensa/esp32s3/common/kernel/esp32s3_userspace.c new file mode 100644 index 0000000000..b5b28a1ec2 --- /dev/null +++ b/boards/xtensa/esp32s3/common/kernel/esp32s3_userspace.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * boards/xtensa/esp32s3/common/kernel/esp32s3_userspace.c + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> + +#include <nuttx/arch.h> +#include <nuttx/mm/mm.h> +#include <nuttx/wqueue.h> +#include <nuttx/userspace.h> + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_NUTTX_USERSPACE +# error "CONFIG_NUTTX_USERSPACE not defined" +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* These 'addresses' of these values are setup by the linker script. */ + +extern uint8_t _stext[]; /* Start of .text */ +extern uint8_t _etext[]; /* End+1 of .text + .rodata */ +extern const uint8_t _eronly[]; /* End+1 of read only section (.text + .rodata) */ +extern uint8_t _sdata[]; /* Start of .data */ +extern uint8_t _edata[]; /* End+1 of .data */ +extern uint8_t _sbss[]; /* Start of .bss */ +extern uint8_t _ebss[]; /* End+1 of .bss */ + +extern uint8_t __ld_udram_end[]; /* End+1 of user ram section */ + +const struct userspace_s userspace locate_data(".userspace") = +{ + /* General memory map */ + + .us_entrypoint = CONFIG_INIT_ENTRYPOINT, + .us_textstart = (uintptr_t)_stext, + .us_textend = (uintptr_t)_etext, + .us_datasource = (uintptr_t)_eronly, + .us_datastart = (uintptr_t)_sdata, + .us_dataend = (uintptr_t)_edata, + .us_bssstart = (uintptr_t)_sbss, + .us_bssend = (uintptr_t)_ebss, + + .us_heapend = (uintptr_t)__ld_udram_end, + + /* Memory manager heap structure */ + + .us_heap = &g_mmheap, + + /* Task/thread startup routines */ + + .task_startup = nxtask_startup, + + /* Signal handler trampoline */ + + .signal_handler = up_signal_handler, + + /* Userspace work queue support (declared in include/nuttx/wqueue.h) */ + +#ifdef CONFIG_LIBC_USRWORK + .work_usrstart = work_usrstart, +#endif +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */ diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_rom.ld b/boards/xtensa/esp32s3/common/scripts/esp32s3_rom.ld index 6070bc65b4..73555ec9c6 100644 --- a/boards/xtensa/esp32s3/common/scripts/esp32s3_rom.ld +++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_rom.ld @@ -385,7 +385,7 @@ PROVIDE( Cache_Op_Addr = 0x400016a4 ); PROVIDE( cache_invalidate_addr = 0x400016b0 ); PROVIDE( Cache_Clean_Addr = 0x400016bc ); PROVIDE( Cache_WriteBack_Addr = 0x400016c8 ); -PROVIDE( Cache_Invalidate_ICache_All = 0x400016d4 ); +PROVIDE( cache_invalidate_icache_all = 0x400016d4 ); PROVIDE( cache_invalidate_dcache_all = 0x400016e0 ); PROVIDE( Cache_Clean_All = 0x400016ec ); PROVIDE( cache_writeback_all = 0x400016f8 ); @@ -445,7 +445,7 @@ PROVIDE( Cache_Owner_Init = 0x40001974 ); PROVIDE( Cache_Occupy_ICache_MEMORY = 0x40001980 ); PROVIDE( Cache_Occupy_DCache_MEMORY = 0x4000198c ); PROVIDE( Cache_MMU_Init = 0x40001998 ); -PROVIDE( Cache_Ibus_MMU_Set = 0x400019a4 ); +PROVIDE( cache_ibus_mmu_set = 0x400019a4 ); PROVIDE( cache_dbus_mmu_set = 0x400019b0 ); PROVIDE( Cache_Count_Flash_Pages = 0x400019bc ); PROVIDE( Cache_Flash_To_SPIRAM_Copy = 0x400019c8 ); diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld b/boards/xtensa/esp32s3/common/scripts/flat_memory.ld similarity index 100% copy from boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld copy to boards/xtensa/esp32s3/common/scripts/flat_memory.ld diff --git a/boards/xtensa/esp32s3/common/scripts/kernel-space.ld b/boards/xtensa/esp32s3/common/scripts/kernel-space.ld new file mode 100644 index 0000000000..48fffb7551 --- /dev/null +++ b/boards/xtensa/esp32s3/common/scripts/kernel-space.ld @@ -0,0 +1,322 @@ +/**************************************************************************** + * boards/xtensa/esp32s3/common/scripts/kernel-space.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. + * + ****************************************************************************/ + +/* Provide these so there is no need for using config files for this */ + +__uirom_start = ORIGIN(UIROM); +__uirom_size = LENGTH(UIROM); +__uirom_end = ORIGIN(UIROM) + LENGTH(UIROM); +__udrom_start = ORIGIN(UDROM); +__udrom_size = LENGTH(UDROM); +__udrom_end = ORIGIN(UDROM) + LENGTH(UDROM); +__uiram_start = ORIGIN(UIRAM); +__uiram_size = LENGTH(UIRAM); +__uiram_end = ORIGIN(UIRAM) + LENGTH(UIRAM); +__udram_start = ORIGIN(UDRAM); +__udram_size = LENGTH(UDRAM); +__udram_end = ORIGIN(UDRAM) + LENGTH(UDRAM); + +/* Provide the kernel boundaries as well */ + +__kirom_start = ORIGIN(KIROM); +__kirom_size = LENGTH(KIROM); +__kdrom_start = ORIGIN(KDROM); +__kdrom_size = LENGTH(KDROM); +__kiram_start = ORIGIN(KIRAM); +__kiram_size = LENGTH(KIRAM); +__kiram_end = ORIGIN(KIRAM) + LENGTH(KIRAM); +__kdram_start = ORIGIN(KDRAM); +__kdram_size = LENGTH(KDRAM); +__kdram_end = ORIGIN(KDRAM) + LENGTH(KDRAM); + +ENTRY(_stext) + +_diram_i_start = 0x40378000; + +SECTIONS +{ + /* Send .iram0 code to iram */ + + .iram0.vectors : + { + /* Vectors go to IRAM */ + + _init_start = ABSOLUTE(.); + + __vectors_start = ABSOLUTE(.); + + /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ + + . = 0x0; + KEEP (*(.window_vectors.text)); + . = 0x180; + KEEP (*(.xtensa_level2_vector.text)); + . = 0x1c0; + KEEP (*(.xtensa_level3_vector.text)); + . = 0x200; + KEEP (*(.xtensa_level4_vector.text)); + . = 0x240; + KEEP (*(.xtensa_level5_vector.text)); + . = 0x280; + KEEP (*(.debug_exception_vector.text)); + . = 0x2c0; + KEEP (*(.nmi_vector.text)); + . = 0x300; + KEEP (*(.kernel_exception_vector.text)); + . = 0x340; + KEEP (*(.user_exception_vector.text)); + . = 0x3c0; + KEEP (*(.double_exception_vector.text)); + . = 0x400; + *(.*_vector.literal) + + . = ALIGN (16); + + __vectors_end = ABSOLUTE(.); + + *(.entry.text) + *(.init.literal) + *(.init) + + _init_end = ABSOLUTE(.); + } >KIRAM + + .iram0.text : + { + /* Code marked as running out of IRAM */ + + _iram_text_start = ABSOLUTE(.); + *(.iram1 .iram1.*) + *librtc.a:(.literal .text .literal.* .text.*) + *libkarch.a:esp32s3_spiflash.*(.literal .text .literal.* .text.*) + *libkarch.a:xtensa_cpupause.*(.literal .text .literal.* .text.*) + *libkarch.a:xtensa_copystate.*(.literal .text .literal.* .text.*) + *libkarch.a:xtensa_interruptcontext.*(.literal .text .literal.* .text.*) + *libkarch.a:xtensa_testset.*(.literal .text .literal.* .text.*) + + *libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*) + *libsched.a:sched_note.*(.literal .text .literal.* .text.*) + *libsched.a:sched_thistask.*(.literal .text .literal.* .text.*) + *libsched.a:spinlock.*(.literal .text .literal.* .text.*) + *libsched.a:irq_csection.*(.literal .text .literal.* .text.*) + *libsched.a:irq_dispatch.*(.literal .text .literal.* .text.*) + + /* align + add 16B for CPU dummy speculative instr. fetch */ + + . = ALIGN(4) + 16; + + _iram_text_end = ABSOLUTE(.); + + _iram_end = ABSOLUTE(.); + } >KIRAM + + .dram0.dummy (NOLOAD) : + { + /* 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(KDRAM) + MAX(_iram_end, _diram_i_start) - _diram_i_start; + } >KDRAM + + /* Shared RAM */ + + .dram0.bss (NOLOAD) : + { + /* .bss initialized on power-up */ + + . = ALIGN (8); + _sbss = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + *libkarch.a:esp32s3_spiflash.*(.bss .bss.* COMMON) + *libkarch.a:xtensa_cpupause.*(.bss .bss.* COMMON) + *libkarch.a:xtensa_copystate.*(.bss .bss.* COMMON) + *libkarch.a:xtensa_interruptcontext.*(.bss .bss.* COMMON) + *libkarch.a:xtensa_testset.*(.bss .bss.* COMMON) + + *libsched.a:sched_suspendscheduler.*(.bss .bss.* COMMON) + *libsched.a:sched_thistask.*(.bss .bss.* COMMON) + *libsched.a:sched_note.*(.bss .bss.* COMMON) + *libsched.a:spinlock.*(.bss .bss.* COMMON) + *libsched.a:irq_csection.*(.bss .bss.* COMMON) + *libsched.a:irq_dispatch.*(.bss .bss.* COMMON) + + . = ALIGN(8); + _ebss = ABSOLUTE(.); + } >KDRAM + + .noinit (NOLOAD): + { + /* This section contains data that is not initialized during load, + * or during the application's initialization sequence. + */ + + *(.noinit) + *(.noinit.*) + } >KDRAM + + .dram0.data : + { + /* .data initialized on power-up in ROMed configurations. */ + + _sdata = ABSOLUTE(.); + KEEP (*(.data)) + KEEP (*(.data.*)) + KEEP (*(.gnu.linkonce.d.*)) + KEEP (*(.data1)) + KEEP (*(.sdata)) + KEEP (*(.sdata.*)) + KEEP (*(.gnu.linkonce.s.*)) + KEEP (*(.sdata2)) + KEEP (*(.sdata2.*)) + KEEP (*(.gnu.linkonce.s2.*)) + KEEP (*(.jcr)) + *(.dram1 .dram1.*) + *libphy.a:(.rodata .rodata.*) + *libkarch.a:esp32s3_spiflash.*(.rodata .rodata.*) + *libkarch.a:xtensa_cpupause.*(.rodata .rodata.*) + *libkarch.a:xtensa_copystate.*(.rodata .rodata.*) + *libkarch.a:xtensa_interruptcontext.*(.rodata .rodata.*) + *libkarch.a:xtensa_testset.*(.rodata .rodata.*) + + *libsched.a:sched_suspendscheduler.*(.rodata .rodata.*) + *libsched.a:sched_thistask.*(.rodata .rodata.*) + *libsched.a:sched_note.*(.rodata .rodata.*) + *libsched.a:spinlock.*(.rodata .rodata.*) + *libsched.a:irq_csection.*(.rodata .rodata.*) + *libsched.a:irq_dispatch.*(.rodata .rodata.*) + + . = ALIGN(4); + _edata = ABSOLUTE(.); + + /* Heap starts at the end of .data */ + + _sheap = ABSOLUTE(.); + } >KDRAM + + .flash.text : + { + _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; + + _etext = .; + } >KIROM + + .flash_rodata_dummy (NOLOAD) : + { + /* This dummy section represents the .flash.text section but in default_rodata_seg. + * Thus, it must have its alignment and (at least) its size. + */ + + /* Start at the same alignment constraint than .flash.text */ + + . = ALIGN(ALIGNOF(.flash.text)); + + /* Create an empty gap as big as .flash.text section */ + + . = SIZEOF(.flash.text); + + /* Prepare the alignment of the section above. Few bytes (0x20) must be + * added for the mapping header. + */ + + . = ALIGN(0x10000) + 0x20; + _rodata_reserved_start = .; + } >KDROM + + .flash.rodata : ALIGN(0x10) + { + _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) + + . = ALIGN(4); + + /* 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. */ + + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + _rodata_reserved_end = ABSOLUTE(.); + . = ALIGN(4); + } >KDROM +} diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld b/boards/xtensa/esp32s3/common/scripts/protected_memory.ld similarity index 55% rename from boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld rename to boards/xtensa/esp32s3/common/scripts/protected_memory.ld index ecf26a8a84..7dc58edc18 100644 --- a/boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld +++ b/boards/xtensa/esp32s3/common/scripts/protected_memory.ld @@ -1,11 +1,11 @@ /**************************************************************************** - * boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld + * boards/xtensa/esp32s3/common/scripts/protected_memory.ld * ESP32-S3 Linker Script Memory Layout * * This file describes the memory layout (memory blocks) as virtual * memory addresses. * - * esp32s3_sections.ld contains output sections to link compiler output + * kernel-space.ld contains output sections to link compiler output * into these memory blocks. * ****************************************************************************/ @@ -51,66 +51,48 @@ MEMORY { + metadata (RX) : org = 0x0, len = 0x18 + ROM (RX) : org = 0x18, len = 0x100000 + /* 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. + * connected to the data port of the CPU and e.g. allow bytewise access. */ - /* IRAM for CPU */ - - iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = SRAM_IRAM_SIZE + KIRAM (RWX) : org = SRAM_IRAM_ORG, len = 48K + UIRAM (RWX) : org = ORIGIN(KIRAM) + LENGTH(KIRAM), len = 64K /* Flash mapped instruction data. */ - /* The 0x20 offset is a convenience for the app binary image generation. + /* The 0x20 offset for the KIROM region is a convenience for the Kernel + * binary image generation in Espressif Application Image format. * 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). */ - irom0_0_seg (RX) : org = 0x42000020, len = FLASH_SIZE - 0x20 + KIROM (RX) : org = 0x42000020, len = 0x80000 - 0x20 + UIROM (RX) : org = 0x42080000, len = 0x180000 - /* Shared data RAM, excluding memory reserved for bootloader and ROM - * bss/data/stack. - */ + /* Shared data RAM, excluding memory reserved for ROM bss/data/stack. */ - dram0_0_seg (RW) : org = SRAM_DRAM_ORG, len = I_D_SRAM_SIZE + KDRAM (RW) : org = SRAM_DRAM_ORG + 0x18000, len = 64K + UDRAM (RW) : org = ORIGIN(KDRAM) + LENGTH(KDRAM), len = 192K /* Flash mapped constant data */ - /* 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). + /* See KIROM region documentation above for the meaning of the 0x20 offset. + * + * The 0x18 offset for the UDROM region is a convenience for the User + * binary image generation following a custom image format, which defines + * a "metadata" output section containing some information that the Kernel + * needs for properly configuring the External Flash MMU when loading the + * User application image. */ - drom0_0_seg (R) : org = 0x3c000020, len = FLASH_SIZE - 0x20 - - /* RTC fast memory (executable). Persists over deep sleep. */ - - rtc_iram_seg(RWX) : org = 0x600fe000, len = 0x2000 - - /* RTC fast memory (same block as above), viewed from data bus */ - - rtc_data_seg(RW) : org = 0x600fe000, len = 0x2000 - - /* RTC slow memory (data accessible). Persists over deep sleep. - * Start of RTC slow memory is reserved for ULP co-processor code + data, - * if enabled. - */ - - rtc_slow_seg(RW) : org = 0x50000000 + CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM, - len = 0x2000 - CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM + KDROM (R) : org = 0x3c000020, len = 0x80000 - 0x20 + UDROM (R) : org = 0x3c080018, len = 0x180000 - 0x18 } -#ifdef CONFIG_ESP32S3_RUN_IRAM - REGION_ALIAS("default_rodata_seg", dram0_0_seg); - REGION_ALIAS("default_code_seg", iram0_0_seg); -#else - REGION_ALIAS("default_rodata_seg", drom0_0_seg); - REGION_ALIAS("default_code_seg", irom0_0_seg); -#endif /* CONFIG_ESP32S3_RUN_IRAM */ - diff --git a/boards/xtensa/esp32s3/common/scripts/user-space.ld b/boards/xtensa/esp32s3/common/scripts/user-space.ld new file mode 100644 index 0000000000..c39d191e11 --- /dev/null +++ b/boards/xtensa/esp32s3/common/scripts/user-space.ld @@ -0,0 +1,231 @@ +/**************************************************************************** + * boards/xtensa/esp32s3/common/scripts/user-space.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. + * + ****************************************************************************/ + +SECTIONS +{ + .metadata : + { + /* DROM metadata: + * - Destination address (VMA) for DROM region + * - Flash offset (LMA) for start of DROM region + * - Size of DROM region + */ + + LONG(ADDR(.userspace)) + LONG(LOADADDR(.userspace)) + LONG(SIZEOF(.userspace) + SIZEOF(.rodata)) + + /* IROM metadata: + * - Destination address (VMA) for IROM region + * - Flash offset (LMA) for start of IROM region + * - Size of IROM region + */ + + LONG(ADDR(.text)) + LONG(LOADADDR(.text)) + LONG(SIZEOF(.text)) + } >metadata + + /* section info */ + + __ld_uirom_start = ORIGIN(UIROM); + __ld_uirom_size = LENGTH(UIROM); + __ld_uirom_end = ORIGIN(UIROM) + LENGTH(UIROM); + __ld_udrom_start = ORIGIN(UDROM); + __ld_udrom_size = LENGTH(UDROM); + __ld_udrom_end = ORIGIN(UDROM) + LENGTH(UDROM); + __ld_uiram_start = ORIGIN(UIRAM); + __ld_uiram_size = LENGTH(UIRAM); + __ld_uiram_end = ORIGIN(UIRAM) + LENGTH(UIRAM); + __ld_udram_start = ORIGIN(UDRAM); + __ld_udram_size = LENGTH(UDRAM); + __ld_udram_end = ORIGIN(UDRAM) + LENGTH(UDRAM); + + _eronly = LOADADDR(.data); + + .userspace : + { + *(.userspace) + } >UDROM AT>ROM + + /* Output sections for the Userspace image are given standard names, so + * instead of the Espressif-usual ".flash.text" we name it as ".text". + * The motivation is to ease debugging with GDB when loading symbols from + * both Kernel and User images since GDB's "add-symbol-file" command + * expects to find a .text section at the provided offset. + */ + + .rodata : + { + . = ALIGN(4); + _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) + + . = (. + 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); + } >UDROM AT>ROM + + .iram0.text : + { + _iram_start = ABSOLUTE(.); + + *(.iram1) + *(.iram1.*) + + _iram_end = ABSOLUTE(.); + } >UIRAM AT>ROM + + /* 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. + */ + + .dram0.dummy (NOLOAD): + { + . = ORIGIN(UDRAM) + _iram_end - _iram_start; + } >UDRAM + + /* Shared RAM */ + + .bss (NOLOAD) : + { + /* .bss initialized on power-up */ + + . = ALIGN (8); + _sbss = ABSOLUTE(.); + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + KEEP (*(.bss)) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(8); + + _ebss = ABSOLUTE(.); + } >UDRAM + + .noinit (NOLOAD): + { + /* This section contains data that is not initialized during load, + * or during the application's initialization sequence. + */ + + . = ALIGN(8); + *(.noinit) + *(.noinit.*) + . = ALIGN(8); + } >UDRAM + + .data : + { + _sdata = ABSOLUTE(.); + KEEP (*(.data)) + KEEP (*(.data.*)) + KEEP (*(.gnu.linkonce.d.*)) + KEEP (*(.data1)) + KEEP (*(.sdata)) + KEEP (*(.sdata.*)) + KEEP (*(.gnu.linkonce.s.*)) + KEEP (*(.sdata2)) + KEEP (*(.sdata2.*)) + KEEP (*(.gnu.linkonce.s2.*)) + KEEP (*(.jcr)) + *(.dram1 .dram1.*) + _edata = ABSOLUTE(.); + . = ALIGN(4); + + /* Heap starts at the end of .data */ + + _sheap = ABSOLUTE(.); + } >UDRAM AT>ROM + + .flash_text_dummy (NOLOAD) : ALIGN(0x00010000) + { + . = SIZEOF(.userspace) + SIZEOF(.rodata); + } >UIROM + + .text : ALIGN(0x00010000) + { + _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) + . = ALIGN(4); + + _etext = .; + } >UIROM AT>ROM +} diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/knsh/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/knsh/defconfig new file mode 100644 index 0000000000..2fc6f11c44 --- /dev/null +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/knsh/defconfig @@ -0,0 +1,55 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32s3-devkit" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32S3_DEVKIT=y +CONFIG_ARCH_CHIP="esp32s3" +CONFIG_ARCH_CHIP_ESP32S3=y +CONFIG_ARCH_CHIP_ESP32S3WROOM1=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_USE_MPU=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILD_PROTECTED=y +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_ESP32S3_UART0=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_NUTTX_USERSPACE=0x3c080018 +CONFIG_PASS1_BUILDIR="boards/xtensa/esp32s3/common/kernel" +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_TESTING_OSTEST_FPUTESTDISABLE=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/include/board_memorymap.h b/boards/xtensa/esp32s3/esp32s3-devkit/include/board_memorymap.h new file mode 100644 index 0000000000..6569e936c2 --- /dev/null +++ b/boards/xtensa/esp32s3/esp32s3-devkit/include/board_memorymap.h @@ -0,0 +1,116 @@ +/**************************************************************************** + * boards/xtensa/esp32s3/esp32s3-devkit/include/board_memorymap.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 __BOARDS_XTENSA_ESP32S3_ESP32S3_DEVKIT_INCLUDE_BOARD_MEMORYMAP_H +#define __BOARDS_XTENSA_ESP32S3_ESP32S3_DEVKIT_INCLUDE_BOARD_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdint.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Kernel ROM */ + +#define KIROM_START (uintptr_t)__kirom_start +#define KIROM_SIZE (uintptr_t)__kirom_size +#define KDROM_START (uintptr_t)__kdrom_start +#define KDROM_SIZE (uintptr_t)__kdrom_size + +/* Kernel RAM */ + +#define KIRAM_START (uintptr_t)__kiram_start +#define KIRAM_SIZE (uintptr_t)__kiram_size +#define KIRAM_END (uintptr_t)__kiram_end +#define KDRAM_START (uintptr_t)__kdram_start +#define KDRAM_SIZE (uintptr_t)__kdram_size +#define KDRAM_END (uintptr_t)__kdram_end + +/* Exception vectors */ + +#define VECTORS_START (uintptr_t)__vectors_start +#define VECTORS_END (uintptr_t)__vectors_end + +/* User ROM */ + +#define UIROM_START (uintptr_t)__uirom_start +#define UIROM_SIZE (uintptr_t)__uirom_size +#define UIROM_END (uintptr_t)__uirom_end +#define UDROM_START (uintptr_t)__udrom_start +#define UDROM_SIZE (uintptr_t)__udrom_size +#define UDROM_END (uintptr_t)__udrom_end + +/* User RAM */ + +#define UIRAM_START (uintptr_t)__uiram_start +#define UIRAM_SIZE (uintptr_t)__uiram_size +#define UIRAM_END (uintptr_t)__uiram_end +#define UDRAM_START (uintptr_t)__udram_start +#define UDRAM_SIZE (uintptr_t)__udram_size +#define UDRAM_END (uintptr_t)__udram_end + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Kernel ROM (RX) */ + +extern uint8_t __kirom_start[]; +extern uint8_t __kirom_size[]; +extern uint8_t __kdrom_start[]; +extern uint8_t __kdrom_size[]; + +/* Kernel RAM (RW) */ + +extern uint8_t __kiram_start[]; +extern uint8_t __kiram_size[]; +extern uint8_t __kiram_end[]; +extern uint8_t __kdram_start[]; +extern uint8_t __kdram_size[]; +extern uint8_t __kdram_end[]; + +/* Exception vectors */ + +extern uint8_t __vectors_start[]; +extern uint8_t __vectors_end[]; + +/* User ROM (RX) */ + +extern uint8_t __uirom_start[]; +extern uint8_t __uirom_size[]; +extern uint8_t __uirom_end[]; +extern uint8_t __udrom_start[]; +extern uint8_t __udrom_size[]; +extern uint8_t __udrom_end[]; + +/* User RAM (RW) */ + +extern uint8_t __uiram_start[]; +extern uint8_t __uiram_size[]; +extern uint8_t __uiram_end[]; +extern uint8_t __udram_start[]; +extern uint8_t __udram_size[]; +extern uint8_t __udram_end[]; + +#endif /* __BOARDS_XTENSA_ESP32S3_ESP32S3_DEVKIT_INCLUDE_BOARD_MEMORYMAP_H */ diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/scripts/Make.defs b/boards/xtensa/esp32s3/esp32s3-devkit/scripts/Make.defs index 306fd42166..8f1b8c8342 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/scripts/Make.defs +++ b/boards/xtensa/esp32s3/esp32s3-devkit/scripts/Make.defs @@ -32,13 +32,21 @@ ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_rom.ld ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld),) ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld else - ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld + ifeq ($(CONFIG_BUILD_PROTECTED),y) + ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)protected_memory.ld + else + ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)flat_memory.ld + endif endif ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld),) ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld else - ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld + ifeq ($(CONFIG_BUILD_PROTECTED),y) + ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)kernel-space.ld + else + ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld + endif endif ifneq ($(CONFIG_DEBUG_NOOPT),y) diff --git a/boards/xtensa/esp32s3/esp32s3-eye/scripts/Make.defs b/boards/xtensa/esp32s3/esp32s3-eye/scripts/Make.defs index ccb902b7f8..f2390049f8 100644 --- a/boards/xtensa/esp32s3/esp32s3-eye/scripts/Make.defs +++ b/boards/xtensa/esp32s3/esp32s3-eye/scripts/Make.defs @@ -32,13 +32,21 @@ ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_rom.ld ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld),) ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld else - ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld + ifeq ($(CONFIG_BUILD_PROTECTED),y) + ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)protected_memory.ld + else + ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)flat_memory.ld + endif endif ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld),) ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld else - ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld + ifeq ($(CONFIG_BUILD_PROTECTED),y) + ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)kernel-space.ld + else + ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld + endif endif ifneq ($(CONFIG_DEBUG_NOOPT),y) diff --git a/tools/esp32s3/Config.mk b/tools/esp32s3/Config.mk index 94772247d1..26b876b5b1 100644 --- a/tools/esp32s3/Config.mk +++ b/tools/esp32s3/Config.mk @@ -80,6 +80,10 @@ endif ESPTOOL_BINS += $(FLASH_APP) +ifeq ($(CONFIG_BUILD_PROTECTED),y) + ESPTOOL_BINS += $(CONFIG_ESP32S3_USER_IMAGE_OFFSET) nuttx_user.bin +endif + # MERGEBIN -- Merge raw binary files into a single file define MERGEBIN
