Ver código fonte

heap: Prevent alloc from IRAM to call dram_alloc_to_iram() on esp32c6 target

Since DRAM and IRAM are superposed on esp32c6 it is not necessary to convert a freshly allocated
DRAM addr to its IRAM equivalent when MALLOC_CAP_EXEC is passed to heap_caps_malloc(). Instead,
proceed with a default allocation since the address returned by multi_heap_malloc() already belongs
to the IRAM region.

Applies for esp32c6 and every boards with superposed DRAM and IRAM addresses.
Guillaume Souchere 3 anos atrás
pai
commit
a5d6f62e7e

+ 10 - 0
components/bootloader_support/include/bootloader_memory_utils.h

@@ -20,6 +20,16 @@ extern "C" {
 
 /** The content of this file is to be kept in sync with the common section of esp_memory_utils.h **/
 
+/**
+ * @brief Check if the IRAM and DRAM are separate or using the same memory space
+ *
+ * @return true if the DRAM and IRAM are sharing the same memory space, false otherwise
+ */
+__attribute__((always_inline))
+inline static bool esp_dram_match_iram(void) {
+    return (SOC_DRAM_LOW == SOC_IRAM_LOW && SOC_DRAM_HIGH == SOC_IRAM_HIGH);
+}
+
 /**
  * @brief Check if the pointer is in iram
  *

+ 10 - 0
components/esp_hw_support/include/esp_memory_utils.h

@@ -20,6 +20,16 @@ extern "C" {
 
 /** Common functions, to be kept in sync with bootloader_memory_utils.h **/
 
+/**
+ * @brief Check if the IRAM and DRAM are separate or using the same memory space
+ *
+ * @return true if the DRAM and IRAM are sharing the same memory space, false otherwise
+ */
+__attribute__((always_inline))
+inline static bool esp_dram_match_iram(void) {
+    return (SOC_DRAM_LOW == SOC_IRAM_LOW && SOC_DRAM_HIGH == SOC_IRAM_HIGH);
+}
+
 /**
  * @brief Check if the pointer is in iram
  *

+ 3 - 1
components/heap/heap_caps.c

@@ -131,7 +131,9 @@ IRAM_ATTR static void *heap_caps_malloc_base( size_t size, uint32_t caps)
                 //doesn't cover, see if they're available in other prios.
                 if ((get_all_caps(heap) & caps) == caps) {
                     //This heap can satisfy all the requested capabilities. See if we can grab some memory using it.
-                    if ((caps & MALLOC_CAP_EXEC) && esp_ptr_in_diram_dram((void *)heap->start)) {
+                    // If MALLOC_CAP_EXEC is requested but the DRAM and IRAM are on the same addresses (like on esp32c6)
+                    // proceed as for a default allocation.
+                    if ((caps & MALLOC_CAP_EXEC) && !esp_dram_match_iram() && esp_ptr_in_diram_dram((void *)heap->start)) {
                         //This is special, insofar that what we're going to get back is a DRAM address. If so,
                         //we need to 'invert' it (lowest address in DRAM == highest address in IRAM and vice-versa) and
                         //add a pointer to the DRAM equivalent before the address we're going to return.