summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2022-02-15 06:41:52 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-02-15 14:43:51 +0100
commit294372afde326b8c277f738f3f8340cdd86f5b92 (patch)
treeeb3323a1c26848a78425d246ae63ddf73f45cac6
parent77880e36ac844c032c9408075e41b5daa6986f1b (diff)
biosmem: Narrow e820 regions as required
Message-Id: <20220215064133.68593-1-damien@zamaudio.com>
-rw-r--r--i386/i386at/biosmem.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/i386/i386at/biosmem.c b/i386/i386at/biosmem.c
index 4f0914ca..78e7bb21 100644
--- a/i386/i386at/biosmem.c
+++ b/i386/i386at/biosmem.c
@@ -83,6 +83,19 @@ static unsigned int biosmem_nr_boot_data __bootdata;
#define BIOSMEM_TYPE_DISABLED 6
/*
+ * Bitmask corresponding to memory ranges that require narrowing
+ * to page boundaries.
+ */
+#define BIOSMEM_MASK_NARROW (((1u << BIOSMEM_TYPE_AVAILABLE) | \
+ (1u << BIOSMEM_TYPE_NVS) | \
+ (1u << BIOSMEM_TYPE_DISABLED)))
+
+/*
+ * Helper macro to test if range type needs narrowing.
+ */
+#define BIOSMEM_NEEDS_NARROW(t) ((1u << t) & BIOSMEM_MASK_NARROW)
+
+/*
* Memory map entry.
*/
struct biosmem_map_entry {
@@ -249,6 +262,17 @@ biosmem_unregister_boot_data(phys_addr_t start, phys_addr_t end)
#ifndef MACH_HYP
static void __boot
+biosmem_map_adjust_alignment(struct biosmem_map_entry *e)
+{
+ uint64_t end = e->base_addr + e->length;
+
+ if (BIOSMEM_NEEDS_NARROW(e->type)) {
+ e->base_addr = vm_page_round (e->base_addr);
+ e->length = vm_page_trunc (end) - e->base_addr;
+ }
+}
+
+static void __boot
biosmem_map_build(const struct multiboot_raw_info *mbi)
{
struct multiboot_raw_mmap_entry *mb_entry, *mb_end;
@@ -268,6 +292,8 @@ biosmem_map_build(const struct multiboot_raw_info *mbi)
entry->type = mb_entry->type;
mb_entry = (void *)mb_entry + sizeof(mb_entry->size) + mb_entry->size;
+
+ biosmem_map_adjust_alignment(entry);
entry++;
}
@@ -283,11 +309,13 @@ biosmem_map_build_simple(const struct multiboot_raw_info *mbi)
entry->base_addr = 0;
entry->length = mbi->mem_lower << 10;
entry->type = BIOSMEM_TYPE_AVAILABLE;
+ biosmem_map_adjust_alignment(entry);
entry++;
entry->base_addr = BIOSMEM_END;
entry->length = mbi->mem_upper << 10;
entry->type = BIOSMEM_TYPE_AVAILABLE;
+ biosmem_map_adjust_alignment(entry);
biosmem_map_size = 2;
}