6161#define PSRAM_EARLY_LOGI ESP_EARLY_LOGI
6262#endif
6363
64+ #if CONFIG_SPIRAM_RODATA
65+ extern uint8_t _rodata_reserved_end ;
66+ #endif /* CONFIG_SPIRAM_RODATA */
67+
68+ #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
69+ extern uint8_t _instruction_reserved_end ;
70+ #endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS */
71+
6472#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
6573extern uint8_t _ext_ram_bss_start ;
6674extern uint8_t _ext_ram_bss_end ;
@@ -71,6 +79,8 @@ extern uint8_t _ext_ram_noinit_start;
7179extern uint8_t _ext_ram_noinit_end ;
7280#endif //#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
7381
82+ #define ALIGN_UP_BY (num , align ) (((num) + ((align) - 1)) & ~((align) - 1))
83+
7484typedef struct {
7585 intptr_t vaddr_start ;
7686 intptr_t vaddr_end ;
@@ -506,6 +516,31 @@ esp_err_t esp_psram_extram_add_to_heap_allocator(void)
506516 ESP_EARLY_LOGI (TAG , "Adding pool of %dK of PSRAM memory to heap allocator" ,
507517 (s_psram_ctx .regions_to_heap [PSRAM_MEM_8BIT_ALIGNED ].size + s_psram_ctx .regions_to_heap [PSRAM_MEM_32BIT_ALIGNED ].size ) / 1024 );
508518
519+ // Here, SOC_MMU_DI_VADDR_SHARED is necessary because, for the targets that have separate data and instruction virtual address spaces,
520+ // the SPIRAM gap created due to the alignment needed while placing the instruction segment in the instruction virtual address space
521+ // cannot be added in heap because the region cannot be configured with write permissions.
522+ #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
523+ if ((uint32_t )& _instruction_reserved_end & (CONFIG_MMU_PAGE_SIZE - 1 )) {
524+ uint32_t instruction_alignment_gap_heap_start , instruction_alignment_gap_heap_end ;
525+ mmu_psram_get_instruction_alignment_gap_info (& instruction_alignment_gap_heap_start , & instruction_alignment_gap_heap_end );
526+ ret = heap_caps_add_region_with_caps (byte_aligned_caps , instruction_alignment_gap_heap_start , instruction_alignment_gap_heap_end );
527+ if (ret == ESP_OK ) {
528+ ESP_EARLY_LOGI (TAG , "Adding pool of %dK of PSRAM memory gap generated due to end address alignment of irom to the heap allocator" , (instruction_alignment_gap_heap_end - instruction_alignment_gap_heap_start ) / 1024 );
529+ }
530+ }
531+ #endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS */
532+
533+ // In the case of ESP32S2, the rodata is mapped to a read-only region (SOC_DROM0_ADDRESS_LOW - SOC_DROM0_ADDRESS_HIGH), thus we cannot add this region to the heap.
534+ #if CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2
535+ if ((uint32_t )& _rodata_reserved_end & (CONFIG_MMU_PAGE_SIZE - 1 )) {
536+ uint32_t rodata_alignment_gap_heap_start , rodata_alignment_gap_heap_end ;
537+ mmu_psram_get_rodata_alignment_gap_info (& rodata_alignment_gap_heap_start , & rodata_alignment_gap_heap_end );
538+ ret = heap_caps_add_region_with_caps (byte_aligned_caps , rodata_alignment_gap_heap_start , rodata_alignment_gap_heap_end );
539+ if (ret == ESP_OK ) {
540+ ESP_EARLY_LOGI (TAG , "Adding pool of %dK of PSRAM memory gap generated due to end address alignment of drom to the heap allocator" , (rodata_alignment_gap_heap_end - rodata_alignment_gap_heap_start ) / 1024 );
541+ }
542+ }
543+ #endif /* CONFIG_SPIRAM_RODATA */
509544 return ESP_OK ;
510545}
511546
@@ -515,8 +550,24 @@ bool IRAM_ATTR esp_psram_check_ptr_addr(const void *p)
515550 return false;
516551 }
517552
518- return ((intptr_t )p >= s_psram_ctx .mapped_regions [PSRAM_MEM_8BIT_ALIGNED ].vaddr_start && (intptr_t )p < s_psram_ctx .mapped_regions [PSRAM_MEM_8BIT_ALIGNED ].vaddr_end ) ||
519- ((intptr_t )p >= s_psram_ctx .mapped_regions [PSRAM_MEM_32BIT_ALIGNED ].vaddr_start && (intptr_t )p < s_psram_ctx .mapped_regions [PSRAM_MEM_32BIT_ALIGNED ].vaddr_end );
553+ if (((intptr_t )p >= s_psram_ctx .mapped_regions [PSRAM_MEM_8BIT_ALIGNED ].vaddr_start && (intptr_t )p < s_psram_ctx .mapped_regions [PSRAM_MEM_8BIT_ALIGNED ].vaddr_end ) ||
554+ ((intptr_t )p >= s_psram_ctx .mapped_regions [PSRAM_MEM_32BIT_ALIGNED ].vaddr_start && (intptr_t )p < s_psram_ctx .mapped_regions [PSRAM_MEM_32BIT_ALIGNED ].vaddr_end )) {
555+ return true;
556+ }
557+
558+ #if CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2
559+ if (mmu_psram_check_ptr_addr_in_rodata_alignment_gap (p )) {
560+ return true;
561+ }
562+ #endif /* CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2 */
563+
564+ #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
565+ if (mmu_psram_check_ptr_addr_in_instruction_alignment_gap (p )) {
566+ return true;
567+ }
568+ #endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED */
569+
570+ return false;
520571}
521572
522573esp_err_t esp_psram_extram_reserve_dma_pool (size_t size )
0 commit comments