From 77df430f301ace141cd143f032afdacd3b910dab Mon Sep 17 00:00:00 2001 From: Eren Terzioglu Date: Thu, 5 Oct 2023 14:39:36 +0300 Subject: [PATCH] xtensa/esp32s2: Add rtc heap support --- arch/xtensa/Kconfig | 1 + arch/xtensa/src/esp32s2/Kconfig | 7 + arch/xtensa/src/esp32s2/Make.defs | 12 + arch/xtensa/src/esp32s2/esp32s2_extraheaps.c | 62 ++++ arch/xtensa/src/esp32s2/esp32s2_rtcheap.c | 226 +++++++++++++ arch/xtensa/src/esp32s2/esp32s2_rtcheap.h | 188 +++++++++++ arch/xtensa/src/esp32s2/esp32s2_textheap.c | 161 +++++++++ arch/xtensa/src/esp32s2/esp32s2_user.c | 317 ------------------ .../xtensa/src/esp32s2/hardware/esp32s2_soc.h | 20 ++ .../esp32c3-devkit/configs/sotest/defconfig | 1 + .../esp32s2/common/scripts/flat_memory.ld | 4 + .../esp32s2/common/scripts/legacy_sections.ld | 5 + .../common/scripts/mcuboot_sections.ld | 5 + .../esp32s2-saola-1/configs/sotest/defconfig | 51 +++ 14 files changed, 743 insertions(+), 317 deletions(-) create mode 100644 arch/xtensa/src/esp32s2/esp32s2_extraheaps.c create mode 100644 arch/xtensa/src/esp32s2/esp32s2_rtcheap.c create mode 100644 arch/xtensa/src/esp32s2/esp32s2_rtcheap.h create mode 100644 arch/xtensa/src/esp32s2/esp32s2_textheap.c create mode 100644 boards/xtensa/esp32s2/esp32s2-saola-1/configs/sotest/defconfig diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index f18939c229..47671e8337 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -53,6 +53,7 @@ config ARCH_CHIP_ESP32S2 select XTENSA_HAVE_INTERRUPTS select ARCH_HAVE_BOOTLOADER select ARCH_HAVE_RESET + select ARCH_HAVE_TEXT_HEAP select ARCH_VECNOTIRQ select LIBC_ARCH_ATOMIC select LIBC_ARCH_MEMCPY diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig index 12e56a62eb..c0a9537d08 100644 --- a/arch/xtensa/src/esp32s2/Kconfig +++ b/arch/xtensa/src/esp32s2/Kconfig @@ -476,6 +476,13 @@ config ESP32S2_ULP_COPROC_RESERVE_MEM int "Reserved ULP co-processor DRAM" default 0 +comment "Additional Heaps" + +config ESP32S2_RTC_HEAP + bool "Use the RTC memory as a separate heap" + select ARCH_HAVE_EXTRA_HEAPS + default n + endmenu # Memory Configuration config ESP32S2_GPIO_IRQ diff --git a/arch/xtensa/src/esp32s2/Make.defs b/arch/xtensa/src/esp32s2/Make.defs index f8fb5c8e2a..2ffbc48385 100644 --- a/arch/xtensa/src/esp32s2/Make.defs +++ b/arch/xtensa/src/esp32s2/Make.defs @@ -98,6 +98,18 @@ ifeq ($(CONFIG_WATCHDOG),y) CHIP_CSRCS += esp32s2_wdt_lowerhalf.c endif +ifeq ($(CONFIG_ARCH_HAVE_EXTRA_HEAPS),y) +CHIP_CSRCS += esp32s2_extraheaps.c +endif + +ifeq ($(CONFIG_ESP32S2_RTC_HEAP),y) +CHIP_CSRCS += esp32s2_rtcheap.c +endif + +ifeq ($(CONFIG_ARCH_USE_TEXT_HEAP),y) +CHIP_CSRCS += esp32s2_textheap.c +endif + ifeq ($(CONFIG_ESP32S2_FREERUN),y) CHIP_CSRCS += esp32s2_freerun.c endif diff --git a/arch/xtensa/src/esp32s2/esp32s2_extraheaps.c b/arch/xtensa/src/esp32s2/esp32s2_extraheaps.c new file mode 100644 index 0000000000..0fcb8f7801 --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_extraheaps.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_extraheaps.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 + +#include "hardware/esp32s2_soc.h" + +#ifdef CONFIG_ESP32S2_RTC_HEAP +#include "esp32s2_rtcheap.h" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_extraheaps_init + * + * Description: + * Initialize any extra heap. + * + ****************************************************************************/ + +void up_extraheaps_init() +{ +#ifdef CONFIG_ESP32S2_RTC_HEAP + /* Initialize the RTC heap */ + + esp32s2_rtcheap_initialize(); +#endif +} + diff --git a/arch/xtensa/src/esp32s2/esp32s2_rtcheap.c b/arch/xtensa/src/esp32s2/esp32s2_rtcheap.c new file mode 100644 index 0000000000..947aaa32bb --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_rtcheap.c @@ -0,0 +1,226 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_rtcheap.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 "esp32s2_rtcheap.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct mm_heap_s *g_rtcheap; + +/**************************************************************************** + * Extern values declaration + ****************************************************************************/ + +/* These values come from the linker scripts. Check boards/xtensa/esp32s2. */ + +extern uint8_t _srtcheap[]; +extern uint8_t _ertcheap[]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s2_rtcheap_initialize + * + * Description: + * Initialize the RTC heap. + * + ****************************************************************************/ + +void esp32s2_rtcheap_initialize(void) +{ + void *start; + size_t size; + + start = (void *)_srtcheap; + size = _ertcheap - _srtcheap; + g_rtcheap = mm_initialize("rtcheap", start, size); +} + +/**************************************************************************** + * Name: esp32s2_rtcheap_malloc + * + * Description: + * Allocate memory from the RTC heap. + * + * Parameters: + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Adress of the allocated memory space. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_malloc(size_t size) +{ + return mm_malloc(g_rtcheap, size); +} + +/**************************************************************************** + * Name: esp32s2_rtcheap_calloc + * + * Description: + * Calculates the size of the allocation and allocate 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: + * Adress of the allocated memory space. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_calloc(size_t n, size_t elem_size) +{ + return mm_calloc(g_rtcheap, n, elem_size); +} + +/**************************************************************************** + * Name: esp32s2_rtcheap_realloc + * + * Description: + * Reallocate memory from the RTC heap. + * + * Parameters: + * ptr - Adress to be reallocate. + * size - Size (in bytes) to be reallocate. + * + * Return Value: + * Adress of the possibly moved memory space. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_realloc(void *ptr, size_t size) +{ + return mm_realloc(g_rtcheap, ptr, size); +} + +/**************************************************************************** + * Name: esp32s2_rtcheap_zalloc + * + * Description: + * Allocate and zero memory from the RTC heap. + * + * Parameters: + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Adress of the allocated memory space. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_zalloc(size_t size) +{ + return mm_zalloc(g_rtcheap, size); +} + +/**************************************************************************** + * Name: esp32s2_rtcheap_free + * + * Description: + * Free memory from the RTC heap. + * + * Parameters: + * mem - Adress to be freed. + * + ****************************************************************************/ + +void esp32s2_rtcheap_free(void *mem) +{ + mm_free(g_rtcheap, mem); +} + +/**************************************************************************** + * Name: esp32s2_rtcheap_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. + * + * 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: + * Adress of the allocated adress. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_memalign(size_t alignment, size_t size) +{ + return mm_memalign(g_rtcheap, alignment, size); +} + +/**************************************************************************** + * Name: esp32s2_rtcheap_heapmember + * + * Description: + * Check if an address lies in the RTC heap. + * + * Parameters: + * mem - The address to check. + * + * Return Value: + * True if the address is a member of the RTC heap. False if not. + * + ****************************************************************************/ + +bool esp32s2_rtcheap_heapmember(void *mem) +{ + return mm_heapmember(g_rtcheap, mem); +} + +/**************************************************************************** + * Name: esp32s2_rtcheap_mallinfo + * + * Description: + * 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 esp32s2_rtcheap_mallinfo(void) +{ + return mm_mallinfo(g_rtcheap); +} diff --git a/arch/xtensa/src/esp32s2/esp32s2_rtcheap.h b/arch/xtensa/src/esp32s2/esp32s2_rtcheap.h new file mode 100644 index 0000000000..fce10cac63 --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_rtcheap.h @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_rtcheap.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_RTCHEAP_H +#define __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_RTCHEAP_H + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +struct mallinfo; /* Forward reference, see malloc.h */ + +/**************************************************************************** + * Name: esp32s2_rtcheap_initialize + * + * Description: + * Initialize the RTC heap. + * + ****************************************************************************/ + +void esp32s2_rtcheap_initialize(void); + +/**************************************************************************** + * Name: esp32s2_rtcheap_malloc + * + * Description: + * Allocate memory from the RTC heap. + * + * Parameters: + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Adress of the allocated memory space. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_malloc(size_t size); + +/**************************************************************************** + * Name: esp32s2_rtcheap_calloc + * + * Description: + * Calculates the size of the allocation and allocate 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: + * Adress of the allocated memory space. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_calloc(size_t n, size_t elem_size); + +/**************************************************************************** + * Name: esp32s2_rtcheap_realloc + * + * Description: + * Reallocate memory from the RTC heap. + * + * Parameters: + * ptr - Adress to be reallocate. + * size - Size (in bytes) to be reallocate. + * + * Return Value: + * Adress of the possibly moved memory space. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_realloc(void *ptr, size_t size); + +/**************************************************************************** + * Name: esp32s2_rtcheap_zalloc + * + * Description: + * Allocate and zero memory from the RTC heap. + * + * Parameters: + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Adress of the allocated memory space. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_zalloc(size_t size); + +/**************************************************************************** + * Name: esp32s2_rtcheap_free + * + * Description: + * Free memory from the RTC heap. + * + * Parameters: + * mem - Adress to be freed. + * + ****************************************************************************/ + +void esp32s2_rtcheap_free(void *mem); + +/**************************************************************************** + * Name: esp32s2_rtcheap_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. + * + * 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: + * Adress of the allocated adress. NULL, if allocation fails. + * + ****************************************************************************/ + +void *esp32s2_rtcheap_memalign(size_t alignment, size_t size); + +/**************************************************************************** + * Name: esp32s2_rtcheap_heapmember + * + * Description: + * Check if an address lies in the RTC heap. + * + * Parameters: + * mem - The address to check. + * + * Return Value: + * True if the address is a member of the RTC heap. False if not. + * + ****************************************************************************/ + +bool esp32s2_rtcheap_heapmember(void *mem); + +/**************************************************************************** + * Name: esp32s2_rtcheap_mallinfo + * + * Description: + * 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 esp32s2_rtcheap_mallinfo(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_RTCHEAP_H */ diff --git a/arch/xtensa/src/esp32s2/esp32s2_textheap.c b/arch/xtensa/src/esp32s2/esp32s2_textheap.c new file mode 100644 index 0000000000..d98e4c06a7 --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_textheap.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_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/esp32s2_soc.h" + +#ifdef CONFIG_ESP32S2_RTC_HEAP +#include "esp32s2_rtcheap.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_ESP32S2_RTC_HEAP +#error "No suitable heap available. Enable ESP32S2_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: + * alignment - Requested alignment. + * size - Size (in bytes) of the memory region to be allocated. + * + * Return Value: + * Adress of the allocated adress. 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_ESP32S2_RTC_HEAP + ret = esp32s2_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 - Adress to be freed. + * + ****************************************************************************/ + +void up_textheap_free(void *p) +{ + if (p) + { +#ifdef CONFIG_ESP32S2_RTC_HEAP + if (esp32s2_ptr_rtc(p)) + { + esp32s2_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_ESP32S2_RTC_HEAP + if (esp32s2_ptr_rtc(p)) + { + return esp32s2_rtcheap_heapmember(p); + } +#endif + + p -= D_I_BUS_OFFSET; + return kmm_heapmember(p); +} diff --git a/arch/xtensa/src/esp32s2/esp32s2_user.c b/arch/xtensa/src/esp32s2/esp32s2_user.c index db6f9cb87e..fa6debd85b 100644 --- a/arch/xtensa/src/esp32s2/esp32s2_user.c +++ b/arch/xtensa/src/esp32s2/esp32s2_user.c @@ -38,11 +38,6 @@ * Public Data ****************************************************************************/ -#ifdef CONFIG_ARCH_USE_TEXT_HEAP -extern char _stextheap[]; -extern char _etextheap[]; -#endif - /**************************************************************************** * Private Data ****************************************************************************/ @@ -58,225 +53,6 @@ extern char _etextheap[]; #ifndef CONFIG_BUILD_FLAT #error permission check not implemented #endif - -/**************************************************************************** - * Name: load_uint8 - * - * Description: - * Fetch a byte using 32-bit aligned access. - * - ****************************************************************************/ - -static uint8_t load_uint8(const uint8_t *p) -{ - const uint32_t *aligned; - uint32_t value; - unsigned int offset; - - aligned = (const uint32_t *)(((uintptr_t)p) & ~3); - value = l32i(aligned); - offset = ((uintptr_t)p) & 3; - switch (offset) - { - case 0: - return value & 0xff; - case 1: - return (value >> 8) & 0xff; - case 2: - return (value >> 16) & 0xff; - case 3: - return (value >> 24) & 0xff; - } - - /* not reached */ - - PANIC(); -} - -/**************************************************************************** - * Name: store_uint8 - * - * Description: - * Store a byte using 32-bit aligned access. - * - ****************************************************************************/ - -static void store_uint8(uint8_t *p, uint8_t v) -{ - uint32_t *aligned; - uint32_t value; - unsigned int offset; - - aligned = (uint32_t *)(((uintptr_t)p) & ~3); - value = l32i(aligned); - offset = ((uintptr_t)p) & 3; - switch (offset) - { - case 0: - value = (value & 0xffffff00) | v; - break; - case 1: - value = (value & 0xffff00ff) | (v << 8); - break; - case 2: - value = (value & 0xff00ffff) | (v << 16); - break; - case 3: - value = (value & 0x00ffffff) | (v << 24); - break; - } - - s32i(aligned, value); -} - -/**************************************************************************** - * Name: decode_s8i - * - * Description: - * Decode S8I instruction using 32-bit aligned access. - * Return non-zero on successful decoding. - * - ****************************************************************************/ - -static int decode_s8i(const uint8_t *p, uint8_t *imm8, uint8_t *s, - uint8_t *t) -{ - /* 23 16 15 12 11 8 7 4 3 0 - * | imm8 |0 1 0 0| s | t |0 0 1 0| - */ - - uint8_t b0 = load_uint8(p); - uint8_t b1 = load_uint8(p + 1); - - if ((b0 & 0xf) == 2 && (b1 & 0xf0) == 0x40) - { - *t = b0 >> 4; - *s = b1 & 0xf; - *imm8 = load_uint8(p + 2); - return 1; - } - - return 0; -} - -/**************************************************************************** - * Name: decode_s16i - * - * Description: - * Decode S16I instruction using 32-bit aligned access. - * Return non-zero on successful decoding. - * - ****************************************************************************/ - -static int decode_s16i(const uint8_t *p, uint8_t *imm8, uint8_t *s, - uint8_t *t) -{ - /* 23 16 15 12 11 8 7 4 3 0 - * | imm8 |0 1 0 1| s | t |0 0 1 0| - */ - - uint8_t b0 = load_uint8(p); - uint8_t b1 = load_uint8(p + 1); - - if ((b0 & 0xf) == 2 && (b1 & 0xf0) == 0x50) - { - *t = b0 >> 4; - *s = b1 & 0xf; - *imm8 = load_uint8(p + 2); - return 1; - } - - return 0; -} - -/**************************************************************************** - * Name: decode_l8ui - * - * Description: - * Decode L8UI instruction using 32-bit aligned access. - * Return non-zero on successful decoding. - * - ****************************************************************************/ - -static int decode_l8ui(const uint8_t *p, uint8_t *imm8, uint8_t *s, - uint8_t *t) -{ - /* 23 16 15 12 11 8 7 4 3 0 - * | imm8 |0 0 0 0| s | t |0 0 1 0| - */ - - uint8_t b0 = load_uint8(p); - uint8_t b1 = load_uint8(p + 1); - - if ((b0 & 0xf) == 2 && (b1 & 0xf0) == 0) - { - *t = b0 >> 4; - *s = b1 & 0xf; - *imm8 = load_uint8(p + 2); - return 1; - } - - return 0; -} - -/**************************************************************************** - * Name: decode_l16ui - * - * Description: - * Decode L16UI instruction using 32-bit aligned access. - * Return non-zero on successful decoding. - * - ****************************************************************************/ - -static int decode_l16ui(const uint8_t *p, uint8_t *imm8, uint8_t *s, - uint8_t *t) -{ - /* 23 16 15 12 11 8 7 4 3 0 - * | imm8 |0 0 0 1| s | t |0 0 1 0| - */ - - uint8_t b0 = load_uint8(p); - uint8_t b1 = load_uint8(p + 1); - - if ((b0 & 0xf) == 2 && (b1 & 0xf0) == 0x10) - { - *t = b0 >> 4; - *s = b1 & 0xf; - *imm8 = load_uint8(p + 2); - return 1; - } - - return 0; -} - -/**************************************************************************** - * Name: advance_pc - * - * Description: - * Advance PC register by the given value. - * - ****************************************************************************/ - -static void advance_pc(uint32_t *regs, int diff) -{ - uint32_t nextpc; - - /* Advance to the next instruction. */ - - nextpc = regs[REG_PC] + diff; -#if XCHAL_HAVE_LOOPS - /* See Xtensa ISA 4.3.2.4 Loopback Semantics */ - - if (regs[REG_LCOUNT] != 0 && nextpc == regs[REG_LEND]) - { - regs[REG_LCOUNT]--; - nextpc = regs[REG_LBEG]; - } - -#endif - regs[REG_PC] = nextpc; -} - #endif /**************************************************************************** @@ -293,99 +69,6 @@ static void advance_pc(uint32_t *regs, int diff) uint32_t *xtensa_user(int exccause, uint32_t *regs) { -#ifdef CONFIG_ARCH_USE_TEXT_HEAP - /* Emulate byte access for module text. - * - * ESP32S2 only allows word-aligned accesses to the instruction memory - * regions. A non-aligned access raises a LoadStoreErrorCause exception. - * We catch those exception and emulate byte access here because it's - * necessary in a few places during dynamic code loading: - * - * - memcpy as a part of read(2) when loading code from a file system. - * - relocation needs to inspect and modify text. - * - * (thus binfo() is used below) - */ - - if (exccause == EXCCAUSE_LOAD_STORE_ERROR && - (uintptr_t)_stextheap <= regs[REG_EXCVADDR] && - (uintptr_t)_etextheap > regs[REG_EXCVADDR]) - { - uint8_t *pc = (uint8_t *)regs[REG_PC]; - uint8_t imm8; - uint8_t s; - uint8_t t; - - binfo("EXCCAUSE_LOAD_STORE_ERROR at %p, pc=%p\n", - (void *)regs[REG_EXCVADDR], - pc); - - if (decode_s8i(pc, &imm8, &s, &t)) - { - binfo("Emulating S8I imm8=%u, s=%u (%p), t=%u (%p)\n", - (unsigned int)imm8, - (unsigned int)s, - (void *)regs[REG_A0 + s], - (unsigned int)t, - (void *)regs[REG_A0 + t]); - - DEBUGASSERT(regs[REG_A0 + s] + imm8 == regs[REG_EXCVADDR]); - store_uint8(((uint8_t *)regs[REG_A0 + s]) + imm8, - regs[REG_A0 + t]); - advance_pc(regs, 3); - return regs; - } - else if (decode_s16i(pc, &imm8, &s, &t)) - { - binfo("Emulating S16I imm8=%u, s=%u (%p), t=%u (%p)\n", - (unsigned int)imm8, - (unsigned int)s, - (void *)regs[REG_A0 + s], - (unsigned int)t, - (void *)regs[REG_A0 + t]); - - DEBUGASSERT(regs[REG_A0 + s] + imm8 == regs[REG_EXCVADDR]); - store_uint8(((uint8_t *)regs[REG_A0 + s]) + imm8, - regs[REG_A0 + t]); - store_uint8(((uint8_t *)regs[REG_A0 + s]) + imm8 + 1, - regs[REG_A0 + t] >> 8); - advance_pc(regs, 3); - return regs; - } - else if (decode_l8ui(pc, &imm8, &s, &t)) - { - binfo("Emulating L8UI imm8=%u, s=%u (%p), t=%u (%p)\n", - (unsigned int)imm8, - (unsigned int)s, - (void *)regs[REG_A0 + s], - (unsigned int)t, - (void *)regs[REG_A0 + t]); - - DEBUGASSERT(regs[REG_A0 + s] + imm8 == regs[REG_EXCVADDR]); - regs[REG_A0 + t] = load_uint8(((uint8_t *)regs[REG_A0 + s]) + - imm8); - advance_pc(regs, 3); - return regs; - } - else if (decode_l16ui(pc, &imm8, &s, &t)) - { - binfo("Emulating L16UI imm8=%u, s=%u (%p), t=%u (%p)\n", - (unsigned int)imm8, - (unsigned int)s, - (void *)regs[REG_A0 + s], - (unsigned int)t, - (void *)regs[REG_A0 + t]); - - DEBUGASSERT(regs[REG_A0 + s] + imm8 == regs[REG_EXCVADDR]); - uint8_t lo = load_uint8(((uint8_t *)regs[REG_A0 + s]) + imm8); - uint8_t hi = load_uint8(((uint8_t *)regs[REG_A0 + s]) + imm8 + 1); - regs[REG_A0 + t] = (hi << 8) | lo; - advance_pc(regs, 3); - return regs; - } - } - -#endif /* xtensa_user_panic never returns. */ xtensa_user_panic(exccause, regs); diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h index c68b45f741..aa0c30cd1f 100644 --- a/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h +++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h @@ -759,4 +759,24 @@ static inline bool IRAM_ATTR esp32s2_ptr_exec(const void *p) || (ip >= SOC_RTC_IRAM_LOW && ip < SOC_RTC_IRAM_HIGH); } +/**************************************************************************** + * Name: esp32s2_ptr_rtc + * + * Description: + * Check if the buffer comes from the RTC RAM. + * + * Parameters: + * p - Adress of the buffer. + * + * Return Value: + * True if given buffer comes from RTC RAM. False if not. + * + ****************************************************************************/ + +static inline bool IRAM_ATTR esp32s2_ptr_rtc(const void *p) +{ + return ((intptr_t)p >= SOC_RTC_DATA_LOW && + (intptr_t)p < SOC_RTC_DATA_HIGH); +} + #endif /* __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32S2_SOC_H */ diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/sotest/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/sotest/defconfig index b39d2ffa69..f0aa1d1934 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/sotest/defconfig +++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/sotest/defconfig @@ -21,6 +21,7 @@ CONFIG_BOARDCTL_OS_SYMTAB=y CONFIG_BOARDCTL_ROMDISK=y CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BUILTIN=y +CONFIG_ESP32C3_RTC_HEAP=y CONFIG_EXAMPLES_SOTEST=y CONFIG_FS_PROCFS=y CONFIG_FS_ROMFS=y diff --git a/boards/xtensa/esp32s2/common/scripts/flat_memory.ld b/boards/xtensa/esp32s2/common/scripts/flat_memory.ld index 24e5fe3b54..a4fde38598 100644 --- a/boards/xtensa/esp32s2/common/scripts/flat_memory.ld +++ b/boards/xtensa/esp32s2/common/scripts/flat_memory.ld @@ -157,3 +157,7 @@ MEMORY REGION_ALIAS("default_rodata_seg", drom0_0_seg); REGION_ALIAS("default_code_seg", irom0_0_seg); #endif /* CONFIG_ESP32S2_RUN_IRAM */ + +/* Mark the end of the RTC heap (top of the RTC region) */ + +_ertcheap = 0x50001fff; diff --git a/boards/xtensa/esp32s2/common/scripts/legacy_sections.ld b/boards/xtensa/esp32s2/common/scripts/legacy_sections.ld index f0b7e97244..9e77a98763 100644 --- a/boards/xtensa/esp32s2/common/scripts/legacy_sections.ld +++ b/boards/xtensa/esp32s2/common/scripts/legacy_sections.ld @@ -226,5 +226,10 @@ SECTIONS { *(.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/esp32s2/common/scripts/mcuboot_sections.ld b/boards/xtensa/esp32s2/common/scripts/mcuboot_sections.ld index 0af713f173..dfc0790ff3 100644 --- a/boards/xtensa/esp32s2/common/scripts/mcuboot_sections.ld +++ b/boards/xtensa/esp32s2/common/scripts/mcuboot_sections.ld @@ -313,5 +313,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/esp32s2/esp32s2-saola-1/configs/sotest/defconfig b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/sotest/defconfig new file mode 100644 index 0000000000..9ebdb60fd6 --- /dev/null +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/sotest/defconfig @@ -0,0 +1,51 @@ +# +# 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="esp32s2-saola-1" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32S2_SAOLA_1=y +CONFIG_ARCH_CHIP="esp32s2" +CONFIG_ARCH_CHIP_ESP32S2=y +CONFIG_ARCH_CHIP_ESP32S2WROVER=y +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_ESP32S2_RTC_HEAP=y +CONFIG_ESP32S2_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