coreboot/src/include/bootmem.h
Julius Werner ae05d095b3 bootmem: Keep OS memory map separate from the start
The patch series ending in 64049be (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 in 1ecec5f (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>
2018-05-10 01:24:40 +00:00

103 lines
3.8 KiB
C

/*
* This file is part of the coreboot project.
*
* Copyright (C) 2014 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef BOOTMEM_H
#define BOOTMEM_H
#include <memrange.h>
#include <stdint.h>
#include <boot/coreboot_tables.h>
/**
* 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.
*/
enum bootmem_type {
BM_MEM_FIRST = 0x10000, /* First entry in this list */
BM_MEM_RAM, /* Memory anyone can use */
BM_MEM_RESERVED, /* Don't use this memory region */
BM_MEM_ACPI, /* ACPI Tables */
BM_MEM_NVS, /* ACPI NVS Memory */
BM_MEM_UNUSABLE, /* Unusable address space */
BM_MEM_VENDOR_RSVD, /* Vendor Reserved */
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_PAYLOAD,
BM_MEM_LAST, /* Last entry in this list */
};
/**
* Write memory coreboot table. Current resource map is serialized into
* memtable (LB_MEM_* types). bootmem library is unusable until this function
* 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);
/* Architecture hook to add bootmem areas the architecture controls when
* bootmem_write_memory_table() is called. */
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. */
void bootmem_add_range(uint64_t start, uint64_t size,
const enum bootmem_type tag);
/* Print current range map of boot memory. */
void bootmem_dump_ranges(void);
typedef bool (*range_action_t)(const struct range_entry *r, void *arg);
/**
* Walk memory tables from OS point of view and call the provided function,
* for every region. The caller has to return false to break out of the loop any
* time, or return true to continue.
*
* @param action The function to call for each memory range.
* @param arg Pointer passed to function @action. Set to NULL if unused.
* @return true if the function 'action' returned false.
*/
bool bootmem_walk_os_mem(range_action_t action, void *arg);
/**
* Walk memory tables and call the provided function, for every region.
* The caller has to return false to break out of the loop any time, or
* return true to continue.
*
* @param action The function to call for each memory range.
* @param arg Pointer passed to function @action. Set to NULL if unused.
* @return true if the function 'action' returned false.
*/
bool bootmem_walk(range_action_t action, void *arg);
/* Return 1 if region targets usable RAM, 0 otherwise. */
int bootmem_region_targets_usable_ram(uint64_t start, uint64_t size);
/* Allocate a temporary buffer from the unused RAM areas. */
void *bootmem_allocate_buffer(size_t size);
#endif /* BOOTMEM_H */