From 1aac284dda6d6996f062e3ec37e7aebb2fca3ca1 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Sat, 18 Apr 2020 23:56:34 +0530 Subject: [PATCH 1/3] heap: add rtc fast memory region to dynamic pool - for ESP32 only enabled in case of unicore config - capability wise this region (8K) is same as DRAM, except non-DMA capable - also fixed small issue in reserved memory region processing when (start == end) --- components/esp32/Kconfig | 12 ++++++++++++ components/esp32s2/Kconfig | 10 ++++++++++ components/soc/include/soc/soc_memory_layout.h | 12 ++++++++++++ components/soc/src/esp32/soc_memory_layout.c | 17 ++++++++++++++--- components/soc/src/esp32s2/soc_memory_layout.c | 16 +++++++++++++++- components/soc/src/memory_layout_utils.c | 2 +- 6 files changed, 64 insertions(+), 5 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index f975dee8e..92081e35f 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -739,6 +739,18 @@ menu "ESP32-specific" This is possible due to handling of exceptions `LoadStoreError (3)` and `LoadStoreAlignmentError (9)` Each unaligned read/write access will incur a penalty of maximum of 167 CPU cycles. + config ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP + bool "Enable RTC fast memory for dynamic allocations" + default y + depends on FREERTOS_UNICORE + help + This config option allows to add RTC fast memory region to system heap with capability + similar to that of DRAM region but without DMA. This memory will be consumed first per + heap initialization order by early startup services and scheduler related code. Speed + wise RTC fast memory operates on APB clock and hence does not have much performance impact. + RTC fast memory is accessible to PRO cpu only and hence this is allowed for single core + configuration only for ESP32. + endmenu # ESP32-Specific menu "Power Management" diff --git a/components/esp32s2/Kconfig b/components/esp32s2/Kconfig index 7cd35a1e9..a4b5392cf 100644 --- a/components/esp32s2/Kconfig +++ b/components/esp32s2/Kconfig @@ -498,6 +498,16 @@ menu "ESP32S2-specific" If enabled, this disables the linking of binary libraries in the application build. Note that after enabling this Wi-Fi/Bluetooth will not work. + config ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP + bool "Enable RTC fast memory for dynamic allocations" + depends on !ESP32S2_MEMPROT_FEATURE + default y + help + This config option allows to add RTC fast memory region to system heap with capability + similar to that of DRAM region but without DMA. This memory will be consumed first per + heap initialization order by early startup services and scheduler related code. Speed + wise RTC fast memory operates on APB clock and hence does not have much performance impact. + endmenu # ESP32S2-Specific menu "Power Management" diff --git a/components/soc/include/soc/soc_memory_layout.h b/components/soc/include/soc/soc_memory_layout.h index d88d356a1..00f69aecc 100644 --- a/components/soc/include/soc/soc_memory_layout.h +++ b/components/soc/include/soc/soc_memory_layout.h @@ -176,6 +176,12 @@ inline static bool IRAM_ATTR esp_ptr_byte_accessible(const void *p) intptr_t ip = (intptr_t) p; bool r; r = (ip >= SOC_BYTE_ACCESSIBLE_LOW && ip < SOC_BYTE_ACCESSIBLE_HIGH); +#if CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP + /* For ESP32 case, RTC fast memory is accessible to PRO cpu only and hence + * for single core configuration (where it gets added to system heap) following + * additional check is required */ + r |= (ip >= SOC_RTC_DRAM_LOW && ip < SOC_RTC_DRAM_HIGH); +#endif #if CONFIG_SPIRAM #if CONFIG_SPIRAM_SIZE != -1 // Fixed size, can be more accurate r |= (ip >= SOC_EXTRAM_DATA_LOW && ip < (SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE)); @@ -190,6 +196,12 @@ inline static bool IRAM_ATTR esp_ptr_internal(const void *p) { bool r; r = ((intptr_t)p >= SOC_MEM_INTERNAL_LOW && (intptr_t)p < SOC_MEM_INTERNAL_HIGH); r |= ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH); +#if CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP + /* For ESP32 case, RTC fast memory is accessible to PRO cpu only and hence + * for single core configuration (where it gets added to system heap) following + * additional check is required */ + r |= ((intptr_t)p >= SOC_RTC_DRAM_LOW && (intptr_t)p < SOC_RTC_DRAM_HIGH); +#endif return r; } diff --git a/components/soc/src/esp32/soc_memory_layout.c b/components/soc/src/esp32/soc_memory_layout.c index 47494d404..2b85731f9 100644 --- a/components/soc/src/esp32/soc_memory_layout.c +++ b/components/soc/src/esp32/soc_memory_layout.c @@ -66,10 +66,10 @@ const soc_memory_type_desc_t soc_memory_types[] = { { "PID5DRAM", { MALLOC_CAP_PID5|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false}, { "PID6DRAM", { MALLOC_CAP_PID6|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false}, { "PID7DRAM", { MALLOC_CAP_PID7|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false}, -#ifdef CONFIG_SPIRAM //Type 15: SPI SRAM data { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false}, -#endif + //Type 16: RTC Fast RAM + { "RTCRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT, 0 }, false, false}, }; const size_t soc_memory_type_count = sizeof(soc_memory_types)/sizeof(soc_memory_type_desc_t); @@ -88,6 +88,9 @@ Because of requirements in the coalescing code which merges adjacent regions, th from low to high start address. */ const soc_memory_region_t soc_memory_regions[] = { +#ifdef CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP + { SOC_RTC_DRAM_LOW, 0x2000, 16, 0}, //RTC Fast Memory +#endif #ifdef CONFIG_SPIRAM { SOC_EXTRAM_DATA_LOW, RESERVE_SPIRAM_SIZE, 15, 0}, //SPI SRAM, if available #endif @@ -183,7 +186,7 @@ SOC_RESERVE_MEMORY_REGION(0x3fffc000, 0x40000000, trace_mem); //Reserve trace me SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_LOW + RESERVE_SPIRAM_SIZE, spi_ram); //SPI RAM gets added later if needed, in spiram.c; reserve it for now #endif -extern int _data_start, _heap_start, _iram_start, _iram_end; +extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end; // Static data region. DRAM used by data+bss and possibly rodata SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data); @@ -191,5 +194,13 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d // ESP32 has an IRAM-only region 0x4008_0000 - 0x4009_FFFF, reserve the used part SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); +// RTC Fast RAM region +#ifdef CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP +#ifdef CONFIG_ESP32_RTCDATA_IN_FAST_MEM +SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data); +#else +SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data); +#endif +#endif #endif /* BOOTLOADER_BUILD */ diff --git a/components/soc/src/esp32s2/soc_memory_layout.c b/components/soc/src/esp32s2/soc_memory_layout.c index fe1fc6c02..8bcd0ae23 100644 --- a/components/soc/src/esp32s2/soc_memory_layout.c +++ b/components/soc/src/esp32s2/soc_memory_layout.c @@ -51,6 +51,8 @@ const soc_memory_type_desc_t soc_memory_types[] = { //Type 4: SPI SRAM data //TODO, in fact, part of them support EDMA, to be supported. { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false}, + //Type 5: RTC Fast RAM + { "RTCRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT, 0 }, false, false}, }; #ifdef CONFIG_ESP32S2_MEMPROT_FEATURE @@ -68,6 +70,9 @@ Because of requirements in the coalescing code which merges adjacent regions, th from low to high start address. */ const soc_memory_region_t soc_memory_regions[] = { +#ifdef CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP + { SOC_RTC_DRAM_LOW, 0x2000, 5, 0}, //RTC Fast Memory +#endif #ifdef CONFIG_SPIRAM { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW, 4, 0}, //SPI SRAM, if available #endif @@ -115,7 +120,7 @@ const size_t soc_memory_region_count = sizeof(soc_memory_regions)/sizeof(soc_mem extern int _dram0_rtos_reserved_start; -extern int _data_start, _heap_start, _iram_start, _iram_end; +extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end; /* Reserved memory regions @@ -141,4 +146,13 @@ SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_dat SOC_RESERVE_MEMORY_REGION(0x3fffc000 - CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM, 0x3fffc000, trace_mem); #endif +// RTC Fast RAM region +#ifdef CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP +#ifdef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM +SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data); +#else +SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data); +#endif +#endif + #endif // BOOTLOADER_BUILD diff --git a/components/soc/src/memory_layout_utils.c b/components/soc/src/memory_layout_utils.c index 969dcf587..1f9a49ed6 100644 --- a/components/soc/src/memory_layout_utils.c +++ b/components/soc/src/memory_layout_utils.c @@ -68,7 +68,7 @@ static void s_prepare_reserved_regions(soc_reserved_region_t *reserved, size_t c reserved[i].start, reserved[i].end); reserved[i].start = reserved[i].start & ~3; /* expand all reserved areas to word boundaries */ reserved[i].end = (reserved[i].end + 3) & ~3; - assert(reserved[i].start < reserved[i].end); + assert(reserved[i].start <= reserved[i].end); if (i < count - 1) { assert(reserved[i + 1].start > reserved[i].start); if (reserved[i].end > reserved[i + 1].start) { From 18c183858751d03984f247065a2f71d25df687ae Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Sun, 19 Apr 2020 11:49:44 +0530 Subject: [PATCH 2/3] esp32s2: add config option to place RTC data in fast RAM --- components/esp32s2/Kconfig | 7 +++++++ components/esp32s2/ld/esp32s2.ld | 2 +- components/esp32s2/ld/esp32s2.project.ld.in | 4 ++-- tools/unit-test-app/configs/single_core_2_s2 | 2 +- tools/unit-test-app/configs/single_core_s2 | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/components/esp32s2/Kconfig b/components/esp32s2/Kconfig index a4b5392cf..c9e4b6017 100644 --- a/components/esp32s2/Kconfig +++ b/components/esp32s2/Kconfig @@ -498,6 +498,13 @@ menu "ESP32S2-specific" If enabled, this disables the linking of binary libraries in the application build. Note that after enabling this Wi-Fi/Bluetooth will not work. + config ESP32S2_RTCDATA_IN_FAST_MEM + bool "Place RTC_DATA_ATTR and RTC_RODATA_ATTR variables into RTC fast memory segment" + default n + help + This option allows to place .rtc_data and .rtc_rodata sections into + RTC fast memory segment to free the slow memory region for ULP programs. + config ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP bool "Enable RTC fast memory for dynamic allocations" depends on !ESP32S2_MEMPROT_FEATURE diff --git a/components/esp32s2/ld/esp32s2.ld b/components/esp32s2/ld/esp32s2.ld index b742f3336..9d3abd3ea 100644 --- a/components/esp32s2/ld/esp32s2.ld +++ b/components/esp32s2/ld/esp32s2.ld @@ -96,7 +96,7 @@ _data_seg_org = ORIGIN(rtc_data_seg); When the option is not defined then use slow memory segment else the data will be placed in fast memory segment TODO: check whether the rtc_data_location is correct for esp32s2 - IDF-761 */ -#ifndef CONFIG_ESP32_RTCDATA_IN_FAST_MEM +#ifndef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM REGION_ALIAS("rtc_data_location", rtc_slow_seg ); #else REGION_ALIAS("rtc_data_location", rtc_data_seg ); diff --git a/components/esp32s2/ld/esp32s2.project.ld.in b/components/esp32s2/ld/esp32s2.project.ld.in index a619b1add..b7df21c44 100644 --- a/components/esp32s2/ld/esp32s2.project.ld.in +++ b/components/esp32s2/ld/esp32s2.project.ld.in @@ -46,7 +46,7 @@ SECTIONS named rtc_wake_stub*.c and the data marked with RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. The memory location of the data is dependent on - CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. + CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option. */ .rtc.data : { @@ -75,7 +75,7 @@ SECTIONS User data marked with RTC_NOINIT_ATTR will be placed into this section. See the file "esp_attr.h" for more information. The memory location of the data is dependent on - CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. + CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option. */ .rtc_noinit (NOLOAD): { diff --git a/tools/unit-test-app/configs/single_core_2_s2 b/tools/unit-test-app/configs/single_core_2_s2 index bb52032af..ca0a8ee64 100644 --- a/tools/unit-test-app/configs/single_core_2_s2 +++ b/tools/unit-test-app/configs/single_core_2_s2 @@ -3,4 +3,4 @@ CONFIG_IDF_TARGET="esp32s2" TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs CONFIG_MEMMAP_SMP=n CONFIG_FREERTOS_UNICORE=y -CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y +CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y diff --git a/tools/unit-test-app/configs/single_core_s2 b/tools/unit-test-app/configs/single_core_s2 index 9348707f1..8607b815b 100644 --- a/tools/unit-test-app/configs/single_core_s2 +++ b/tools/unit-test-app/configs/single_core_s2 @@ -3,4 +3,4 @@ CONFIG_IDF_TARGET="esp32s2" TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs test_utils CONFIG_MEMMAP_SMP=n CONFIG_FREERTOS_UNICORE=y -CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y +CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y From 0d208aababe8e4c9775f9ef325db8cb9ecdff6f4 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Tue, 21 Apr 2020 15:27:53 +0530 Subject: [PATCH 3/3] mbedtls: esp32s2: check and reallocate output buffer if its from non-DMA range Earlier check was for only input buffer but it is quite likely to have output buffer also from non-DMA memory range and hence requirement to reallocate and then copy data from AES engine. --- components/mbedtls/port/esp32s2/aes.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/mbedtls/port/esp32s2/aes.c b/components/mbedtls/port/esp32s2/aes.c index 9f0450f1a..6ac113c88 100644 --- a/components/mbedtls/port/esp32s2/aes.c +++ b/components/mbedtls/port/esp32s2/aes.c @@ -448,6 +448,10 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, input_needs_realloc = true; } + if (!esp_ptr_dma_ext_capable(output) && !esp_ptr_dma_capable(output)) { + output_needs_realloc = true; + } + /* If either input or output is unaccessible to the DMA then they need to be reallocated */ if (input_needs_realloc || output_needs_realloc) { return esp_aes_process_dma_ext_ram(ctx, input, output, len, stream_out, input_needs_realloc, output_needs_realloc);