diff --git a/ChangeLog b/ChangeLog index 70fa29313..9fe3fa8b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-06-20 Vladimir Serbinenko + + Support >3GiB and <16MiB RAM in i386-qemu. + + * kern/i386/qemu/mmap.c (QEMU_CMOS_MEMSIZE2_HIGH): New const. + (QEMU_CMOS_MEMSIZE2_LOW): Likewise. + (grub_lower_mem): Removed. + (grub_upper_mem): Likewise. + (mem_size): Made static. + (above_4g): New variable. + (grub_machine_mmap_init): Detect small mem_size and above_4g. + (grub_machine_mmap_iterate): Order in ascending order and add above_4g + support. + 2010-06-20 Vladimir Serbinenko Cirrus 5446 and Bochs video cards support. diff --git a/kern/i386/qemu/mmap.c b/kern/i386/qemu/mmap.c index c7fc4f45e..f2a998e78 100644 --- a/kern/i386/qemu/mmap.c +++ b/kern/i386/qemu/mmap.c @@ -27,21 +27,37 @@ #define QEMU_CMOS_MEMSIZE_HIGH 0x35 #define QEMU_CMOS_MEMSIZE_LOW 0x34 +#define QEMU_CMOS_MEMSIZE2_HIGH 0x31 +#define QEMU_CMOS_MEMSIZE2_LOW 0x30 + #define min(a,b) ((a) > (b) ? (b) : (a)) extern char _start[]; extern char _end[]; -grub_size_t grub_lower_mem, grub_upper_mem; -grub_uint64_t mem_size; +static grub_uint64_t mem_size, above_4g; void grub_machine_mmap_init () { - mem_size = grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH) << 24 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW) << 16; + mem_size = ((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH)) << 24 + | ((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW)) << 16; + if (mem_size > 0) + { + /* Don't ask... */ + mem_size += (16 * 1024 * 1024); + } + else + { + mem_size + = ((((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE2_HIGH)) << 18) + | ((grub_uint64_t) (grub_cmos_read (QEMU_CMOS_MEMSIZE2_LOW)) << 10)) + + 1024 * 1024; + } - /* Don't ask... */ - mem_size += (16 * 1024 * 1024); + above_4g = (((grub_uint64_t) grub_cmos_read (0x5b)) << 16) + | (((grub_uint64_t) grub_cmos_read (0x5c)) << 24) + | (((grub_uint64_t) grub_cmos_read (0x5d)) << 32); } grub_err_t @@ -57,6 +73,12 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin GRUB_MACHINE_MEMORY_RESERVED)) return 1; + /* Everything else is free. */ + if (hook (0x100000, + min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000, + GRUB_MACHINE_MEMORY_AVAILABLE)) + return 1; + /* Protect boot.img, which contains the gdt. It is mapped at the top of memory (it is also mapped below 0x100000, but we already reserved that area). */ if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE, @@ -64,10 +86,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin GRUB_MACHINE_MEMORY_RESERVED)) return 1; - /* Everything else is free. */ - if (hook (0x100000, - min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000, - GRUB_MACHINE_MEMORY_AVAILABLE)) + if (above_4g != 0 && hook (0x100000000ULL, above_4g, + GRUB_MACHINE_MEMORY_AVAILABLE)) return 1; return 0;