diff --git a/components/esp32s2/Kconfig b/components/esp32s2/Kconfig index e6102314ec..6998011d0f 100644 --- a/components/esp32s2/Kconfig +++ b/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 diff --git a/components/esp_common/test/test_attr.c b/components/esp_common/test/test_attr.c index 7c5f5f5a4a..abd771cf08 100644 --- a/components/esp_common/test/test_attr.c +++ b/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]") diff --git a/components/esp_hw_support/Kconfig.spiram.common b/components/esp_hw_support/Kconfig.spiram.common index 7dbf539af9..4356b127cb 100644 --- a/components/esp_hw_support/Kconfig.spiram.common +++ b/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. diff --git a/components/esp_hw_support/esp_memory_utils.c b/components/esp_hw_support/esp_memory_utils.c index 644d2bdf26..7cb083c56d 100644 --- a/components/esp_hw_support/esp_memory_utils.c +++ b/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 diff --git a/components/esp_hw_support/include/esp_private/spiram_private.h b/components/esp_hw_support/include/esp_private/spiram_private.h new file mode 100644 index 0000000000..646f6ce067 --- /dev/null +++ b/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 +#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 diff --git a/components/esp_hw_support/include/soc/esp32/spiram.h b/components/esp_hw_support/include/soc/esp32/spiram.h index a6086f3d31..9b6105c5c7 100644 --- a/components/esp_hw_support/include/soc/esp32/spiram.h +++ b/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 diff --git a/components/esp_hw_support/include/soc/esp32s2/spiram.h b/components/esp_hw_support/include/soc/esp32s2/spiram.h index 15b9868764..49e29247bf 100644 --- a/components/esp_hw_support/include/soc/esp32s2/spiram.h +++ b/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 diff --git a/components/esp_hw_support/include/soc/esp32s3/spiram.h b/components/esp_hw_support/include/soc/esp32s3/spiram.h index e25a15d692..d9dacce89b 100644 --- a/components/esp_hw_support/include/soc/esp32s3/spiram.h +++ b/components/esp_hw_support/include/soc/esp32s3/spiram.h @@ -5,8 +5,7 @@ */ -#ifndef __ESP_SPIRAM_H -#define __ESP_SPIRAM_H +#pragma once #include #include @@ -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 diff --git a/components/esp_hw_support/include/spinlock.h b/components/esp_hw_support/include/spinlock.h index 2254de40c4..7c7aee48df 100644 --- a/components/esp_hw_support/include/spinlock.h +++ b/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 diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 3832c4358e..7f625fd4f4 100644 --- a/components/esp_hw_support/linker.lf +++ b/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) diff --git a/components/esp_hw_support/port/esp32/esp_himem.c b/components/esp_hw_support/port/esp32/esp_himem.c index 3bdbdf9059..15c0e26ab6 100644 --- a/components/esp_hw_support/port/esp32/esp_himem.c +++ b/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" diff --git a/components/esp_hw_support/port/esp32/spiram.c b/components/esp_hw_support/port/esp32/spiram.c index 9164947d45..bc49f3743c 100644 --- a/components/esp_hw_support/port/esp32/spiram.c +++ b/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; } diff --git a/components/esp_hw_support/port/esp32s2/CMakeLists.txt b/components/esp_hw_support/port/esp32s2/CMakeLists.txt index 4883f875a9..dad5721108 100644 --- a/components/esp_hw_support/port/esp32s2/CMakeLists.txt +++ b/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}") diff --git a/components/esp_hw_support/port/esp32s2/spiram.c b/components/esp_hw_support/port/esp32s2/spiram.c index ff3d46f48f..c65cab5159 100644 --- a/components/esp_hw_support/port/esp32s2/spiram.c +++ b/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 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); -} - -//TODO IDF-4380 -size_t esp_spiram_get_size(void) +esp_err_t IRAM_ATTR esp_spiram_get_mapped_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_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 (!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; diff --git a/components/esp_hw_support/port/esp32s2/spiram_psram.c b/components/esp_hw_support/port/esp32s2/spiram_psram.c index 223d3c183e..9611486b1d 100644 --- a/components/esp_hw_support/port/esp32s2/spiram_psram.c +++ b/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); +} diff --git a/components/esp_hw_support/port/esp32s2/spiram_psram.h b/components/esp_hw_support/port/esp32s2/spiram_psram.h index 819bdc6203..cc21a7de4b 100644 --- a/components/esp_hw_support/port/esp32s2/spiram_psram.h +++ b/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. */ -psram_size_t psram_get_size(void); +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. + */ +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 diff --git a/components/esp_hw_support/port/esp32s3/CMakeLists.txt b/components/esp_hw_support/port/esp32s3/CMakeLists.txt index c6d09bf069..fd797ad315 100644 --- a/components/esp_hw_support/port/esp32s3/CMakeLists.txt +++ b/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") + 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}") diff --git a/components/esp_hw_support/port/esp32s3/opiram_psram.c b/components/esp_hw_support/port/esp32s3/opiram_psram.c index 1f05a386de..fdd0f86c91 100644 --- a/components/esp_hw_support/port/esp32s3/opiram_psram.c +++ b/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 diff --git a/components/esp_hw_support/port/esp32s3/spiram.c b/components/esp_hw_support/port/esp32s3/spiram.c index c39c876ecf..7ac6a8fdb8 100644 --- a/components/esp_hw_support/port/esp32s3/spiram.c +++ b/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 #include #include #include "sdkconfig.h" #include "esp_attr.h" #include "esp_err.h" +#include "esp_log.h" +#include "esp_heap_caps_init.h" +#include "esp_private/spiram_private.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 "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; } - if ((SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) < s_mapped_size) { + 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; + } +#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; + } +} diff --git a/components/esp_hw_support/port/esp32s3/spiram_psram.c b/components/esp_hw_support/port/esp32s3/spiram_psram.c index 9ca43271ec..2e5ecb377e 100644 --- a/components/esp_hw_support/port/esp32s3/spiram_psram.c +++ b/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 diff --git a/components/esp_hw_support/port/esp32s3/spiram_psram.h b/components/esp_hw_support/port/esp32s3/spiram_psram.h index dde57cb938..2e02363c69 100644 --- a/components/esp_hw_support/port/esp32s3/spiram_psram.h +++ b/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, diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 86a4d84b4d..89e9f1de57 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/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); diff --git a/components/esp_hw_support/test/test_psram.c b/components/esp_hw_support/test/test_psram.c index 2ec2b7b859..659cedc827 100644 --- a/components/esp_hw_support/test/test_psram.c +++ b/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" diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index ff716c49cf..270a6a94d8 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -249,7 +249,6 @@ SECTIONS { . = ALIGN (8); _bss_start = ABSOLUTE(.); - *(.ext_ram.bss*) mapping[dram0_bss] diff --git a/components/esp_system/ld/esp32s3/memory.ld.in b/components/esp_system/ld/esp32s3/memory.ld.in index 1623aa15b4..529a348176 100644 --- a/components/esp_system/ld/esp32s3/memory.ld.in +++ b/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 diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index b0b585465e..b1885ee3ac 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/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) : { diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 6265d4f667..333f537d27 100644 --- a/components/esp_system/port/cpu_start.c +++ b/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 diff --git a/components/heap/heap_tlsf_config.h b/components/heap/heap_tlsf_config.h index f26daf81f6..48189b0ed5 100644 --- a/components/heap/heap_tlsf_config.h +++ b/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 diff --git a/components/soc/esp32s3/include/soc/soc.h b/components/soc/esp32s3/include/soc/soc.h index b5df8e1201..bc94faf5f6 100644 --- a/components/soc/esp32s3/include/soc/soc.h +++ b/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 diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index dab9191fe9..b783c4592c 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/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. diff --git a/docs/en/migration-guides/system.rst b/docs/en/migration-guides/system.rst index a87cb9209c..5ae55c6ef6 100644 --- a/docs/en/migration-guides/system.rst +++ b/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 ``/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 ``/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``.