summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/i386/multiboot.c2
-rw-r--r--pc-bios/optionrom/multiboot.S40
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: