diff --git a/include/zephyr/multi_heap/shared_multi_heap.h b/include/zephyr/multi_heap/shared_multi_heap.h index a9cdf120fae..652ecb5eb7a 100644 --- a/include/zephyr/multi_heap/shared_multi_heap.h +++ b/include/zephyr/multi_heap/shared_multi_heap.h @@ -73,6 +73,9 @@ enum shared_multi_heap_attr { /** non-cacheable */ SMH_REG_ATTR_NON_CACHEABLE, + /** external Memory */ + SMH_REG_ATTR_EXTERNAL, + /** must be the last item */ SMH_REG_ATTR_NUM, }; diff --git a/soc/espressif/common/CMakeLists.txt b/soc/espressif/common/CMakeLists.txt index 9cd2b6747ac..98984d2503f 100644 --- a/soc/espressif/common/CMakeLists.txt +++ b/soc/espressif/common/CMakeLists.txt @@ -4,3 +4,5 @@ if(CONFIG_SOC_SERIES_ESP32 OR CONFIG_SOC_SERIES_ESP32S2 OR CONFIG_SOC_SERIES_ESP32S3) zephyr_include_directories(include) endif() + +zephyr_sources_ifdef(CONFIG_ESP_SPIRAM psram.c) diff --git a/soc/espressif/common/Kconfig.spiram b/soc/espressif/common/Kconfig.spiram index b3e1896997c..051131debac 100644 --- a/soc/espressif/common/Kconfig.spiram +++ b/soc/espressif/common/Kconfig.spiram @@ -7,6 +7,7 @@ config ESP_SPIRAM bool "Support for external, SPI-connected RAM" default n if MCUBOOT default n if ESP32_USE_UNSUPPORTED_REVISION && SOC_SERIES_ESP32 + select SHARED_MULTI_HEAP help This enables support for an external SPI RAM chip, connected in parallel with the main SPI flash chip. @@ -14,15 +15,6 @@ config ESP_SPIRAM menu "SPI RAM config" depends on ESP_SPIRAM -config ESP_HEAP_MIN_EXTRAM_THRESHOLD - int "Minimum threshold for external RAM allocation" - default 8192 - range 1024 131072 - help - Threshold to decide if memory will be allocated from DRAM - or SPIRAM. If value of allocation size is less than this value, - memory will be allocated from internal RAM. - config ESP_HEAP_SEARCH_ALL_REGIONS bool "Search for all available heap regions" default y diff --git a/soc/espressif/common/include/psram.h b/soc/espressif/common/include/psram.h new file mode 100644 index 00000000000..a7d65935929 --- /dev/null +++ b/soc/espressif/common/include/psram.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +int esp_init_psram(void); + +int esp_psram_smh_init(void); diff --git a/soc/espressif/common/psram.c b/soc/espressif/common/psram.c new file mode 100644 index 00000000000..ca62fa9b922 --- /dev/null +++ b/soc/espressif/common/psram.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define PSRAM_ADDR (DT_REG_ADDR(DT_NODELABEL(psram0))) + +extern int _spiram_heap_start; +extern int _ext_ram_bss_start; +extern int _ext_ram_bss_end; + +struct shared_multi_heap_region smh_psram = { + .addr = (uintptr_t)&_spiram_heap_start, + .size = CONFIG_ESP_SPIRAM_SIZE, + .attr = SMH_REG_ATTR_EXTERNAL, +}; + +int esp_psram_smh_init(void) +{ + shared_multi_heap_pool_init(); + smh_psram.size = CONFIG_ESP_SPIRAM_SIZE - ((int)&_spiram_heap_start - PSRAM_ADDR); + return shared_multi_heap_add(&smh_psram, NULL); +} + +void esp_init_psram(void) +{ + if (esp_psram_init()) { + ets_printf("Failed to Initialize external RAM, aborting.\n"); + return; + } + + if (esp_psram_get_size() < CONFIG_ESP_SPIRAM_SIZE) { + ets_printf("External RAM size is less than configured.\n"); + } + + if (esp_psram_is_initialized()) { + if (!esp_psram_extram_test()) { + ets_printf("External RAM failed memory test!"); + return; + } + } + + memset(&_ext_ram_bss_start, 0, + (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start)); +} diff --git a/soc/espressif/esp32/soc.c b/soc/espressif/esp32/soc.c index 390c8b29004..ad50f3210a4 100644 --- a/soc/espressif/esp32/soc.c +++ b/soc/espressif/esp32/soc.c @@ -14,8 +14,7 @@ #include #include #if CONFIG_ESP_SPIRAM -#include -#include +#include "psram.h" #endif #include @@ -45,11 +44,6 @@ #define TAG "boot.esp32" -#if CONFIG_ESP_SPIRAM -extern int _ext_ram_bss_start; -extern int _ext_ram_bss_end; -#endif - extern void z_prep_c(void); extern void esp_reset_reason_init(void); @@ -155,26 +149,7 @@ void IRAM_ATTR __esp_platform_start(void) #endif #if CONFIG_ESP_SPIRAM - esp_err_t err = esp_psram_init(); - - if (err != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Failed to Initialize SPIRAM, aborting."); - abort(); - } - if (esp_psram_get_size() < CONFIG_ESP_SPIRAM_SIZE) { - ESP_EARLY_LOGE(TAG, "SPIRAM size is less than configured size, aborting."); - abort(); - } - - if (esp_psram_is_initialized()) { - if (!esp_psram_extram_test()) { - ESP_EARLY_LOGE(TAG, "External RAM failed memory test!"); - abort(); - } - } - - memset(&_ext_ram_bss_start, 0, - (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start)); + esp_init_psram(); #endif /* CONFIG_ESP_SPIRAM */ /* Scheduler is not started at this point. Hence, guard functions @@ -190,6 +165,15 @@ void IRAM_ATTR __esp_platform_start(void) esp_intr_initialize(); +#if CONFIG_ESP_SPIRAM + /* Init Shared Multi Heap for PSRAM */ + int err = esp_psram_smh_init(); + + if (err) { + printk("Failed to initialize PSRAM shared multi heap (%d)\n", err); + } +#endif + /* Start Zephyr */ z_prep_c(); diff --git a/soc/espressif/esp32s2/soc.c b/soc/espressif/esp32s2/soc.c index a3d0170a0f0..6414bc23928 100644 --- a/soc/espressif/esp32s2/soc.c +++ b/soc/espressif/esp32s2/soc.c @@ -15,8 +15,7 @@ #include #include #if CONFIG_ESP_SPIRAM -#include -#include +#include "psram.h" #endif #include @@ -44,11 +43,6 @@ extern void rtc_clk_cpu_freq_set_xtal(void); extern void esp_reset_reason_init(void); extern void z_prep_c(void); -#if CONFIG_ESP_SPIRAM -extern int _ext_ram_bss_start; -extern int _ext_ram_bss_end; -#endif - /* * This is written in C rather than assembly since, during the port bring up, * Zephyr is being booted by the Espressif bootloader. With it, the C stack @@ -110,27 +104,7 @@ void __attribute__((section(".iram1"))) __esp_platform_start(void) esp_mmu_map_init(); #if CONFIG_ESP_SPIRAM - esp_err_t err = esp_psram_init(); - - if (err != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Failed to Initialize SPIRAM, aborting."); - abort(); - } - if (esp_psram_get_size() < CONFIG_ESP_SPIRAM_SIZE) { - ESP_EARLY_LOGE(TAG, "SPIRAM size is less than configured size, aborting."); - abort(); - } - - if (esp_psram_is_initialized()) { - if (!esp_psram_extram_test()) { - ESP_EARLY_LOGE(TAG, "External RAM failed memory test!"); - abort(); - } - } - - memset(&_ext_ram_bss_start, 0, - (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start)); - + esp_init_psram(); #endif /* CONFIG_ESP_SPIRAM */ esp_timer_early_init(); @@ -146,6 +120,16 @@ void __attribute__((section(".iram1"))) __esp_platform_start(void) #endif /* !CONFIG_MCUBOOT */ esp_intr_initialize(); + +#if CONFIG_ESP_SPIRAM + /* Init Shared Multi Heap for PSRAM */ + int err = esp_psram_smh_init(); + + if (err) { + printk("Failed to initialize PSRAM shared multi heap (%d)\n", err); + } +#endif + /* Start Zephyr */ z_prep_c(); diff --git a/soc/espressif/esp32s3/soc.c b/soc/espressif/esp32s3/soc.c index 2c45f2e866c..079a879326c 100644 --- a/soc/espressif/esp32s3/soc.c +++ b/soc/espressif/esp32s3/soc.c @@ -19,12 +19,10 @@ #include #if CONFIG_ESP_SPIRAM -#include -#include +#include "psram.h" #endif #include -#include #include #include #include @@ -50,11 +48,6 @@ #define TAG "boot.esp32s3" -#if CONFIG_ESP_SPIRAM -extern int _ext_ram_bss_start; -extern int _ext_ram_bss_end; -#endif - extern void z_prep_c(void); extern void esp_reset_reason_init(void); @@ -161,28 +154,7 @@ void IRAM_ATTR __esp_platform_start(void) esp_mmu_map_init(); #if CONFIG_ESP_SPIRAM - esp_err_t err = esp_psram_init(); - - if (err != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Failed to Initialize external RAM, aborting."); - abort(); - } - - if (esp_psram_get_size() < CONFIG_ESP_SPIRAM_SIZE) { - ESP_EARLY_LOGE(TAG, "External RAM size is less than configured, aborting."); - abort(); - } - - if (esp_psram_is_initialized()) { - if (!esp_psram_extram_test()) { - ESP_EARLY_LOGE(TAG, "External RAM failed memory test!"); - abort(); - } - } - - memset(&_ext_ram_bss_start, 0, - (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start)); - + esp_init_psram(); #endif /* CONFIG_ESP_SPIRAM */ /* Apply SoC patches */ @@ -214,6 +186,15 @@ void IRAM_ATTR __esp_platform_start(void) esp_intr_initialize(); +#if CONFIG_ESP_SPIRAM + /* Init Shared Multi Heap for PSRAM */ + int err = esp_psram_smh_init(); + + if (err) { + printk("Failed to initialize PSRAM shared multi heap (%d)\n", err); + } +#endif + /* Start Zephyr */ z_prep_c();