diff options
author | Richard Braun <rbraun@sceen.net> | 2016-09-05 23:47:22 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2016-09-06 00:02:03 +0200 |
commit | ae902513130a14ffded5d00216e8729d3f5ed7fa (patch) | |
tree | 3f14e5be9f791d0a32721f8463fd85b913dce959 /i386/i386at/model_dep.c | |
parent | f6a2436d282a06e5f34789c8c5917e838fa26643 (diff) |
Make early physical page allocation truely reliable
Import upstream biosmem changes and adjust for local modifications.
Specifically, this change makes the biosmem module reliably track all
boot data by storing their addresses in a sorted array. This allows
both the early page allocator and the biosmem_free_usable function
to accurately find any range of free pages.
* i386/i386at/biosmem.c: Remove inclusion of <i386at/elf.h>.
(_start, _end): Remove variable declarations.
(BIOSMEM_MAX_BOOT_DATA): New macro.
(struct biosmem_boot_data): New type.
(biosmem_boot_data_array, biosmem_nr_boot_data): New variables.
(biosmem_heap_start, biosmem_heap_bottom, biosmem_heap_top,
biosmem_heap_end): Change type to phys_addr_t.
(biosmem_panic_inval_boot_data): New variable.
(biosmem_panic_too_many_boot_data): Likewise.
(biosmem_panic_toobig_msg): Variable renamed ...
(biosmem_panic_too_big_msg): ... to this.
(biosmem_register_boot_data): New function.
(biosmem_unregister_boot_data): Likewise.
(biosmem_map_adjust): Update reference to panic message.
(biosmem_map_find_avail): Add detailed description.
(biosmem_save_cmdline_sizes): Remove function.
(biosmem_find_heap_clip): Likewise.
(biosmem_find_heap): Likewise.
(biosmem_find_avail_clip, biosmem_find_avail): New functions.
(biosmem_setup_allocator): Receive const multiboot info, replace
calls to biosmem_find_heap with calls to biosmem_find_avail and
update accordingly. Register the heap as boot data.
(biosmem_xen_bootstrap): Register the Xen boot info and the heap as
boot data.
(biosmem_bootstrap): Receive const multiboot information. Remove call
to biosmem_save_cmdline_sizes.
(biosmem_bootalloc): Remove assertion on the VM system state.
(biosmem_type_desc, biosmem_map_show): Build only if DEBUG is true.
(biosmem_unregister_temporary_boot_data): New function.
(biosmem_free_usable_range): Change address range format.
(biosmem_free_usable_entry): Rewrite to use biosmem_find_avail
without abusing it.
(biosmem_free_usable): Call biosmem_unregister_temporary_boot_data,
update call to biosmem_free_usable_entry.
* i386/i386at/biosmem.h (biosmem_register_boot_data): New function.
(biosmem_bootalloc): Update description.
(biosmem_bootstrap): Update description and declaration.
(biosmem_free_usable): Likewise.
* i386/i386at/model_dep.c: Include <i386at/elf.h>.
(machine_init): Update call to biosmem_free_usable.
(register_boot_data): New function.
(i386at_init): Call register_boot_data where appropriate.
Diffstat (limited to 'i386/i386at/model_dep.c')
-rw-r--r-- | i386/i386at/model_dep.c | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c index 8e98bd9e..87d6cefa 100644 --- a/i386/i386at/model_dep.c +++ b/i386/i386at/model_dep.c @@ -66,6 +66,7 @@ #include <i386/model_dep.h> #include <i386at/autoconf.h> #include <i386at/biosmem.h> +#include <i386at/elf.h> #include <i386at/idt.h> #include <i386at/int_init.h> #include <i386at/kd.h> @@ -158,9 +159,7 @@ void machine_init(void) * This is particularly important for the Linux drivers which * require available DMA memory. */ -#ifndef MACH_HYP - biosmem_free_usable((struct multiboot_raw_info *) &boot_info); -#endif /* MACH_HYP */ + biosmem_free_usable(); /* * Set up to use floating point. @@ -274,6 +273,65 @@ void db_reset_cpu(void) halt_all_cpus(1); } +#ifndef MACH_HYP + +static void +register_boot_data(const struct multiboot_raw_info *mbi) +{ + struct multiboot_raw_module *mod; + struct elf_shdr *shdr; + unsigned long tmp; + unsigned int i; + + extern char _start[], _end[]; + + /* XXX For now, register all boot data as permanent */ + + biosmem_register_boot_data(_kvtophys(&_start), _kvtophys(&_end), FALSE); + + if ((mbi->flags & MULTIBOOT_LOADER_CMDLINE) && (mbi->cmdline != 0)) { + biosmem_register_boot_data(mbi->cmdline, + mbi->cmdline + strlen((void *)mbi->cmdline) + 1, FALSE); + } + + if (mbi->flags & MULTIBOOT_LOADER_MODULES) { + i = mbi->mods_count * sizeof(struct multiboot_raw_module); + biosmem_register_boot_data(mbi->mods_addr, mbi->mods_addr + i, FALSE); + + tmp = phystokv(mbi->mods_addr); + + for (i = 0; i < mbi->mods_count; i++) { + mod = (struct multiboot_raw_module *)tmp + i; + biosmem_register_boot_data(mod->mod_start, mod->mod_end, FALSE); + + if (mod->string != 0) { + biosmem_register_boot_data(mod->string, + mod->string + strlen((void *)mod->string) + 1, + FALSE); + } + } + } + + if (mbi->flags & MULTIBOOT_LOADER_SHDR) { + tmp = mbi->shdr_num * mbi->shdr_size; + biosmem_register_boot_data(mbi->shdr_addr, mbi->shdr_addr + tmp, FALSE); + + tmp = phystokv(mbi->shdr_addr); + + for (i = 0; i < mbi->shdr_num; i++) { + shdr = (struct elf_shdr *)(tmp + (i * mbi->shdr_size)); + + if ((shdr->type != ELF_SHT_SYMTAB) + && (shdr->type != ELF_SHT_STRTAB)) + continue; + + biosmem_register_boot_data(shdr->addr, shdr->addr + shdr->size, FALSE); + } + } +} + +#endif /* MACH_HYP */ + /* * Basic PC VM initialization. * Turns on paging and changes the kernel segments to use high linear addresses. @@ -301,6 +359,7 @@ i386at_init(void) #ifdef MACH_HYP biosmem_xen_bootstrap(); #else /* MACH_HYP */ + register_boot_data((struct multiboot_raw_info *) &boot_info); biosmem_bootstrap((struct multiboot_raw_info *) &boot_info); #endif /* MACH_HYP */ |