diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 47671e8337..eec777b1a4 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -83,6 +83,7 @@ config ARCH_CHIP_ESP32S3 select ARCH_HAVE_MPU select ARCH_HAVE_MULTICPU select ARCH_HAVE_RESET + select ARCH_HAVE_TEXT_HEAP select ARCH_HAVE_TESTSET select ARCH_VECNOTIRQ select LIBC_PREVENT_STRING_KERNEL diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index 396cd96b0e..f4d8faff62 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -906,6 +906,11 @@ config ESP32S3_SPIRAM_USER_HEAP endchoice # ESP32S3_SPIRAM_HEAP +config ESP32S3_RTC_HEAP + bool "Use the RTC memory as a separate heap" + select ARCH_HAVE_EXTRA_HEAPS + default n + endmenu # Memory Configuration config ESP32S3_GPIO_IRQ diff --git a/arch/xtensa/src/esp32s3/Make.defs b/arch/xtensa/src/esp32s3/Make.defs index 502fcbcf14..a0c90f09ee 100644 --- a/arch/xtensa/src/esp32s3/Make.defs +++ b/arch/xtensa/src/esp32s3/Make.defs @@ -156,6 +156,14 @@ ifeq ($(CONFIG_ARCH_HAVE_EXTRA_HEAPS),y) CHIP_CSRCS += esp32s3_extraheaps.c endif +ifeq ($(CONFIG_ESP32S3_RTC_HEAP),y) +CHIP_CSRCS += esp32s3_rtcheap.c +endif + +ifeq ($(CONFIG_ARCH_USE_TEXT_HEAP),y) +CHIP_CSRCS += esp32s3_textheap.c +endif + ifeq ($(CONFIG_ESP32S3_TOUCH),y) CHIP_CSRCS += esp32s3_touch.c endif diff --git a/arch/xtensa/src/esp32s3/esp32s3_extraheaps.c b/arch/xtensa/src/esp32s3/esp32s3_extraheaps.c index 539cfaa402..48688a6d70 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_extraheaps.c +++ b/arch/xtensa/src/esp32s3/esp32s3_extraheaps.c @@ -25,6 +25,10 @@ #include #include +#ifdef CONFIG_ESP32S3_RTC_HEAP +# include "esp32s3_rtcheap.h" +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -42,5 +46,10 @@ void up_extraheaps_init(void) #ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP xtensa_imm_initialize(); #endif +#ifdef CONFIG_ESP32S3_RTC_HEAP + /* Initialize the RTC heap */ + + esp32s3_rtcheap_initialize(); +#endif } diff --git a/arch/xtensa/src/esp32s3/esp32s3_imm.c b/arch/xtensa/src/esp32s3/esp32s3_imm.c index e1e432670c..c8ed901c84 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_imm.c +++ b/arch/xtensa/src/esp32s3/esp32s3_imm.c @@ -79,7 +79,7 @@ void xtensa_imm_initialize(void) * size - Size (in bytes) of the memory region to be allocated. * * Return Value: - * Adress of the allocated memory space. NULL, if allocation fails. + * Address of the allocated memory space. NULL, if allocation fails. * ****************************************************************************/ @@ -100,7 +100,7 @@ void *xtensa_imm_malloc(size_t size) * elem_size - Size (in bytes) of the type to be allocated. * * Return Value: - * Adress of the allocated memory space. NULL, if allocation fails. + * Address of the allocated memory space. NULL, if allocation fails. * ****************************************************************************/ @@ -116,11 +116,11 @@ void *xtensa_imm_calloc(size_t n, size_t elem_size) * Reallocate memory from the internal heap. * * Input Parameters: - * ptr - Adress to be reallocate. - * size - Size (in bytes) to be reallocate. + * ptr - Address to be reallocated. + * size - Size (in bytes) to be reallocated. * * Return Value: - * Adress of the possibly moved memory space. NULL, if allocation fails. + * Address of the possibly moved memory space. NULL, if allocation fails. * ****************************************************************************/ @@ -139,7 +139,7 @@ void *xtensa_imm_realloc(void *ptr, size_t size) * size - Size (in bytes) of the memory region to be allocated. * * Return Value: - * Adress of the allocated memory space. NULL, if allocation fails. + * Address of the allocated memory space. NULL, if allocation fails. * ****************************************************************************/ @@ -155,7 +155,7 @@ void *xtensa_imm_zalloc(size_t size) * Free memory from the internal heap. * * Input Parameters: - * mem - Adress to be freed. + * mem - Address to be freed. * * Returned Value: * None. @@ -180,10 +180,10 @@ void xtensa_imm_free(void *mem) * * Input Parameters: * alignment - Requested alignment. - * size - Size (in bytes) of the memory region to be allocated. + * size - Size (in bytes) of the memory region to be allocated. * * Return Value: - * Adress of the allocated adress. NULL, if allocation fails. + * Address of the allocated address. NULL, if allocation fails. * ****************************************************************************/ diff --git a/arch/xtensa/src/esp32s3/esp32s3_rtcheap.c b/arch/xtensa/src/esp32s3/esp32s3_rtcheap.c index 1fe5293a5f..87946e7344 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_rtcheap.c +++ b/arch/xtensa/src/esp32s3/esp32s3_rtcheap.c @@ -75,6 +75,9 @@ void esp32s3_rtcheap_initialize(void) * Parameters: * size - Size (in bytes) of the memory region to be allocated. * + * Return Value: + * Address of the allocated memory space. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_malloc(size_t size) @@ -86,9 +89,16 @@ void *esp32s3_rtcheap_malloc(size_t size) * Name: esp32s3_rtcheap_calloc * * Description: - * Calculates the size of the allocation and allocate memory from + * Calculates the size of the allocation and allocates memory from * the RTC heap. * + * Parameters: + * n - Size (in types) of the memory region to be allocated. + * elem_size - Size (in bytes) of the type to be allocated. + * + * Return Value: + * Address of the allocated memory space. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_calloc(size_t n, size_t elem_size) @@ -102,6 +112,13 @@ void *esp32s3_rtcheap_calloc(size_t n, size_t elem_size) * Description: * Reallocate memory from the RTC heap. * + * Parameters: + * ptr - Address to be reallocated. + * size - Size (in bytes) to be reallocated. + * + * Return Value: + * Address of the possibly moved memory space. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_realloc(void *ptr, size_t size) @@ -115,6 +132,12 @@ void *esp32s3_rtcheap_realloc(void *ptr, size_t size) * Description: * Allocate and zero memory from the RTC heap. * + * Parameters: + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Address of the allocated memory space. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_zalloc(size_t size) @@ -128,6 +151,9 @@ void *esp32s3_rtcheap_zalloc(size_t size) * Description: * Free memory from the RTC heap. * + * Parameters: + * mem - Address to be freed. + * ****************************************************************************/ void esp32s3_rtcheap_free(void *mem) @@ -150,6 +176,9 @@ void esp32s3_rtcheap_free(void *mem) * alignment - Requested alignment. * size - Size (in bytes) of the memory region to be allocated. * + * Return Value: + * Address of the allocated adddress. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_memalign(size_t alignment, size_t size) @@ -184,6 +213,9 @@ bool esp32s3_rtcheap_heapmember(void *mem) * user heap. * * Parameters: + * None. + * + * Return Value: * info - Where memory information will be copied. * ****************************************************************************/ diff --git a/arch/xtensa/src/esp32s3/esp32s3_rtcheap.h b/arch/xtensa/src/esp32s3/esp32s3_rtcheap.h index 9909f812ba..edd8d56c3c 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_rtcheap.h +++ b/arch/xtensa/src/esp32s3/esp32s3_rtcheap.h @@ -54,6 +54,9 @@ void esp32s3_rtcheap_initialize(void); * Parameters: * size - Size (in bytes) of the memory region to be allocated. * + * Return Value: + * Address of the allocated memory space. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_malloc(size_t size); @@ -62,9 +65,16 @@ void *esp32s3_rtcheap_malloc(size_t size); * Name: esp32s3_rtcheap_calloc * * Description: - * Calculates the size of the allocation and allocate memory from + * Calculates the size of the allocation and allocates memory from * the RTC heap. * + * Parameters: + * n - Size (in types) of the memory region to be allocated. + * elem_size - Size (in bytes) of the type to be allocated. + * + * Return Value: + * Address of the allocated memory space. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_calloc(size_t n, size_t elem_size); @@ -75,6 +85,13 @@ void *esp32s3_rtcheap_calloc(size_t n, size_t elem_size); * Description: * Reallocate memory from the RTC heap. * + * Parameters: + * ptr - Address to be reallocated. + * size - Size (in bytes) to be reallocated. + * + * Return Value: + * Address of the possibly moved memory space. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_realloc(void *ptr, size_t size); @@ -85,6 +102,12 @@ void *esp32s3_rtcheap_realloc(void *ptr, size_t size); * Description: * Allocate and zero memory from the RTC heap. * + * Parameters: + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Address of the allocated memory space. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_zalloc(size_t size); @@ -95,6 +118,9 @@ void *esp32s3_rtcheap_zalloc(size_t size); * Description: * Free memory from the RTC heap. * + * Parameters: + * mem - Address to be freed. + * ****************************************************************************/ void esp32s3_rtcheap_free(void *mem); @@ -110,6 +136,13 @@ void esp32s3_rtcheap_free(void *mem); * The alignment argument must be a power of two (not checked). 8-byte * alignment is guaranteed by normal malloc calls. * + * Parameters: + * alignment - Requested alignment. + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Address of the allocated adddress. NULL, if allocation fails. + * ****************************************************************************/ void *esp32s3_rtcheap_memalign(size_t alignment, size_t size); @@ -137,6 +170,12 @@ bool esp32s3_rtcheap_heapmember(void *mem); * mallinfo returns a copy of updated current heap information for the * user heap. * + * Parameters: + * None. + * + * Return Value: + * info - Where memory information will be copied. + * ****************************************************************************/ struct mallinfo esp32s3_rtcheap_mallinfo(void); diff --git a/arch/xtensa/src/esp32s3/esp32s3_textheap.c b/arch/xtensa/src/esp32s3/esp32s3_textheap.c new file mode 100644 index 0000000000..d6d1907fcc --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_textheap.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_textheap.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 +#include +#include +#include + +#include +#include +#include + +#include "hardware/esp32s3_soc.h" + +#ifdef CONFIG_ESP32S3_RTC_HEAP +# include "esp32s3_rtcheap.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_ESP32S3_RTC_HEAP +#error "No suitable heap available. Enable ESP32S3_RTC_HEAP." +#endif + +#define D_I_BUS_OFFSET 0x700000 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_textheap_memalign + * + * Description: + * memalign requests more than enough space from malloc, finds a region + * within that chunk that meets the alignment request and then frees any + * leading or trailing space in text heap. + * + * The alignment argument must be a power of two (not checked). 8-byte + * alignment is guaranteed by normal malloc calls. + * + * Parameters: + * align - Requested alignment. + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Address of the allocated address. NULL, if allocation fails. + * + ****************************************************************************/ + +void *up_textheap_memalign(size_t align, size_t size) +{ + void *ret = NULL; + + /* Prioritise allocating from RTC. If that fails, allocate from the + * main heap. + */ + +#ifdef CONFIG_ESP32S3_RTC_HEAP + ret = esp32s3_rtcheap_memalign(align, size); +#endif + + if (ret == NULL) + { + ret = kmm_memalign(align, size); + if (ret) + { + /* kmm_memalign buffer is at the Data bus offset. Adjust it so we + * can access it from the Instruction bus. + */ + + ret += D_I_BUS_OFFSET; + } + } + + return ret; +} + +/**************************************************************************** + * Name: up_textheap_free + * + * Description: + * Free memory from the text heap. + * + * Parameters: + * mem - Address to be freed. + * + ****************************************************************************/ + +void up_textheap_free(void *p) +{ + if (p) + { +#ifdef CONFIG_ESP32S3_RTC_HEAP + if (esp32s3_ptr_rtc(p)) + { + esp32s3_rtcheap_free(p); + } + else +#endif + { + p -= D_I_BUS_OFFSET; + kmm_free(p); + } + } +} + +/**************************************************************************** + * Name: up_textheap_heapmember + * + * Description: + * Check if an address lies in text heap. + * + * Parameters: + * mem - The address to check. + * + * Return Value: + * True if the address is a member of the text heap. False if not. + * + ****************************************************************************/ + +bool up_textheap_heapmember(void *p) +{ + if (p == NULL) + { + return false; + } + +#ifdef CONFIG_ESP32S3_RTC_HEAP + if (esp32s3_ptr_rtc(p)) + { + return esp32s3_rtcheap_heapmember(p); + } +#endif + + p -= D_I_BUS_OFFSET; + return kmm_heapmember(p); +} diff --git a/arch/xtensa/src/esp32s3/hardware/esp32s3_soc.h b/arch/xtensa/src/esp32s3/hardware/esp32s3_soc.h index d38ee869c6..f6337da0ec 100644 --- a/arch/xtensa/src/esp32s3/hardware/esp32s3_soc.h +++ b/arch/xtensa/src/esp32s3/hardware/esp32s3_soc.h @@ -553,6 +553,26 @@ static inline bool IRAM_ATTR esp32s3_ptr_exec(const void *p) || (ip >= SOC_RTC_IRAM_LOW && ip < SOC_RTC_IRAM_HIGH); } +/**************************************************************************** + * Name: esp32s3_ptr_rtc + * + * Description: + * Check if the buffer comes from the RTC RAM. + * + * Parameters: + * p - Address of the buffer. + * + * Return Value: + * True if given buffer comes from RTC RAM. False if not. + * + ****************************************************************************/ + +static inline bool IRAM_ATTR esp32s3_ptr_rtc(const void *p) +{ + return ((intptr_t)p >= SOC_RTC_DATA_LOW && + (intptr_t)p < SOC_RTC_DATA_HIGH); +} + #endif /* __ASSEMBLY__ */ #endif /* __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_SOC_H */ diff --git a/boards/xtensa/esp32s3/common/scripts/flat_memory.ld b/boards/xtensa/esp32s3/common/scripts/flat_memory.ld index 9a2acc1acb..0df435f650 100644 --- a/boards/xtensa/esp32s3/common/scripts/flat_memory.ld +++ b/boards/xtensa/esp32s3/common/scripts/flat_memory.ld @@ -179,3 +179,6 @@ MEMORY REGION_ALIAS("default_code_seg", irom0_0_seg); #endif /* CONFIG_ESP32S3_RUN_IRAM */ +/* Mark the end of the RTC heap (top of the RTC region) */ + +_ertcheap = 0x50001fff; diff --git a/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld b/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld index 22ebcdbcd8..ed4a6cbb34 100644 --- a/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld +++ b/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld @@ -367,4 +367,15 @@ SECTIONS . = ALIGN(4); _iram_end = ABSOLUTE(.); } >iram0_0_seg + + .rtc.data : + { + *(.rtc.data) + *(.rtc.rodata) + + /* Whatever is left from the RTC memory is used as a special heap. */ + + . = ALIGN (4); + _srtcheap = ABSOLUTE(.); + } > rtc_slow_seg } diff --git a/boards/xtensa/esp32s3/common/scripts/mcuboot_sections.ld b/boards/xtensa/esp32s3/common/scripts/mcuboot_sections.ld index fe59f59fb7..e8cbb99b23 100644 --- a/boards/xtensa/esp32s3/common/scripts/mcuboot_sections.ld +++ b/boards/xtensa/esp32s3/common/scripts/mcuboot_sections.ld @@ -333,5 +333,10 @@ SECTIONS { *(.rtc.data) *(.rtc.rodata) + + /* Whatever is left from the RTC memory is used as a special heap. */ + + . = ALIGN (4); + _srtcheap = ABSOLUTE(.); } >rtc_data_seg AT>ROM } diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/sotest/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/sotest/defconfig new file mode 100644 index 0000000000..f996774c55 --- /dev/null +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/sotest/defconfig @@ -0,0 +1,52 @@ +# +# 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_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_INTERRUPTSTACK=2048 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARDCTL_OS_SYMTAB=y +CONFIG_BOARDCTL_ROMDISK=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_ESP32S3_RTC_HEAP=y +CONFIG_ESP32S3_UART0=y +CONFIG_EXAMPLES_SOTEST=y +CONFIG_EXPERIMENTAL=y +CONFIG_FS_PROCFS=y +CONFIG_FS_ROMFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_DLFCN=y +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_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSLOG_BUFFER=y +CONFIG_SYSTEM_NSH=y +CONFIG_UART0_SERIAL_CONSOLE=y