summaryrefslogtreecommitdiff
path: root/i386/i386at/model_dep.c
diff options
context:
space:
mode:
Diffstat (limited to 'i386/i386at/model_dep.c')
-rw-r--r--i386/i386at/model_dep.c65
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 */