diff --git a/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld index 377afa3ecb..84faa88e42 100644 --- a/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld @@ -1,14 +1,40 @@ /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. - * We put 2nd bootloader in the high address space (before ROM stack/data/bss). - * See memory usage for ROM bootloader at the end of this file. + * + * ESP32-C3 ROM static data usage is as follows: + * - 0x3fccae00 - 0x3fcdc710: Shared buffers, used in UART/USB/SPI download mode only + * - 0x3fcdc710 - 0x3fcde710: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x3fcde710 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x3fcdc710). */ +/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ +iram_dram_offset = 0x700000; + +/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x3fcdc710; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2000; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + MEMORY { - iram_seg (RWX) : org = 0x403CE000, len = 0x2000 - iram_loader_seg (RWX) : org = 0x403D0000, len = 0x6000 - dram_seg (RW) : org = 0x3FCD6000, len = 0x4000 + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len } /* Default entry point: */ @@ -176,17 +202,34 @@ SECTIONS /** * Appendix: Memory Usage of ROM bootloader * - * +--------+--------------+------+ 0x3FCC_AE00 - * | ^ | - * | | | - * | | data/bss | - * | | | - * | v | - * +------------------------------+ 0x3FCD_C710 - * | ^ | - * | | | - * | | stack | - * | | | - * | v | - * +------------------------------+ 0x3FCD_E710 + * 0x3fccae00 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x3fcdc710 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x3fcde710 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x3fcdf060 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x3fcdf664 ------------------> _dram0_rtos_reserved_end + * | | + * 0x3fcdf830 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x3fce0000 ------------------> _data_end_interface */ diff --git a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld index 65ce41aa14..6719e17cff 100644 --- a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld @@ -1,14 +1,40 @@ /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. - * We put 2nd bootloader in the high address space (before ROM stack/data/bss). - * See memory usage for ROM bootloader at the end of this file. + * + * ESP32-H2 ROM static data usage is as follows: + * - 0x3fccb900 - 0x3fcdd210: Shared buffers, used in UART/USB/SPI download mode only + * - 0x3fcdd210 - 0x3fcdf210: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x3fcdf210 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x3fce9704). For alignment purpose we shall use value (0x3fce9700). */ +/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ +iram_dram_offset = 0x700000; + +/* We consider 0x3fce9700 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x3fcdd120; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2000; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + MEMORY { - iram_seg (RWX) : org = 0x403CE000, len = 0x2000 - iram_loader_seg (RWX) : org = 0x403D0000, len = 0x6000 - dram_seg (RW) : org = 0x3FCD6000, len = 0x4000 + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len } /* Default entry point: */ @@ -173,17 +199,34 @@ SECTIONS /** * Appendix: Memory Usage of ROM bootloader * - * +--------+--------------+------+ 0x3FCC_B900 - * | ^ | - * | | | - * | | data/bss | - * | | | - * | v | - * +------------------------------+ 0x3FCD_D210 - * | ^ | - * | | | - * | | stack | - * | | | - * | v | - * +------------------------------+ 0x3FCD_F210 + * 0x3fccb81c ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x3fcdd120 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x3fcdf120 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x3fcdfa6c ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x3fcdfe40 ------------------> _dram0_rtos_reserved_end + * | | + * 0x3fcdfe4c ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x3fce0000 ------------------> _data_end_interface */ diff --git a/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld b/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld index 66924478ae..f3c3818de6 100644 --- a/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld @@ -206,3 +206,42 @@ SECTIONS } > iram_seg } + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x3fcd7e00 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x3fce9710 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x3fceb710 ------------------> __stack (pro cpu) + * | | + * | | Startup app cpu stack + * | | + * 0x3fced710 ------------------> __stack_app (app cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x3fceee34 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x3fcef770 ------------------> _dram0_rtos_reserved_end + * | | + * 0x3fcef81c ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x3fcf0000 ------------------> _data_end_interface + */ diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 86a4d84b4d..e6327e1592 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -37,8 +37,6 @@ static DRAM_ATTR sleep_retention_t s_retention; #if SOC_PM_SUPPORT_TAGMEM_PD -#define TAGMEM_PD_MEM_TYPE_CAPS (MALLOC_CAP_DMA | MALLOC_CAP_DEFAULT) - #if CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP static int cache_tagmem_retention_setup(uint32_t code_seg_vaddr, uint32_t code_seg_size, uint32_t data_seg_vaddr, uint32_t data_seg_size) { @@ -123,7 +121,7 @@ static esp_err_t esp_sleep_tagmem_pd_low_init(bool enable) int tagmem_sz = cache_tagmem_retention_setup(code_start, code_size, data_start, data_size); void *buf = heap_caps_aligned_alloc(SOC_RTC_CNTL_TAGMEM_PD_DMA_ADDR_ALIGN, tagmem_sz + RTC_HAL_DMA_LINK_NODE_SIZE, - TAGMEM_PD_MEM_TYPE_CAPS); + MALLOC_CAP_RETENTION); if (buf) { memset(buf, 0, tagmem_sz + RTC_HAL_DMA_LINK_NODE_SIZE); s_retention.retent.tagmem.link_addr = rtc_cntl_hal_dma_link_init(buf, @@ -157,19 +155,13 @@ static esp_err_t esp_sleep_tagmem_pd_low_init(bool enable) #if SOC_PM_SUPPORT_CPU_PD -#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 -#define CPU_PD_MEM_TYPE_CAPS (MALLOC_CAP_RETENTION | MALLOC_CAP_DEFAULT) -#else -#define CPU_PD_MEM_TYPE_CAPS (MALLOC_CAP_DMA | MALLOC_CAP_DEFAULT) -#endif - esp_err_t esp_sleep_cpu_pd_low_init(bool enable) { if (enable) { if (s_retention.retent.cpu_pd_mem == NULL) { void *buf = heap_caps_aligned_alloc(SOC_RTC_CNTL_CPU_PD_DMA_ADDR_ALIGN, SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE, - CPU_PD_MEM_TYPE_CAPS); + MALLOC_CAP_RETENTION); if (buf) { memset(buf, 0, SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE); s_retention.retent.cpu_pd_mem = rtc_cntl_hal_dma_link_init(buf, diff --git a/components/heap/include/esp_heap_caps.h b/components/heap/include/esp_heap_caps.h index c7d85d4217..e71f617dd5 100644 --- a/components/heap/include/esp_heap_caps.h +++ b/components/heap/include/esp_heap_caps.h @@ -33,7 +33,7 @@ extern "C" { #define MALLOC_CAP_INTERNAL (1<<11) ///< Memory must be internal; specifically it should not disappear when flash/spiram cache is switched off #define MALLOC_CAP_DEFAULT (1<<12) ///< Memory can be returned in a non-capability-specific memory allocation (e.g. malloc(), calloc()) call #define MALLOC_CAP_IRAM_8BIT (1<<13) ///< Memory must be in IRAM and allow unaligned access -#define MALLOC_CAP_RETENTION (1<<14) +#define MALLOC_CAP_RETENTION (1<<14) ///< Memory must be able to accessed by retention DMA #define MALLOC_CAP_RTCRAM (1<<15) ///< Memory must be in RTC fast memory #define MALLOC_CAP_INVALID (1<<31) ///< Memory can't be used / list end marker diff --git a/components/heap/port/esp32c3/memory_layout.c b/components/heap/port/esp32c3/memory_layout.c index 3ca3272417..1f3825e41f 100644 --- a/components/heap/port/esp32c3/memory_layout.c +++ b/components/heap/port/esp32c3/memory_layout.c @@ -33,23 +33,31 @@ * - Most other malloc caps only fit in one region anyway. * */ -const soc_memory_type_desc_t soc_memory_types[] = { + +/* Index of memory in `soc_memory_types[]` */ +enum { + SOC_MEMORY_TYPE_DRAM = 0, + SOC_MEMORY_TYPE_STACK_DRAM = 1, + SOC_MEMORY_TYPE_DIRAM = 2, + SOC_MEMORY_TYPE_RTCRAM = 3, + SOC_MEMORY_TYPE_NUM, +}; + +const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { // Type 0: DRAM - { "DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, false}, + [SOC_MEMORY_TYPE_DRAM] = { "DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, false}, // Type 1: DRAM used for startup stacks - { "STACK/DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, MALLOC_CAP_RETENTION }, false, true}, + [SOC_MEMORY_TYPE_STACK_DRAM] = { "STACK/DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_EXEC | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, MALLOC_CAP_RETENTION }, false, true}, // Type 2: DRAM which has an alias on the I-port - { "D/IRAM", { 0, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT | MALLOC_CAP_EXEC }, true, false}, - // Type 3: IRAM - { "IRAM", { MALLOC_CAP_EXEC | MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, 0, 0 }, false, false}, - // Type 4: RTCRAM - { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT }, false, false}, + [SOC_MEMORY_TYPE_DIRAM] = { "D/IRAM", { 0, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT | MALLOC_CAP_EXEC }, true, false}, + // Type 3: RTCRAM + [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT }, false, false}, }; #ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE -#define SOC_MEMORY_TYPE_DEFAULT 0 +#define SOC_MEMORY_TYPE_DEFAULT SOC_MEMORY_TYPE_DRAM #else -#define SOC_MEMORY_TYPE_DEFAULT 2 +#define SOC_MEMORY_TYPE_DEFAULT SOC_MEMORY_TYPE_DIRAM #endif const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memory_type_desc_t); @@ -61,12 +69,19 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor * this list should always be sorted from low to high by start address. * */ + +/** + * Register the shared buffer area of the last memory block into the heap during heap initialization + */ +#define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) + const soc_memory_region_t soc_memory_regions[] = { - { 0x3FC80000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x40380000}, //Block 4, can be remapped to ROM, can be used as trace memory - { 0x3FCA0000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x403A0000}, //Block 5, can be remapped to ROM, can be used as trace memory - { 0x3FCC0000, 0x20000, 1, 0x403C0000}, //Block 9, can be used as trace memory + { 0x3FC80000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x40380000}, //D/IRAM level1, can be used as trace memory + { 0x3FCA0000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x403A0000}, //D/IRAM level2, can be used as trace memory + { 0x3FCC0000, (APP_USABLE_DRAM_END-0x3FCC0000), SOC_MEMORY_TYPE_DEFAULT, 0x403C0000}, //D/IRAM level3, can be used as trace memory + { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_STACK_DRAM, MAP_DRAM_TO_IRAM(APP_USABLE_DRAM_END)}, //D/IRAM level3, can be used as trace memory (ROM reserved area) #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP - { 0x50000000, 0x2000, 4, 0}, //Fast RTC memory + { 0x50000000, 0x2000, SOC_MEMORY_TYPE_RTCRAM, 0}, //Fast RTC memory #endif }; diff --git a/components/heap/port/esp32h2/memory_layout.c b/components/heap/port/esp32h2/memory_layout.c index 7783e55c01..1da96453d4 100644 --- a/components/heap/port/esp32h2/memory_layout.c +++ b/components/heap/port/esp32h2/memory_layout.c @@ -33,23 +33,30 @@ * - Most other malloc caps only fit in one region anyway. * */ -const soc_memory_type_desc_t soc_memory_types[] = { +/* Index of memory in `soc_memory_types[]` */ +enum { + SOC_MEMORY_TYPE_DRAM = 0, + SOC_MEMORY_TYPE_STACK_DRAM = 1, + SOC_MEMORY_TYPE_DIRAM = 2, + SOC_MEMORY_TYPE_RTCRAM = 3, + SOC_MEMORY_TYPE_NUM, +}; + +const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { // Type 0: DRAM - { "DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, false}, + [SOC_MEMORY_TYPE_DRAM] = { "DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, false}, // Type 1: DRAM used for startup stacks - { "STACK/DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, MALLOC_CAP_RETENTION }, false, true}, + [SOC_MEMORY_TYPE_STACK_DRAM] = { "STACK/DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, MALLOC_CAP_RETENTION }, false, true}, // Type 2: DRAM which has an alias on the I-port - { "D/IRAM", { 0, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT | MALLOC_CAP_EXEC }, true, false}, - // Type 3: IRAM - { "IRAM", { MALLOC_CAP_EXEC | MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, 0, 0 }, false, false}, - // Type 4: RTCRAM - { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT }, false, false}, + [SOC_MEMORY_TYPE_DIRAM] = { "D/IRAM", { 0, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT | MALLOC_CAP_EXEC }, true, false}, + // Type 3: RTCRAM + [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT }, false, false}, }; #ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE -#define SOC_MEMORY_TYPE_DEFAULT 0 +#define SOC_MEMORY_TYPE_DEFAULT SOC_MEMORY_TYPE_DRAM #else -#define SOC_MEMORY_TYPE_DEFAULT 2 +#define SOC_MEMORY_TYPE_DEFAULT SOC_MEMORY_TYPE_DIRAM #endif const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memory_type_desc_t); @@ -61,12 +68,19 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor * this list should always be sorted from low to high by start address. * */ + +/** + * Register the shared buffer area of the last memory block into the heap during heap initialization + */ +#define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) + const soc_memory_region_t soc_memory_regions[] = { - { 0x3FC80000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x40380000}, //Block 4, can be remapped to ROM, can be used as trace memory - { 0x3FCA0000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x403A0000}, //Block 5, can be remapped to ROM, can be used as trace memory - { 0x3FCC0000, 0x20000, 1, 0x403C0000}, //Block 9, can be used as trace memory + { 0x3FC80000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x40380000}, //D/IRAM level1, can be used as trace memory + { 0x3FCA0000, 0x20000, SOC_MEMORY_TYPE_DEFAULT, 0x403A0000}, //D/IRAM level2, can be used as trace memory + { 0x3FCC0000, (APP_USABLE_DRAM_END-0x3FCC0000), SOC_MEMORY_TYPE_DEFAULT, 0x403C0000}, //D/IRAM level3, can be used as trace memory + { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_STACK_DRAM, MAP_DRAM_TO_IRAM(APP_USABLE_DRAM_END)}, //D/IRAM level3, can be used as trace memory (ROM reserved area) #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP - { 0x50000000, 0x2000, 4, 0}, //Fast RTC memory + { 0x50000000, 0x2000, SOC_MEMORY_TYPE_RTCRAM, 0}, //Fast RTC memory #endif }; diff --git a/components/heap/port/esp32s3/memory_layout.c b/components/heap/port/esp32s3/memory_layout.c index a2d4c85a5b..50da7e1fa2 100644 --- a/components/heap/port/esp32s3/memory_layout.c +++ b/components/heap/port/esp32s3/memory_layout.c @@ -28,21 +28,34 @@ * - Most other malloc caps only fit in one region anyway. * */ -const soc_memory_type_desc_t soc_memory_types[] = { + +/* Index of memory in `soc_memory_types[]` */ +enum { + SOC_MEMORY_TYPE_DRAM = 0, + SOC_MEMORY_TYPE_STACK_DRAM = 1, + SOC_MEMORY_TYPE_DIRAM = 2, + SOC_MEMORY_TYPE_IRAM = 3, + SOC_MEMORY_TYPE_SPIRAM = 4, + SOC_MEMORY_TYPE_NODMARAM = 5, + SOC_MEMORY_TYPE_RTCRAM = 6, + SOC_MEMORY_TYPE_NUM, +}; + +const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { // Type 0: DRAM - { "DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, false}, + [SOC_MEMORY_TYPE_DRAM] = { "DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, false}, // Type 1: DRAM used for startup stacks - { "STACK/DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, true}, + [SOC_MEMORY_TYPE_STACK_DRAM] = { "STACK/DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT | MALLOC_CAP_RETENTION, MALLOC_CAP_EXEC | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, true}, // Type 2: DRAM which has an alias on the I-port - { "D/IRAM", { 0, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT | MALLOC_CAP_EXEC }, true, false}, + [SOC_MEMORY_TYPE_DIRAM] = { "D/IRAM", { 0, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT | MALLOC_CAP_EXEC | MALLOC_CAP_RETENTION}, true, false}, // Type 3: IRAM - { "IRAM", { MALLOC_CAP_EXEC | MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, 0, 0 }, false, false}, + [SOC_MEMORY_TYPE_IRAM] = { "IRAM", { MALLOC_CAP_EXEC | MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, 0, 0 }, false, false}, // Type 4: SPI SRAM data - { "SPIRAM", { MALLOC_CAP_SPIRAM | MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT}, false, false}, + [SOC_MEMORY_TYPE_SPIRAM] = { "SPIRAM", { MALLOC_CAP_SPIRAM | MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT}, false, false}, // Type 5: DRAM which is not DMA accesible - { "NON_DMA_DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT, 0 }, false, false}, + [SOC_MEMORY_TYPE_NODMARAM] = { "NON_DMA_DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT, 0 }, false, false}, // Type 6: RTC Fast RAM - { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT }, false, false}, + [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT }, false, false}, }; const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memory_type_desc_t); @@ -54,28 +67,35 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor * this list should always be sorted from low to high by start address. * */ + +/** + * Register the shared buffer area of the last memory block into the heap during heap initialization + */ +#define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) + const soc_memory_region_t soc_memory_regions[] = { #ifdef CONFIG_SPIRAM - { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_SIZE, 4, 0}, //SPI SRAM, if available + { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_SIZE, SOC_MEMORY_TYPE_SPIRAM, 0}, //SPI SRAM, if available #endif #if CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB - { 0x40374000, 0x4000, 3, 0}, //Level 1, IRAM + { 0x40374000, 0x4000, SOC_MEMORY_TYPE_IRAM, 0}, //Level 1, IRAM #endif - { 0x3FC88000, 0x8000, 2, 0x40378000}, //Level 2, IDRAM, can be used as trace memroy - { 0x3FC90000, 0x10000, 2, 0x40380000}, //Level 3, IDRAM, can be used as trace memroy - { 0x3FCA0000, 0x10000, 2, 0x40390000}, //Level 4, IDRAM, can be used as trace memroy - { 0x3FCB0000, 0x10000, 2, 0x403A0000}, //Level 5, IDRAM, can be used as trace memroy - { 0x3FCC0000, 0x10000, 2, 0x403B0000}, //Level 6, IDRAM, can be used as trace memroy - { 0x3FCD0000, 0x10000, 2, 0x403C0000}, //Level 7, IDRAM, can be used as trace memroy - { 0x3FCE0000, 0x10000, 1, 0}, //Level 8, IDRAM, can be used as trace memroy, contains stacks used by startup flow, recycled by heap allocator in app_main task + { 0x3FC88000, 0x8000, SOC_MEMORY_TYPE_DIRAM, 0x40378000}, //Level 2, IDRAM, can be used as trace memroy + { 0x3FC90000, 0x10000, SOC_MEMORY_TYPE_DIRAM, 0x40380000}, //Level 3, IDRAM, can be used as trace memroy + { 0x3FCA0000, 0x10000, SOC_MEMORY_TYPE_DIRAM, 0x40390000}, //Level 4, IDRAM, can be used as trace memroy + { 0x3FCB0000, 0x10000, SOC_MEMORY_TYPE_DIRAM, 0x403A0000}, //Level 5, IDRAM, can be used as trace memroy + { 0x3FCC0000, 0x10000, SOC_MEMORY_TYPE_DIRAM, 0x403B0000}, //Level 6, IDRAM, can be used as trace memroy + { 0x3FCD0000, 0x10000, SOC_MEMORY_TYPE_DIRAM, 0x403C0000}, //Level 7, IDRAM, can be used as trace memroy + { 0x3FCE0000, (APP_USABLE_DRAM_END-0x3FCE0000), SOC_MEMORY_TYPE_DIRAM, 0x403D0000}, //Level 8, IDRAM, can be used as trace memroy, + { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_STACK_DRAM, MAP_DRAM_TO_IRAM(APP_USABLE_DRAM_END)}, //Level 8, IDRAM, can be used as trace memroy, ROM reserved area, recycled by heap allocator in app_main task #if CONFIG_ESP32S3_DATA_CACHE_16KB || CONFIG_ESP32S3_DATA_CACHE_32KB - { 0x3FCF0000, 0x8000, 0, 0}, //Level 9, DRAM + { 0x3FCF0000, 0x8000, SOC_MEMORY_TYPE_DRAM, 0}, //Level 9, DRAM, DMA is accessible but retention DMA is inaccessible #endif #if CONFIG_ESP32S3_DATA_CACHE_16KB - { 0x3C000000, 0x4000, 5, 0}, + { 0x3C000000, 0x4000, SOC_MEMORY_TYPE_DRAM, 0}, //Level 10, DRAM, DMA is accessible but retention DMA is inaccessible #endif #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP - { 0x600fe000, 0x2000, 6, 0}, //Fast RTC memory + { 0x600fe000, 0x2000, SOC_MEMORY_TYPE_RTCRAM, 0}, //Fast RTC memory #endif }; diff --git a/components/heap/test/test_realloc.c b/components/heap/test/test_realloc.c index 60a7749fb0..fdacc3a2f6 100644 --- a/components/heap/test/test_realloc.c +++ b/components/heap/test/test_realloc.c @@ -51,14 +51,12 @@ TEST_CASE("realloc move data to a new heap type", "[heap]") // move data from 'a' to IRAM char *b = heap_caps_realloc(a, 64, MALLOC_CAP_EXEC); TEST_ASSERT_NOT_NULL(b); - TEST_ASSERT_NOT_EQUAL(a, b); TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_INVALID, true)); TEST_ASSERT_EQUAL_HEX32_ARRAY(buf, b, 64 / sizeof(uint32_t)); // Move data back to DRAM char *c = heap_caps_realloc(b, 48, MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(c); - TEST_ASSERT_NOT_EQUAL(b, c); TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_INVALID, true)); TEST_ASSERT_EQUAL_HEX8_ARRAY(buf, c, 48); diff --git a/components/soc/esp32c3/include/soc/soc.h b/components/soc/esp32c3/include/soc/soc.h index 72dbb15a60..574cb8d3b1 100644 --- a/components/soc/esp32c3/include/soc/soc.h +++ b/components/soc/esp32c3/include/soc/soc.h @@ -238,6 +238,10 @@ #define SOC_DIRAM_DRAM_LOW 0x3FC80000 #define SOC_DIRAM_DRAM_HIGH 0x3FCE0000 +#define SOC_I_D_OFFSET (SOC_DIRAM_IRAM_LOW - SOC_DIRAM_DRAM_LOW) +#define MAP_DRAM_TO_IRAM(addr) (addr + SOC_I_D_OFFSET) +#define MAP_IRAM_TO_DRAM(addr) (addr - SOC_I_D_OFFSET) + // Region of memory accessible via DMA. See esp_ptr_dma_capable(). #define SOC_DMA_LOW 0x3FC88000 #define SOC_DMA_HIGH 0x3FD00000 @@ -250,10 +254,6 @@ //(excluding RTC data region, that's checked separately.) See esp_ptr_internal(). #define SOC_MEM_INTERNAL_LOW 0x3FC80000 #define SOC_MEM_INTERNAL_HIGH 0x3FCE0000 -#define SOC_MEM_INTERNAL_LOW1 0x40370000 -#define SOC_MEM_INTERNAL_HIGH1 0x403E0000 -#define SOC_MEM_INTERNAL_LOW2 0x600FE000 -#define SOC_MEM_INTERNAL_HIGH2 0x60100000 #define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_IRAM_HIGH - SOC_IRAM_LOW) ///< Largest span of contiguous memory (DRAM or IRAM) in the address space @@ -266,7 +266,8 @@ #define SOC_DEBUG_HIGH 0x28000000 // Start (highest address) of ROM boot stack, only relevant during early boot -#define SOC_ROM_STACK_START 0x3fcebf10 +#define SOC_ROM_STACK_START 0x3fcde710 +#define SOC_ROM_STACK_SIZE 0x2000 //On RISC-V CPUs, the interrupt sources are all external interrupts, whose type, source and priority are configured by SW. //There is no HW NMI conception. SW should controlled the masked levels through INT_THRESH_REG. diff --git a/components/soc/esp32h2/include/soc/soc.h b/components/soc/esp32h2/include/soc/soc.h index 68854d35d5..db5c19720e 100644 --- a/components/soc/esp32h2/include/soc/soc.h +++ b/components/soc/esp32h2/include/soc/soc.h @@ -266,6 +266,10 @@ #define SOC_DIRAM_DRAM_LOW 0x3FC80000 #define SOC_DIRAM_DRAM_HIGH 0x3FCE0000 +#define SOC_I_D_OFFSET (SOC_DIRAM_IRAM_LOW - SOC_DIRAM_DRAM_LOW) +#define MAP_DRAM_TO_IRAM(addr) (addr + SOC_I_D_OFFSET) +#define MAP_IRAM_TO_DRAM(addr) (addr - SOC_I_D_OFFSET) + // Region of memory accessible via DMA. See esp_ptr_dma_capable(). #define SOC_DMA_LOW 0x3FC88000 #define SOC_DMA_HIGH 0x3FD00000 @@ -278,10 +282,6 @@ //(excluding RTC data region, that's checked separately.) See esp_ptr_internal(). #define SOC_MEM_INTERNAL_LOW 0x3FC80000 #define SOC_MEM_INTERNAL_HIGH 0x3FCE0000 -#define SOC_MEM_INTERNAL_LOW1 0x40370000 -#define SOC_MEM_INTERNAL_HIGH1 0x403E0000 -#define SOC_MEM_INTERNAL_LOW2 0x600FE000 -#define SOC_MEM_INTERNAL_HIGH2 0x60100000 #define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_IRAM_HIGH - SOC_IRAM_LOW) ///< Largest span of contiguous memory (DRAM or IRAM) in the address space @@ -294,7 +294,8 @@ #define SOC_DEBUG_HIGH 0x28000000 // Start (highest address) of ROM boot stack, only relevant during early boot -#define SOC_ROM_STACK_START 0x3fcebf10 +#define SOC_ROM_STACK_START 0x3fcdf120 +#define SOC_ROM_STACK_SIZE 0x2000 //On RISC-V CPUs, the interrupt sources are all external interrupts, whose type, source and priority are configured by SW. //There is no HW NMI conception. SW should controlled the masked levels through INT_THRESH_REG. diff --git a/components/soc/esp32s2/include/soc/soc.h b/components/soc/esp32s2/include/soc/soc.h index ae4cf0103a..2f62a827a0 100644 --- a/components/soc/esp32s2/include/soc/soc.h +++ b/components/soc/esp32s2/include/soc/soc.h @@ -277,6 +277,10 @@ #define SOC_DIRAM_DRAM_LOW 0x3FFB0000 #define SOC_DIRAM_DRAM_HIGH 0x40000000 +#define SOC_I_D_OFFSET (SOC_DIRAM_IRAM_LOW - SOC_DIRAM_DRAM_LOW) +#define MAP_DRAM_TO_IRAM(addr) (addr + SOC_I_D_OFFSET) +#define MAP_IRAM_TO_DRAM(addr) (addr - SOC_I_D_OFFSET) + // Region of memory accessible via DMA in internal memory. See esp_ptr_dma_capable(). #define SOC_DMA_LOW 0x3FFB0000 #define SOC_DMA_HIGH 0x40000000 diff --git a/components/soc/esp32s3/include/soc/soc.h b/components/soc/esp32s3/include/soc/soc.h index b16809779a..f63b3ec762 100644 --- a/components/soc/esp32s3/include/soc/soc.h +++ b/components/soc/esp32s3/include/soc/soc.h @@ -284,6 +284,10 @@ #define SOC_DIRAM_DRAM_LOW 0x3FC88000 #define SOC_DIRAM_DRAM_HIGH 0x3FCF0000 +#define SOC_I_D_OFFSET (SOC_DIRAM_IRAM_LOW - SOC_DIRAM_DRAM_LOW) +#define MAP_DRAM_TO_IRAM(addr) (addr + SOC_I_D_OFFSET) +#define MAP_IRAM_TO_DRAM(addr) (addr - SOC_I_D_OFFSET) + // Region of memory accessible via DMA in internal memory. See esp_ptr_dma_capable(). #define SOC_DMA_LOW 0x3FC88000 #define SOC_DMA_HIGH 0x3FD00000 @@ -303,7 +307,8 @@ #define SOC_MEM_INTERNAL_HIGH 0x403E2000 // Start (highest address) of ROM boot stack, only relevant during early boot -#define SOC_ROM_STACK_START 0x3fcebf10 +#define SOC_ROM_STACK_START 0x3fceb710 +#define SOC_ROM_STACK_SIZE 0x2000 //interrupt cpu using table, Please see the core-isa.h /************************************************************************************************************* diff --git a/tools/test_apps/system/memprot/main/esp32s2/test_memprot_main.c b/tools/test_apps/system/memprot/main/esp32s2/test_memprot_main.c index 0dc7bf9c90..523f3029df 100644 --- a/tools/test_apps/system/memprot/main/esp32s2/test_memprot_main.c +++ b/tools/test_apps/system/memprot/main/esp32s2/test_memprot_main.c @@ -94,9 +94,6 @@ static uint8_t fnc_call0_buff[] = {0xf0, 0x22, 0x11, 0x0d, 0xf0, 0x00, 0x00, 0x0 volatile bool g_override_illegal_instruction = false; -#define MAP_DRAM_TO_IRAM(addr) (addr - SOC_DIRAM_DRAM_LOW + SOC_DIRAM_IRAM_LOW) -#define MAP_IRAM_TO_DRAM(addr) (addr - SOC_DIRAM_IRAM_LOW + SOC_DIRAM_DRAM_LOW) - #define SRAM_TEST_BUFFER_SIZE 0x400 #define SRAM_TEST_OFFSET 0x200