2008-08-11 Robert Millan * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pc/mmap.c'. * include/grub/i386/pc/init.h (GRUB_MACHINE_MEMORY_AVAILABLE): New macro. (grub_available_iterate): New function declaration. * kern/i386/pc/init.c (grub_machine_init): Move e820 parsing from here ... * kern/i386/pc/mmap.c: New file. (grub_available_iterate): ... to here. Replace hardcoded region type check value with `GRUB_MACHINE_MEMORY_AVAILABLE'. * include/grub/i386/coreboot/memory.h: Remove `'. (GRUB_LINUXBIOS_MEMORY_AVAILABLE): Rename (for consistency) to ... (GRUB_MACHINE_MEMORY_AVAILABLE): ... this. (grub_available_iterate): Redeclare to return `void', and redeclare its hook to use grub_uint64_t as addr and size parameters. * kern/i386/coreboot/init.c (grub_machine_init): Adjust heap_init() parameters to match with new grub_available_iterate() declaration. Move region type check from here ... * kern/i386/coreboot/mmap.c (grub_available_iterate): ... to here. Index: conf/i386-pc.rmk =================================================================== --- conf/i386-pc.rmk (revision 1800) +++ conf/i386-pc.rmk (working copy) @@ -43,7 +43,8 @@ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ kern/time.c \ - kern/i386/dl.c kern/i386/pc/init.c kern/parser.c kern/partition.c \ + kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \ + kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c \ Index: kern/i386/pc/init.c =================================================================== --- kern/i386/pc/init.c (revision 1800) +++ kern/i386/pc/init.c (working copy) @@ -132,9 +132,6 @@ void grub_machine_init (void) { - grub_uint32_t cont; - struct grub_machine_mmap_entry *entry - = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; int i; /* Initialize the console as early as possible. */ @@ -156,55 +153,35 @@ add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END, grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END); - /* Check if grub_get_mmap_entry works. */ - cont = grub_get_mmap_entry (entry, 0); - - if (entry->size) - do - { - /* Avoid the lower memory. */ - if (entry->addr < 0x100000) - { - if (entry->len <= 0x100000 - entry->addr) - goto next; - - entry->len -= 0x100000 - entry->addr; - entry->addr = 0x100000; - } - - /* Ignore >4GB. */ - if (entry->addr <= 0xFFFFFFFF && entry->type == 1) - { - grub_addr_t addr; - grub_size_t len; - - addr = (grub_addr_t) entry->addr; - len = ((addr + entry->len > 0xFFFFFFFF) - ? 0xFFFFFFFF - addr - : (grub_size_t) entry->len); - add_mem_region (addr, len); - } - - next: - if (! cont) - break; - - cont = grub_get_mmap_entry (entry, cont); - } - while (entry->size); - else + auto int hook (grub_uint64_t, grub_uint64_t); + int hook (grub_uint64_t addr, grub_uint64_t size) { - grub_uint32_t eisa_mmap = grub_get_eisa_mmap (); - - if (eisa_mmap) + /* Avoid the lower memory. */ + if (addr < 0x100000) { - add_mem_region (0x100000, (eisa_mmap & 0xFFFF) << 10); - add_mem_region (0x1000000, eisa_mmap & ~0xFFFF); + if (size <= 0x100000 - addr) + return 0; + + size -= 0x100000 - addr; + addr = 0x100000; } - else - add_mem_region (0x100000, grub_get_memsize (1) << 10); + + /* Ignore >4GB. */ + if (addr <= 0xFFFFFFFF) + { + grub_size_t len; + + len = (grub_size_t) ((addr + size > 0xFFFFFFFF) + ? 0xFFFFFFFF - addr + : size); + add_mem_region (addr, len); + } + + return 0; } + grub_available_iterate (hook); + compact_mem_regions (); /* Add the memory regions to free memory, except for the region starting Index: kern/i386/pc/mmap.c =================================================================== --- kern/i386/pc/mmap.c (revision 0) +++ kern/i386/pc/mmap.c (revision 0) @@ -0,0 +1,61 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +void +grub_available_iterate (int (*hook) (grub_uint64_t, grub_uint64_t)) +{ + grub_uint32_t cont; + struct grub_machine_mmap_entry *entry + = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + /* Check if grub_get_mmap_entry works. */ + cont = grub_get_mmap_entry (entry, 0); + + if (entry->size) + do + { + if (entry->type != GRUB_MACHINE_MEMORY_AVAILABLE) + goto next; + + if (hook (entry->addr, entry->len)) + break; + + next: + if (! cont) + break; + + cont = grub_get_mmap_entry (entry, cont); + } + while (entry->size); + else + { + grub_uint32_t eisa_mmap = grub_get_eisa_mmap (); + + if (eisa_mmap) + { + if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10) == 0) + hook (0x1000000, eisa_mmap & ~0xFFFF); + } + else + hook (0x100000, grub_get_memsize (1) << 10); + } +} Index: kern/i386/coreboot/init.c =================================================================== --- kern/i386/coreboot/init.c (revision 1800) +++ kern/i386/coreboot/init.c (working copy) @@ -82,12 +82,9 @@ grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE; grub_upper_mem = 0; - auto int heap_init (mem_region_t); - int heap_init (mem_region_t mem_region) + auto int heap_init (grub_uint64_t, grub_uint64_t); + int heap_init (grub_uint64_t addr, grub_uint64_t size) { - grub_uint64_t addr = mem_region->addr; - grub_uint64_t size = mem_region->size; - #if GRUB_CPU_SIZEOF_VOID_P == 4 /* Restrict ourselves to 32-bit memory space. */ if (addr > ULONG_MAX) @@ -101,9 +98,6 @@ grub_upper_mem = grub_max (grub_upper_mem, addr + size); - if (mem_region->type != GRUB_LINUXBIOS_MEMORY_AVAILABLE) - return 0; - /* Avoid the lower memory. */ if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE) { Index: kern/i386/coreboot/mmap.c =================================================================== --- kern/i386/coreboot/mmap.c (revision 1800) +++ kern/i386/coreboot/mmap.c (working copy) @@ -64,7 +64,7 @@ } grub_err_t -grub_available_iterate (int (*hook) (mem_region_t)) +grub_available_iterate (int (*hook) (grub_uint64_t, grub_uint64_t)) { mem_region_t mem_region; @@ -79,8 +79,13 @@ sizeof (struct grub_linuxbios_table_item)); for (; (long) mem_region < (long) table_item + (long) table_item->size; mem_region++) - if (hook (mem_region)) - return 1; + { + if (mem_region->type != GRUB_MACHINE_MEMORY_AVAILABLE) + continue; + + if (hook (mem_region->addr, mem_region->size)) + return 1; + } return 0; } Index: include/grub/i386/pc/init.h =================================================================== --- include/grub/i386/pc/init.h (revision 1800) +++ include/grub/i386/pc/init.h (working copy) @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc. + * Copyright (C) 2002,2004,2005,2007,2008 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,6 +35,7 @@ grub_uint32_t size; grub_uint64_t addr; grub_uint64_t len; +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 grub_uint32_t type; } __attribute__((packed)); @@ -43,6 +44,9 @@ grub_uint32_t EXPORT_FUNC(grub_get_mmap_entry) (struct grub_machine_mmap_entry *entry, grub_uint32_t cont); +void EXPORT_FUNC(grub_available_iterate) + (int (*hook) (grub_uint64_t, grub_uint64_t)); + /* Turn on/off Gate A20. */ void grub_gate_a20 (int on); Index: include/grub/i386/coreboot/memory.h =================================================================== --- include/grub/i386/coreboot/memory.h (revision 1800) +++ include/grub/i386/coreboot/memory.h (working copy) @@ -25,7 +25,6 @@ #ifndef ASM_FILE #include -#include #endif #define GRUB_MEMORY_MACHINE_LOWER_USABLE 0x9fc00 /* 640 kiB - 1 kiB */ @@ -55,13 +54,13 @@ { grub_uint64_t addr; grub_uint64_t size; -#define GRUB_LINUXBIOS_MEMORY_AVAILABLE 1 +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 grub_uint32_t type; }; typedef struct grub_linuxbios_mem_region *mem_region_t; -grub_err_t EXPORT_FUNC(grub_available_iterate) - (int (*hook) (mem_region_t)); +void EXPORT_FUNC(grub_available_iterate) + (int (*hook) (grub_uint64_t, grub_uint64_t)); #endif