mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 12:35:28 +00:00
soc: Allow components to reserve fixed memory ranges that they need
No longer necessary to keep all reserved addresses in 'soc'. Means 'soc' does not need to know about 'bt', for example. Also means that Bluetooth can be enabled in config without any memory being reserved for BT controller. Only if code calling the BT controller is linked in, will this memory be reserved...
This commit is contained in:
@@ -52,74 +52,21 @@ void heap_caps_enable_nonos_stack_heaps()
|
||||
}
|
||||
}
|
||||
|
||||
//Modify regions array to disable the given range of memory.
|
||||
static void disable_mem_region(soc_memory_region_t *regions, intptr_t from, intptr_t to)
|
||||
{
|
||||
//Align from and to on word boundaries
|
||||
from = from & ~3;
|
||||
to = (to + 3) & ~3;
|
||||
|
||||
for (int i = 0; i < soc_memory_region_count; i++) {
|
||||
soc_memory_region_t *region = ®ions[i];
|
||||
|
||||
intptr_t regStart = region->start;
|
||||
intptr_t regEnd = region->start + region->size;
|
||||
if (regStart >= from && regEnd <= to) {
|
||||
//Entire region falls in the range. Disable entirely.
|
||||
regions[i].type = -1;
|
||||
} else if (regStart >= from && regEnd > to && regStart < to) {
|
||||
//Start of the region falls in the range. Modify address/len.
|
||||
intptr_t overlap = to - regStart;
|
||||
region->start += overlap;
|
||||
region->size -= overlap;
|
||||
if (region->iram_address) {
|
||||
region->iram_address += overlap;
|
||||
}
|
||||
} else if (regStart < from && regEnd > from && regEnd <= to) {
|
||||
//End of the region falls in the range. Modify length.
|
||||
region->size -= regEnd - from;
|
||||
} else if (regStart < from && regEnd > to) {
|
||||
//Range punches a hole in the region! We do not support this.
|
||||
ESP_EARLY_LOGE(TAG, "region %d: hole punching is not supported!", i);
|
||||
regions->type = -1; //Just disable memory region. That'll teach them!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Warning: These variables are assumed to have the start and end of the data and iram
|
||||
area used statically by the program, respectively. These variables are defined in the ld
|
||||
file.
|
||||
*/
|
||||
extern int _data_start, _heap_start, _init_start, _iram_text_end;
|
||||
|
||||
/*
|
||||
Initialize the heap allocator. We pass it a bunch of region descriptors, but we need to modify those first to accommodate for
|
||||
the data as loaded by the bootloader.
|
||||
ToDo: The regions are different when stuff like trace memory, BT, ... is used. Modify the regions struct on the fly for this.
|
||||
Same with loading of apps. Same with using SPI RAM.
|
||||
*/
|
||||
/* Initialize the heap allocator to use all of the memory not
|
||||
used by static data or reserved for other purposes
|
||||
*/
|
||||
void heap_caps_init()
|
||||
{
|
||||
/* Copy the soc_memory_regions data to the stack, so we can
|
||||
manipulate it. */
|
||||
soc_memory_region_t regions[soc_memory_region_count];
|
||||
memcpy(regions, soc_memory_regions, sizeof(soc_memory_region_t)*soc_memory_region_count);
|
||||
|
||||
//Disable the bits of memory where this code is loaded.
|
||||
disable_mem_region(regions, (intptr_t)&_data_start, (intptr_t)&_heap_start); //DRAM used by bss/data static variables
|
||||
disable_mem_region(regions, (intptr_t)&_init_start, (intptr_t)&_iram_text_end); //IRAM used by code
|
||||
|
||||
// Disable all regions reserved on this SoC
|
||||
for (int i = 0; i < soc_reserved_region_count; i++) {
|
||||
disable_mem_region(regions, soc_reserved_regions[i].start,
|
||||
soc_reserved_regions[i].end);
|
||||
}
|
||||
/* Get the array of regions that we can use for heaps
|
||||
(with reserved memory removed already.)
|
||||
*/
|
||||
size_t num_regions = soc_get_available_memory_region_max_count();
|
||||
soc_memory_region_t regions[num_regions];
|
||||
num_regions = soc_get_available_memory_regions(regions);
|
||||
|
||||
//The heap allocator will treat every region given to it as separate. In order to get bigger ranges of contiguous memory,
|
||||
//it's useful to coalesce adjacent regions that have the same type.
|
||||
|
||||
for (int i = 1; i < soc_memory_region_count; i++) {
|
||||
for (int i = 1; i < num_regions; i++) {
|
||||
soc_memory_region_t *a = ®ions[i - 1];
|
||||
soc_memory_region_t *b = ®ions[i];
|
||||
if (b->start == a->start + a->size && b->type == a->type ) {
|
||||
@@ -131,7 +78,7 @@ void heap_caps_init()
|
||||
|
||||
/* Count the heaps left after merging */
|
||||
size_t num_heaps = 0;
|
||||
for (int i = 0; i < soc_memory_region_count; i++) {
|
||||
for (int i = 0; i < num_regions; i++) {
|
||||
if (regions[i].type != -1) {
|
||||
num_heaps++;
|
||||
}
|
||||
@@ -145,7 +92,7 @@ void heap_caps_init()
|
||||
size_t heap_idx = 0;
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "Initializing. RAM available for dynamic allocation:");
|
||||
for (int i = 0; i < soc_memory_region_count; i++) {
|
||||
for (int i = 0; i < num_regions; i++) {
|
||||
soc_memory_region_t *region = ®ions[i];
|
||||
const soc_memory_type_desc_t *type = &soc_memory_types[region->type];
|
||||
heap_t *heap = &temp_heaps[heap_idx];
|
||||
|
Reference in New Issue
Block a user