This is needed because the e820 memory regions are not necessarily page aligned. This fixes ACPICA probing of root table mapping.
TESTED with experimental acpi. --- i386/i386at/biosmem.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/i386/i386at/biosmem.c b/i386/i386at/biosmem.c index 4f0914ca..779e542b 100644 --- a/i386/i386at/biosmem.c +++ b/i386/i386at/biosmem.c @@ -73,14 +73,22 @@ static unsigned int biosmem_nr_boot_data __bootdata; #define BIOSMEM_MAX_MAP_SIZE 128 /* - * Memory range types. + * Memory range types (as bitmask) */ -#define BIOSMEM_TYPE_AVAILABLE 1 -#define BIOSMEM_TYPE_RESERVED 2 -#define BIOSMEM_TYPE_ACPI 3 -#define BIOSMEM_TYPE_NVS 4 -#define BIOSMEM_TYPE_UNUSABLE 5 -#define BIOSMEM_TYPE_DISABLED 6 +#define BIOSMEM_TYPE_AVAILABLE (1u << 0) +#define BIOSMEM_TYPE_RESERVED (1u << 1) +#define BIOSMEM_TYPE_ACPI (1u << 2) +#define BIOSMEM_TYPE_NVS (1u << 3) +#define BIOSMEM_TYPE_UNUSABLE (1u << 4) +#define BIOSMEM_TYPE_DISABLED (1u << 5) + +/* + * Bitmask corresponding to memory ranges that require narrowing + * to page boundaries. Unset ranges in the mask require widening. + */ +#define BIOSMEM_MASK_NARROW ((BIOSMEM_TYPE_AVAILABLE | \ + BIOSMEM_TYPE_NVS | \ + BIOSMEM_TYPE_DISABLED)) /* * Memory map entry. @@ -248,6 +256,18 @@ 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) +{ + if (e->type & BIOSMEM_MASK_NARROW) { + e->base_addr = vm_page_round (e->base_addr); + e->length = vm_page_trunc (e->length); + } else { + e->base_addr = vm_page_trunc (e->base_addr); + e->length = vm_page_round (e->length); + } +} + static void __boot biosmem_map_build(const struct multiboot_raw_info *mbi) { @@ -268,6 +288,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 +305,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; } -- 2.34.1