qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/3] multiboot: Calculate upper_mem in the ROM


From: Kevin Wolf
Subject: [Qemu-devel] [PATCH 2/3] multiboot: Calculate upper_mem in the ROM
Date: Sun, 23 Jun 2013 22:07:45 +0200

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 <address@hidden>
---
 hw/i386/multiboot.c           |    2 --
 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 09211e0..985ca1e 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 a0f3602..b7efe4d 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:
-- 
1.7.7




reply via email to

[Prev in Thread] Current Thread [Next in Thread]