Hi,

This patch decouples memory map parsing into a separate grub_available_iterate()
function, for i386-pc and i386-coreboot.  It is mostly intended as a cleanup.
Makes the code more modular so that, for example, the multiboot loader can
construct a memory map without having specific knowledge of the platform,
allows to recombine various init.c & mmap.c in different ways, etc.

Maybe it will be possible to recombine pc/init.c with coreboot/init.c in a
single file later on, although I'm not sure if that might be overkill.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."
2008-08-11  Robert Millan  <[EMAIL PROTECTED]>

	* 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/err.h>'.
	(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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/types.h>
+
+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 <grub/types.h>
-#include <grub/err.h>
 #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
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to