[PATCH] coreinfo:  Add multiboot parsing support

Rename the "coreboot" menu "firmware", and add a module to parse
the multiboot table.  For now, just parse memory, but it can be
expanded as needed.

Signed-off-by: Jordan Crouse <jordan@cosmicpenguin.net>

Index: coreinfo/Kconfig
===================================================================
--- coreinfo.orig/Kconfig	2008-11-07 15:49:53.000000000 -0700
+++ coreinfo/Kconfig	2008-11-11 09:17:10.000000000 -0700
@@ -70,6 +70,12 @@
 	help
 	  This option will increase the ELF file size by ca. 2250 bytes.
 
+config MODULE_MULTIBOOT
+	bool "Enable the multiboot module"
+	default y
+	help
+	  This option will increase the ELF file size by ca. 1792 bytes.
+
 config MODULE_CPUINFO
 	bool "Enable the cpuinfo module"
 	default y
Index: coreinfo/Makefile
===================================================================
--- coreinfo.orig/Makefile	2008-11-07 15:49:25.000000000 -0700
+++ coreinfo/Makefile	2008-11-07 15:49:38.000000000 -0700
@@ -53,7 +53,7 @@
 CFLAGS := -Wall -Werror -Os $(INCLUDES)
 OBJECTS = cpuinfo_module.o cpuid.S.o pci_module.o coreboot_module.o \
 	  nvram_module.o bootlog_module.o ramdump_module.o lar_module.o \
-	  coreinfo.o
+	  multiboot_module.o coreinfo.o
 OBJS    = $(patsubst %,$(obj)/%,$(OBJECTS))
 TARGET  = $(obj)/coreinfo.elf
 
Index: coreinfo/coreinfo.c
===================================================================
--- coreinfo.orig/coreinfo.c	2008-11-07 15:47:38.000000000 -0700
+++ coreinfo/coreinfo.c	2008-11-07 15:52:41.000000000 -0700
@@ -27,6 +27,7 @@
 extern struct coreinfo_module cpuinfo_module;
 extern struct coreinfo_module pci_module;
 extern struct coreinfo_module coreboot_module;
+extern struct coreinfo_module multiboot_module;
 extern struct coreinfo_module nvram_module;
 extern struct coreinfo_module bootlog_module;
 extern struct coreinfo_module ramdump_module;
@@ -47,10 +48,13 @@
 #endif
 };
 
-struct coreinfo_module *coreboot_modules[] = {
+struct coreinfo_module *firmware_modules[] = {
 #ifdef CONFIG_MODULE_COREBOOT
 	&coreboot_module,
 #endif
+#ifdef CONFIG_MODULE_MULTIBOOT
+	&multiboot_module,
+#endif
 #ifdef CONFIG_MODULE_BOOTLOG
 	&bootlog_module,
 #endif
@@ -71,9 +75,9 @@
 		.count = ARRAY_SIZE(system_modules),
 	},
 	{
-		.name = "Coreboot",
-		.modules = coreboot_modules,
-		.count = ARRAY_SIZE(coreboot_modules),
+		.name = "Firmware",
+		.modules = firmware_modules,
+		.count = ARRAY_SIZE(firmware_modules),
 	}
 };
 
Index: coreinfo/multiboot_module.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ coreinfo/multiboot_module.c	2008-11-11 09:24:18.000000000 -0700
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the coreinfo project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program 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; version 2 of the License.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <multiboot_tables.h>
+#include "coreinfo.h"
+
+#ifdef CONFIG_MODULE_MULTIBOOT
+
+#define MAX_MEMORY_COUNT  10
+
+static struct {
+	int mem_count;
+
+	struct {
+		u64 start;
+		u64 size;
+		int type;
+	} range[MAX_MEMORY_COUNT];
+} cb_info;
+
+static int tables_good = 0;
+
+int multiboot_module_redraw(WINDOW *win)
+{
+	int row = 2;
+	int i;
+
+	print_module_title(win, "Multiboot Tables");
+
+	if (tables_good == 0) {
+		mvwprintw(win, row++, 1, "No multiboot tables were found");
+		return 0;
+	}
+
+	row++;
+	mvwprintw(win, row++, 1, "-- Memory Map --");
+
+	for (i = 0; i < cb_info.mem_count; i++) {
+
+		if (cb_info.range[i].type == 1)
+			mvwprintw(win, row++, 3, "     RAM: ");
+		else
+			mvwprintw(win, row++, 3, "Reserved: ");
+
+		wprintw(win, "%16.16llx - %16.16llx",
+			cb_info.range[i].start,
+			cb_info.range[i].start + cb_info.range[i].size - 1);
+	}
+
+	return 0;
+}
+
+static void parse_memory(struct multiboot_header *table)
+{
+        u8 *start = (u8 *) phys_to_virt(table->mmap_addr);
+        u8 *ptr = start;
+	int i = 0;
+
+	cb_info.mem_count = 0;
+
+        while(ptr < (start + table->mmap_length)) {
+                struct multiboot_mmap *mmap = (struct multiboot_mmap *) ptr;
+
+		cb_info.range[i].start = mmap->addr;
+		cb_info.range[i].size = mmap->length;
+		cb_info.range[i].type = mmap->type;
+
+		if (++cb_info.mem_count == MAX_MEMORY_COUNT)
+			return;
+
+                ptr += (mmap->size + sizeof(mmap->size));
+		i++;
+        }
+}
+
+static void parse_header(unsigned long addr)
+{
+	struct multiboot_header *table = (struct multiboot_header *) addr;
+
+	if (table->flags & MULTIBOOT_FLAGS_MMAP)
+		parse_memory(table);
+}
+
+static int multiboot_module_init(void)
+{
+	unsigned long mbaddr;
+	tables_good = sysinfo_have_multiboot(&mbaddr);
+
+	parse_header(mbaddr);
+
+	return tables_good ? 0 : -1;
+}
+
+struct coreinfo_module multiboot_module = {
+	.name = "Multiboot",
+	.init = multiboot_module_init,
+	.redraw = multiboot_module_redraw,
+};
+
+#else
+
+struct coreinfo_module multiboot_module = {
+};
+
+#endif
