@@ -54,6 +54,17 @@ static int s_drom_paddr_offset;
5454static uint32_t s_do_load_from_flash (uint32_t flash_paddr_start , uint32_t size , uint32_t target_vaddr_start , uint32_t target_paddr_start )
5555{
5656 uint32_t flash_end_page_vaddr = SOC_DRAM_FLASH_ADDRESS_HIGH - CONFIG_MMU_PAGE_SIZE ;
57+ uint32_t psram_vaddr_start ;
58+
59+ #if !CONFIG_SPIRAM_BOOT_INIT
60+ // Once PMP sets up the IROM/DROM split, the target_vaddr_start would not be configured to write (W) access. Thus, performing s_do_load_from_flash() post the PMP split
61+ // is configured, copying the flash contents to the PSRAM would generate a store access fault.
62+ // Thus, we need to choose a different PSRAM virtual address (that would have the PMP write (W) access) to map and copy the flash contents into the PSRAM.
63+ // Choosing the second last PSRAM page instead of the last one, to avoid overlap with flash_end_page_vaddr for targets that share the same flash and psram virtual space.
64+ uint32_t psram_second_last_page_vaddr = SOC_DRAM_PSRAM_ADDRESS_HIGH - 2 * CONFIG_MMU_PAGE_SIZE ;
65+ assert ((psram_second_last_page_vaddr % CONFIG_MMU_PAGE_SIZE ) == 0 );
66+ #endif
67+
5768 ESP_EARLY_LOGV (TAG , "flash_paddr_start: 0x%" PRIx32 ", flash_end_page_vaddr: 0x%" PRIx32 ", size: 0x%" PRIx32 ", target_vaddr_start: 0x%" PRIx32 , flash_paddr_start , flash_end_page_vaddr , size , target_vaddr_start );
5869 assert ((flash_paddr_start % CONFIG_MMU_PAGE_SIZE ) == 0 );
5970 assert ((flash_end_page_vaddr % CONFIG_MMU_PAGE_SIZE ) == 0 );
@@ -62,15 +73,28 @@ static uint32_t s_do_load_from_flash(uint32_t flash_paddr_start, uint32_t size,
6273 uint32_t mapped_size = 0 ;
6374 while (mapped_size < size ) {
6475 uint32_t actual_mapped_len = 0 ;
65- mmu_hal_map_region (MMU_LL_PSRAM_MMU_ID , MMU_TARGET_PSRAM0 , target_vaddr_start , target_paddr_start + mapped_size , CONFIG_MMU_PAGE_SIZE , & actual_mapped_len );
76+ #if !CONFIG_SPIRAM_BOOT_INIT
77+ psram_vaddr_start = psram_second_last_page_vaddr ;
78+ #else
79+ psram_vaddr_start = target_vaddr_start ;
80+ #endif /* !CONFIG_SPIRAM_BOOT_INIT*/
81+
82+ mmu_hal_map_region (MMU_LL_PSRAM_MMU_ID , MMU_TARGET_PSRAM0 , psram_vaddr_start , target_paddr_start + mapped_size , CONFIG_MMU_PAGE_SIZE , & actual_mapped_len );
6683 assert (actual_mapped_len == CONFIG_MMU_PAGE_SIZE );
6784
6885 mmu_hal_map_region (MMU_LL_FLASH_MMU_ID , MMU_TARGET_FLASH0 , flash_end_page_vaddr , flash_paddr_start + mapped_size , CONFIG_MMU_PAGE_SIZE , & actual_mapped_len );
6986 assert (actual_mapped_len == CONFIG_MMU_PAGE_SIZE );
7087
71- cache_hal_invalidate_addr (target_vaddr_start , CONFIG_MMU_PAGE_SIZE );
88+ cache_hal_invalidate_addr (psram_vaddr_start , CONFIG_MMU_PAGE_SIZE );
7289 cache_hal_invalidate_addr (flash_end_page_vaddr , CONFIG_MMU_PAGE_SIZE );
73- memcpy ((void * )target_vaddr_start , (void * )flash_end_page_vaddr , CONFIG_MMU_PAGE_SIZE );
90+ memcpy ((void * )psram_vaddr_start , (void * )flash_end_page_vaddr , CONFIG_MMU_PAGE_SIZE );
91+
92+ #if !CONFIG_SPIRAM_BOOT_INIT
93+ cache_hal_writeback_addr (psram_vaddr_start , CONFIG_MMU_PAGE_SIZE );
94+ mmu_hal_map_region (MMU_LL_PSRAM_MMU_ID , MMU_TARGET_PSRAM0 , target_vaddr_start , target_paddr_start + mapped_size , CONFIG_MMU_PAGE_SIZE , & actual_mapped_len );
95+ assert (actual_mapped_len == CONFIG_MMU_PAGE_SIZE );
96+ cache_hal_invalidate_addr (target_vaddr_start , CONFIG_MMU_PAGE_SIZE );
97+ #endif /* !CONFIG_SPIRAM_BOOT_INIT */
7498
7599 ESP_EARLY_LOGV (TAG , "target_vaddr_start: 0x%" PRIx32 , target_vaddr_start );
76100 mapped_size += CONFIG_MMU_PAGE_SIZE ;
0 commit comments