Select one of the symbols to view example projects that use it.
 
Outline
#include <stdint.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "soc/soc_memory_layout.h"
#include "esp_rom_caps.h"
#include "esp32c3/rom/rom_layout.h"
#include "esp32s3/rom/rom_layout.h"
#include "esp32c2/rom/rom_layout.h"
#include "esp32c6/rom/rom_layout.h"
#include "esp32c61/rom/rom_layout.h"
#include "esp32c5/rom/rom_layout.h"
#include "esp32h2/rom/rom_layout.h"
#include "esp32p4/rom/rom_layout.h"
TAG
s_get_num_reserved_regions()
soc_get_available_memory_region_max_count()
s_compare_reserved_regions(const void *, const void *)
s_prepare_reserved_regions(soc_reserved_region_t *, size_t)
soc_get_available_memory_regions(soc_memory_region_t *)
Files
loading...
SourceVuESP-IDF Framework and ExamplesESP-IDFcomponents/heap/port/memory_layout_utils.c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 *//* ... */ #include <stdint.h> #include <string.h> #include "sdkconfig.h" #include "esp_log.h" #include "soc/soc_memory_layout.h" #include "esp_rom_caps.h"6 includes #if ESP_ROM_HAS_LAYOUT_TABLE #ifdef CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/rom_layout.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/rom_layout.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/rom_layout.h" #elif CONFIG_IDF_TARGET_ESP32C6 #include "esp32c6/rom/rom_layout.h" #elif CONFIG_IDF_TARGET_ESP32C61 //TODO: IDF-9526, refactor this #include "esp32c61/rom/rom_layout.h" #elif CONFIG_IDF_TARGET_ESP32C5 #include "esp32c5/rom/rom_layout.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/rom_layout.h" #elif CONFIG_IDF_TARGET_ESP32P4 #include "esp32p4/rom/rom_layout.h" #endif/* ... */ #endif // ESP_ROM_HAS_LAYOUT_TABLE static const char *TAG = "memory_layout"; /* These variables come from the linker script, delimit the start and end of entries created via SOC_RESERVE_MEMORY_REGION() macro. *//* ... */ extern soc_reserved_region_t soc_reserved_memory_region_start; extern soc_reserved_region_t soc_reserved_memory_region_end; static size_t s_get_num_reserved_regions(void) { size_t result = ( &soc_reserved_memory_region_end - &soc_reserved_memory_region_start ); #if ESP_ROM_HAS_LAYOUT_TABLE return result + 1; // ROM table means one entry needs to be added at runtime #else return result; #endif }{ ... } size_t soc_get_available_memory_region_max_count(void) { /* Worst-case: each reserved memory region splits an available region in two, so the maximum possible number of regions is the number of regions of memory plus the number of reservations *//* ... */ return soc_memory_region_count + s_get_num_reserved_regions(); }{ ... } static int s_compare_reserved_regions(const void *a, const void *b) { const soc_reserved_region_t *r_a = (soc_reserved_region_t *)a; const soc_reserved_region_t *r_b = (soc_reserved_region_t *)b; return (int)r_a->start - (int)r_b->start; }{ ... } /* Initialize a mutable array of reserved regions in 'reserved', then sort it by start address and check for overlapping reserved regions (illegal). *//* ... */ static void s_prepare_reserved_regions(soc_reserved_region_t *reserved, size_t count) { #if ESP_ROM_HAS_LAYOUT_TABLE /* Get the ROM layout to find which part of DRAM is reserved */ const ets_rom_layout_t *layout = ets_rom_layout_p; reserved[0].start = (intptr_t)layout->dram0_rtos_reserved_start; #ifdef SOC_DIRAM_ROM_RESERVE_HIGH reserved[0].end = SOC_DIRAM_ROM_RESERVE_HIGH; #else reserved[0].end = SOC_DIRAM_DRAM_HIGH; #endif memcpy(reserved + 1, &soc_reserved_memory_region_start, (count - 1) * sizeof(soc_reserved_region_t));/* ... */ #else memcpy(reserved, &soc_reserved_memory_region_start, count * sizeof(soc_reserved_region_t)); #endif /* Sort by starting address */ qsort(reserved, count, sizeof(soc_reserved_region_t), s_compare_reserved_regions); /* Validity checks */ ESP_EARLY_LOGV(TAG, "reserved range is %p - %p", &soc_reserved_memory_region_start, &soc_reserved_memory_region_end); ESP_EARLY_LOGD(TAG, "Checking %d reserved memory ranges:", count); for (size_t i = 0; i < count; i++) { ESP_EARLY_LOGD(TAG, "Reserved memory range 0x%08x - 0x%08x", reserved[i].start, reserved[i].end); reserved[i].start = reserved[i].start & ~3; /* expand all reserved areas to word boundaries */ reserved[i].end = (reserved[i].end + 3) & ~3; assert(reserved[i].start <= reserved[i].end); if (i < count - 1) { assert(reserved[i + 1].start > reserved[i].start); if (reserved[i].end > reserved[i + 1].start) { ESP_EARLY_LOGE(TAG, "SOC_RESERVE_MEMORY_REGION region range " \ "0x%08x - 0x%08x overlaps with 0x%08x - 0x%08x", reserved[i].start, reserved[i].end, reserved[i + 1].start, reserved[i + 1].end); abort(); }{...} }{...} }{...} }{ ... } size_t soc_get_available_memory_regions(soc_memory_region_t *regions) { soc_memory_region_t *out_region = regions; /* make a local copy of the "input" regions so we can modify them */ soc_memory_region_t in_regions[soc_memory_region_count]; memcpy(in_regions, soc_memory_regions, sizeof(in_regions)); soc_memory_region_t *in_region = in_regions; size_t num_reserved = s_get_num_reserved_regions(); soc_reserved_region_t reserved[num_reserved]; s_prepare_reserved_regions(reserved, num_reserved); /* Go through the "in" regions (full regions, with no reserved sections removed from them) one at a time, trim off each reserved region, and then copy them to an out_region once trimmed *//* ... */ ESP_EARLY_LOGD(TAG, "Building list of available memory regions:"); while (in_region != in_regions + soc_memory_region_count) { soc_memory_region_t in = *in_region; ESP_EARLY_LOGV(TAG, "Examining memory region 0x%08x - 0x%08x", in.start, in.start + in.size); intptr_t in_start = in.start; intptr_t in_end = in_start + in.size; bool copy_in_to_out = true; bool move_to_next = true; for (size_t i = 0; i < num_reserved; i++) { if (reserved[i].end <= in_start) { /* reserved region ends before 'in' starts */ continue; }{...} else if (reserved[i].start >= in_end) { /* reserved region starts after 'in' ends */ break; }{...} else if (reserved[i].start <= in_start && reserved[i].end >= in_end) { /* reserved covers all of 'in' */ ESP_EARLY_LOGV(TAG, "Region 0x%08x - 0x%08x inside of reserved 0x%08x - 0x%08x", in_start, in_end, reserved[i].start, reserved[i].end); /* skip 'in' entirely */ copy_in_to_out = false; break; }{...} else if (in_start < reserved[i].start && in_end > reserved[i].end) { /* reserved contained inside 'in', need to "hole punch" */ ESP_EARLY_LOGV(TAG, "Region 0x%08x - 0x%08x contains reserved 0x%08x - 0x%08x", in_start, in_end, reserved[i].start, reserved[i].end); assert(in_start < reserved[i].start); assert(in_end > reserved[i].end); /* shrink this region to end where the reserved section starts */ in_end = reserved[i].start; in.size = in_end - in_start; /* update in_region so the 'next' iteration uses the region after the reserved section *//* ... */ in_region->size -= (reserved[i].end - in_region->start); in_region->start = reserved[i].end; /* add first region, then re-run while loop with the updated in_region */ move_to_next = false; break; }{...} else if (reserved[i].start <= in_start) { /* reserved overlaps start of 'in' */ ESP_EARLY_LOGV(TAG, "Start of region 0x%08x - 0x%08x overlaps reserved 0x%08x - 0x%08x", in_start, in_end, reserved[i].start, reserved[i].end); in.start = reserved[i].end; in_start = in.start; in.size = in_end - in_start; }{...} else { /* reserved overlaps end of 'in' */ ESP_EARLY_LOGV(TAG, "End of region 0x%08x - 0x%08x overlaps reserved 0x%08x - 0x%08x", in_start, in_end, reserved[i].start, reserved[i].end); in_end = reserved[i].start; in.size = in_end - in_start; }{...} }{...} /* ignore regions smaller than 16B */ if (in.size <= 16) { copy_in_to_out = false; }{...} if (copy_in_to_out) { ESP_EARLY_LOGD(TAG, "Available memory region 0x%08x - 0x%08x", in.start, in.start + in.size); *out_region++ = in; }{...} if (move_to_next) { in_region++; }{...} }{...} return (out_region - regions); /* return number of regions */ }{ ... }
Details