1
6
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
60
61
67
68
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
133
134
135
136
137
138
139
140
141
142
143
150
157
158
159
160
161
162
163
164
165
166
167
169
170
171
172
173
174
175
187
188
189
190
193
194
198
201
202
203
204
/* ... */
#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
#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
static const char *TAG = "memory_layout";
/* ... */
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;
#else
return result;
#endif
}{ ... }
size_t soc_get_available_memory_region_max_count(void)
{
/* ... */
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;
}{ ... }
/* ... */
static void s_prepare_reserved_regions(soc_reserved_region_t *reserved, size_t count)
{
#if ESP_ROM_HAS_LAYOUT_TABLE
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
qsort(reserved, count, sizeof(soc_reserved_region_t), s_compare_reserved_regions);
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;
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;
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);
/* ... */
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) {
continue;
}{...} else if (reserved[i].start >= in_end) {
break;
}{...} else if (reserved[i].start <= in_start &&
reserved[i].end >= in_end) {
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);
copy_in_to_out = false;
break;
}{...} else if (in_start < reserved[i].start &&
in_end > reserved[i].end) {
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);
in_end = reserved[i].start;
in.size = in_end - in_start;
/* ... */
in_region->size -= (reserved[i].end - in_region->start);
in_region->start = reserved[i].end;
move_to_next = false;
break;
}{...} else if (reserved[i].start <= in_start) {
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 {
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;
}{...}
}{...}
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);
}{ ... }