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:
Angus Gratton
2018-06-22 17:32:58 +10:00
committed by bot
parent f2f2744b29
commit a5ae5ac4b3
7 changed files with 283 additions and 92 deletions

View File

@@ -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 = &regions[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 = &regions[i - 1];
soc_memory_region_t *b = &regions[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 = &regions[i];
const soc_memory_type_desc_t *type = &soc_memory_types[region->type];
heap_t *heap = &temp_heaps[heap_idx];