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