summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2018-11-30 21:24:56 +0100
committerAlexander Graf <agraf@suse.de>2018-12-02 21:59:37 +0100
commit7b78d6438a2b3a7f58a34934b54a1a83733b8fdd (patch)
treee7701d578d250b5cc47abad743bb73ec0738ec12 /lib
parent335ce71db78b80ab43cf68fcf812fb99bac84c86 (diff)
downloadu-boot-7b78d6438a2b3a7f58a34934b54a1a83733b8fdd.tar.gz
u-boot-7b78d6438a2b3a7f58a34934b54a1a83733b8fdd.tar.bz2
u-boot-7b78d6438a2b3a7f58a34934b54a1a83733b8fdd.zip
efi_loader: Reserve unaccessible memory
On some systems, not all RAM may be usable within U-Boot. Maybe the memory maps are incomplete, maybe it's used as workaround for broken DMA. But whatever the reason may be, a platform can say that it does not wish to have its RAM accessed above a certain address by defining board_get_usable_ram_top(). In the efi_loader world, we ignored that hint, mostly because very few boards actually have real restrictions around this. So let's honor the board's wish to not access high addresses during boot time. The best way to do so is by indicating the respective pages as "allocated by firmware". That way, Operating Systems will still use the pages after boot, but before boot no allocation will use them. Reported-by: Baruch Siach <baruch@tkos.co.il> Signed-off-by: Alexander Graf <agraf@suse.de> Reviewed-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Tested-by: Baruch Siach <baruch@tkos.co.il>
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_memory.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index f225a9028c..73bfbb65c4 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -551,8 +551,13 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
__weak void efi_add_known_memory(void)
{
+ u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
int i;
+ /* Fix for 32bit targets with ram_top at 4G */
+ if (!ram_top)
+ ram_top = 0x100000000ULL;
+
/* Add RAM */
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
u64 ram_end, ram_start, pages;
@@ -564,11 +569,32 @@ __weak void efi_add_known_memory(void)
ram_end &= ~EFI_PAGE_MASK;
ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
- if (ram_end > ram_start) {
- pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
+ if (ram_end <= ram_start) {
+ /* Invalid mapping, keep going. */
+ continue;
+ }
+
+ pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
+ efi_add_memory_map(ram_start, pages,
+ EFI_CONVENTIONAL_MEMORY, false);
+
+ /*
+ * Boards may indicate to the U-Boot memory core that they
+ * can not support memory above ram_top. Let's honor this
+ * in the efi_loader subsystem too by declaring any memory
+ * above ram_top as "already occupied by firmware".
+ */
+ if (ram_top < ram_start) {
+ /* ram_top is before this region, reserve all */
efi_add_memory_map(ram_start, pages,
- EFI_CONVENTIONAL_MEMORY, false);
+ EFI_BOOT_SERVICES_DATA, true);
+ } else if ((ram_top >= ram_start) && (ram_top < ram_end)) {
+ /* ram_top is inside this region, reserve parts */
+ pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT;
+
+ efi_add_memory_map(ram_top, pages,
+ EFI_BOOT_SERVICES_DATA, true);
}
}
}