mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/esp32s2_flash_mmap_cache2phys_phys2cache' into 'master'
flash mmap: fix bug for cache2phys and phys2cache on esp32s2 See merge request espressif/esp-idf!8526
This commit is contained in:
commit
1056d2a1b7
@ -199,6 +199,15 @@ void IRAM_ATTR call_start_cpu0(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
extern void instruction_flash_page_info_init(void);
|
||||
instruction_flash_page_info_init();
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
extern void rodata_flash_page_info_init(void);
|
||||
rodata_flash_page_info_init();
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
extern void esp_spiram_enable_instruction_access(void);
|
||||
esp_spiram_enable_instruction_access();
|
||||
|
@ -91,6 +91,54 @@ void esp_spiram_writeback_cache(void);
|
||||
*/
|
||||
esp_err_t esp_spiram_reserve_dma_pool(size_t size);
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
|
||||
extern int _instruction_reserved_start, _instruction_reserved_end;
|
||||
|
||||
/**
|
||||
* @brief Get the start page number of the instruction in SPI flash
|
||||
*
|
||||
* @return start page number
|
||||
*/
|
||||
uint32_t instruction_flash_start_page_get(void);
|
||||
/**
|
||||
* @brief Get the end page number of the instruction in SPI flash
|
||||
*
|
||||
* @return end page number
|
||||
*/
|
||||
uint32_t instruction_flash_end_page_get(void);
|
||||
/**
|
||||
* @brief Get the offset of instruction from SPI flash to SPI RAM
|
||||
*
|
||||
* @return instruction offset
|
||||
*/
|
||||
int instruction_flash2spiram_offset(void);
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
|
||||
extern int _rodata_reserved_start, _rodata_reserved_end;
|
||||
|
||||
/**
|
||||
* @brief Get the start page number of the rodata in SPI flash
|
||||
*
|
||||
* @return start page number
|
||||
*/
|
||||
uint32_t rodata_flash_start_page_get(void);
|
||||
/**
|
||||
* @brief Get the end page number of the rodata in SPI flash
|
||||
*
|
||||
* @return end page number
|
||||
*/
|
||||
uint32_t rodata_flash_end_page_get(void);
|
||||
/**
|
||||
* @brief Get the offset number of rodata from SPI flash to SPI RAM
|
||||
*
|
||||
* @return rodata offset
|
||||
*/
|
||||
int rodata_flash2spiram_offset(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -251,6 +251,7 @@ SECTIONS
|
||||
/* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */
|
||||
.flash.rodata : ALIGN(0x10)
|
||||
{
|
||||
_rodata_reserved_start = ABSOLUTE(.);
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
|
||||
*(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||
@ -308,12 +309,14 @@ SECTIONS
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
_rodata_reserved_end = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
} >default_rodata_seg
|
||||
|
||||
.flash.text :
|
||||
{
|
||||
_stext = .;
|
||||
_instruction_reserved_start = ABSOLUTE(.);
|
||||
_text_start = ABSOLUTE(.);
|
||||
|
||||
mapping[flash_text]
|
||||
@ -324,6 +327,7 @@ SECTIONS
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
_text_end = ABSOLUTE(.);
|
||||
_instruction_reserved_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
|
||||
/* Similar to _iram_start, this symbol goes here so it is
|
||||
|
@ -161,6 +161,18 @@ static uint32_t page0_page = INVALID_PHY_PAGE;
|
||||
static uint32_t instrcution_in_spiram = 0;
|
||||
static uint32_t rodata_in_spiram = 0;
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
static int instr_flash2spiram_offs = 0;
|
||||
static uint32_t instr_start_page = 0;
|
||||
static uint32_t instr_end_page = 0;
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
static int rodata_flash2spiram_offs = 0;
|
||||
static uint32_t rodata_start_page = 0;
|
||||
static uint32_t rodata_end_page = 0;
|
||||
#endif
|
||||
|
||||
uint32_t esp_spiram_instruction_access_enabled(void)
|
||||
{
|
||||
return instrcution_in_spiram;
|
||||
@ -171,6 +183,7 @@ uint32_t esp_spiram_rodata_access_enabled(void)
|
||||
return rodata_in_spiram;
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
esp_err_t esp_spiram_enable_instruction_access(void)
|
||||
{
|
||||
uint32_t pages_in_flash = 0;
|
||||
@ -181,12 +194,19 @@ esp_err_t esp_spiram_enable_instruction_access(void)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_EARLY_LOGI(TAG, "Instructions copied and mapped to SPIRAM");
|
||||
uint32_t instr_mmu_offset = ((uint32_t)&_instruction_reserved_start & 0xFFFFFF)/MMU_PAGE_SIZE;
|
||||
uint32_t mmu_value = *(volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS0_MMU_START + instr_mmu_offset*sizeof(uint32_t));
|
||||
mmu_value &= MMU_ADDRESS_MASK;
|
||||
instr_flash2spiram_offs = mmu_value - pages_for_flash;
|
||||
ESP_EARLY_LOGV(TAG, "Instructions from flash page%d copy to SPIRAM page%d, Offset: %d", mmu_value, pages_for_flash, instr_flash2spiram_offs);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS0, IRAM0_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS1, IRAM1_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
instrcution_in_spiram = 1;
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
esp_err_t esp_spiram_enable_rodata_access(void)
|
||||
{
|
||||
uint32_t pages_in_flash = 0;
|
||||
@ -201,6 +221,11 @@ esp_err_t esp_spiram_enable_rodata_access(void)
|
||||
}
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "Read only data copied and mapped to SPIRAM");
|
||||
uint32_t rodata_mmu_offset = ((uint32_t)&_rodata_reserved_start & 0xFFFFFF)/MMU_PAGE_SIZE;
|
||||
uint32_t mmu_value = *(volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS2_MMU_START + rodata_mmu_offset*sizeof(uint32_t));
|
||||
mmu_value &= MMU_ADDRESS_MASK;
|
||||
rodata_flash2spiram_offs = mmu_value - pages_for_flash;
|
||||
ESP_EARLY_LOGV(TAG, "Rodata from flash page%d copy to SPIRAM page%d, Offset: %d", mmu_value, pages_for_flash, rodata_flash2spiram_offs);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS2, DROM0_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS0, DRAM0_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS1, DRAM1_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
@ -208,6 +233,61 @@ esp_err_t esp_spiram_enable_rodata_access(void)
|
||||
rodata_in_spiram = 1;
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
void instruction_flash_page_info_init(void)
|
||||
{
|
||||
uint32_t instr_page_cnt = ((uint32_t)&_instruction_reserved_end - SOC_IROM_LOW + MMU_PAGE_SIZE - 1)/MMU_PAGE_SIZE;
|
||||
uint32_t instr_mmu_offset = ((uint32_t)&_instruction_reserved_start & 0xFFFFFF)/MMU_PAGE_SIZE;
|
||||
|
||||
instr_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS0_MMU_START + instr_mmu_offset*sizeof(uint32_t));
|
||||
instr_start_page &= MMU_ADDRESS_MASK;
|
||||
instr_end_page = instr_start_page + instr_page_cnt - 1;
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR instruction_flash_start_page_get(void)
|
||||
{
|
||||
return instr_start_page;
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR instruction_flash_end_page_get(void)
|
||||
{
|
||||
return instr_end_page;
|
||||
}
|
||||
|
||||
int IRAM_ATTR instruction_flash2spiram_offset(void)
|
||||
{
|
||||
return instr_flash2spiram_offs;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
void rodata_flash_page_info_init(void)
|
||||
{
|
||||
uint32_t rodata_page_cnt = ((uint32_t)&_rodata_reserved_end - SOC_DROM_LOW + MMU_PAGE_SIZE - 1)/MMU_PAGE_SIZE;
|
||||
uint32_t rodata_mmu_offset = ((uint32_t)&_rodata_reserved_start & 0xFFFFFF)/MMU_PAGE_SIZE;
|
||||
|
||||
rodata_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS2_MMU_START + rodata_mmu_offset*sizeof(uint32_t));
|
||||
rodata_start_page &= MMU_ADDRESS_MASK;
|
||||
rodata_end_page = rodata_start_page + rodata_page_cnt - 1;
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR rodata_flash_start_page_get(void)
|
||||
{
|
||||
return rodata_start_page;
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR rodata_flash_end_page_get(void)
|
||||
{
|
||||
return rodata_end_page;
|
||||
}
|
||||
|
||||
int IRAM_ATTR rodata_flash2spiram_offset(void)
|
||||
{
|
||||
return rodata_flash2spiram_offs;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t esp_spiram_init(void)
|
||||
{
|
||||
|
@ -467,11 +467,11 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable
|
||||
uint32_t instruction_use_spiram = 0;
|
||||
uint32_t rodata_use_spiram = 0;
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
extern uint32_t esp_spiram_instruction_access_enabled();
|
||||
extern uint32_t esp_spiram_instruction_access_enabled(void);
|
||||
instruction_use_spiram = esp_spiram_instruction_access_enabled();
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
extern uint32_t esp_spiram_rodata_access_enabled();
|
||||
extern uint32_t esp_spiram_rodata_access_enabled(void);
|
||||
rodata_use_spiram = esp_spiram_rodata_access_enabled();
|
||||
#endif
|
||||
|
||||
|
@ -378,15 +378,26 @@ uint32_t spi_flash_cache2phys(const void *cached)
|
||||
{
|
||||
intptr_t c = (intptr_t)cached;
|
||||
size_t cache_page;
|
||||
int offset = 0;
|
||||
if (c >= VADDR1_START_ADDR && c < VADDR1_FIRST_USABLE_ADDR) {
|
||||
/* IRAM address, doesn't map to flash */
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
} else if (c < VADDR1_FIRST_USABLE_ADDR) {
|
||||
/* expect cache is in DROM */
|
||||
cache_page = (c - VADDR0_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + DROM0_PAGES_START;
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
if (c >= (uint32_t)&_rodata_reserved_start && c <= (uint32_t)&_rodata_reserved_end) {
|
||||
offset = rodata_flash2spiram_offset();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* expect cache is in IROM */
|
||||
cache_page = (c - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START;
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
if (c >= (uint32_t)&_instruction_reserved_start && c <= (uint32_t)&_instruction_reserved_end) {
|
||||
offset = instruction_flash2spiram_offset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cache_page >= PAGES_LIMIT) {
|
||||
@ -398,7 +409,7 @@ uint32_t spi_flash_cache2phys(const void *cached)
|
||||
/* page is not mapped */
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
}
|
||||
uint32_t phys_offs = (phys_page & MMU_ADDR_MASK)* SPI_FLASH_MMU_PAGE_SIZE;
|
||||
uint32_t phys_offs = ((phys_page & MMU_ADDR_MASK) + offset) * SPI_FLASH_MMU_PAGE_SIZE;
|
||||
return phys_offs | (c & (SPI_FLASH_MMU_PAGE_SIZE-1));
|
||||
}
|
||||
|
||||
@ -422,7 +433,24 @@ const void *IRAM_ATTR spi_flash_phys2cache(uint32_t phys_offs, spi_flash_mmap_me
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
DPORT_INTERRUPT_DISABLE();
|
||||
for (int i = start; i < end; i++) {
|
||||
if (DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]) == PAGE_IN_FLASH(phys_page)) {
|
||||
uint32_t mmu_value = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]);
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
if (phys_page >= instruction_flash_start_page_get() && phys_page <= instruction_flash_end_page_get()) {
|
||||
if (mmu_value & MMU_ACCESS_SPIRAM) {
|
||||
mmu_value += instruction_flash2spiram_offset();
|
||||
mmu_value = (mmu_value & MMU_ADDR_MASK) | MMU_ACCESS_FLASH;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_RODATA
|
||||
if (phys_page >= rodata_flash_start_page_get() && phys_page <= rodata_flash_start_page_get()) {
|
||||
if (mmu_value & MMU_ACCESS_SPIRAM) {
|
||||
mmu_value += rodata_flash2spiram_offset();
|
||||
mmu_value = (mmu_value & MMU_ADDR_MASK) | MMU_ACCESS_FLASH;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (mmu_value == PAGE_IN_FLASH(phys_page)) {
|
||||
i -= page_delta;
|
||||
intptr_t cache_page = base + (SPI_FLASH_MMU_PAGE_SIZE * i);
|
||||
DPORT_INTERRUPT_RESTORE();
|
||||
|
@ -539,7 +539,7 @@ UT_034:
|
||||
|
||||
UT_035:
|
||||
extends: .unit_test_s2_template
|
||||
parallel: 34
|
||||
parallel: 36
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_1
|
||||
|
5
tools/unit-test-app/configs/spi_flash_config_1_s2
Normal file
5
tools/unit-test-app/configs/spi_flash_config_1_s2
Normal file
@ -0,0 +1,5 @@
|
||||
TEST_COMPONENTS=spi_flash
|
||||
CONFIG_ESP32S2_SPIRAM_SUPPORT=y
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
|
||||
CONFIG_SPIRAM_RODATA=n
|
||||
CONFIG_IDF_TARGET="esp32s2"
|
5
tools/unit-test-app/configs/spi_flash_config_2_s2
Normal file
5
tools/unit-test-app/configs/spi_flash_config_2_s2
Normal file
@ -0,0 +1,5 @@
|
||||
TEST_COMPONENTS=spi_flash
|
||||
CONFIG_ESP32S2_SPIRAM_SUPPORT=y
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
|
||||
CONFIG_SPIRAM_RODATA=y
|
||||
CONFIG_IDF_TARGET="esp32s2"
|
5
tools/unit-test-app/configs/spi_flash_config_3_s2
Normal file
5
tools/unit-test-app/configs/spi_flash_config_3_s2
Normal file
@ -0,0 +1,5 @@
|
||||
TEST_COMPONENTS=spi_flash
|
||||
CONFIG_ESP32S2_SPIRAM_SUPPORT=y
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=n
|
||||
CONFIG_SPIRAM_RODATA=y
|
||||
CONFIG_IDF_TARGET="esp32s2"
|
Loading…
Reference in New Issue
Block a user