/* * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include "sdkconfig.h" #include "esp_attr.h" #include "esp_log.h" #include "esp_check.h" #include "esp_intr_alloc.h" #include "esp_cache.h" #include "esp_heap_caps.h" #include "esp_private/esp_psram_mspi.h" __attribute__((unused)) static DRAM_ATTR char TAG[] = "MSPI Timing"; #if ESP_PSRAM_MSPI_MB_WORKAROUND static void *s_psram_mb_dummy_cacheline; //dummy cacheline for cache memory barrier #endif esp_err_t esp_psram_mspi_mb_init(void) { #if ESP_PSRAM_MSPI_MB_WORKAROUND s_psram_mb_dummy_cacheline = heap_caps_calloc(1, CONFIG_CACHE_L1_CACHE_LINE_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_CACHE_ALIGNED); if (!s_psram_mb_dummy_cacheline) { ESP_EARLY_LOGE(TAG, "Failed to allocate dummy cacheline for PSRAM memory barrier!"); } #endif return ESP_OK; } void IRAM_ATTR esp_psram_mspi_mb(void) { #if ESP_PSRAM_MSPI_MB_WORKAROUND if (s_psram_mb_dummy_cacheline) { uint32_t *p = (uint32_t *)s_psram_mb_dummy_cacheline; *p = (*p + 1) % UINT32_MAX; __attribute__((unused)) esp_err_t ret = ESP_FAIL; ret = esp_cache_msync(s_psram_mb_dummy_cacheline, sizeof(uint32_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); //malloc is aligned, no need to writeback all assert(ret == ESP_OK); asm volatile("fence"); } #endif }