1 /* 2 * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <stdint.h> 8 #include <stdlib.h> 9 #include "sdkconfig.h" 10 #include "esp_attr.h" 11 #include "soc/soc.h" 12 #include "soc/dport_reg.h" 13 #include "soc/tracemem_config.h" 14 #include "heap_memory_layout.h" 15 #include "esp_heap_caps.h" 16 17 /** 18 * @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC. 19 * Each type of memory map consists of one or more regions in the address space. 20 * Each type contains an array of prioritized capabilities. 21 * Types with later entries are only taken if earlier ones can't fulfill the memory request. 22 * 23 * - For a normal malloc (MALLOC_CAP_DEFAULT), give away the DRAM-only memory first, then pass off any dual-use IRAM regions, finally eat into the application memory. 24 * - For a malloc where 32-bit-aligned-only access is okay, first allocate IRAM, then DRAM, finally application IRAM. 25 * - Application mallocs (PIDx) will allocate IRAM first, if possible, then DRAM. 26 * - Most other malloc caps only fit in one region anyway. 27 * 28 */ 29 30 /* Index of memory in `soc_memory_types[]` */ 31 enum { 32 SOC_MEMORY_TYPE_DRAM = 0, 33 SOC_MEMORY_TYPE_STACK_DRAM = 1, 34 SOC_MEMORY_TYPE_DIRAM = 2, 35 SOC_MEMORY_TYPE_STACK_DIRAM = 3, 36 SOC_MEMORY_TYPE_IRAM = 4, 37 SOC_MEMORY_TYPE_SPIRAM = 5, 38 SOC_MEMORY_TYPE_NODMARAM = 6, 39 SOC_MEMORY_TYPE_RTCRAM = 7, 40 SOC_MEMORY_TYPE_NUM, 41 }; 42 43 const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { 44 // Type 0: DRAM 45 [SOC_MEMORY_TYPE_DRAM] = { "DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, false}, 46 // Type 1: DRAM used for startup stacks 47 [SOC_MEMORY_TYPE_STACK_DRAM] = { "STACK/DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT | MALLOC_CAP_RETENTION, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, false, true}, 48 // Type 2: DRAM which has an alias on the I-port 49 [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}, 50 // Type 3: DIRAM used for startup stacks 51 [SOC_MEMORY_TYPE_STACK_DIRAM] = { "STACK/DIRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT | MALLOC_CAP_RETENTION, MALLOC_CAP_EXEC | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, true, true}, 52 // Type 4: IRAM 53 [SOC_MEMORY_TYPE_IRAM] = { "IRAM", { MALLOC_CAP_EXEC | MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, 0, 0 }, false, false}, 54 // Type 5: SPI SRAM data 55 [SOC_MEMORY_TYPE_SPIRAM] = { "SPIRAM", { MALLOC_CAP_SPIRAM | MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT}, false, false}, 56 // Type 6: DRAM which is not DMA accesible 57 [SOC_MEMORY_TYPE_NODMARAM] = { "NON_DMA_DRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT, 0 }, false, false}, 58 // Type 7: RTC Fast RAM 59 [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT }, false, false}, 60 }; 61 62 #ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE 63 #define SOC_MEMORY_TYPE_DEFAULT SOC_MEMORY_TYPE_DRAM 64 #define SOC_MEMORY_TYPE_STACK_DEFAULT SOC_MEMORY_TYPE_STACK_DRAM 65 #else 66 #define SOC_MEMORY_TYPE_DEFAULT SOC_MEMORY_TYPE_DIRAM 67 #define SOC_MEMORY_TYPE_STACK_DEFAULT SOC_MEMORY_TYPE_STACK_DIRAM 68 #endif 69 70 const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memory_type_desc_t); 71 72 /** 73 * @brief Region descriptors. These describe all regions of memory available, and map them to a type in the above type. 74 * 75 * @note Because of requirements in the coalescing code which merges adjacent regions, 76 * this list should always be sorted from low to high by start address. 77 * 78 */ 79 80 /** 81 * Register the shared buffer area of the last memory block into the heap during heap initialization 82 */ 83 #define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) 84 85 const soc_memory_region_t soc_memory_regions[] = { 86 #ifdef CONFIG_SPIRAM 87 { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_SIZE, SOC_MEMORY_TYPE_SPIRAM, 0}, //SPI SRAM, if available 88 #endif 89 #if CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB 90 { 0x40374000, 0x4000, SOC_MEMORY_TYPE_IRAM, 0}, //Level 1, IRAM 91 #endif 92 { 0x3FC88000, 0x8000, SOC_MEMORY_TYPE_DEFAULT, 0x40378000}, //Level 2, IDRAM, can be used as trace memory 93 { 0x3FC90000, 0x10000, SOC_MEMORY_TYPE_DEFAULT, 0x40380000}, //Level 3, IDRAM, can be used as trace memory 94 { 0x3FCA0000, 0x10000, SOC_MEMORY_TYPE_DEFAULT, 0x40390000}, //Level 4, IDRAM, can be used as trace memory 95 { 0x3FCB0000, 0x10000, SOC_MEMORY_TYPE_DEFAULT, 0x403A0000}, //Level 5, IDRAM, can be used as trace memory 96 { 0x3FCC0000, 0x10000, SOC_MEMORY_TYPE_DEFAULT, 0x403B0000}, //Level 6, IDRAM, can be used as trace memory 97 { 0x3FCD0000, 0x10000, SOC_MEMORY_TYPE_DEFAULT, 0x403C0000}, //Level 7, IDRAM, can be used as trace memory 98 { 0x3FCE0000, (APP_USABLE_DRAM_END-0x3FCE0000), SOC_MEMORY_TYPE_DEFAULT, 0x403D0000}, //Level 8, IDRAM, can be used as trace memory, 99 { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_STACK_DEFAULT, MAP_DRAM_TO_IRAM(APP_USABLE_DRAM_END)}, //Level 8, IDRAM, can be used as trace memory, ROM reserved area, recycled by heap allocator in app_main task 100 #if CONFIG_ESP32S3_DATA_CACHE_16KB || CONFIG_ESP32S3_DATA_CACHE_32KB 101 { 0x3FCF0000, 0x8000, SOC_MEMORY_TYPE_DRAM, 0}, //Level 9, DRAM, DMA is accessible but retention DMA is inaccessible 102 #endif 103 #if CONFIG_ESP32S3_DATA_CACHE_16KB 104 { 0x3C000000, 0x4000, SOC_MEMORY_TYPE_DRAM, 0}, //Level 10, DRAM, DMA is accessible but retention DMA is inaccessible 105 #endif 106 #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP 107 { 0x600fe000, 0x2000, SOC_MEMORY_TYPE_RTCRAM, 0}, //Fast RTC memory 108 #endif 109 }; 110 111 const size_t soc_memory_region_count = sizeof(soc_memory_regions) / sizeof(soc_memory_region_t); 112 113 extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end; // defined in sections.ld.in 114 extern int _rtc_reserved_start, _rtc_reserved_end; 115 116 /** 117 * Reserved memory regions. 118 * These are removed from the soc_memory_regions array when heaps are created. 119 * 120 */ 121 122 // Static data region. DRAM used by data+bss and possibly rodata 123 SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data); 124 125 // ESP32S3 has a big D/IRAM region, the part used by code is reserved 126 // The address of the D/I bus are in the same order, directly shift IRAM address to get reserved DRAM address 127 #define I_D_OFFSET (SOC_DIRAM_IRAM_LOW - SOC_DIRAM_DRAM_LOW) 128 // .text region in diram. DRAM used by text (shared with IBUS). 129 SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start - I_D_OFFSET, (intptr_t)&_iram_end - I_D_OFFSET, iram_code); 130 131 #if CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB 132 SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code_2); 133 #endif 134 135 #ifdef CONFIG_SPIRAM 136 /* Reserve the whole possible SPIRAM region here, spiram.c will add some or all of this 137 * memory to heap depending on the actual SPIRAM chip size. */ 138 SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_data_region); 139 #endif 140 141 #if CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM > 0 142 SOC_RESERVE_MEMORY_REGION(TRACEMEM_BLK0_ADDR, TRACEMEM_BLK0_ADDR + CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM / 2, trace_mem0); 143 SOC_RESERVE_MEMORY_REGION(TRACEMEM_BLK1_ADDR, TRACEMEM_BLK1_ADDR + CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM / 2, trace_mem1); 144 #endif 145 146 // RTC Fast RAM region 147 #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP 148 #ifdef CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM 149 SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data); 150 #else 151 SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data); 152 #endif 153 #endif 154 155 SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_reserved_start, (intptr_t)&_rtc_reserved_end, rtc_reserved_data); 156