bootmem: Keep OS memory map separate from the start
The patch series ending in64049be
(lib/bootmem: Add method to walk OS POV memory tables) expanded the bootmem framework to also keep track of memory regions that are only relevant while coreboot is still executing, such as the ramstage code and data. Mixing this into the exsting bootmem ranges has already caused an issue on CONFIG_RELOCATEABLE_RAMSTAGE boards, because the ramstage code in CBMEM is marked as BM_RAMSTAGE which ends up getting translated back to LB_RAM in the OS tables. This was fixed in1ecec5f
(lib/bootmem: ensure ramstage memory isn't given to OS) for this specific case, but unfortunately Arm boards can have a similar problem where their stack space is sometimes located in an SRAM region that should not be made available as RAM to the OS. Since both the resources made available to the OS and the regions reserved for coreboot can be different for each platform, we should find a generic solution to this rather than trying to deal with each issue individually. This patch solves the problem by keeping the OS point of view and the coreboot-specific ranges separate from the start, rather than cloning it out later. Ranges only relevant to the coreboot view will never touch the OS-specific layout, to avoid the problem of losing information about the original memory type of the underlying region that needs to be restored for the OS view. This both supersedes the RELOCATABLE_RAMSTAGE fix and resolves the problems on Arm boards. Change-Id: I7bb018456b58ad9b0cfb0b8da8c26b791b487fbb Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/26182 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Nico Huber <nico.h@gmx.de> Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
40e6d2ebbd
commit
ae05d095b3
|
@ -38,6 +38,8 @@ 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 */
|
||||||
|
/* Tags below this point are ignored for the OS table. */
|
||||||
|
BM_MEM_OS_CUTOFF = BM_MEM_TABLE,
|
||||||
BM_MEM_RAMSTAGE,
|
BM_MEM_RAMSTAGE,
|
||||||
BM_MEM_PAYLOAD,
|
BM_MEM_PAYLOAD,
|
||||||
BM_MEM_LAST, /* Last entry in this list */
|
BM_MEM_LAST, /* Last entry in this list */
|
||||||
|
|
|
@ -67,17 +67,6 @@ static uint32_t bootmem_to_lb_tag(const enum bootmem_type tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootmem_convert_ranges(void)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 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(&bootmem_os, &bootmem);
|
|
||||||
memranges_update_tag(&bootmem_os, BM_MEM_RAMSTAGE, BM_MEM_RAM);
|
|
||||||
memranges_update_tag(&bootmem_os, BM_MEM_PAYLOAD, BM_MEM_RAM);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bootmem_init(void)
|
static void bootmem_init(void)
|
||||||
{
|
{
|
||||||
const unsigned long cacheable = IORESOURCE_CACHEABLE;
|
const unsigned long cacheable = IORESOURCE_CACHEABLE;
|
||||||
|
@ -93,24 +82,16 @@ static void bootmem_init(void)
|
||||||
*/
|
*/
|
||||||
memranges_init(bm, cacheable, cacheable, BM_MEM_RAM);
|
memranges_init(bm, cacheable, cacheable, BM_MEM_RAM);
|
||||||
memranges_add_resources(bm, reserved, reserved, BM_MEM_RESERVED);
|
memranges_add_resources(bm, reserved, reserved, BM_MEM_RESERVED);
|
||||||
|
memranges_clone(&bootmem_os, bm);
|
||||||
|
|
||||||
/* Add memory used by CBMEM. */
|
/* Add memory used by CBMEM. */
|
||||||
cbmem_add_bootmem();
|
cbmem_add_bootmem();
|
||||||
|
|
||||||
/* Add memory used by coreboot -- only if RELOCATABLE_RAMSTAGE is not
|
bootmem_add_range((uintptr_t)_stack, _stack_size, BM_MEM_RAMSTAGE);
|
||||||
* used. When RELOCATABLE_RAMSTAGE is employed ramstage lives in cbmem
|
bootmem_add_range((uintptr_t)_program, _program_size, BM_MEM_RAMSTAGE);
|
||||||
* so cbmem_add_bootmem() takes care of that memory region. */
|
|
||||||
if (!IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) {
|
|
||||||
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();
|
bootmem_platform_add_ranges();
|
||||||
|
|
||||||
bootmem_convert_ranges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bootmem_add_range(uint64_t start, uint64_t size,
|
void bootmem_add_range(uint64_t start, uint64_t size,
|
||||||
|
@ -118,10 +99,13 @@ 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);
|
||||||
|
if (tag <= BM_MEM_OS_CUTOFF) {
|
||||||
|
/* Can't change OS tables anymore after they are written out. */
|
||||||
|
assert(!bootmem_memory_table_written());
|
||||||
|
memranges_insert(&bootmem_os, start, size, tag);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void bootmem_write_memory_table(struct lb_memory *mem)
|
void bootmem_write_memory_table(struct lb_memory *mem)
|
||||||
|
@ -159,8 +143,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_RAMSTAGE, "RAMSTAGE" },
|
||||||
{ BM_MEM_PAYLOAD, "RAM, PAYLOAD" },
|
{ BM_MEM_PAYLOAD, "PAYLOAD" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *bootmem_range_string(const enum bootmem_type tag)
|
static const char *bootmem_range_string(const enum bootmem_type tag)
|
||||||
|
|
Loading…
Reference in New Issue