diff options
-rw-r--r-- | hw/i386/multiboot.c | 2 | ||||
-rw-r--r-- | pc-bios/optionrom/multiboot.S | 40 |
2 files changed, 40 insertions, 2 deletions
diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 09211e0534..985ca1ed84 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -315,8 +315,6 @@ int load_multiboot(FWCfgState *fw_cfg, | MULTIBOOT_FLAGS_CMDLINE | MULTIBOOT_FLAGS_MODULES | MULTIBOOT_FLAGS_MMAP); - stl_p(bootinfo + MBI_MEM_LOWER, 640); - stl_p(bootinfo + MBI_MEM_UPPER, (ram_size / 1024) - 1024); stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8000ffff); /* XXX: use the -boot switch? */ stl_p(bootinfo + MBI_MMAP_ADDR, ADDR_E820_MAP); diff --git a/pc-bios/optionrom/multiboot.S b/pc-bios/optionrom/multiboot.S index a0f3602956..b7efe4de34 100644 --- a/pc-bios/optionrom/multiboot.S +++ b/pc-bios/optionrom/multiboot.S @@ -123,6 +123,46 @@ mmap_store_entry: jnz mmap_loop mmap_done: + /* Calculate upper_mem field: The amount of memory between 1 MB and + the first upper memory hole. Get it from the mmap. */ + xor %di, %di + mov $0x100000, %edx +upper_mem_entry: + cmp %fs:0x2c, %di + je upper_mem_done + add $4, %di + + /* Skip if type != 1 */ + cmpl $1, %es:16(%di) + jne upper_mem_next + + /* Skip if > 4 GB */ + movl %es:4(%di), %eax + test %eax, %eax + jnz upper_mem_next + + /* Check for contiguous extension (base <= %edx < base + length) */ + movl %es:(%di), %eax + cmp %eax, %edx + jb upper_mem_next + addl %es:8(%di), %eax + cmp %eax, %edx + jae upper_mem_next + + /* If so, update %edx, and restart the search (mmap isn't ordered) */ + mov %eax, %edx + xor %di, %di + jmp upper_mem_entry + +upper_mem_next: + addl %es:-4(%di), %edi + jmp upper_mem_entry + +upper_mem_done: + sub $0x100000, %edx + shr $10, %edx + mov %edx, %fs:0x8 + real_to_prot: /* Load the GDT before going into protected mode */ lgdt: |