Forráskód Böngészése

psram: support .bss on psram on esp32s3

Armando 3 éve
szülő
commit
f8249550f8
31 módosított fájl, 579 hozzáadás és 372 törlés
  1. 7 2
      components/esp32s2/Kconfig
  2. 1 1
      components/esp_common/test/test_attr.c
  3. 1 1
      components/esp_hw_support/Kconfig.spiram.common
  4. 30 16
      components/esp_hw_support/esp_memory_utils.c
  5. 57 0
      components/esp_hw_support/include/esp_private/spiram_private.h
  6. 1 23
      components/esp_hw_support/include/soc/esp32/spiram.h
  7. 0 7
      components/esp_hw_support/include/soc/esp32s2/spiram.h
  8. 1 36
      components/esp_hw_support/include/soc/esp32s3/spiram.h
  9. 15 1
      components/esp_hw_support/include/spinlock.h
  10. 1 1
      components/esp_hw_support/linker.lf
  11. 1 0
      components/esp_hw_support/port/esp32/esp_himem.c
  12. 49 8
      components/esp_hw_support/port/esp32/spiram.c
  13. 5 4
      components/esp_hw_support/port/esp32s2/CMakeLists.txt
  14. 76 49
      components/esp_hw_support/port/esp32s2/spiram.c
  15. 33 17
      components/esp_hw_support/port/esp32s2/spiram_psram.c
  16. 22 15
      components/esp_hw_support/port/esp32s2/spiram_psram.h
  17. 9 7
      components/esp_hw_support/port/esp32s3/CMakeLists.txt
  18. 8 4
      components/esp_hw_support/port/esp32s3/opiram_psram.c
  19. 192 150
      components/esp_hw_support/port/esp32s3/spiram.c
  20. 8 7
      components/esp_hw_support/port/esp32s3/spiram_psram.c
  21. 4 4
      components/esp_hw_support/port/esp32s3/spiram_psram.h
  22. 1 1
      components/esp_hw_support/sleep_retention.c
  23. 13 3
      components/esp_hw_support/test/test_psram.c
  24. 0 1
      components/esp_system/ld/esp32s2/sections.ld.in
  25. 6 1
      components/esp_system/ld/esp32s3/memory.ld.in
  26. 20 2
      components/esp_system/ld/esp32s3/sections.ld.in
  27. 4 6
      components/esp_system/port/cpu_start.c
  28. 2 0
      components/heap/heap_tlsf_config.h
  29. 1 1
      components/soc/esp32s3/include/soc/soc.h
  30. 2 2
      docs/en/api-guides/external-ram.rst
  31. 9 2
      docs/en/migration-guides/system.rst

+ 7 - 2
components/esp32s2/Kconfig

@@ -195,9 +195,14 @@ menu "ESP32S2-specific"
                 bool "20Mhz clock speed"
         endchoice
 
+        config SPIRAM_SPEED
+            int
+            default 80 if SPIRAM_SPEED_80M
+            default 40 if SPIRAM_SPEED_40M
+            default 40 if SPIRAM_SPEED_26M
+            default 40 if SPIRAM_SPEED_20M
 
-        # insert non-chip-specific items here NOERROR
-        source "$IDF_PATH/components/esp_hw_support/Kconfig.spiram.common"
+        source "$IDF_PATH/components/esp_hw_support/Kconfig.spiram.common"   #insert non-chip-specific items here
 
     endmenu
 

+ 1 - 1
components/esp_common/test/test_attr.c

@@ -116,7 +116,7 @@ TEST_CASE_MULTIPLE_STAGES("Spiram test noinit memory", "[spiram]", write_spiram_
 
 
 #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
-#define TEST_BSS_NUM    256
+#define TEST_BSS_NUM    (256 * 1024)
 static EXT_RAM_ATTR uint32_t s_bss_buffer[TEST_BSS_NUM];
 
 TEST_CASE("Test variables placed in external .bss segment", "[ld]")

+ 1 - 1
components/esp_hw_support/Kconfig.spiram.common

@@ -92,7 +92,7 @@ config SPIRAM_MALLOC_RESERVE_INTERNAL
 config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
     bool "Allow .bss segment placed in external memory"
     default n
-    depends on SPIRAM && (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2) # ESP32-S3 IDF-1974
+    depends on SPIRAM
     select ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY
     help
         If enabled, variables with EXT_RAM_ATTR attribute will be placed in SPIRAM instead of internal DRAM.

+ 30 - 16
components/esp_hw_support/esp_memory_utils.c

@@ -12,17 +12,22 @@
 #include "soc/soc_caps.h"
 #include "esp_attr.h"
 #include "esp_memory_utils.h"
+#include "esp_private/spiram_private.h"
 
 
-//TODO: IDF-4855, replace PSRAM related address region into PSRAM private APIs
-
 bool esp_ptr_dma_ext_capable(const void *p)
 {
-#ifdef SOC_PSRAM_DMA_CAPABLE
-    return (intptr_t)p >= SOC_DMA_EXT_LOW && (intptr_t)p < SOC_DMA_EXT_HIGH;
+#if !SOC_PSRAM_DMA_CAPABLE
+    return false;
+#endif  //!SOC_PSRAM_DMA_CAPABLE
+#if CONFIG_SPIRAM
+    intptr_t vaddr_start = 0;
+    intptr_t vaddr_end = 0;
+    esp_spiram_get_mapped_range(&vaddr_start, &vaddr_end);
+    return (intptr_t)p >= vaddr_start && (intptr_t)p < vaddr_end;
 #else
     return false;
-#endif
+#endif  //CONFIG_SPIRAM
 }
 
 bool esp_ptr_byte_accessible(const void *p)
@@ -37,27 +42,36 @@ bool esp_ptr_byte_accessible(const void *p)
     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));
-#else
-    r |= (ip >= SOC_EXTRAM_DATA_LOW && ip < (SOC_EXTRAM_DATA_HIGH));
-#endif
+    intptr_t vaddr_start = 0;
+    intptr_t vaddr_end = 0;
+    esp_spiram_get_mapped_range(&vaddr_start, &vaddr_end);
+    r |= (ip >= vaddr_start && ip < vaddr_end);
 #endif
     return r;
 }
 
-bool esp_ptr_external_ram(const void *p) {
-#if SOC_SPIRAM_SUPPORTED
-    return ((intptr_t)p >= SOC_EXTRAM_DATA_LOW && (intptr_t)p < SOC_EXTRAM_DATA_HIGH);
+bool esp_ptr_external_ram(const void *p)
+{
+#if !SOC_SPIRAM_SUPPORTED
+    return false;
+#endif  //!SOC_SPIRAM_SUPPORTED
+#if CONFIG_SPIRAM
+    intptr_t vaddr_start = 0;
+    intptr_t vaddr_end = 0;
+    esp_spiram_get_mapped_range(&vaddr_start, &vaddr_end);
+    return (intptr_t)p >= vaddr_start && (intptr_t)p < vaddr_end;
 #else
-    return false; // SoC has no external RAM
-#endif
+    return false;
+#endif  //CONFIG_SPIRAM
 }
 
 #if CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
 bool esp_stack_ptr_in_extram(uint32_t sp)
 {
+    intptr_t vaddr_start = 0;
+    intptr_t vaddr_end = 0;
+    esp_spiram_get_mapped_range(&vaddr_start, &vaddr_end);
     //Check if stack ptr is in between SOC_EXTRAM_DATA_LOW and SOC_EXTRAM_DATA_HIGH, and 16 byte aligned.
-    return !(sp < SOC_EXTRAM_DATA_LOW + 0x10 || sp > SOC_EXTRAM_DATA_HIGH - 0x10 || ((sp & 0xF) != 0));
+    return !(sp < vaddr_start + 0x10 || sp > vaddr_end - 0x10 || ((sp & 0xF) != 0));
 }
 #endif

+ 57 - 0
components/esp_hw_support/include/esp_private/spiram_private.h

@@ -0,0 +1,57 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <stddef.h>
+#include "esp_err.h"
+#include "soc/soc_caps.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    ESP_SPIRAM_SIZE_16MBITS = 0,   /*!< SPI RAM size is 16 MBits */
+    ESP_SPIRAM_SIZE_32MBITS = 1,   /*!< SPI RAM size is 32 MBits */
+    ESP_SPIRAM_SIZE_64MBITS = 2,   /*!< SPI RAM size is 64 MBits */
+    ESP_SPIRAM_SIZE_INVALID,       /*!< SPI RAM size is invalid */
+} esp_spiram_size_t;
+
+/**
+ * @brief Get the size of the attached SPI RAM chip selected in menuconfig
+ *
+ * @return Size in bytes, or 0 if no external RAM chip support compiled in.
+ */
+size_t esp_spiram_get_size(void);
+
+/**
+ * @brief Get the psram mapped vaddr range
+ *
+ * @param[out] out_vstart PSRAM virtual address start
+ * @param[out] out_vend   PSRAM virtual address end
+ *
+ * @return
+ *        - ESP_OK                  On success
+ *        - ESP_ERR_INVALID_STATE   PSRAM is not initialized successfully
+ */
+esp_err_t esp_spiram_get_mapped_range(intptr_t *out_vstart, intptr_t *out_vend);
+
+/**
+ * @brief Get the psram alloced vaddr range
+ *
+ * @param[out] out_vstart PSRAM virtual address start
+ * @param[out] out_vend   PSRAM virtual address end
+ *
+ * @return
+ *        - ESP_OK                  On success
+ *        - ESP_ERR_INVALID_STATE   PSRAM is not initialized successfully
+ */
+esp_err_t esp_spiram_get_alloced_range(intptr_t *out_vstart, intptr_t *out_vend);
+
+#ifdef __cplusplus
+}
+#endif

+ 1 - 23
components/esp_hw_support/include/soc/esp32/spiram.h

@@ -17,20 +17,7 @@
 extern "C" {
 #endif
 
-typedef enum {
-    ESP_SPIRAM_SIZE_16MBITS = 0,   /*!< SPI RAM size is 16 MBits */
-    ESP_SPIRAM_SIZE_32MBITS = 1,   /*!< SPI RAM size is 32 MBits */
-    ESP_SPIRAM_SIZE_64MBITS = 2,   /*!< SPI RAM size is 64 MBits */
-    ESP_SPIRAM_SIZE_INVALID,       /*!< SPI RAM size is invalid */
-} esp_spiram_size_t;
-
-/**
- * @brief get SPI RAM size
- * @return
- *     - ESP_SPIRAM_SIZE_INVALID if SPI RAM not enabled or not valid
- *     - SPI RAM size
- */
-esp_spiram_size_t esp_spiram_get_chip_size(void);
+//TODO: IDF-4382, unify `target/spiram.h`, update migration guide as well
 
 /**
  * @brief Initialize spiram interface/hardware. Normally called from cpu_start.c.
@@ -67,15 +54,6 @@ bool esp_spiram_test(void);
  */
 esp_err_t esp_spiram_add_to_heapalloc(void);
 
-
-/**
- * @brief Get the size of the attached SPI RAM chip selected in menuconfig
- *
- * @return Size in bytes, or 0 if no external RAM chip support compiled in.
- */
-size_t esp_spiram_get_size(void);
-
-
 /**
  * @brief Force a writeback of the data in the SPI RAM cache. This is to be called whenever
  * cache is disabled, because disabling cache on the ESP32 discards the data in the SPI

+ 0 - 7
components/esp_hw_support/include/soc/esp32s2/spiram.h

@@ -29,13 +29,6 @@ esp_err_t esp_spiram_init(void);
  */
 esp_err_t esp_spiram_add_to_heapalloc(void);
 
-/**
- * @brief Get the size of the attached SPI RAM chip selected in menuconfig
- *
- * @return Size in bytes, or 0 if no external RAM chip support compiled in.
- */
-size_t esp_spiram_get_size(void);
-
 /**
  * @brief Force a writeback of the data in the SPI RAM cache. This is to be called whenever
  * cache is disabled, because disabling cache on the ESP32 discards the data in the SPI

+ 1 - 36
components/esp_hw_support/include/soc/esp32s3/spiram.h

@@ -5,8 +5,7 @@
  */
 
 
-#ifndef __ESP_SPIRAM_H
-#define __ESP_SPIRAM_H
+#pragma once
 
 #include <stddef.h>
 #include <stdint.h>
@@ -24,43 +23,11 @@ extern "C" {
  */
 esp_err_t esp_spiram_init(void);
 
-/**
- * @brief Configure Cache/MMU for access to external SPI RAM.
- *
- * Normally this function is called from cpu_start, if CONFIG_SPIRAM_BOOT_INIT
- * option is enabled. Applications which need to enable SPI RAM at run time
- * can disable CONFIG_SPIRAM_BOOT_INIT, and call this function later.
- *
- * @attention this function must be called with flash cache disabled.
- */
-void esp_spiram_init_cache(void);
-
-
-/**
- * @brief Memory test for SPI RAM. Should be called after SPI RAM is initialized and
- * (in case of a dual-core system) the app CPU is online. This test overwrites the
- * memory with crap, so do not call after e.g. the heap allocator has stored important
- * stuff in SPI RAM.
- *
- * @return true on success, false on failed memory test
- */
-bool esp_spiram_test(void);
-
-
 /**
  * @brief Add the initialized SPI RAM to the heap allocator.
  */
 esp_err_t esp_spiram_add_to_heapalloc(void);
 
-/**
- * @brief Get the available physical size of the attached SPI RAM chip
- *
- * @note If ECC is enabled, the available physical size would be smaller than the physical size. See `CONFIG_SPIRAM_ECC_ENABLE`
- *
- * @return Size in bytes, or 0 if no external RAM chip support compiled in.
- */
-size_t esp_spiram_get_size(void);
-
 /**
  * @brief Force a writeback of the data in the SPI RAM cache. This is to be called whenever
  * cache is disabled, because disabling cache on the ESP32 discards the data in the SPI
@@ -160,5 +127,3 @@ int rodata_flash2spiram_offset(void);
 #ifdef __cplusplus
 }
 #endif
-
-#endif

+ 15 - 1
components/esp_hw_support/include/spinlock.h

@@ -10,6 +10,7 @@
 #include "sdkconfig.h"
 #include "hal/cpu_hal.h"
 #include "compare_set.h"
+#include "soc/soc.h"
 
 #if __XTENSA__
 #include "xtensa/xtruntime.h"
@@ -36,6 +37,19 @@ typedef struct {
     NEED_VOLATILE_MUX uint32_t count;
 }spinlock_t;
 
+#if (CONFIG_ESP32_SPIRAM_SUPPORT)
+/**
+ * @brief Check if the pointer is on external ram
+ * @param p pointer
+ * @return true: on external ram; false: not on external ram
+ */
+static inline bool __attribute__((always_inline)) spinlock_ptr_external_ram(const void *p)
+{
+    //On esp32, this external virtual address rergion is for psram
+    return ((intptr_t)p >= SOC_EXTRAM_DATA_LOW && (intptr_t)p < SOC_EXTRAM_DATA_HIGH);
+}
+#endif
+
 /**
  * @brief Initialize a lock to its default state - unlocked
  * @param lock - spinlock object to initialize
@@ -95,7 +109,7 @@ static inline bool __attribute__((always_inline)) spinlock_acquire(spinlock_t *l
         result = core_id;
 
 #if defined(CONFIG_ESP32_SPIRAM_SUPPORT)
-        if (esp_ptr_external_ram(lock)) {
+        if (spinlock_ptr_external_ram(lock)) {
             compare_and_set_extram(&lock->owner, SPINLOCK_FREE, &result);
         } else {
 #endif

+ 1 - 1
components/esp_hw_support/linker.lf

@@ -15,7 +15,7 @@ entries:
             spiram_psram (noflash)
         if SPIRAM_MODE_OCT = y:
             opiram_psram (noflash)
-    if IDF_TARGET_ESP32S2 = y:
+    if IDF_TARGET_ESP32S2 = y && SPIRAM:
         mmu_psram (noflash)
     if PERIPH_CTRL_FUNC_IN_IRAM = y:
         periph_ctrl: periph_module_reset (noflash)

+ 1 - 0
components/esp_hw_support/port/esp32/esp_himem.c

@@ -7,6 +7,7 @@
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "esp32/spiram.h"
+#include "esp_private/spiram_private.h"
 #include "esp32/rom/cache.h"
 #include "sdkconfig.h"
 #include "esp_himem.h"

+ 49 - 8
components/esp_hw_support/port/esp32/spiram.c

@@ -17,6 +17,7 @@ we add more types of external RAM memory, this can be made into a more intellige
 #include "esp_attr.h"
 #include "esp_err.h"
 #include "esp32/spiram.h"
+#include "esp_private/spiram_private.h"
 #include "spiram_psram.h"
 #include "esp_log.h"
 #include "freertos/FreeRTOS.h"
@@ -55,6 +56,12 @@ extern uint8_t _ext_ram_bss_start, _ext_ram_bss_end;
 extern uint8_t _ext_ram_noinit_start, _ext_ram_noinit_end;
 #endif
 
+//These variables are in bytes
+static intptr_t s_allocable_vaddr_start;
+static intptr_t s_allocable_vaddr_end;
+static intptr_t s_mapped_vaddr_start;
+static intptr_t s_mapped_vaddr_end;
+
 static bool spiram_inited=false;
 
 
@@ -132,6 +139,9 @@ void IRAM_ATTR esp_spiram_init_cache(void)
     DPORT_CLEAR_PERI_REG_MASK(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DRAM1);
     cache_sram_mmu_set(1, 0, SOC_EXTRAM_DATA_LOW, 0, 32, (size / 1024 / 32));
 #endif
+
+    s_mapped_vaddr_start = (intptr_t)SOC_EXTRAM_DATA_LOW;
+    s_mapped_vaddr_end = s_mapped_vaddr_start + size;
 }
 
 esp_spiram_size_t esp_spiram_get_chip_size(void)
@@ -155,6 +165,7 @@ esp_spiram_size_t esp_spiram_get_chip_size(void)
 
 esp_err_t esp_spiram_init(void)
 {
+    assert(!spiram_inited);
     esp_err_t r;
     r = psram_enable(PSRAM_SPEED, PSRAM_MODE);
     if (r != ESP_OK) {
@@ -189,20 +200,50 @@ esp_err_t esp_spiram_add_to_heapalloc(void)
 {
     //Add entire external RAM region to heap allocator. Heap allocator knows the capabilities of this type of memory, so there's
     //no need to explicitly specify them.
-    intptr_t mallocable_ram_start = (intptr_t)SOC_EXTRAM_DATA_LOW;
+    s_allocable_vaddr_start = (intptr_t)SOC_EXTRAM_DATA_LOW;
 #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
-    if (mallocable_ram_start < (intptr_t)&_ext_ram_bss_end) {
-        mallocable_ram_start = (intptr_t)&_ext_ram_bss_end;
+    if (s_allocable_vaddr_start < (intptr_t)&_ext_ram_bss_end) {
+        s_allocable_vaddr_start = (intptr_t)&_ext_ram_bss_end;
     }
 #endif
 #if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
-    if (mallocable_ram_start < (intptr_t)&_ext_ram_noinit_end) {
-        mallocable_ram_start = (intptr_t)&_ext_ram_noinit_end;
+    if (s_allocable_vaddr_start < (intptr_t)&_ext_ram_noinit_end) {
+        s_allocable_vaddr_start = (intptr_t)&_ext_ram_noinit_end;
     }
 #endif
-    intptr_t mallocable_ram_end = (intptr_t)SOC_EXTRAM_DATA_LOW + spiram_size_usable_for_malloc() - 1;
-    ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", (mallocable_ram_end - mallocable_ram_start)/1024);
-    return heap_caps_add_region(mallocable_ram_start, mallocable_ram_end);
+    s_allocable_vaddr_end = (intptr_t)SOC_EXTRAM_DATA_LOW + spiram_size_usable_for_malloc() - 1;
+    ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", (s_allocable_vaddr_end - s_allocable_vaddr_start)/1024);
+    return heap_caps_add_region(s_allocable_vaddr_start, s_allocable_vaddr_end);
+}
+
+esp_err_t IRAM_ATTR esp_spiram_get_mapped_range(intptr_t *out_vstart, intptr_t *out_vend)
+{
+    if (!out_vstart || !out_vend) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    if (!spiram_inited) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    *out_vstart = s_mapped_vaddr_start;
+    *out_vend = s_mapped_vaddr_end;
+    return ESP_OK;
+}
+
+esp_err_t esp_spiram_get_alloced_range(intptr_t *out_vstart, intptr_t *out_vend)
+{
+    if (!out_vstart || !out_vend) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    if (!spiram_inited) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    *out_vstart = s_allocable_vaddr_start;
+    *out_vend = s_allocable_vaddr_end;
+    return ESP_OK;
 }
 
 

+ 5 - 4
components/esp_hw_support/port/esp32s2/CMakeLists.txt

@@ -17,10 +17,11 @@ if(NOT BOOTLOADER_BUILD)
                      "esp_hmac.c"
                      "esp_crypto_lock.c"
                      "esp_ds.c"
-                     "dport_access.c"
-                     "spiram.c"
-                     "mmu_psram.c"
-                     "spiram_psram.c")
+                     "dport_access.c")
+
+    if(CONFIG_SPIRAM)
+        list(APPEND srcs "spiram.c" "mmu_psram.c" "spiram_psram.c")
+    endif()
 endif()
 
 add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")

+ 76 - 49
components/esp_hw_support/port/esp32s2/spiram.c

@@ -19,6 +19,7 @@
 #include "freertos/FreeRTOS.h"
 #include "freertos/xtensa_api.h"
 #include "esp_heap_caps_init.h"
+#include "esp_private/spiram_private.h"
 #include "esp32s2/spiram.h"
 #include "esp_private/mmu_psram.h"
 #include "spiram_psram.h"
@@ -44,47 +45,48 @@ extern uint8_t _ext_ram_bss_end;
 #endif //#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
 
 //These variables are in bytes
-static uint32_t s_allocable_vaddr_start;
-static uint32_t s_allocable_vaddr_end;
+static intptr_t s_allocable_vaddr_start;
+static intptr_t s_allocable_vaddr_end;
+static intptr_t s_mapped_vaddr_start;
+static intptr_t s_mapped_vaddr_end;
 
-static bool spiram_inited=false;
+static bool s_spiram_inited;
 static const char* TAG = "spiram";
 
-bool esp_spiram_test(uint32_t v_start, uint32_t size);
+static bool esp_spiram_test(uint32_t v_start, uint32_t size);
 
 
 esp_err_t esp_spiram_init(void)
 {
-    esp_err_t r;
-    r = psram_enable(PSRAM_SPEED, PSRAM_MODE);
-    if (r != ESP_OK) {
+    assert(!s_spiram_inited);
+    esp_err_t ret;
+    ret = psram_enable(PSRAM_SPEED, PSRAM_MODE);
+    if (ret != ESP_OK) {
 #if CONFIG_SPIRAM_IGNORE_NOTFOUND
         ESP_EARLY_LOGE(TAG, "SPI RAM enabled but initialization failed. Bailing out.");
 #endif
-        return r;
+        return ret;
     }
+    s_spiram_inited = true;
 
-    spiram_inited = true;
+    uint32_t psram_physical_size = 0;
+    ret = psram_get_physical_size(&psram_physical_size);
+    assert(ret == ESP_OK);
 
-    //TODO IDF-4380
-    size_t spiram_size = esp_spiram_get_size();
 #if (CONFIG_SPIRAM_SIZE != -1)
-    if (spiram_size != CONFIG_SPIRAM_SIZE) {
-        ESP_EARLY_LOGE(TAG, "Expected %dKiB chip but found %dKiB chip. Bailing out..", CONFIG_SPIRAM_SIZE/1024, spiram_size/1024);
+    if (psram_physical_size != CONFIG_SPIRAM_SIZE) {
+        ESP_EARLY_LOGE(TAG, "Expected %dMB chip but found %dMB chip. Bailing out..", CONFIG_SPIRAM_SIZE / 1024 / 1024, psram_physical_size / 1024 / 1024);
         return ESP_ERR_INVALID_SIZE;
     }
 #endif
+    ESP_EARLY_LOGI(TAG, "Found %dMBit SPI RAM device", psram_physical_size / (1024 * 1024));
+    ESP_EARLY_LOGI(TAG, "Speed: %dMHz", CONFIG_SPIRAM_SPEED);
 
-    ESP_EARLY_LOGI(TAG, "Found %dMBit SPI RAM device",
-                                          (spiram_size*8)/(1024*1024));
-    ESP_EARLY_LOGI(TAG, "SPI RAM mode: %s", PSRAM_SPEED == PSRAM_CACHE_S40M ? "sram 40m" : \
-                                          PSRAM_SPEED == PSRAM_CACHE_S80M ? "sram 80m" : "sram 20m");
-    ESP_EARLY_LOGI(TAG, "PSRAM initialized, cache is in %s mode.", \
-                                          (PSRAM_MODE==PSRAM_VADDR_MODE_EVENODD)?"even/odd (2-core)": \
-                                          (PSRAM_MODE==PSRAM_VADDR_MODE_LOWHIGH)?"low/high (2-core)": \
-                                          (PSRAM_MODE==PSRAM_VADDR_MODE_NORMAL)?"normal (1-core)":"ERROR");
+    uint32_t psram_available_size = 0;
+    ret = psram_get_available_size(&psram_available_size);
+    assert(ret == ESP_OK);
 
-    uint32_t psram_available_size = spiram_size;
+    __attribute__((unused)) uint32_t total_available_size = psram_available_size;
     /**
      * `start_page` is the psram physical address in MMU page size.
      * MMU page size on ESP32S2 is 64KB
@@ -99,8 +101,8 @@ esp_err_t esp_spiram_init(void)
 
     //------------------------------------Copy Flash .text to PSRAM-------------------------------------//
 #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
-    r = mmu_config_psram_text_segment(start_page, spiram_size, &used_page);
-    if (r != ESP_OK) {
+    ret = mmu_config_psram_text_segment(start_page, total_available_size, &used_page);
+    if (ret != ESP_OK) {
         ESP_EARLY_LOGE(TAG, "No enough psram memory for instructon!");
         abort();
     }
@@ -111,8 +113,8 @@ esp_err_t esp_spiram_init(void)
 
     //------------------------------------Copy Flash .rodata to PSRAM-------------------------------------//
 #if CONFIG_SPIRAM_RODATA
-    r = mmu_config_psram_rodata_segment(start_page, spiram_size, &used_page);
-    if (r != ESP_OK) {
+    ret = mmu_config_psram_rodata_segment(start_page, total_available_size, &used_page);
+    if (ret != ESP_OK) {
         ESP_EARLY_LOGE(TAG, "No enough psram memory for rodata!");
         abort();
     }
@@ -121,10 +123,10 @@ esp_err_t esp_spiram_init(void)
     ESP_EARLY_LOGV(TAG, "after copy .rodata, used page is %d, start_page is %d, psram_available_size is %d B", used_page, start_page, psram_available_size);
 #endif  //#if CONFIG_SPIRAM_RODATA
 
-    //Map the PSRAM physical range to MMU
+    //----------------------------------Map the PSRAM physical range to MMU-----------------------------//
     static DRAM_ATTR uint32_t vaddr_start = 0;
     mmu_map_psram(MMU_PAGE_TO_BYTES(start_page), MMU_PAGE_TO_BYTES(start_page) + psram_available_size, &vaddr_start);
-    if (r != ESP_OK) {
+    if (ret != ESP_OK) {
         ESP_EARLY_LOGE(TAG, "MMU PSRAM mapping wrong!");
         abort();
     }
@@ -141,6 +143,8 @@ esp_err_t esp_spiram_init(void)
     /*------------------------------------------------------------------------------
     * After mapping, we DON'T care about the PSRAM PHYSICAL ADDRESSS ANYMORE!
     *----------------------------------------------------------------------------*/
+    s_mapped_vaddr_start = vaddr_start;
+    s_mapped_vaddr_end = vaddr_start + psram_available_size;
     s_allocable_vaddr_start = vaddr_start;
     s_allocable_vaddr_end = vaddr_start + psram_available_size;
 
@@ -157,35 +161,58 @@ esp_err_t esp_spiram_init(void)
     return ESP_OK;
 }
 
+/**
+ * Add the PSRAM available region to heap allocator. Heap allocator knows the capabilities of this type of memory,
+ * so there's no need to explicitly specify them.
+ */
 esp_err_t esp_spiram_add_to_heapalloc(void)
 {
-    return heap_caps_add_region(s_allocable_vaddr_start, s_allocable_vaddr_end - 1);
+    ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", (s_allocable_vaddr_end - s_allocable_vaddr_start) / 1024);
+    return heap_caps_add_region(s_allocable_vaddr_start, s_allocable_vaddr_end);
 }
 
-static uint8_t *dma_heap;
+esp_err_t IRAM_ATTR esp_spiram_get_mapped_range(intptr_t *out_vstart, intptr_t *out_vend)
+{
+    if (!out_vstart || !out_vend) {
+        return ESP_ERR_INVALID_ARG;
+    }
 
-esp_err_t esp_spiram_reserve_dma_pool(size_t size) {
-    if (size==0) return ESP_OK; //no-op
-    ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size/1024);
-    dma_heap=heap_caps_malloc(size, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
-    if (!dma_heap) return ESP_ERR_NO_MEM;
-    uint32_t caps[]={MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT};
-    return heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap+size-1);
+    if (!s_spiram_inited) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    *out_vstart = s_mapped_vaddr_start;
+    *out_vend = s_mapped_vaddr_end;
+    return ESP_OK;
 }
 
-//TODO IDF-4380
-size_t esp_spiram_get_size(void)
+esp_err_t esp_spiram_get_alloced_range(intptr_t *out_vstart, intptr_t *out_vend)
 {
-    if (!spiram_inited) {
-        ESP_EARLY_LOGE(TAG, "SPI RAM not initialized");
-        abort();
+    if (!out_vstart || !out_vend) {
+        return ESP_ERR_INVALID_ARG;
     }
 
-    psram_size_t size=psram_get_size();
-    if (size==PSRAM_SIZE_16MBITS) return 2*1024*1024;
-    if (size==PSRAM_SIZE_32MBITS) return 4*1024*1024;
-    if (size==PSRAM_SIZE_64MBITS) return 8*1024*1024;
-    return CONFIG_SPIRAM_SIZE;
+    if (!s_spiram_inited) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    *out_vstart = s_allocable_vaddr_start;
+    *out_vend = s_allocable_vaddr_end;
+    return ESP_OK;
+}
+
+esp_err_t esp_spiram_reserve_dma_pool(size_t size)
+{
+    if (size == 0) {
+        return ESP_OK; //no-op
+    }
+    ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size/1024);
+    uint8_t *dma_heap = heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
+    if (!dma_heap) {
+        return ESP_ERR_NO_MEM;
+    }
+    uint32_t caps[] = {MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT};
+    return heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap + size);
 }
 
 /*
@@ -206,7 +233,7 @@ void IRAM_ATTR esp_spiram_writeback_cache(void)
  */
 bool esp_spiram_is_initialized(void)
 {
-    return spiram_inited;
+    return s_spiram_inited;
 }
 
 uint8_t esp_spiram_get_cs_io(void)
@@ -219,7 +246,7 @@ uint8_t esp_spiram_get_cs_io(void)
  true when RAM seems OK, false when test fails. WARNING: Do not run this before the 2nd cpu has been
  initialized (in a two-core system) or after the heap allocator has taken ownership of the memory.
 */
-bool esp_spiram_test(uint32_t v_start, uint32_t size)
+static bool esp_spiram_test(uint32_t v_start, uint32_t size)
 {
     volatile int *spiram = (volatile int *)v_start;
 

+ 33 - 17
components/esp_hw_support/port/esp32s2/spiram_psram.c

@@ -34,8 +34,6 @@
 #include "driver/spi_common.h"
 #include "esp_private/periph_ctrl.h"
 #include "bootloader_common.h"
-
-#if CONFIG_SPIRAM
 #include "soc/rtc.h"
 
 static const char* TAG = "psram";
@@ -378,20 +376,6 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
     s_psram_cs_io = psram_io.psram_cs_io;
 }
 
-psram_size_t psram_get_size(void)
-{
-    if ((PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_64MBITS) || PSRAM_IS_64MBIT_TRIAL(s_psram_id)) {
-        return PSRAM_SIZE_64MBITS;
-    } else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_32MBITS) {
-        return PSRAM_SIZE_32MBITS;
-    } else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_16MBITS) {
-        return PSRAM_SIZE_16MBITS;
-    } else {
-        return PSRAM_SIZE_MAX;
-    }
-    return PSRAM_SIZE_MAX;
-}
-
 //used in UT only
 bool psram_is_32mbit_ver0(void)
 {
@@ -542,4 +526,36 @@ static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psra
 
     CLEAR_PERI_REG_MASK(SPI_MEM_MISC_REG(0), SPI_MEM_CS1_DIS_M); //ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM)
 }
-#endif // CONFIG_SPIRAM
+
+
+/*---------------------------------------------------------------------------------
+ * Following APIs are not required to be IRAM-Safe
+ *
+ * Consider moving these to another file if this kind of APIs grows dramatically
+ *-------------------------------------------------------------------------------*/
+esp_err_t psram_get_physical_size(uint32_t *out_size_bytes)
+{
+    if (!out_size_bytes) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    if ((PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_64MBITS) || PSRAM_IS_64MBIT_TRIAL(s_psram_id)) {
+        *out_size_bytes = PSRAM_SIZE_8MB;
+    } else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_32MBITS) {
+        *out_size_bytes = PSRAM_SIZE_4MB;
+    } else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_16MBITS) {
+        *out_size_bytes = PSRAM_SIZE_2MB;
+    } else {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+    return ESP_OK;
+}
+
+/**
+ * This function is to get the available physical psram size in bytes.
+ * On ESP32S2, all of the PSRAM physical region are available
+ */
+esp_err_t psram_get_available_size(uint32_t *out_size_bytes)
+{
+    return psram_get_physical_size(out_size_bytes);
+}

+ 22 - 15
components/esp_hw_support/port/esp32s2/spiram_psram.h

@@ -4,13 +4,20 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
+#pragma once
 
-#ifndef _PSRAM_H
-#define _PSRAM_H
 #include "soc/spi_mem_reg.h"
 #include "esp_err.h"
 #include "sdkconfig.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PSRAM_SIZE_2MB                  (2 * 1024 * 1024)
+#define PSRAM_SIZE_4MB                  (4 * 1024 * 1024)
+#define PSRAM_SIZE_8MB                  (8 * 1024 * 1024)
+
 typedef enum {
     PSRAM_CACHE_S80M = 1,
     PSRAM_CACHE_S40M,
@@ -19,12 +26,6 @@ typedef enum {
     PSRAM_CACHE_MAX,
 } psram_cache_mode_t;
 
-typedef enum {
-    PSRAM_SIZE_16MBITS = 0,
-    PSRAM_SIZE_32MBITS = 1,
-    PSRAM_SIZE_64MBITS = 2,
-    PSRAM_SIZE_MAX,
-} psram_size_t;
 
 /*
 See the TRM, chapter PID/MPU/MMU, header 'External RAM' for the definitions of these modes.
@@ -40,12 +41,20 @@ typedef enum {
 } psram_vaddr_mode_t;
 
 /**
- * @brief get psram size
- * @return
- *     - PSRAM_SIZE_MAX if psram not enabled or not valid
- *     - PSRAM size
+ * @brief To get the physical psram size in bytes.
+ *
+ * @param[out] out_size_bytes    physical psram size in bytes.
+ */
+esp_err_t psram_get_physical_size(uint32_t *out_size_bytes);
+
+/**
+ * @brief To get the available physical psram size in bytes.
+ *
+ * @note On ESP32S2, all of the PSRAM physical region are available
+ *
+ * @param[out] out_size_bytes    availabe physical psram size in bytes.
  */
-psram_size_t psram_get_size(void);
+esp_err_t psram_get_available_size(uint32_t *out_size_bytes);
 
 /**
  * @brief psram cache enable function
@@ -74,5 +83,3 @@ esp_err_t esp_spiram_wrap_set(spiram_wrap_mode_t mode);
  * @return psram CS IO
  */
 uint8_t psram_get_cs_io(void);
-
-#endif

+ 9 - 7
components/esp_hw_support/port/esp32s3/CMakeLists.txt

@@ -16,15 +16,17 @@ if(NOT BOOTLOADER_BUILD)
         "dport_access.c"
         "esp_hmac.c"
         "esp_ds.c"
-        "esp_crypto_lock.c"
-        "spiram.c")
+        "esp_crypto_lock.c")
 
-    if(CONFIG_SPIRAM_MODE_QUAD)
-        list(APPEND srcs "spiram_psram.c")
-    elseif(CONFIG_SPIRAM_MODE_OCT)
-        list(APPEND srcs "opiram_psram.c")
-    endif()
+    if(CONFIG_SPIRAM)
+        list(APPEND srcs "spiram.c")
 
+        if(CONFIG_SPIRAM_MODE_QUAD)
+            list(APPEND srcs "spiram_psram.c")
+        elseif(CONFIG_SPIRAM_MODE_OCT)
+            list(APPEND srcs "opiram_psram.c")
+        endif()
+    endif()
 endif()
 
 add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")

+ 8 - 4
components/esp_hw_support/port/esp32s3/opiram_psram.c

@@ -25,8 +25,6 @@
 #include "driver/gpio.h"
 #include "driver/spi_common.h"
 #include "esp_private/periph_ctrl.h"
-
-#if CONFIG_SPIRAM_MODE_OCT
 #include "soc/rtc.h"
 #include "esp_private/spi_flash_os.h"
 
@@ -383,6 +381,10 @@ static void s_config_psram_spi_phases(void)
  *-------------------------------------------------------------------------------*/
 esp_err_t psram_get_physical_size(uint32_t *out_size_bytes)
 {
+    if (!out_size_bytes) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
     *out_size_bytes = s_psram_size;
     return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
 }
@@ -393,6 +395,10 @@ esp_err_t psram_get_physical_size(uint32_t *out_size_bytes)
  */
 esp_err_t psram_get_available_size(uint32_t *out_size_bytes)
 {
+    if (!out_size_bytes) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
 #if CONFIG_SPIRAM_ECC_ENABLE
     *out_size_bytes = s_psram_size * 15 / 16;
 #else
@@ -400,5 +406,3 @@ esp_err_t psram_get_available_size(uint32_t *out_size_bytes)
 #endif
     return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
 }
-
-#endif  //#if CONFIG_SPIRAM_MODE_OCT

+ 192 - 150
components/esp_hw_support/port/esp32s3/spiram.c

@@ -1,45 +1,35 @@
-/*
-Abstraction layer for spi-ram. For now, it's no more than a stub for the spiram_psram functions, but if
-we add more types of external RAM memory, this can be made into a more intelligent dispatcher.
-*/
-
 /*
  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
 
+
+/*----------------------------------------------------------------------------------------------------
+ * Abstraction layer for PSRAM. PSRAM device related registers and MMU/Cache related code shouls be
+ * abstracted to lower layers.
+ *
+ * When we add more types of external RAM memory, this can be made into a more intelligent dispatcher.
+ *----------------------------------------------------------------------------------------------------*/
 #include <stdint.h>
 #include <string.h>
 #include <sys/param.h>
 #include "sdkconfig.h"
 #include "esp_attr.h"
 #include "esp_err.h"
-#include "esp32s3/spiram.h"
-#include "spiram_psram.h"
 #include "esp_log.h"
-#include "freertos/FreeRTOS.h"
-#include "freertos/xtensa_api.h"
-#include "soc/soc.h"
 #include "esp_heap_caps_init.h"
-#include "soc/soc_memory_layout.h"
-#include "soc/dport_reg.h"
-#include "esp32s3/rom/cache.h"
-#include "soc/ext_mem_defs.h"
-#include "soc/extmem_reg.h"
+#include "esp_private/spiram_private.h"
+#include "esp32s3/spiram.h"
+#include "spiram_psram.h"
+#include "hal/mmu_hal.h"
+#include "hal/cache_ll.h"
 
-/**
- * @note consider abstract these cache register operations, so as to make `spiram.c` not needed to be IRAM-SAFE.
- * This file only contains abstract operations.
- */
 
 #define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
 
 #define MMU_PAGE_SIZE    0x10000
-
-#if CONFIG_SPIRAM
-
-static const char *TAG = "spiram";
+#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
 
 #if CONFIG_SPIRAM_SPEED_40M
 #define PSRAM_SPEED PSRAM_CACHE_S40M
@@ -47,79 +37,171 @@ static const char *TAG = "spiram";
 #define PSRAM_SPEED PSRAM_CACHE_S80M
 #endif
 
-static bool s_spiram_inited = false;
+
+static const char *TAG = "spiram";
+static bool s_spiram_inited;
 
 //These variables are in bytes
-static uint32_t s_allocable_vaddr_start;
-static uint32_t s_allocable_vaddr_end;
-static DRAM_ATTR uint32_t s_mapped_vaddr_start;
-static DRAM_ATTR uint32_t s_mapped_size;
+static intptr_t s_allocable_vaddr_start;
+static intptr_t s_allocable_vaddr_end;
+static intptr_t s_mapped_vaddr_start;
+static intptr_t s_mapped_vaddr_end;
 
-/**
- * Initially map all psram physical address to virtual address.
- * If psram physical size is larger than virtual address range, then only map the virtual address range.
- */
-void IRAM_ATTR esp_spiram_init_cache(void)
+
+#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
+extern uint8_t _ext_ram_bss_start;
+extern uint8_t _ext_ram_bss_end;
+#endif //#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
+
+
+static bool esp_spiram_test(uint32_t v_start, uint32_t size);
+
+
+esp_err_t esp_spiram_init(void)
 {
-    esp_err_t ret = psram_get_available_size(&s_mapped_size);
+    assert(!s_spiram_inited);
+    esp_err_t ret;
+    uint32_t psram_physical_size = 0;
+    ret = psram_enable(PSRAM_SPEED, PSRAM_MODE);
     if (ret != ESP_OK) {
-        abort();
+#if CONFIG_SPIRAM_IGNORE_NOTFOUND
+        ESP_EARLY_LOGE(TAG, "SPI RAM enabled but initialization failed. Bailing out.");
+#endif
+        return ret;
+    }
+    s_spiram_inited = true;
+
+    ret = psram_get_physical_size(&psram_physical_size);
+    assert(ret == ESP_OK);
+
+#if (CONFIG_SPIRAM_SIZE != -1)
+    if (psram_physical_size != CONFIG_SPIRAM_SIZE) {
+        ESP_EARLY_LOGE(TAG, "Expected %dMB chip but found %dMB chip. Bailing out..", (CONFIG_SPIRAM_SIZE / 1024 / 1024), (psram_physical_size / 1024 / 1024));
+        return ESP_ERR_INVALID_SIZE;
     }
-    if ((SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) < s_mapped_size) {
+#endif
+    ESP_EARLY_LOGI(TAG, "Found %dMB SPI RAM device", psram_physical_size / (1024 * 1024));
+    ESP_EARLY_LOGI(TAG, "Speed: %dMHz", CONFIG_SPIRAM_SPEED);
+
+    /**
+     * TODO IDF-4318
+     * Add these feature here:
+     * - Copy Flash text into PSRAM
+     * - Copy Flash rodata into PSRAM
+     */
+    //----------------------------------Map the PSRAM physical range to MMU-----------------------------//
+    uint32_t vaddr_start = 0;
+    extern uint32_t _rodata_reserved_end;
+    uint32_t rodata_end_aligned = ALIGN_UP_BY((uint32_t)&_rodata_reserved_end, MMU_PAGE_SIZE);
+    vaddr_start = rodata_end_aligned;
+    ESP_EARLY_LOGV(TAG, "rodata_end_aligned is 0x%x bytes", rodata_end_aligned);
+
+    uint32_t psram_available_size = 0;
+    ret = psram_get_available_size(&psram_available_size);
+    assert(ret == ESP_OK);
+
+    if (vaddr_start + psram_available_size > DRAM0_CACHE_ADDRESS_HIGH) {
         //Decide these logics when there's a real PSRAM with larger size
         ESP_EARLY_LOGE(TAG, "Virtual address not enough for PSRAM!");
         abort();
     }
-    s_mapped_vaddr_start = SOC_EXTRAM_DATA_HIGH - s_mapped_size;
 
-    Cache_Suspend_DCache();
-    Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, s_mapped_vaddr_start, 0, 64, s_mapped_size >> 16, 0);
-    REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE0_BUS);
+    //On ESP32S3, MMU is shared for both of the cores. Note this when porting `spiram.c`
+    uint32_t actual_mapped_len = 0;
+    mmu_hal_map_region(0, MMU_TARGET_PSRAM0, vaddr_start, 0, psram_available_size, &actual_mapped_len);
+    ESP_EARLY_LOGV(TAG, "actual_mapped_len is 0x%x bytes", actual_mapped_len);
+
+    cache_bus_mask_t bus_mask = cache_ll_l1_get_bus(0, vaddr_start, actual_mapped_len);
+    cache_ll_l1_enable_bus(0, bus_mask);
 #if !CONFIG_FREERTOS_UNICORE
-    REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE1_BUS);
+    bus_mask = cache_ll_l1_get_bus(1, vaddr_start, actual_mapped_len);
+    cache_ll_l1_enable_bus(1, bus_mask);
 #endif
-    Cache_Resume_DCache(0);
 
-    //Currently no non-heap stuff on ESP32S3
-    s_allocable_vaddr_start = s_mapped_vaddr_start;
-    s_allocable_vaddr_end = SOC_EXTRAM_DATA_HIGH;
+#if CONFIG_SPIRAM_MEMTEST
+    //After mapping, simple test SPIRAM first
+    bool ext_ram_ok = esp_spiram_test(vaddr_start, psram_available_size);
+    if (!ext_ram_ok) {
+        ESP_EARLY_LOGE(TAG, "External RAM failed memory test!");
+        abort();
+    }
+#endif  //#if CONFIG_SPIRAM_MEMTEST
+
+
+    /*------------------------------------------------------------------------------
+    * After mapping, we DON'T care about the PSRAM PHYSICAL ADDRESSS ANYMORE!
+    *----------------------------------------------------------------------------*/
+    s_mapped_vaddr_start = vaddr_start;
+    s_mapped_vaddr_end = vaddr_start + psram_available_size;
+    s_allocable_vaddr_start = vaddr_start;
+    s_allocable_vaddr_end = vaddr_start + psram_available_size;
+
+
+    //------------------------------------Configure .bss in PSRAM-------------------------------------//
+#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
+    //should never be negative number
+    uint32_t ext_bss_size = ((intptr_t)&_ext_ram_bss_end - (intptr_t)&_ext_ram_bss_start);
+    ESP_EARLY_LOGV(TAG, "_ext_ram_bss_start is 0x%x, _ext_ram_bss_start is 0x%x, ext_bss_size is 0x%x bytes", &_ext_ram_bss_start, &_ext_ram_bss_end, ext_bss_size);
+
+    s_allocable_vaddr_start += ext_bss_size;
+#endif  //#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
+
+    ESP_EARLY_LOGV(TAG, "s_allocable_vaddr_start is 0x%x, s_allocable_vaddr_end is 0x%x", s_allocable_vaddr_start, s_allocable_vaddr_end);
+    return ESP_OK;
 }
 
-/*
- Simple RAM test. Writes a word every 32 bytes. Takes about a second to complete for 4MiB. Returns
- true when RAM seems OK, false when test fails. WARNING: Do not run this before the 2nd cpu has been
- initialized (in a two-core system) or after the heap allocator has taken ownership of the memory.
-*/
-bool esp_spiram_test(void)
+/**
+ * Add the PSRAM available region to heap allocator. Heap allocator knows the capabilities of this type of memory,
+ * so there's no need to explicitly specify them.
+ */
+esp_err_t esp_spiram_add_to_heapalloc(void)
 {
-    volatile int *spiram = (volatile int *)s_mapped_vaddr_start;
+    ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", (s_allocable_vaddr_end - s_allocable_vaddr_start) / 1024);
+    return heap_caps_add_region(s_allocable_vaddr_start, s_allocable_vaddr_end);
+}
 
-    size_t s = s_mapped_size;
-    size_t p;
-    int errct = 0;
-    int initial_err = -1;
+esp_err_t IRAM_ATTR esp_spiram_get_mapped_range(intptr_t *out_vstart, intptr_t *out_vend)
+{
+    if (!out_vstart || !out_vend) {
+        return ESP_ERR_INVALID_ARG;
+    }
 
-    for (p = 0; p < (s / sizeof(int)); p += 8) {
-        spiram[p] = p ^ 0xAAAAAAAA;
+    if (!s_spiram_inited) {
+        return ESP_ERR_INVALID_STATE;
     }
-    for (p = 0; p < (s / sizeof(int)); p += 8) {
-        if (spiram[p] != (p ^ 0xAAAAAAAA)) {
-            errct++;
-            if (errct == 1) {
-                initial_err = p * 4;
-            }
-            if (errct < 4) {
-                ESP_EARLY_LOGE(TAG, "SPI SRAM error@%08x:%08x/%08x \n", &spiram[p], spiram[p], p ^ 0xAAAAAAAA);
-            }
-        }
+
+    *out_vstart = s_mapped_vaddr_start;
+    *out_vend = s_mapped_vaddr_end;
+    return ESP_OK;
+}
+
+esp_err_t esp_spiram_get_alloced_range(intptr_t *out_vstart, intptr_t *out_vend)
+{
+    if (!out_vstart || !out_vend) {
+        return ESP_ERR_INVALID_ARG;
     }
-    if (errct) {
-        ESP_EARLY_LOGE(TAG, "SPI SRAM memory test fail. %d/%d writes failed, first @ %X\n", errct, s / 32, initial_err + SOC_EXTRAM_DATA_LOW);
-        return false;
-    } else {
-        ESP_EARLY_LOGI(TAG, "SPI SRAM memory test OK");
-        return true;
+
+    if (!s_spiram_inited) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    *out_vstart = s_allocable_vaddr_start;
+    *out_vend = s_allocable_vaddr_end;
+    return ESP_OK;
+}
+
+esp_err_t esp_spiram_reserve_dma_pool(size_t size)
+{
+    if (size == 0) {
+        return ESP_OK;
+    }
+    ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size / 1024);
+    uint8_t *dma_heap = heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
+    if (!dma_heap) {
+        return ESP_ERR_NO_MEM;
     }
+    uint32_t caps[] = {MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT};
+    return heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap + size);
 }
 
 //TODO IDF-4318
@@ -222,81 +304,6 @@ int IRAM_ATTR rodata_flash2spiram_offset(void)
 }
 #endif
 
-esp_err_t esp_spiram_init(void)
-{
-    esp_err_t r;
-    uint32_t psram_physical_size = 0;
-    r = psram_enable(PSRAM_SPEED, PSRAM_MODE);
-    if (r != ESP_OK) {
-#if CONFIG_SPIRAM_IGNORE_NOTFOUND
-        ESP_EARLY_LOGE(TAG, "SPI RAM enabled but initialization failed. Bailing out.");
-#endif
-        return r;
-    }
-    s_spiram_inited = true;
-
-    r = psram_get_physical_size(&psram_physical_size);
-    if (r != ESP_OK) {
-        abort();
-    }
-#if (CONFIG_SPIRAM_SIZE != -1)
-    if (psram_physical_size != CONFIG_SPIRAM_SIZE) {
-        ESP_EARLY_LOGE(TAG, "Expected %dMB chip but found %dMB chip. Bailing out..", (CONFIG_SPIRAM_SIZE / 1024 / 1024), (psram_physical_size / 1024 / 1024));
-        return ESP_ERR_INVALID_SIZE;
-    }
-#endif
-    ESP_EARLY_LOGI(TAG, "Found %dMB SPI RAM device", psram_physical_size / (1024 * 1024));
-    ESP_EARLY_LOGI(TAG, "Speed: %dMHz", CONFIG_SPIRAM_SPEED);
-    ESP_EARLY_LOGI(TAG, "Initialized, cache is in %s mode.", \
-                   (PSRAM_MODE == PSRAM_VADDR_MODE_EVENODD) ? "even/odd (2-core)" : \
-                   (PSRAM_MODE == PSRAM_VADDR_MODE_LOWHIGH) ? "low/high (2-core)" : \
-                   (PSRAM_MODE == PSRAM_VADDR_MODE_NORMAL) ? "normal (1-core)" : "ERROR");
-    return ESP_OK;
-}
-
-/**
- * Add entire external RAM region to heap allocator. Heap allocator knows the capabilities of this type of memory,
- * so there's no need to explicitly specify them.
- */
-esp_err_t esp_spiram_add_to_heapalloc(void)
-{
-    ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", (s_allocable_vaddr_end - s_allocable_vaddr_start) / 1024);
-    return heap_caps_add_region(s_allocable_vaddr_start, s_allocable_vaddr_end - 1);
-}
-
-
-static uint8_t *dma_heap;
-
-esp_err_t esp_spiram_reserve_dma_pool(size_t size)
-{
-    if (size == 0) {
-        return ESP_OK;    //no-op
-    }
-    ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size / 1024);
-    dma_heap = heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
-    if (!dma_heap) {
-        return ESP_ERR_NO_MEM;
-    }
-    uint32_t caps[] = {MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT};
-    return heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap + size - 1);
-}
-
-size_t esp_spiram_get_size(void)
-{
-    if (!s_spiram_inited) {
-        ESP_EARLY_LOGE(TAG, "SPI RAM not initialized");
-        abort();
-    }
-
-    uint32_t size = 0;  //in bytes
-    esp_err_t ret = psram_get_available_size(&size);
-    if (ret == ESP_OK) {
-        return size;
-    } else {
-        return 0;
-    }
-}
-
 /*
  Before flushing the cache, if psram is enabled as a memory-mapped thing, we need to write back the data in the cache to the psram first,
  otherwise it will get lost. For now, we just read 64/128K of random PSRAM memory to do this.
@@ -323,4 +330,39 @@ uint8_t esp_spiram_get_cs_io(void)
     return psram_get_cs_io();
 }
 
-#endif
+/*
+ Simple RAM test. Writes a word every 32 bytes. Takes about a second to complete for 4MiB. Returns
+ true when RAM seems OK, false when test fails. WARNING: Do not run this before the 2nd cpu has been
+ initialized (in a two-core system) or after the heap allocator has taken ownership of the memory.
+*/
+static bool esp_spiram_test(uint32_t v_start, uint32_t size)
+{
+    volatile int *spiram = (volatile int *)v_start;
+
+    size_t s = size;
+    size_t p;
+    int errct = 0;
+    int initial_err = -1;
+
+    for (p = 0; p < (s / sizeof(int)); p += 8) {
+        spiram[p] = p ^ 0xAAAAAAAA;
+    }
+    for (p = 0; p < (s / sizeof(int)); p += 8) {
+        if (spiram[p] != (p ^ 0xAAAAAAAA)) {
+            errct++;
+            if (errct == 1) {
+                initial_err = p * 4;
+            }
+            if (errct < 4) {
+                ESP_EARLY_LOGE(TAG, "SPI SRAM error@%08x:%08x/%08x \n", &spiram[p], spiram[p], p ^ 0xAAAAAAAA);
+            }
+        }
+    }
+    if (errct) {
+        ESP_EARLY_LOGE(TAG, "SPI SRAM memory test fail. %d/%d writes failed, first @ %X\n", errct, s / 32, initial_err + SOC_EXTRAM_DATA_LOW);
+        return false;
+    } else {
+        ESP_EARLY_LOGI(TAG, "SPI SRAM memory test OK");
+        return true;
+    }
+}

+ 8 - 7
components/esp_hw_support/port/esp32s3/spiram_psram.c

@@ -1,7 +1,3 @@
-/*
- Driver bits for PSRAM chips (at the moment only the ESP-PSRAM32 chip).
-*/
-
 /*
  * SPDX-FileCopyrightText: 2013-2021 Espressif Systems (Shanghai) CO LTD
  *
@@ -35,8 +31,6 @@
 #include "driver/spi_common.h"
 #include "esp_private/periph_ctrl.h"
 #include "bootloader_common.h"
-
-#if CONFIG_SPIRAM_MODE_QUAD
 #include "soc/rtc.h"
 #include "esp_private/spi_flash_os.h"
 
@@ -409,6 +403,10 @@ static void config_psram_spi_phases(void)
  *-------------------------------------------------------------------------------*/
 esp_err_t psram_get_physical_size(uint32_t *out_size_bytes)
 {
+    if (!out_size_bytes) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
     *out_size_bytes = s_psram_size;
     return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
 }
@@ -421,7 +419,10 @@ esp_err_t psram_get_physical_size(uint32_t *out_size_bytes)
  */
 esp_err_t psram_get_available_size(uint32_t *out_size_bytes)
 {
+    if (!out_size_bytes) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
     *out_size_bytes = s_psram_size;
     return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
 }
-#endif // CONFIG_SPIRAM

+ 4 - 4
components/esp_hw_support/port/esp32s3/spiram_psram.h

@@ -9,16 +9,16 @@
 #include "esp_err.h"
 #include "sdkconfig.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define PSRAM_SIZE_2MB                  (2 * 1024 * 1024)
 #define PSRAM_SIZE_4MB                  (4 * 1024 * 1024)
 #define PSRAM_SIZE_8MB                  (8 * 1024 * 1024)
 #define PSRAM_SIZE_16MB                 (16 * 1024 * 1024)
 #define PSRAM_SIZE_32MB                 (32 * 1024 * 1024)
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 typedef enum {
     PSRAM_CACHE_S80M = 1,
     PSRAM_CACHE_S40M,

+ 1 - 1
components/esp_hw_support/sleep_retention.c

@@ -116,7 +116,7 @@ static esp_err_t esp_sleep_tagmem_pd_low_init(bool enable)
             uint32_t data_size = (uint32_t)(_rodata_reserved_end - _rodata_start);
 #else
             uint32_t data_start = SOC_DROM_LOW;
-            uint32_t data_size = (SOC_EXTRAM_DATA_HIGH-SOC_EXTRAM_DATA_LOW) + (SOC_DROM_HIGH-SOC_DROM_LOW);
+            uint32_t data_size = SOC_EXTRAM_DATA_SIZE;
 #endif
             ESP_LOGI(TAG, "Code start at %08x, total %.2f KiB, data start at %08x, total %.2f KiB",
                     code_start, (float)code_size/1024, data_start, (float)data_size/1024);

+ 13 - 3
components/esp_hw_support/test/test_psram.c

@@ -14,17 +14,27 @@
 #include "test_utils.h"
 #include "unity.h"
 #include "esp_heap_caps.h"
+#include "esp_private/spiram_private.h"
 #if CONFIG_SPIRAM
 #include "spiram.h"
 
 const static char *TAG = "PSRAM";
 
+
 #if CONFIG_SPIRAM_MODE_OCT
 #define TEST_ALLOC_SIZE    (4 * 1024 * 1024)
 #else
 #define TEST_ALLOC_SIZE    (1 * 1024 * 1024)
 #endif
 
+static bool s_check_valid_psram_alloced_range(const void *p)
+{
+    intptr_t vaddr_start = 0;
+    intptr_t vaddr_end = 0;
+    esp_spiram_get_alloced_range(&vaddr_start, &vaddr_end);
+    return (intptr_t)p >= vaddr_start && (intptr_t)p < vaddr_end;
+}
+
 TEST_CASE("test psram heap allocable","[psram]")
 {
     uint32_t *ext_buffer = (uint32_t *)heap_caps_calloc(TEST_ALLOC_SIZE, 1, MALLOC_CAP_SPIRAM);
@@ -32,9 +42,8 @@ TEST_CASE("test psram heap allocable","[psram]")
 
     uintptr_t start = (uintptr_t)ext_buffer;
     uintptr_t end = (uintptr_t)ext_buffer + TEST_ALLOC_SIZE;
-    ESP_LOGI(TAG, "test ext buffer start addr is %x, end addr is %x", start, end);
-    TEST_ASSERT((start >= SOC_EXTRAM_DATA_LOW) && (end <= SOC_EXTRAM_DATA_HIGH));
-
+    ESP_LOGI(TAG, "test ext buffer start addr is 0x%x, end addr is 0x%x", start, end);
+    TEST_ASSERT(s_check_valid_psram_alloced_range((void *)start) && s_check_valid_psram_alloced_range((void *)end));
 
     for (int i = 0; i < TEST_ALLOC_SIZE / sizeof(uint32_t); i++) {
         ext_buffer[i] = (i + 1) ^ 0xaaaaaaaa;
@@ -47,6 +56,7 @@ TEST_CASE("test psram heap allocable","[psram]")
     free(ext_buffer);
 }
 
+
 #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_RODATA
 #include "esp_timer.h"
 #include "esp32s3/rom/spi_flash.h"

+ 0 - 1
components/esp_system/ld/esp32s2/sections.ld.in

@@ -249,7 +249,6 @@ SECTIONS
   {
     . = ALIGN (8);
     _bss_start = ABSOLUTE(.);
-    *(.ext_ram.bss*)
 
     mapping[dram0_bss]
 

+ 6 - 1
components/esp_system/ld/esp32s3/memory.ld.in

@@ -90,7 +90,7 @@ MEMORY
 
 #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
   /* Flash mapped constant data */
-  drom0_0_seg (R) :                  org = 0x3C000020, len = 0x800000-0x20
+  drom0_0_seg (R) :                  org = 0x3C000020, len = 0x2000000-0x20
 
   /* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
 #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
@@ -115,6 +115,11 @@ MEMORY
 #else
   rtc_slow_seg(RW)  :                org = 0x50000000 , len = 0x2000
 #endif // CONFIG_ULP_COPROC_ENABLED
+  /**
+   * `extern_ram_seg` and `drom0_0_seg` share the same bus and the address region.
+   * A dummy section is used to avoid overlap. See `.ext_ram.dummy` in `sections.ld.in`
+   */
+  extern_ram_seg(RWX) :              org = 0x3c000020 , len = 0x2000000-0x20
 }
 
 #if CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE

+ 20 - 2
components/esp_system/ld/esp32s3/sections.ld.in

@@ -231,7 +231,6 @@ SECTIONS
   {
     . = ALIGN (8);
     _bss_start = ABSOLUTE(.);
-    *(.ext_ram.bss*)
 
     mapping[dram0_bss]
 
@@ -292,7 +291,7 @@ SECTIONS
    */
   .flash_rodata_dummy (NOLOAD):
   {
-    _flash_rodata_dummy_start = .;
+    _flash_rodata_dummy_start = ABSOLUTE(.);
     /* Start at the same alignment constraint than .flash.text */
     . = ALIGN(ALIGNOF(.flash.text));
     /* Create an empty gap as big as .flash.text section */
@@ -381,6 +380,25 @@ SECTIONS
     mapping[rodata_noload]
   } > default_rodata_seg
 
+  /**
+   * This section is required to skip flash rodata sections, because `extern_ram_seg`
+   * and `drom0_0_seg` are on the same bus
+   */
+  .ext_ram.dummy (NOLOAD):
+  {
+    . = ORIGIN(extern_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start);
+    . = ALIGN (0x10000);
+  } > extern_ram_seg
+
+  /* This section holds .ext_ram.bss data, and will be put in PSRAM */
+  .ext_ram.bss (NOLOAD) :
+  {
+    _ext_ram_bss_start = ABSOLUTE(.);
+    mapping[extern_ram]
+    . = ALIGN(4);
+    _ext_ram_bss_end = ABSOLUTE(.);
+  } > extern_ram_seg
+
   /* Marks the end of IRAM code segment */
   .iram0.text_end (NOLOAD) :
   {

+ 4 - 6
components/esp_system/port/cpu_start.c

@@ -389,12 +389,10 @@ void IRAM_ATTR call_start_cpu0(void)
     bootloader_init_mem();
 #if CONFIG_SPIRAM_BOOT_INIT
     if (esp_spiram_init() != ESP_OK) {
-#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
 #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
         ESP_EARLY_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment");
         abort();
 #endif
-#endif
 
 #if CONFIG_SPIRAM_IGNORE_NOTFOUND
         ESP_EARLY_LOGI(TAG, "Failed to init external RAM; continuing without it.");
@@ -405,11 +403,11 @@ void IRAM_ATTR call_start_cpu0(void)
 #endif
     }
     //TODO: IDF-4382
-#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3
+#if CONFIG_IDF_TARGET_ESP32
     if (g_spiram_ok) {
         esp_spiram_init_cache();
     }
-#endif  //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3, //TODO: IDF-4382
+#endif  //#if CONFIG_IDF_TARGET_ESP32, //TODO: IDF-4382
 #endif
 
 #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
@@ -439,7 +437,7 @@ void IRAM_ATTR call_start_cpu0(void)
 
 #if CONFIG_SPIRAM_MEMTEST
     //TODO: IDF-4382
-#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3
+#if CONFIG_IDF_TARGET_ESP32
     if (g_spiram_ok) {
         bool ext_ram_ok = esp_spiram_test();
         if (!ext_ram_ok) {
@@ -447,7 +445,7 @@ void IRAM_ATTR call_start_cpu0(void)
             abort();
         }
     }
-#endif  //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3, //TODO: IDF-4382
+#endif  //CONFIG_IDF_TARGET_ESP32, //TODO: IDF-4382
 #endif  //CONFIG_SPIRAM_MEMTEST
 
     //TODO: IDF-4382

+ 2 - 0
components/heap/heap_tlsf_config.h

@@ -87,6 +87,8 @@ enum tlsf_config
 	FL_INDEX_MAX = 23, //Each pool can have up 8MB
 	#elif (TLSF_MAX_POOL_SIZE <= (16 * 1024 * 1024))
 	FL_INDEX_MAX = 24, //Each pool can have up 16MB
+	#elif (TLSF_MAX_POOL_SIZE <= (32 * 1024 * 1024))
+	FL_INDEX_MAX = 25, //Each pool can have up 32MB
 	#else
 	#error "Higher TLSF pool sizes should be added for this new config"
 	#endif

+ 1 - 1
components/soc/esp32s3/include/soc/soc.h

@@ -185,7 +185,7 @@
 #define SOC_RTC_DATA_LOW  0x50000000
 #define SOC_RTC_DATA_HIGH 0x50002000
 
-#define SOC_EXTRAM_DATA_LOW 0x3D000000
+#define SOC_EXTRAM_DATA_LOW 0x3C000000
 #define SOC_EXTRAM_DATA_HIGH 0x3E000000
 #define SOC_IROM_MASK_LOW  0x40000000
 #define SOC_IROM_MASK_HIGH 0x4001A100

+ 2 - 2
docs/en/api-guides/external-ram.rst

@@ -129,8 +129,8 @@ External RAM use has the following restrictions:
 
  * When flash cache is disabled (for example, if the flash is being written to), the external RAM also becomes inaccessible; any reads from or writes to it will lead to an illegal cache access exception. This is also the reason why ESP-IDF does not by default allocate any task stacks in external RAM (see below).
 
-  * External RAM cannot be used as a place to store DMA transaction descriptors or as a buffer for a DMA transfer to read from or write into. Therefore when External RAM is enabled, any buffers that will be used in combination with DMA must be allocated using ``heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL)`` and can be freed using a standard ``free()`` call. 
-  
+  * External RAM cannot be used as a place to store DMA transaction descriptors or as a buffer for a DMA transfer to read from or write into. Therefore when External RAM is enabled, any buffer that will be used in combination with DMA must be allocated using ``heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL)`` and can be freed using a standard ``free()`` call.
+
   .. only:: SOC_PSRAM_DMA_CAPABLE
 
     Note, although {IDF_TARGET_NAME} has hardware support for DMA to/from external RAM, this is not yet supported in ESP-IDF.

+ 9 - 2
docs/en/migration-guides/system.rst

@@ -41,10 +41,17 @@ ESP HW Support
 - The header file ``esp_intr.h`` has been deleted. Please include ``esp_intr_alloc.h`` to allocate and manipulate interrupts.
 - The header file ``esp_panic.h`` has been deleted. ESP-IDF developers should include ``esp_private/panic_reason.h`` to get supported panic reasons. And should include ``esp_debug_helpers.h`` to use any debug related helper functions, e.g. print backtrace.
 - The header file ``soc_log.h`` is now renamed to ``esp_hw_log.h`` and all logging macros have been updated from ``SOC_LOGx`` to ``ESP_HW_LOGx``. ESP-IDF users must use the later form.
-- The header file ``esp_spiram.h`` file is deleted. Users should use the ``<target>/spiram.h`` file instead.
-- The header file ``esp32/himem.h`` file is deleted. Users should use the esp_himem.h file instead.
 - The header files ``spinlock.h``, ``clk_ctrl_os.h`` and ``rtc_wdt.h`` must now be included without the ``soc`` prefix. Eg:- ``#include "spinlock.h"``.
 
+PSRAM
+^^^^^
+
+- The header file ``esp_spiram.h`` file has been deleted. Users should use the ``<target>/spiram.h`` file instead.
+- The header file ``esp32/himem.h`` file has been deleted. Users should use the esp_himem.h file instead.
+- `esp_spiram_get_chip_size` has been deleted.
+- `esp_spiram_get_size` has been moved to `esp_private/spiram_private.h`
+
+
 ESP System
 ----------
 - The header files ``esp_random.h``, ``esp_mac.h`` and ``esp_chip_info.h``, which were all previously indirectly included via the header file ``esp_system.h``, must now be included directly. These headers are removed from ``esp_system.h``.