feat(psram): xip psram c61

This commit is contained in:
Armando 2024-09-03 14:10:24 +08:00
parent 8842e5764f
commit fce2680e91
10 changed files with 66 additions and 10 deletions

View File

@ -44,5 +44,39 @@ menu "SPI RAM config"
default 80 if SPIRAM_SPEED_80M
default 40 if SPIRAM_SPEED_40M
config SPIRAM_FETCH_INSTRUCTIONS
bool
help
Enable this option allows moving application's instruction segment from the SPI Flash to PSRAM
config SPIRAM_RODATA
bool
help
Enable this option allows moving application's rodata segment from the SPI Flash to
PSRAM
config SPIRAM_XIP_FROM_PSRAM
bool "Enable Executable in place from (XiP) from PSRAM feature (READ HELP)"
default n
select SPIRAM_FETCH_INSTRUCTIONS
select SPIRAM_RODATA
select SPIRAM_FLASH_LOAD_TO_PSRAM
help
If enabled, firmware in flash including instructions and data will be moved into PSRAM on startup,
firmware code will execute directly from PSRAM.
With this option enabled, code that requires execution during an MSPI1 Flash operation
does not have to be placed in IRAM. Therefore codes that need to be executing during Flash
operations can continue working normally.
This feature is useful for high throughput peripheral involved applications to improve
the performance during MSPI1 flash operations.
config SPIRAM_FLASH_LOAD_TO_PSRAM
bool
help
This is a helper indicating this condition:
`CONFIG_SPIRAM_XIP_FROM_PSRAM && CONFIG_IDF_TARGET_ESP32C61`
source "$IDF_PATH/components/esp_psram/Kconfig.spiram.common" # insert non-chip-specific items here
endmenu

View File

@ -30,7 +30,7 @@ extern "C" {
#if CONFIG_IDF_TARGET_ESP32
#define MMU_PAGE_SIZE 0x8000
#else
#define MMU_PAGE_SIZE 0x10000
#define MMU_PAGE_SIZE CONFIG_MMU_PAGE_SIZE
#define MMU_PAGE_TO_BYTES(page_id) ((page_id) * MMU_PAGE_SIZE)
#define BYTES_TO_MMU_PAGE(bytes) ((bytes) / MMU_PAGE_SIZE)
#endif

View File

@ -85,7 +85,7 @@ esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size
uint32_t flash_irom_paddr_start = 0;
image_process_get_flash_segments_info(&flash_drom_paddr_start, &flash_irom_paddr_start);
flash_irom_paddr_start = ALIGN_DOWN_BY(flash_irom_paddr_start, CONFIG_MMU_PAGE_SIZE);
ESP_EARLY_LOGI(TAG, "flash_irom_paddr_start: 0x%x", flash_irom_paddr_start);
ESP_EARLY_LOGV(TAG, "flash_irom_paddr_start: 0x%x", flash_irom_paddr_start);
if ((MMU_PAGE_TO_BYTES(start_page) + irom_size) > psram_size) {
ESP_EARLY_LOGE(TAG, "PSRAM space not enough for the Flash instructions, need %"PRId32" B, from %"PRId32" B to %"PRId32" B", irom_size, MMU_PAGE_TO_BYTES(start_page), MMU_PAGE_TO_BYTES(start_page) + irom_size);
@ -106,6 +106,7 @@ esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size
start_page += BYTES_TO_MMU_PAGE(irom_size);
*out_page = start_page;
ESP_EARLY_LOGI(TAG, ".text xip on psram");
return ESP_OK;
}
#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
@ -120,7 +121,7 @@ esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_si
uint32_t flash_irom_paddr_start = 0;
image_process_get_flash_segments_info(&flash_drom_paddr_start, &flash_irom_paddr_start);
flash_drom_paddr_start = ALIGN_DOWN_BY(flash_drom_paddr_start, CONFIG_MMU_PAGE_SIZE);
ESP_EARLY_LOGI(TAG, "flash_drom_paddr_start: 0x%x", flash_drom_paddr_start);
ESP_EARLY_LOGV(TAG, "flash_drom_paddr_start: 0x%x", flash_drom_paddr_start);
if ((MMU_PAGE_TO_BYTES(start_page) + drom_size) > psram_size) {
ESP_EARLY_LOGE(TAG, "PSRAM space not enough for the Flash rodata, need %"PRId32" B, from %"PRId32" B to %"PRId32" B", drom_size, MMU_PAGE_TO_BYTES(start_page), MMU_PAGE_TO_BYTES(start_page) + drom_size);
@ -141,6 +142,7 @@ esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_si
start_page += BYTES_TO_MMU_PAGE(drom_size);
*out_page = start_page;
ESP_EARLY_LOGI(TAG, ".rodata xip on psram");
return ESP_OK;
}
#endif //#if CONFIG_SPIRAM_RODATA

View File

@ -108,6 +108,7 @@ def test_psram_esp32c5(dut: Dut) -> None:
'config',
[
'esp32c61_release',
'esp32c61_advanced',
],
indirect=True,
)

View File

@ -0,0 +1,15 @@
CONFIG_IDF_TARGET="esp32c61"
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_SPEED_80M=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"

View File

@ -20,6 +20,8 @@
extern "C" {
#endif
#define MMU_LL_FLASH_MMU_ID 0
#define MMU_LL_PSRAM_MMU_ID 0
#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE)
#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1)
@ -212,7 +214,6 @@ static inline uint32_t mmu_ll_format_paddr(uint32_t mmu_id, uint32_t paddr, mmu_
__attribute__((always_inline)) static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32_t mmu_val, mmu_target_t target)
{
(void)mmu_id;
(void)target;
uint32_t mmu_raw_value;
if (mmu_ll_cache_encryption_enabled()) {
mmu_val |= SOC_MMU_SENSITIVE;

View File

@ -58,7 +58,7 @@ extern "C" {
* valid bit + value bits
* valid bit is BIT(9), so value bits are 0x1ff
*/
#define SOC_MMU_VALID_VAL_MASK 0x3ff
#define SOC_MMU_VALID_VAL_MASK (SOC_MMU_ACCESS_SPIRAM - 1)
/**
* Max MMU available paddr page num.
* `SOC_MMU_MAX_PADDR_PAGE_NUM * SOC_MMU_PAGE_SIZE` means the max paddr address supported by the MMU. e.g.:

View File

@ -277,7 +277,7 @@ const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memo
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_FLASH_LOAD_TO_PSRAM
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
if (phys_page >= instruction_flash_start_page_get() && phys_page <= instruction_flash_end_page_get()) {
target = MMU_TARGET_PSRAM0;
@ -291,7 +291,7 @@ const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memo
phys_offs -= rodata_flash2spiram_offset() * CONFIG_MMU_PAGE_SIZE;
}
#endif
#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET
#endif //#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM
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);
@ -383,7 +383,7 @@ size_t spi_flash_cache2phys(const void *cached)
int offset = 0;
#if !SOC_MMU_PER_EXT_MEM_TARGET //TODO: IDF-9049
#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM
#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();
@ -394,7 +394,7 @@ size_t spi_flash_cache2phys(const void *cached)
offset = instruction_flash2spiram_offset();
}
#endif
#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET
#endif //#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM
return paddr + offset * CONFIG_MMU_PAGE_SIZE;
}

View File

@ -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
@ -38,6 +37,8 @@ def test_flash_mmap_rom_impl(dut: Dut) -> None:
XIP_CONFIGS = [
pytest.param('xip_psram_esp32s2', marks=[pytest.mark.esp32s2]),
pytest.param('xip_psram_esp32s3', marks=[pytest.mark.esp32s3]),
pytest.param('xip_psram_esp32c5', marks=[pytest.mark.esp32c5]),
pytest.param('xip_psram_esp32c61', marks=[pytest.mark.esp32c61]),
]

View File

@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32c61"
CONFIG_SPIRAM_XIP_FROM_PSRAM=y