]> git.proxmox.com Git - qemu.git/commitdiff
multiboot: Calculate upper_mem in the ROM
authorKevin Wolf <mail@kevin-wolf.de>
Sun, 23 Jun 2013 20:07:45 +0000 (22:07 +0200)
committerAnthony Liguori <aliguori@us.ibm.com>
Fri, 28 Jun 2013 19:01:52 +0000 (14:01 -0500)
The upper_mem field of the Multiboot information struct doesn't really
contain the RAM size - 1 MB like we used to calculate it, but only the
memory from 1 MB up to the first (upper) memory hole.

In order to correctly retrieve this information, the multiboot ROM now
looks at the mmap it creates anyway and tries to find the size of
contiguous usable memory from 1 MB.

Drop the multiboot.c definition of lower_mem and upper_mem because both
are queried at runtime now.

Signed-off-by: Kevin Wolf <mail@kevin-wolf.de>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1372018066-21822-3-git-send-email-mail@kevin-wolf.de
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
hw/i386/multiboot.c
pc-bios/optionrom/multiboot.S

index 09211e053453e4ae5b9ad38c0f673acffbb60246..985ca1ed8457bbd6b1585c5582430a35b755dc81 100644 (file)
@@ -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);
 
index a0f36029569d526829001213678eea973e63e063..b7efe4de343138c767d9e7a43d5f13d788f1048a 100644 (file)
@@ -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: