/* * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include "esp_idf_version.h" #include "esp_attr.h" #include "esp_heap_caps.h" #include "soc/soc.h" #include "private/elf_platform.h" #ifdef CONFIG_ELF_LOADER_LOAD_PSRAM #ifdef CONFIG_IDF_TARGET_ESP32S3 #define OFFSET_TEXT_VALUE (SOC_IROM_LOW - SOC_DROM_LOW) #endif #endif /** * @brief Allocate block of memory. * * @param n - Memory size in byte * @param exec - True: memory can run executable code; False: memory can R/W data * * @return Memory pointer if success or NULL if failed. */ void *esp_elf_malloc(uint32_t n, bool exec) { uint32_t caps; #if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR #ifdef CONFIG_ELF_LOADER_LOAD_PSRAM caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT; #else caps = exec ? MALLOC_CAP_EXEC : MALLOC_CAP_8BIT; #endif #else #ifdef CONFIG_ELF_LOADER_LOAD_PSRAM caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT; #else caps = MALLOC_CAP_8BIT; #endif #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) caps |= MALLOC_CAP_CACHE_ALIGNED; #endif #endif return heap_caps_malloc(n, caps); } /** * @brief Free block of memory. * * @param ptr - memory block pointer allocated by "esp_elf_malloc" * * @return None */ void esp_elf_free(void *ptr) { heap_caps_free(ptr); } /** * @brief Remap symbol from ".data" to ".text" section. * * @param elf - ELF object pointer * @param sym - ELF symbol table * * @return Remapped symbol value */ #ifdef CONFIG_ELF_LOADER_CACHE_OFFSET uintptr_t elf_remap_text(esp_elf_t *elf, uintptr_t sym) { uintptr_t mapped_sym; esp_elf_sec_t *sec = &elf->sec[ELF_SEC_TEXT]; if ((sym >= sec->addr) && (sym < (sec->addr + sec->size))) { #ifdef CONFIG_ELF_LOADER_SET_MMU mapped_sym = sym + elf->text_off; #else mapped_sym = sym + OFFSET_TEXT_VALUE; #endif } else { mapped_sym = sym; } return mapped_sym; } #endif /** * @brief Flush data from cache to external RAM. * * @param None * * @return None */ #ifdef CONFIG_ELF_LOADER_LOAD_PSRAM void IRAM_ATTR esp_elf_arch_flush(void) { extern void spi_flash_disable_interrupts_caches_and_other_cpu(void); extern void spi_flash_enable_interrupts_caches_and_other_cpu(void); #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) extern void Cache_WriteBack_All(void); Cache_WriteBack_All(); #else void esp_spiram_writeback_cache(void); esp_spiram_writeback_cache(); #endif spi_flash_disable_interrupts_caches_and_other_cpu(); spi_flash_enable_interrupts_caches_and_other_cpu(); } #endif