mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'test/add_cache2phys_xip_tests_v5.3' into 'release/v5.3'
fix(mmap): fixed spi_flash_phys2cache, spi_flash_cache2phys return addr in PSRAM issue (v5.3) See merge request espressif/esp-idf!33628
This commit is contained in:
@@ -270,81 +270,6 @@ uint32_t spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory)
|
||||
return len / CONFIG_MMU_PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
size_t spi_flash_cache2phys(const void *cached)
|
||||
{
|
||||
if (cached == NULL) {
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
uint32_t paddr = 0;
|
||||
mmu_target_t target = 0;
|
||||
|
||||
#if CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM //TODO: IDF-9049
|
||||
paddr = mmu_xip_psram_flash_vaddr_to_paddr(cached);
|
||||
//SPI_FLASH_CACHE2PHYS_FAIL is UINT32_MAX
|
||||
if (paddr != SPI_FLASH_CACHE2PHYS_FAIL) {
|
||||
return paddr;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = esp_mmu_vaddr_to_paddr((void *)cached, &paddr, &target);
|
||||
if (ret != ESP_OK) {
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
|
||||
#if !SOC_MMU_PER_EXT_MEM_TARGET //TODO: IDF-9049
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
if ((uint32_t)cached >= (uint32_t)&_rodata_reserved_start && (uint32_t)cached <= (uint32_t)&_rodata_reserved_end) {
|
||||
offset = rodata_flash2spiram_offset();
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
if ((uint32_t)cached >= (uint32_t)&_instruction_reserved_start && (uint32_t)cached <= (uint32_t)&_instruction_reserved_end) {
|
||||
offset = instruction_flash2spiram_offset();
|
||||
}
|
||||
#endif
|
||||
#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET
|
||||
|
||||
return paddr + offset * CONFIG_MMU_PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memory)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
void *ptr = NULL;
|
||||
mmu_target_t target = MMU_TARGET_FLASH0;
|
||||
|
||||
__attribute__((unused)) uint32_t phys_page = phys_offs / CONFIG_MMU_PAGE_SIZE;
|
||||
#if !SOC_MMU_PER_EXT_MEM_TARGET
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
if (phys_page >= instruction_flash_start_page_get() && phys_page <= instruction_flash_end_page_get()) {
|
||||
target = MMU_TARGET_PSRAM0;
|
||||
phys_offs -= instruction_flash2spiram_offset() * CONFIG_MMU_PAGE_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
if (phys_page >= rodata_flash_start_page_get() && phys_page <= rodata_flash_start_page_get()) {
|
||||
target = MMU_TARGET_PSRAM0;
|
||||
phys_offs -= rodata_flash2spiram_offset() * CONFIG_MMU_PAGE_SIZE;
|
||||
}
|
||||
#endif
|
||||
#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET
|
||||
|
||||
mmu_vaddr_t type = (memory == SPI_FLASH_MMAP_DATA) ? MMU_VADDR_DATA : MMU_VADDR_INSTRUCTION;
|
||||
ret = esp_mmu_paddr_to_vaddr(phys_offs, target, type, &ptr);
|
||||
if (ret == ESP_ERR_NOT_FOUND) {
|
||||
return NULL;
|
||||
}
|
||||
assert(ret == ESP_OK);
|
||||
return (const void *)ptr;
|
||||
}
|
||||
|
||||
static bool IRAM_ATTR is_page_mapped_in_cache(uint32_t phys_addr, const void **out_ptr)
|
||||
{
|
||||
*out_ptr = NULL;
|
||||
@@ -397,3 +322,80 @@ IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length)
|
||||
return ret;
|
||||
}
|
||||
#endif //!CONFIG_SPI_FLASH_ROM_IMPL
|
||||
|
||||
#if !CONFIG_SPI_FLASH_ROM_IMPL || CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA
|
||||
//The ROM implementation returns physical address of the PSRAM when the .text or .rodata is in the PSRAM.
|
||||
//Always patch it when SPIRAM_FETCH_INSTRUCTIONS or SPIRAM_RODATA is set.
|
||||
size_t spi_flash_cache2phys(const void *cached)
|
||||
{
|
||||
if (cached == NULL) {
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
uint32_t paddr = 0;
|
||||
mmu_target_t target = 0;
|
||||
|
||||
#if CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM //TODO: IDF-9049
|
||||
paddr = mmu_xip_psram_flash_vaddr_to_paddr(cached);
|
||||
//SPI_FLASH_CACHE2PHYS_FAIL is UINT32_MAX
|
||||
if (paddr != SPI_FLASH_CACHE2PHYS_FAIL) {
|
||||
return paddr;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = esp_mmu_vaddr_to_paddr((void *)cached, &paddr, &target);
|
||||
if (ret != ESP_OK) {
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
|
||||
#if !SOC_MMU_PER_EXT_MEM_TARGET //TODO: IDF-9049
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
if ((uint32_t)cached >= (uint32_t)&_rodata_reserved_start && (uint32_t)cached <= (uint32_t)&_rodata_reserved_end) {
|
||||
offset = rodata_flash2spiram_offset();
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
if ((uint32_t)cached >= (uint32_t)&_instruction_reserved_start && (uint32_t)cached <= (uint32_t)&_instruction_reserved_end) {
|
||||
offset = instruction_flash2spiram_offset();
|
||||
}
|
||||
#endif
|
||||
#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET
|
||||
|
||||
return paddr + offset * CONFIG_MMU_PAGE_SIZE;
|
||||
}
|
||||
|
||||
const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memory)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
void *ptr = NULL;
|
||||
mmu_target_t target = MMU_TARGET_FLASH0;
|
||||
|
||||
__attribute__((unused)) uint32_t phys_page = phys_offs / CONFIG_MMU_PAGE_SIZE;
|
||||
#if !SOC_MMU_PER_EXT_MEM_TARGET
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
if (phys_page >= instruction_flash_start_page_get() && phys_page <= instruction_flash_end_page_get()) {
|
||||
target = MMU_TARGET_PSRAM0;
|
||||
phys_offs -= instruction_flash2spiram_offset() * CONFIG_MMU_PAGE_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
if (phys_page >= rodata_flash_start_page_get() && phys_page <= rodata_flash_start_page_get()) {
|
||||
target = MMU_TARGET_PSRAM0;
|
||||
phys_offs -= rodata_flash2spiram_offset() * CONFIG_MMU_PAGE_SIZE;
|
||||
}
|
||||
#endif
|
||||
#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET
|
||||
|
||||
mmu_vaddr_t type = (memory == SPI_FLASH_MMAP_DATA) ? MMU_VADDR_DATA : MMU_VADDR_INSTRUCTION;
|
||||
ret = esp_mmu_paddr_to_vaddr(phys_offs, target, type, &ptr);
|
||||
if (ret == ESP_ERR_NOT_FOUND) {
|
||||
return NULL;
|
||||
}
|
||||
assert(ret == ESP_OK);
|
||||
return (const void *)ptr;
|
||||
}
|
||||
#endif //!CONFIG_SPI_FLASH_ROM_IMPL || CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA
|
||||
|
||||
@@ -39,6 +39,11 @@ components/spi_flash/test_apps/flash_mmap:
|
||||
depends_components:
|
||||
- esp_mm
|
||||
- spi_flash
|
||||
enable:
|
||||
- if: CONFIG_NAME in ["release", "rom_impl"] and IDF_TARGET not in ["linux", "esp32c61"]
|
||||
- if: CONFIG_NAME == "xip_psram" and IDF_TARGET in ["esp32s2", "esp32s3", "esp32p4"]
|
||||
# S2 doesn't have ROM for flash
|
||||
- if: CONFIG_NAME == "xip_psram_with_rom_impl" and IDF_TARGET in ["esp32s3", "esp32p4"]
|
||||
|
||||
components/spi_flash/test_apps/flash_suspend:
|
||||
disable:
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "esp_log.h"
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
@@ -517,3 +518,14 @@ TEST_CASE("no stale data read post mmap and write partition", "[spi_flash][mmap]
|
||||
TEST_ASSERT_EQUAL(0, memcmp(buf, read_data, sizeof(buf)));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("spi_flash_cache2phys points to correct address", "[spi_flash]")
|
||||
{
|
||||
//_rodata_start, which begins with appdesc, is always the first segment of the bin.
|
||||
extern int _rodata_start;
|
||||
size_t addr = spi_flash_cache2phys(&_rodata_start);
|
||||
|
||||
const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, "factory");
|
||||
ESP_LOGI("running bin", "0x%p", (void*)addr);
|
||||
TEST_ASSERT_HEX32_WITHIN(CONFIG_MMU_PAGE_SIZE/2, factory->address + CONFIG_MMU_PAGE_SIZE/2, addr);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
factory, 0, 0, 0x10000, 1M
|
||||
flash_test, data, fat, , 528K
|
||||
flash_test, data, fat, 0x10000, 528K
|
||||
# This partition is placed to this weird address intentionally to test spi_flash_cache2phys
|
||||
factory, 0, 0, 0xF0000, 1M
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
@@ -35,19 +34,20 @@ def test_flash_mmap_rom_impl(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=30)
|
||||
|
||||
|
||||
XIP_CONFIGS = [
|
||||
pytest.param('xip_psram_esp32s2', marks=[pytest.mark.esp32s2]),
|
||||
pytest.param('xip_psram_esp32s3', marks=[pytest.mark.esp32s3]),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', XIP_CONFIGS, indirect=True)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'xip_psram',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_flash_mmap_xip_psram(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=30)
|
||||
|
||||
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
|
||||
@@ -1,3 +0,0 @@
|
||||
CONFIG_IDF_TARGET="esp32s2"
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
|
||||
CONFIG_SPIRAM_RODATA=y
|
||||
@@ -1,3 +0,0 @@
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
|
||||
CONFIG_SPIRAM_RODATA=y
|
||||
@@ -1,4 +1,3 @@
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
|
||||
CONFIG_SPIRAM_RODATA=y
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
|
||||
CONFIG_SPI_FLASH_ROM_IMPL=y
|
||||
|
||||
Reference in New Issue
Block a user