lib/bootmem: Add more bootmem tags
Introduce new bootmem tags to allow more fine grained control over buffer allocation on various platforms. The new tags are: BM_MEM_RAMSTAGE : Memory where any kind of boot firmware resides and that should not be touched by bootmem (by example: stack, TTB, program, ...). BM_MEM_PAYLOAD : Memory where any kind of payload resides and that should not be touched by bootmem. Starting with this commit all bootmem methods will no longer see memory that is used by coreboot as usable RAM. Bootmem changes: * Introduce a weak function to add platform specific memranges. * Mark memory allocated by bootmem as BM_TAG_PAYLOAD. * Assert on failures. * Add _stack and _program as BM_MEM_RAMSTAGE. ARMv7 and ARMv8 specific changes: * Add _ttb and _postram_cbfs_cache as BM_MEM_RAMSTAGE. ARMv7 specific changes: * Add _ttb_subtables as BM_MEM_RAMSTAGE. Change-Id: I0c983ce43616147c519a43edee3b61d54eadbb9a Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/25383 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
6f15ba0112
commit
23d62dd15c
|
@ -18,6 +18,7 @@
|
||||||
#include <bootmem.h>
|
#include <bootmem.h>
|
||||||
#include <boot/tables.h>
|
#include <boot/tables.h>
|
||||||
#include <boot/coreboot_tables.h>
|
#include <boot/coreboot_tables.h>
|
||||||
|
#include <symbols.h>
|
||||||
|
|
||||||
void arch_write_tables(uintptr_t coreboot_table)
|
void arch_write_tables(uintptr_t coreboot_table)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +26,16 @@ void arch_write_tables(uintptr_t coreboot_table)
|
||||||
|
|
||||||
void bootmem_arch_add_ranges(void)
|
void bootmem_arch_add_ranges(void)
|
||||||
{
|
{
|
||||||
|
DECLARE_OPTIONAL_REGION(ttb_subtables);
|
||||||
|
|
||||||
|
bootmem_add_range((uintptr_t)_ttb, _ttb_size, BM_MEM_RAMSTAGE);
|
||||||
|
bootmem_add_range((uintptr_t)_ttb_subtables, _ttb_subtables_size,
|
||||||
|
BM_MEM_RAMSTAGE);
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_COMMON_CBFS_SPI_WRAPPER))
|
||||||
|
return;
|
||||||
|
bootmem_add_range((uintptr_t)_postram_cbfs_cache,
|
||||||
|
_postram_cbfs_cache_size, BM_MEM_RAMSTAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lb_arch_add_records(struct lb_header *header)
|
void lb_arch_add_records(struct lb_header *header)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <bootmem.h>
|
#include <bootmem.h>
|
||||||
#include <boot/tables.h>
|
#include <boot/tables.h>
|
||||||
#include <boot/coreboot_tables.h>
|
#include <boot/coreboot_tables.h>
|
||||||
|
#include <symbols.h>
|
||||||
|
|
||||||
void arch_write_tables(uintptr_t coreboot_table)
|
void arch_write_tables(uintptr_t coreboot_table)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +26,12 @@ void arch_write_tables(uintptr_t coreboot_table)
|
||||||
|
|
||||||
void bootmem_arch_add_ranges(void)
|
void bootmem_arch_add_ranges(void)
|
||||||
{
|
{
|
||||||
|
bootmem_add_range((uintptr_t)_ttb, _ttb_size, BM_MEM_RAMSTAGE);
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_COMMON_CBFS_SPI_WRAPPER))
|
||||||
|
return;
|
||||||
|
bootmem_add_range((uintptr_t)_postram_cbfs_cache,
|
||||||
|
_postram_cbfs_cache_size, BM_MEM_RAMSTAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lb_arch_add_records(struct lb_header *header)
|
void lb_arch_add_records(struct lb_header *header)
|
||||||
|
|
|
@ -21,7 +21,12 @@
|
||||||
#include <boot/coreboot_tables.h>
|
#include <boot/coreboot_tables.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bootmem types match to LB_MEM tags.
|
* Bootmem types match to LB_MEM tags, except for the following:
|
||||||
|
* BM_MEM_RAMSTAGE : Memory where any kind of boot firmware resides and that
|
||||||
|
* should not be touched by bootmem (by example: stack,
|
||||||
|
* TTB, program, ...).
|
||||||
|
* BM_MEM_PAYLOAD : Memory where any kind of payload resides and that should
|
||||||
|
* not be touched by bootmem.
|
||||||
* Start at 0x10000 to make sure that the caller doesn't provide LB_MEM tags.
|
* Start at 0x10000 to make sure that the caller doesn't provide LB_MEM tags.
|
||||||
*/
|
*/
|
||||||
enum bootmem_type {
|
enum bootmem_type {
|
||||||
|
@ -33,18 +38,29 @@ enum bootmem_type {
|
||||||
BM_MEM_UNUSABLE, /* Unusable address space */
|
BM_MEM_UNUSABLE, /* Unusable address space */
|
||||||
BM_MEM_VENDOR_RSVD, /* Vendor Reserved */
|
BM_MEM_VENDOR_RSVD, /* Vendor Reserved */
|
||||||
BM_MEM_TABLE, /* Ram configuration tables are kept in */
|
BM_MEM_TABLE, /* Ram configuration tables are kept in */
|
||||||
|
BM_MEM_RAMSTAGE,
|
||||||
|
BM_MEM_PAYLOAD,
|
||||||
BM_MEM_LAST, /* Last entry in this list */
|
BM_MEM_LAST, /* Last entry in this list */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Write memory coreboot table. Current resource map is serialized into
|
/**
|
||||||
|
* Write memory coreboot table. Current resource map is serialized into
|
||||||
* memtable (LB_MEM_* types). bootmem library is unusable until this function
|
* memtable (LB_MEM_* types). bootmem library is unusable until this function
|
||||||
* is called first in the write tables path before payload is loaded. */
|
* is called first in the write tables path before payload is loaded.
|
||||||
|
*
|
||||||
|
* Bootmem types match to LB_MEM tags, except for the following:
|
||||||
|
* BM_MEM_RAMSTAGE : Translates to LB_MEM_RAM.
|
||||||
|
* BM_MEM_PAYLOAD : Translates to LB_MEM_RAM.
|
||||||
|
*/
|
||||||
void bootmem_write_memory_table(struct lb_memory *mem);
|
void bootmem_write_memory_table(struct lb_memory *mem);
|
||||||
|
|
||||||
/* Architecture hook to add bootmem areas the architecture controls when
|
/* Architecture hook to add bootmem areas the architecture controls when
|
||||||
* bootmem_write_memory_table() is called. */
|
* bootmem_write_memory_table() is called. */
|
||||||
void bootmem_arch_add_ranges(void);
|
void bootmem_arch_add_ranges(void);
|
||||||
|
|
||||||
|
/* Platform hook to add bootmem areas the platform / board controls. */
|
||||||
|
void bootmem_platform_add_ranges(void);
|
||||||
|
|
||||||
/* Add a range of a given type to the bootmem address space. */
|
/* Add a range of a given type to the bootmem address space. */
|
||||||
void bootmem_add_range(uint64_t start, uint64_t size,
|
void bootmem_add_range(uint64_t start, uint64_t size,
|
||||||
const enum bootmem_type tag);
|
const enum bootmem_type tag);
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
#include <cbmem.h>
|
#include <cbmem.h>
|
||||||
#include <device/resource.h>
|
#include <device/resource.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <symbols.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static int initialized;
|
static int initialized;
|
||||||
|
static int table_written;
|
||||||
static struct memranges bootmem;
|
static struct memranges bootmem;
|
||||||
|
|
||||||
static int bootmem_is_initialized(void)
|
static int bootmem_is_initialized(void)
|
||||||
|
@ -30,6 +32,16 @@ static int bootmem_is_initialized(void)
|
||||||
return initialized;
|
return initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bootmem_memory_table_written(void)
|
||||||
|
{
|
||||||
|
return table_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Platform hook to add bootmem areas the platform / board controls. */
|
||||||
|
void __attribute__((weak)) bootmem_platform_add_ranges(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert bootmem tag to LB_MEM tag */
|
/* Convert bootmem tag to LB_MEM tag */
|
||||||
static uint32_t bootmem_to_lb_tag(const enum bootmem_type tag)
|
static uint32_t bootmem_to_lb_tag(const enum bootmem_type tag)
|
||||||
{
|
{
|
||||||
|
@ -73,7 +85,12 @@ static void bootmem_init(void)
|
||||||
/* Add memory used by CBMEM. */
|
/* Add memory used by CBMEM. */
|
||||||
cbmem_add_bootmem();
|
cbmem_add_bootmem();
|
||||||
|
|
||||||
|
/* Add memory used by coreboot. */
|
||||||
|
bootmem_add_range((uintptr_t)_stack, _stack_size, BM_MEM_RAMSTAGE);
|
||||||
|
bootmem_add_range((uintptr_t)_program, _program_size, BM_MEM_RAMSTAGE);
|
||||||
|
|
||||||
bootmem_arch_add_ranges();
|
bootmem_arch_add_ranges();
|
||||||
|
bootmem_platform_add_ranges();
|
||||||
}
|
}
|
||||||
|
|
||||||
void bootmem_add_range(uint64_t start, uint64_t size,
|
void bootmem_add_range(uint64_t start, uint64_t size,
|
||||||
|
@ -81,6 +98,8 @@ void bootmem_add_range(uint64_t start, uint64_t size,
|
||||||
{
|
{
|
||||||
assert(tag > BM_MEM_FIRST && tag < BM_MEM_LAST);
|
assert(tag > BM_MEM_FIRST && tag < BM_MEM_LAST);
|
||||||
assert(bootmem_is_initialized());
|
assert(bootmem_is_initialized());
|
||||||
|
assert(!bootmem_memory_table_written() || tag == BM_MEM_RAMSTAGE ||
|
||||||
|
tag == BM_MEM_PAYLOAD);
|
||||||
|
|
||||||
memranges_insert(&bootmem, start, size, tag);
|
memranges_insert(&bootmem, start, size, tag);
|
||||||
}
|
}
|
||||||
|
@ -89,13 +108,22 @@ void bootmem_write_memory_table(struct lb_memory *mem)
|
||||||
{
|
{
|
||||||
const struct range_entry *r;
|
const struct range_entry *r;
|
||||||
struct lb_memory_range *lb_r;
|
struct lb_memory_range *lb_r;
|
||||||
|
struct memranges bm;
|
||||||
|
|
||||||
lb_r = &mem->map[0];
|
lb_r = &mem->map[0];
|
||||||
|
|
||||||
bootmem_init();
|
bootmem_init();
|
||||||
bootmem_dump_ranges();
|
bootmem_dump_ranges();
|
||||||
|
|
||||||
memranges_each_entry(r, &bootmem) {
|
/**
|
||||||
|
* Convert BM_MEM_RAMSTAGE and BM_MEM_PAYLOAD to BM_MEM_RAM and
|
||||||
|
* merge ranges. The payload doesn't care about memory used by firmware.
|
||||||
|
*/
|
||||||
|
memranges_clone(&bm, &bootmem);
|
||||||
|
memranges_update_tag(&bm, BM_MEM_RAMSTAGE, BM_MEM_RAM);
|
||||||
|
memranges_update_tag(&bm, BM_MEM_PAYLOAD, BM_MEM_RAM);
|
||||||
|
|
||||||
|
memranges_each_entry(r, &bm) {
|
||||||
lb_r->start = pack_lb64(range_entry_base(r));
|
lb_r->start = pack_lb64(range_entry_base(r));
|
||||||
lb_r->size = pack_lb64(range_entry_size(r));
|
lb_r->size = pack_lb64(range_entry_size(r));
|
||||||
lb_r->type = bootmem_to_lb_tag(range_entry_tag(r));
|
lb_r->type = bootmem_to_lb_tag(range_entry_tag(r));
|
||||||
|
@ -103,6 +131,10 @@ void bootmem_write_memory_table(struct lb_memory *mem)
|
||||||
lb_r++;
|
lb_r++;
|
||||||
mem->size += sizeof(struct lb_memory_range);
|
mem->size += sizeof(struct lb_memory_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memranges_teardown(&bm);
|
||||||
|
|
||||||
|
table_written = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct range_strings {
|
struct range_strings {
|
||||||
|
@ -118,6 +150,8 @@ static const struct range_strings type_strings[] = {
|
||||||
{ BM_MEM_UNUSABLE, "UNUSABLE" },
|
{ BM_MEM_UNUSABLE, "UNUSABLE" },
|
||||||
{ BM_MEM_VENDOR_RSVD, "VENDOR RESERVED" },
|
{ BM_MEM_VENDOR_RSVD, "VENDOR RESERVED" },
|
||||||
{ BM_MEM_TABLE, "CONFIGURATION TABLES" },
|
{ BM_MEM_TABLE, "CONFIGURATION TABLES" },
|
||||||
|
{ BM_MEM_RAMSTAGE, "RAM, RAMSTAGE" },
|
||||||
|
{ BM_MEM_PAYLOAD, "RAM, PAYLOAD" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *bootmem_range_string(const enum bootmem_type tag)
|
static const char *bootmem_range_string(const enum bootmem_type tag)
|
||||||
|
@ -212,7 +246,7 @@ void *bootmem_allocate_buffer(size_t size)
|
||||||
begin = end - size;
|
begin = end - size;
|
||||||
|
|
||||||
/* Mark buffer as unusuable for future buffer use. */
|
/* Mark buffer as unusuable for future buffer use. */
|
||||||
bootmem_add_range(begin, size, BM_MEM_UNUSABLE);
|
bootmem_add_range(begin, size, BM_MEM_PAYLOAD);
|
||||||
|
|
||||||
return (void *)(uintptr_t)begin;
|
return (void *)(uintptr_t)begin;
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,7 +381,7 @@ static int load_self_segments(struct segment *head, struct prog *payload,
|
||||||
*/
|
*/
|
||||||
if (check_regions) {
|
if (check_regions) {
|
||||||
bootmem_add_range(ptr->s_dstaddr, ptr->s_memsz,
|
bootmem_add_range(ptr->s_dstaddr, ptr->s_memsz,
|
||||||
BM_MEM_UNUSABLE);
|
BM_MEM_PAYLOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlaps_coreboot(ptr))
|
if (!overlaps_coreboot(ptr))
|
||||||
|
|
Loading…
Reference in New Issue