xtensa/esp32: Support allocation of userspace heap into External RAM

Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
This commit is contained in:
Gustavo Henrique Nihei
2023-01-11 15:37:13 -03:00
committed by Xiang Xiao
parent fc176addeb
commit 705e29fb27
5 changed files with 190 additions and 56 deletions
+54 -23
View File
@@ -182,16 +182,6 @@ config ESP32_RUN_IRAM
This loads all of NuttX inside IRAM. Used to test somewhat small This loads all of NuttX inside IRAM. Used to test somewhat small
images that can fit entirely in IRAM. 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" menu "ESP32 Peripheral Selection"
config ESP32_UART config ESP32_UART
@@ -579,10 +569,9 @@ config ESP32_SPI3
select SPI select SPI
config ESP32_SPIRAM config ESP32_SPIRAM
bool "SPI RAM Support" bool "SPI RAM"
default n default n
select ARCH_HAVE_HEAP2 if !ESP32_USER_DATA_EXTMEM select ARCH_HAVE_HEAP2
select XTENSA_IMEM_USE_SEPARATE_HEAP
if ESP32_SPIRAM && SMP if ESP32_SPIRAM && SMP
@@ -764,6 +753,41 @@ config ESP32_ULP_COPROC_RESERVE_MEM
int "Reserved ULP co-processor DRAM" int "Reserved ULP co-processor DRAM"
default 0 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 endmenu # Memory Configuration
config ESP32_GPIO_IRQ config ESP32_GPIO_IRQ
@@ -772,7 +796,7 @@ config ESP32_GPIO_IRQ
---help--- ---help---
Enable support for interrupting GPIO pins Enable support for interrupting GPIO pins
menu "UART configuration" menu "UART Configuration"
depends on ESP32_UART depends on ESP32_UART
if ESP32_UART0 if ESP32_UART0
@@ -829,6 +853,7 @@ config ESP32_UART0_TXDMA
bool "Enable UART0 TX DMA" bool "Enable UART0 TX DMA"
select ARCH_DMA select ARCH_DMA
select UART0_TXDMA select UART0_TXDMA
select ESP32_IMM_HEAP if ESP32_SPIRAM
depends on EXPERIMENTAL depends on EXPERIMENTAL
---help--- ---help---
Due to a hardware bug on the DMA used by the UART 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" bool "Enable UART1 TX DMA"
select ARCH_DMA select ARCH_DMA
select UART1_TXDMA select UART1_TXDMA
select ESP32_IMM_HEAP if ESP32_SPIRAM
depends on EXPERIMENTAL depends on EXPERIMENTAL
---help--- ---help---
Due to a hardware bug on the DMA used by the UART 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" bool "Enable UART2 TX DMA"
select ARCH_DMA select ARCH_DMA
select UART2_TXDMA select UART2_TXDMA
select ESP32_IMM_HEAP if ESP32_SPIRAM
depends on EXPERIMENTAL depends on EXPERIMENTAL
---help--- ---help---
Due to a hardware bug on the DMA used by the UART Due to a hardware bug on the DMA used by the UART
@@ -1000,7 +1027,7 @@ config UART_DMADESC_NUM
endmenu # UART configuration endmenu # UART configuration
menu "I2C configuration" menu "I2C Configuration"
depends on ESP32_I2C depends on ESP32_I2C
if ESP32_I2C0 if ESP32_I2C0
@@ -1093,7 +1120,7 @@ config ESP32_TWAI_REGDEBUG
endmenu #ESP32_TWAI endmenu #ESP32_TWAI
menu "SPI configuration" menu "SPI Configuration"
depends on ESP32_SPI depends on ESP32_SPI
config ESP32_SPI_SWCS config ESP32_SPI_SWCS
@@ -1112,11 +1139,15 @@ config ESP32_SPI_UDCS
config ESP32_SPI2_DMA config ESP32_SPI2_DMA
bool "SPI2 use DMA" bool "SPI2 use DMA"
default y default y
select ARCH_DMA
select ESP32_IMM_HEAP if ESP32_SPIRAM
depends on ESP32_SPI2 depends on ESP32_SPI2
config ESP32_SPI3_DMA config ESP32_SPI3_DMA
bool "SPI3 use DMA" bool "SPI3 use DMA"
default y default y
select ARCH_DMA
select ESP32_IMM_HEAP if ESP32_SPIRAM
depends on ESP32_SPI3 depends on ESP32_SPI3
config SPI_DMADESC_NUM config SPI_DMADESC_NUM
@@ -1657,7 +1688,7 @@ endif # ESP32_PCNT_U7
endmenu # ESP32_PCNT endmenu # ESP32_PCNT
menu "SPI Flash configuration" menu "SPI Flash Configuration"
choice ESP32_FLASH_MODE choice ESP32_FLASH_MODE
prompt "SPI Flash mode" prompt "SPI Flash mode"
@@ -1745,7 +1776,7 @@ endif
if ESP32_SPIFLASH if ESP32_SPIFLASH
comment "General storage MTD configuration" comment "General storage MTD Configuration"
config ESP32_STORAGE_MTD_ENCRYPT config ESP32_STORAGE_MTD_ENCRYPT
bool "Encrypt Storage MTD partition" bool "Encrypt Storage MTD partition"
@@ -1775,7 +1806,7 @@ config ESP32_SPIFLASH_DEBUG
if ESP32_APP_FORMAT_LEGACY if ESP32_APP_FORMAT_LEGACY
comment "Partition Table configuration" comment "Partition Table Configuration"
config ESP32_PARTITION_TABLE config ESP32_PARTITION_TABLE
bool "Create MTD partitions from Partition Table" bool "Create MTD partitions from Partition Table"
@@ -1794,7 +1825,7 @@ endif # ESP32_SPIFLASH
endmenu # SPI Flash configuration endmenu # SPI Flash configuration
menu "SPI RAM Config" menu "SPI RAM Configuration"
depends on ESP32_SPIRAM depends on ESP32_SPIRAM
choice ESP32_SPIRAM_TYPE choice ESP32_SPIRAM_TYPE
@@ -1899,7 +1930,7 @@ config SPIRAM_BANKSWITCH_RESERVE
endmenu #SPI RAM Config endmenu #SPI RAM Config
menu "Ethernet configuration" menu "Ethernet Configuration"
depends on ESP32_EMAC depends on ESP32_EMAC
config ESP32_ETH_NRXDESC config ESP32_ETH_NRXDESC
@@ -1938,7 +1969,7 @@ config ESP32_ETH_PHY_ADDR
endmenu # ESP32_EMAC endmenu # ESP32_EMAC
menu "Wi-Fi configuration" menu "Wi-Fi Configuration"
depends on ESP32_WIFI depends on ESP32_WIFI
choice choice
@@ -2192,7 +2223,7 @@ config ESP32_RTC_CLK_SRC_INT_8MD256
endchoice endchoice
endmenu # "RTC Configuration" endmenu # "RTC Configuration"
menu "LEDC configuration" menu "LEDC Configuration"
depends on ESP32_LEDC depends on ESP32_LEDC
menuconfig ESP32_LEDC_TIM0 menuconfig ESP32_LEDC_TIM0
+71 -28
View File
@@ -38,18 +38,22 @@
#endif #endif
#include <arch/esp32/memory_layout.h> #include <arch/esp32/memory_layout.h>
#ifdef CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE #include "xtensa.h"
#include <nuttx/himem/himem.h> #ifdef CONFIG_ESP32_SPIRAM
#include "esp32_himem.h" #include "esp32_himem.h"
#endif #endif
#include "xtensa.h"
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * 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 # define MM_ADDREGION kmm_addregion
#else #else
# define MM_ADDREGION umm_addregion # define MM_ADDREGION umm_addregion
@@ -76,32 +80,56 @@
void up_allocate_heap(void **heap_start, size_t *heap_size) void up_allocate_heap(void **heap_start, size_t *heap_size)
{ {
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) uintptr_t ubase;
uintptr_t ubase = USERSPACE->us_dataend; uintptr_t utop;
uintptr_t utop = USERSPACE->us_heapend; size_t usize;
size_t usize = utop - ubase;
#if defined(CONFIG_ESP32_USER_DATA_EXTMEM) && \ #ifdef CONFIG_MM_KERNEL_HEAP
defined(CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE) # 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(); 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", minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n",
ubase, utop, usize); ubase, utop, usize);
DEBUGASSERT(utop > ubase);
board_autoled_on(LED_HEAPALLOCATE); board_autoled_on(LED_HEAPALLOCATE);
/* Return the userspace heap settings */ /* Return the userspace heap settings */
*heap_start = (void *)ubase; *heap_start = (void *)ubase;
*heap_size = usize; *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 * userspace heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates
* (and protects) the kernel space heap. * (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) && \ #ifdef CONFIG_MM_KERNEL_HEAP
defined(__KERNEL__)
void up_allocate_kheap(void **heap_start, size_t *heap_size) 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 /* These values come from the linker scripts (kernel-space.ld and
* protected_memory.ld). * protected_memory.ld).
* Check boards/xtensa/esp32. * Check boards/xtensa/esp32.
*/ */
uintptr_t kbase = (uintptr_t)_sheap; kbase = (uintptr_t)_sheap;
uintptr_t ktop = KDRAM_0_END; ktop = KDRAM_0_END;
size_t ksize = ktop - kbase; 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", minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n",
kbase, ktop, ksize); kbase, ktop, ksize);
DEBUGASSERT(ktop > kbase);
board_autoled_on(LED_HEAPALLOCATE); board_autoled_on(LED_HEAPALLOCATE);
*heap_start = (void *)kbase; *heap_start = (void *)kbase;
*heap_size = ksize; *heap_size = ksize;
} }
#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */ #endif /* CONFIG_MM_KERNEL_HEAP */
/**************************************************************************** /****************************************************************************
* Name: xtensa_add_region * Name: xtensa_add_region
@@ -168,7 +210,7 @@ void xtensa_add_region(void)
availregions = 2; availregions = 2;
#endif #endif
#if defined(CONFIG_ESP32_SPIRAM) && !defined(CONFIG_BUILD_PROTECTED) #ifdef CONFIG_ESP32_SPIRAM_COMMON_HEAP
availregions++; availregions++;
#endif #endif
@@ -184,6 +226,7 @@ void xtensa_add_region(void)
MM_ADDREGION(start, size); MM_ADDREGION(start, size);
#endif #endif
#ifndef MM_USER_HEAP_IRAM
/* Skip internal heap region if CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP is /* Skip internal heap region if CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP is
* enabled. * enabled.
*/ */
@@ -191,6 +234,7 @@ void xtensa_add_region(void)
start = (void *)ESP32_IMEM_START + XTENSA_IMEM_REGION_SIZE; start = (void *)ESP32_IMEM_START + XTENSA_IMEM_REGION_SIZE;
size = (size_t)(uintptr_t)_eheap - (size_t)start; size = (size_t)(uintptr_t)_eheap - (size_t)start;
MM_ADDREGION(start, size); MM_ADDREGION(start, size);
#endif
#ifndef CONFIG_ESP32_BLE #ifndef CONFIG_ESP32_BLE
start = (void *)HEAP_REGION0_START; start = (void *)HEAP_REGION0_START;
@@ -198,7 +242,7 @@ void xtensa_add_region(void)
MM_ADDREGION(start, size); MM_ADDREGION(start, size);
#endif #endif
#if defined(CONFIG_ESP32_SPIRAM) && defined(CONFIG_ARCH_HAVE_HEAP2) #ifdef CONFIG_ESP32_SPIRAM_COMMON_HEAP
#ifdef CONFIG_XTENSA_EXTMEM_BSS #ifdef CONFIG_XTENSA_EXTMEM_BSS
start = (void *)(_ebss_extmem); start = (void *)(_ebss_extmem);
size = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem); size = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem);
@@ -206,9 +250,8 @@ void xtensa_add_region(void)
start = (void *)CONFIG_HEAP2_BASE; start = (void *)CONFIG_HEAP2_BASE;
size = CONFIG_HEAP2_SIZE; size = CONFIG_HEAP2_SIZE;
#endif #endif
#ifdef CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE
size -= esp_himem_reserved_area_size(); size -= esp_himem_reserved_area_size();
#endif
MM_ADDREGION(start, size); MM_ADDREGION(start, size);
#endif #endif
} }
+2
View File
@@ -27,6 +27,8 @@
#include <stddef.h> #include <stddef.h>
#include <nuttx/himem/himem.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
@@ -21,12 +21,13 @@ CONFIG_ARCH_XTENSA=y
CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y CONFIG_DEV_ZERO=y
CONFIG_ESP32_IMM_HEAP=y
CONFIG_ESP32_SPIRAM=y CONFIG_ESP32_SPIRAM=y
CONFIG_ESP32_UART0=y CONFIG_ESP32_UART0=y
CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_HEAP2_BASE=0x3F800000 CONFIG_HEAP2_BASE=0x3f800000
CONFIG_HEAP2_SIZE=4194304 CONFIG_HEAP2_SIZE=4194304
CONFIG_IDLETHREAD_STACKSIZE=3072 CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INIT_ENTRYPOINT="nsh_main"
@@ -47,7 +48,6 @@ CONFIG_RAM_START=0x20000000
CONFIG_RR_INTERVAL=200 CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORK=y CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_WAITPID=y CONFIG_SCHED_WAITPID=y
CONFIG_SPI=y
CONFIG_START_DAY=6 CONFIG_START_DAY=6
CONFIG_START_MONTH=12 CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011 CONFIG_START_YEAR=2011
@@ -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