1 /*
2  * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdlib.h>
8 #include <stdint.h>
9 
10 #include "sdkconfig.h"
11 #include "soc/soc.h"
12 #include "soc/tracemem_config.h"
13 #include "heap_memory_layout.h"
14 #include "esp_heap_caps.h"
15 
16 /* Memory layout for ESP32 SoC */
17 
18 /*
19 Memory type descriptors. These describe the capabilities of a type of memory in the SoC. Each type of memory
20 map consist of one or more regions in the address space.
21 
22 Each type contains an array of prioritised capabilities; types with later entries are only taken if earlier
23 ones can't fulfill the memory request.
24 
25 The prioritised capabilities work roughly like this:
26 - For a normal malloc (MALLOC_CAP_DEFAULT), give away the DRAM-only memory first, then pass off any dual-use IRAM regions,
27   finally eat into the application memory.
28 - For a malloc where 32-bit-aligned-only access is okay, first allocate IRAM, then DRAM, finally application IRAM.
29 - Application mallocs (PIDx) will allocate IRAM first, if possible, then DRAM.
30 - Most other malloc caps only fit in one region anyway.
31 
32 */
33 const soc_memory_type_desc_t soc_memory_types[] = {
34     //Type 0: DRAM
35     { "DRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA|MALLOC_CAP_32BIT, 0 }, false, false},
36     // Type 1: DRAM used for startup stacks
37     { "DRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA|MALLOC_CAP_32BIT, 0 }, false, true},
38     //Type 2: DRAM which has an alias on the I-port
39     { "D/IRAM", { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL|MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }, true, false},
40     //Type 3: IRAM
41     //In ESP32S2, All IRAM region are available by D-port (D/IRAM).
42     { "IRAM", { MALLOC_CAP_EXEC|MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL, 0, 0 }, false, false},
43     //Type 4: SPI SRAM data
44     //TODO, in fact, part of them support EDMA, to be supported.
45     { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false},
46     //Type 5: RTC Fast RAM
47     { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT }, false, false},
48 };
49 
50 #ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
51 #define SOC_MEMORY_TYPE_DEFAULT 0
52 #else
53 #define SOC_MEMORY_TYPE_DEFAULT 2
54 #endif
55 
56 const size_t soc_memory_type_count = sizeof(soc_memory_types)/sizeof(soc_memory_type_desc_t);
57 
58 /*
59 Region descriptors. These describe all regions of memory available, and map them to a type in the above type.
60 
61 Because of requirements in the coalescing code which merges adjacent regions, this list should always be sorted
62 from low to high start address.
63 */
64 const soc_memory_region_t soc_memory_regions[] = {
65 #ifdef CONFIG_SPIRAM
66     { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_SIZE, 4, 0}, //SPI SRAM, if available
67 #endif
68 #if CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB
69 #if CONFIG_ESP32S2_DATA_CACHE_0KB
70     { 0x3FFB2000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40022000}, //Block 1, can be use as I/D cache memory
71     { 0x3FFB4000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40024000}, //Block 2, can be use as D cache memory
72     { 0x3FFB6000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40026000}, //Block 3, can be use as D cache memory
73 #elif CONFIG_ESP32S2_DATA_CACHE_8KB
74     { 0x3FFB4000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40024000}, //Block 2, can be use as D cache memory
75     { 0x3FFB6000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40026000}, //Block 3, can be use as D cache memory
76 #else
77     { 0x3FFB6000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40026000}, //Block 3, can be use as D cache memory
78 #endif
79 #else
80 #if CONFIG_ESP32S2_DATA_CACHE_0KB
81     { 0x3FFB4000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40024000}, //Block SOC_MEMORY_TYPE_DEFAULT, can be use as D cache memory
82     { 0x3FFB6000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40026000}, //Block 3, can be use as D cache memory
83 #elif CONFIG_ESP32S2_DATA_CACHE_8KB
84     { 0x3FFB6000, 0x2000, SOC_MEMORY_TYPE_DEFAULT, 0x40026000}, //Block 3, can be use as D cache memory
85 #endif
86 #endif
87     { 0x3FFB8000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40028000}, //Block 4,  can be remapped to ROM, can be used as trace memory
88     { 0x3FFBC000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x4002C000}, //Block 5,  can be remapped to ROM, can be used as trace memory
89     { 0x3FFC0000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40030000}, //Block 6,  can be used as trace memory
90     { 0x3FFC4000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40034000}, //Block 7,  can be used as trace memory
91     { 0x3FFC8000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40038000}, //Block 8,  can be used as trace memory
92     { 0x3FFCC000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x4003C000}, //Block 9,  can be used as trace memory
93 
94     { 0x3FFD0000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40040000}, //Block 10,  can be used as trace memory
95     { 0x3FFD4000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40044000}, //Block 11,  can be used as trace memory
96     { 0x3FFD8000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40048000}, //Block 12,  can be used as trace memory
97     { 0x3FFDC000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x4004C000}, //Block 13,  can be used as trace memory
98     { 0x3FFE0000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40050000}, //Block 14,  can be used as trace memory
99     { 0x3FFE4000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40054000}, //Block 15,  can be used as trace memory
100     { 0x3FFE8000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40058000}, //Block 16,  can be used as trace memory
101     { 0x3FFEC000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x4005C000}, //Block 17,  can be used as trace memory
102     { 0x3FFF0000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40060000}, //Block 18,  can be used for MAC dump, can be used as trace memory
103     { 0x3FFF4000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40064000}, //Block 19,  can be used for MAC dump, can be used as trace memory
104     { 0x3FFF8000, 0x4000, SOC_MEMORY_TYPE_DEFAULT, 0x40068000}, //Block 20,  can be used for MAC dump, can be used as trace memory
105     { 0x3FFFC000, 0x4000, 1, 0x4006C000}, //Block 21,  can be used for MAC dump, can be used as trace memory, used for startup stack
106 #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
107     { SOC_RTC_DRAM_LOW, 0x2000, 5, 0}, //RTC Fast Memory
108 #endif
109 };
110 
111 const size_t soc_memory_region_count = sizeof(soc_memory_regions)/sizeof(soc_memory_region_t);
112 
113 
114 extern int _dram0_rtos_reserved_start;
115 extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end;
116 extern int _rtc_reserved_start, _rtc_reserved_end;
117 
118 /* Reserved memory regions
119 
120    These are removed from the soc_memory_regions array when heaps are created.
121  */
122 //ROM data region
123 SOC_RESERVE_MEMORY_REGION((intptr_t)&_dram0_rtos_reserved_start, SOC_BYTE_ACCESSIBLE_HIGH, rom_data_region);
124 
125 // Static data region. DRAM used by data+bss and possibly rodata
126 SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data);
127 
128 // ESP32S2 has a big D/IRAM region, the part used by code is reserved
129 // The address of the D/I bus are in the same order, directly shift IRAM address to get reserved DRAM address
130 #define I_D_OFFSET (SOC_IRAM_LOW - SOC_DRAM_LOW)
131 SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start - I_D_OFFSET, (intptr_t)&_iram_end - I_D_OFFSET, iram_code);
132 
133 #ifdef CONFIG_SPIRAM
134 /* Reserve the whole possible SPIRAM region here, spiram.c will add some or all of this
135  * memory to heap depending on the actual SPIRAM chip size. */
136 SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_data_region);
137 #endif
138 
139 // Blocks 19 and 20 may be reserved for the trace memory
140 #if CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM > 0
141 SOC_RESERVE_MEMORY_REGION(TRACEMEM_BLK0_ADDR, TRACEMEM_BLK0_ADDR + CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM / 2, trace_mem0);
142 SOC_RESERVE_MEMORY_REGION(TRACEMEM_BLK1_ADDR, TRACEMEM_BLK1_ADDR + CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM / 2, trace_mem1);
143 #endif
144 
145 // RTC Fast RAM region
146 #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
147 #ifdef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM
148 SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data);
149 #else
150 SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data);
151 #endif
152 #endif
153 
154 SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_reserved_start, (intptr_t)&_rtc_reserved_end, rtc_reserved_data);
155