From 705e29fb274a615d8c36fda2d19e5a5fd696786a Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Nihei Date: Wed, 11 Jan 2023 15:37:13 -0300 Subject: [PATCH] xtensa/esp32: Support allocation of userspace heap into External RAM Signed-off-by: Gustavo Henrique Nihei --- arch/xtensa/src/esp32/Kconfig | 77 +++++++++---- arch/xtensa/src/esp32/esp32_allocateheap.c | 105 ++++++++++++------ arch/xtensa/src/esp32/esp32_himem.h | 2 + .../esp32-devkitc/configs/psram/defconfig | 4 +- .../configs/psram_usrheap/defconfig | 58 ++++++++++ 5 files changed, 190 insertions(+), 56 deletions(-) create mode 100644 boards/xtensa/esp32/esp32-devkitc/configs/psram_usrheap/defconfig diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index 1249edd131..da92b64e8d 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -182,16 +182,6 @@ config ESP32_RUN_IRAM This loads all of NuttX inside IRAM. Used to test somewhat small images that can fit entirely in IRAM. -config ESP32_RTC_HEAP - bool "Use the RTC memory as a separate heap" - select ARCH_HAVE_EXTRA_HEAPS - default n - -config ESP32_IRAM_HEAP - bool "Use the rest of IRAM as a separate heap" - select ARCH_HAVE_EXTRA_HEAPS - default n - menu "ESP32 Peripheral Selection" config ESP32_UART @@ -579,10 +569,9 @@ config ESP32_SPI3 select SPI config ESP32_SPIRAM - bool "SPI RAM Support" + bool "SPI RAM" default n - select ARCH_HAVE_HEAP2 if !ESP32_USER_DATA_EXTMEM - select XTENSA_IMEM_USE_SEPARATE_HEAP + select ARCH_HAVE_HEAP2 if ESP32_SPIRAM && SMP @@ -764,6 +753,41 @@ config ESP32_ULP_COPROC_RESERVE_MEM int "Reserved ULP co-processor DRAM" default 0 +comment "Additional Heaps" + +choice ESP32_SPIRAM_HEAP + prompt "SPI RAM heap function" + default ESP32_SPIRAM_COMMON_HEAP if BUILD_FLAT + default ESP32_SPIRAM_USER_HEAP if BUILD_PROTECTED + depends on ESP32_SPIRAM + ---help--- + Select how the SPI RAM will be used as heap. + + config ESP32_SPIRAM_COMMON_HEAP + bool "Additional region to kernel heap" + + config ESP32_SPIRAM_USER_HEAP + bool "Separated userspace heap" + select MM_KERNEL_HEAP + select ESP32_USER_DATA_EXTMEM if BUILD_PROTECTED + +endchoice + +config ESP32_IMM_HEAP + bool "Reserve part of DRAM as a separate heap" + select XTENSA_IMEM_USE_SEPARATE_HEAP + default n + +config ESP32_RTC_HEAP + bool "Use the RTC memory as a separate heap" + select ARCH_HAVE_EXTRA_HEAPS + default n + +config ESP32_IRAM_HEAP + bool "Use the rest of IRAM as a separate heap" + select ARCH_HAVE_EXTRA_HEAPS + default n + endmenu # Memory Configuration config ESP32_GPIO_IRQ @@ -772,7 +796,7 @@ config ESP32_GPIO_IRQ ---help--- Enable support for interrupting GPIO pins -menu "UART configuration" +menu "UART Configuration" depends on ESP32_UART if ESP32_UART0 @@ -829,6 +853,7 @@ config ESP32_UART0_TXDMA bool "Enable UART0 TX DMA" select ARCH_DMA select UART0_TXDMA + select ESP32_IMM_HEAP if ESP32_SPIRAM depends on EXPERIMENTAL ---help--- Due to a hardware bug on the DMA used by the UART @@ -895,6 +920,7 @@ config ESP32_UART1_TXDMA bool "Enable UART1 TX DMA" select ARCH_DMA select UART1_TXDMA + select ESP32_IMM_HEAP if ESP32_SPIRAM depends on EXPERIMENTAL ---help--- Due to a hardware bug on the DMA used by the UART @@ -961,6 +987,7 @@ config ESP32_UART2_TXDMA bool "Enable UART2 TX DMA" select ARCH_DMA select UART2_TXDMA + select ESP32_IMM_HEAP if ESP32_SPIRAM depends on EXPERIMENTAL ---help--- Due to a hardware bug on the DMA used by the UART @@ -1000,7 +1027,7 @@ config UART_DMADESC_NUM endmenu # UART configuration -menu "I2C configuration" +menu "I2C Configuration" depends on ESP32_I2C if ESP32_I2C0 @@ -1093,7 +1120,7 @@ config ESP32_TWAI_REGDEBUG endmenu #ESP32_TWAI -menu "SPI configuration" +menu "SPI Configuration" depends on ESP32_SPI config ESP32_SPI_SWCS @@ -1112,11 +1139,15 @@ config ESP32_SPI_UDCS config ESP32_SPI2_DMA bool "SPI2 use DMA" default y + select ARCH_DMA + select ESP32_IMM_HEAP if ESP32_SPIRAM depends on ESP32_SPI2 config ESP32_SPI3_DMA bool "SPI3 use DMA" default y + select ARCH_DMA + select ESP32_IMM_HEAP if ESP32_SPIRAM depends on ESP32_SPI3 config SPI_DMADESC_NUM @@ -1657,7 +1688,7 @@ endif # ESP32_PCNT_U7 endmenu # ESP32_PCNT -menu "SPI Flash configuration" +menu "SPI Flash Configuration" choice ESP32_FLASH_MODE prompt "SPI Flash mode" @@ -1745,7 +1776,7 @@ endif if ESP32_SPIFLASH -comment "General storage MTD configuration" +comment "General storage MTD Configuration" config ESP32_STORAGE_MTD_ENCRYPT bool "Encrypt Storage MTD partition" @@ -1775,7 +1806,7 @@ config ESP32_SPIFLASH_DEBUG if ESP32_APP_FORMAT_LEGACY -comment "Partition Table configuration" +comment "Partition Table Configuration" config ESP32_PARTITION_TABLE bool "Create MTD partitions from Partition Table" @@ -1794,7 +1825,7 @@ endif # ESP32_SPIFLASH endmenu # SPI Flash configuration -menu "SPI RAM Config" +menu "SPI RAM Configuration" depends on ESP32_SPIRAM choice ESP32_SPIRAM_TYPE @@ -1899,7 +1930,7 @@ config SPIRAM_BANKSWITCH_RESERVE endmenu #SPI RAM Config -menu "Ethernet configuration" +menu "Ethernet Configuration" depends on ESP32_EMAC config ESP32_ETH_NRXDESC @@ -1938,7 +1969,7 @@ config ESP32_ETH_PHY_ADDR endmenu # ESP32_EMAC -menu "Wi-Fi configuration" +menu "Wi-Fi Configuration" depends on ESP32_WIFI choice @@ -2192,7 +2223,7 @@ config ESP32_RTC_CLK_SRC_INT_8MD256 endchoice endmenu # "RTC Configuration" -menu "LEDC configuration" +menu "LEDC Configuration" depends on ESP32_LEDC menuconfig ESP32_LEDC_TIM0 diff --git a/arch/xtensa/src/esp32/esp32_allocateheap.c b/arch/xtensa/src/esp32/esp32_allocateheap.c index b37ed374d6..7386a94f75 100644 --- a/arch/xtensa/src/esp32/esp32_allocateheap.c +++ b/arch/xtensa/src/esp32/esp32_allocateheap.c @@ -38,18 +38,22 @@ #endif #include -#ifdef CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE -#include +#include "xtensa.h" +#ifdef CONFIG_ESP32_SPIRAM #include "esp32_himem.h" #endif -#include "xtensa.h" - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -#ifdef CONFIG_BUILD_PROTECTED +#ifdef CONFIG_MM_KERNEL_HEAP +# if defined(CONFIG_ESP32_SPIRAM) && defined(CONFIG_ARCH_HAVE_HEAP2) +# define MM_USER_HEAP_EXTRAM +# else +# define MM_USER_HEAP_IRAM +# endif + # define MM_ADDREGION kmm_addregion #else # define MM_ADDREGION umm_addregion @@ -76,32 +80,56 @@ 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 = USERSPACE->us_heapend; - size_t usize = utop - ubase; + uintptr_t ubase; + uintptr_t utop; + size_t usize; -#if defined(CONFIG_ESP32_USER_DATA_EXTMEM) && \ - defined(CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE) +#ifdef CONFIG_MM_KERNEL_HEAP +# ifdef CONFIG_BUILD_PROTECTED + ubase = USERSPACE->us_dataend; + utop = USERSPACE->us_heapend; + usize = utop - ubase; +# ifdef CONFIG_ESP32_USER_DATA_EXTMEM usize -= esp_himem_reserved_area_size(); -#endif +# endif + +# elif defined(CONFIG_BUILD_FLAT) +# ifdef MM_USER_HEAP_EXTRAM +# ifdef CONFIG_XTENSA_EXTMEM_BSS + ubase = (uintptr_t)_ebss_extmem; + usize = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem); +# else + ubase = CONFIG_HEAP2_BASE; + usize = CONFIG_HEAP2_SIZE; +# endif + usize -= esp_himem_reserved_area_size(); + utop = ubase + usize; + +# elif defined(MM_USER_HEAP_IRAM) + ubase = ESP32_IMEM_START + XTENSA_IMEM_REGION_SIZE; + utop = (uintptr_t)_eheap; + usize = utop - ubase; +# endif /* MM_USER_HEAP_EXTRAM */ + +# endif /* CONFIG_BUILD_PROTECTED */ + +#else /* !CONFIG_MM_KERNEL_HEAP */ + ubase = (uintptr_t)_sheap; + utop = HEAP_REGION1_END; + usize = utop - ubase; +#endif /* CONFIG_MM_KERNEL_HEAP */ minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n", ubase, utop, usize); + DEBUGASSERT(utop > ubase); + board_autoled_on(LED_HEAPALLOCATE); /* Return the userspace heap settings */ *heap_start = (void *)ubase; *heap_size = usize; -#else - board_autoled_on(LED_HEAPALLOCATE); - - *heap_start = (void *)_sheap; - DEBUGASSERT(HEAP_REGION1_END > (uintptr_t)*heap_start); - *heap_size = (size_t)(HEAP_REGION1_END - (uintptr_t)*heap_start); -#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */ } /**************************************************************************** @@ -114,30 +142,44 @@ void up_allocate_heap(void **heap_start, size_t *heap_size) * userspace heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates * (and protects) the kernel space heap. * + * For Flat build (CONFIG_BUILD_FLAT=y), this function enables a separate + * (although unprotected) heap for the kernel. + * ****************************************************************************/ -#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) && \ - defined(__KERNEL__) +#ifdef CONFIG_MM_KERNEL_HEAP void up_allocate_kheap(void **heap_start, size_t *heap_size) { + uintptr_t kbase; + uintptr_t ktop; + size_t ksize; + +#ifdef CONFIG_BUILD_PROTECTED /* These values come from the linker scripts (kernel-space.ld and * protected_memory.ld). * Check boards/xtensa/esp32. */ - uintptr_t kbase = (uintptr_t)_sheap; - uintptr_t ktop = KDRAM_0_END; - size_t ksize = ktop - kbase; + kbase = (uintptr_t)_sheap; + ktop = KDRAM_0_END; + ksize = ktop - kbase; +#elif defined(CONFIG_BUILD_FLAT) + kbase = (uintptr_t)_sheap; + ktop = HEAP_REGION1_END; + ksize = ktop - kbase; +#endif minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n", kbase, ktop, ksize); + DEBUGASSERT(ktop > kbase); + board_autoled_on(LED_HEAPALLOCATE); *heap_start = (void *)kbase; *heap_size = ksize; } -#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */ +#endif /* CONFIG_MM_KERNEL_HEAP */ /**************************************************************************** * Name: xtensa_add_region @@ -168,7 +210,7 @@ void xtensa_add_region(void) availregions = 2; #endif -#if defined(CONFIG_ESP32_SPIRAM) && !defined(CONFIG_BUILD_PROTECTED) +#ifdef CONFIG_ESP32_SPIRAM_COMMON_HEAP availregions++; #endif @@ -184,6 +226,7 @@ void xtensa_add_region(void) MM_ADDREGION(start, size); #endif +#ifndef MM_USER_HEAP_IRAM /* Skip internal heap region if CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP is * enabled. */ @@ -191,6 +234,7 @@ void xtensa_add_region(void) start = (void *)ESP32_IMEM_START + XTENSA_IMEM_REGION_SIZE; size = (size_t)(uintptr_t)_eheap - (size_t)start; MM_ADDREGION(start, size); +#endif #ifndef CONFIG_ESP32_BLE start = (void *)HEAP_REGION0_START; @@ -198,17 +242,16 @@ void xtensa_add_region(void) MM_ADDREGION(start, size); #endif -#if defined(CONFIG_ESP32_SPIRAM) && defined(CONFIG_ARCH_HAVE_HEAP2) +#ifdef CONFIG_ESP32_SPIRAM_COMMON_HEAP #ifdef CONFIG_XTENSA_EXTMEM_BSS start = (void *)(_ebss_extmem); - size = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem); + size = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem); #else start = (void *)CONFIG_HEAP2_BASE; - size = CONFIG_HEAP2_SIZE; + size = CONFIG_HEAP2_SIZE; #endif -#ifdef CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE size -= esp_himem_reserved_area_size(); -#endif + MM_ADDREGION(start, size); #endif } diff --git a/arch/xtensa/src/esp32/esp32_himem.h b/arch/xtensa/src/esp32/esp32_himem.h index 1f29c51154..d2da026372 100644 --- a/arch/xtensa/src/esp32/esp32_himem.h +++ b/arch/xtensa/src/esp32/esp32_himem.h @@ -27,6 +27,8 @@ #include +#include + #ifdef __cplusplus extern "C" { diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig index 83fc9f0158..6782e9f08d 100644 --- a/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig +++ b/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig @@ -21,12 +21,13 @@ CONFIG_ARCH_XTENSA=y CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BUILTIN=y CONFIG_DEV_ZERO=y +CONFIG_ESP32_IMM_HEAP=y CONFIG_ESP32_SPIRAM=y CONFIG_ESP32_UART0=y CONFIG_FS_PROCFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y -CONFIG_HEAP2_BASE=0x3F800000 +CONFIG_HEAP2_BASE=0x3f800000 CONFIG_HEAP2_SIZE=4194304 CONFIG_IDLETHREAD_STACKSIZE=3072 CONFIG_INIT_ENTRYPOINT="nsh_main" @@ -47,7 +48,6 @@ CONFIG_RAM_START=0x20000000 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_HPWORK=y CONFIG_SCHED_WAITPID=y -CONFIG_SPI=y CONFIG_START_DAY=6 CONFIG_START_MONTH=12 CONFIG_START_YEAR=2011 diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/psram_usrheap/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/psram_usrheap/defconfig new file mode 100644 index 0000000000..65f23cad03 --- /dev/null +++ b/boards/xtensa/esp32/esp32-devkitc/configs/psram_usrheap/defconfig @@ -0,0 +1,58 @@ +# +# 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="esp32-devkitc" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32_DEVKITC=y +CONFIG_ARCH_CHIP="esp32" +CONFIG_ARCH_CHIP_ESP32=y +CONFIG_ARCH_CHIP_ESP32WROVER=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DEV_ZERO=y +CONFIG_ESP32_SPIRAM=y +CONFIG_ESP32_SPIRAM_USER_HEAP=y +CONFIG_ESP32_UART0=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_HEAP2_BASE=0x3f800000 +CONFIG_HEAP2_SIZE=4194304 +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_IOB_NBUFFERS=36 +CONFIG_IOB_NCHAINS=36 +CONFIG_IOB_THROTTLE=8 +CONFIG_MM_IOB=y +CONFIG_MM_REGIONS=3 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_RAMTEST=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y