[coreboot] r83 - in trunk/filo: . configs drivers drivers/newusb fs include/grub main main/grub util

svn at coreboot.org svn at coreboot.org
Wed Oct 22 13:19:52 CEST 2008


Author: stepan
Date: 2008-10-22 13:19:52 +0200 (Wed, 22 Oct 2008)
New Revision: 83

Modified:
   trunk/filo/Config.in
   trunk/filo/Makefile
   trunk/filo/build.sh
   trunk/filo/configs/defconfig
   trunk/filo/drivers/ide.c
   trunk/filo/drivers/newusb/usb.c
   trunk/filo/fs/blockdev.c
   trunk/filo/fs/fsys_ext2fs.c
   trunk/filo/include/grub/shared.h
   trunk/filo/main/filo.c
   trunk/filo/main/grub/builtins.c
   trunk/filo/main/grub/char_io.c
   trunk/filo/main/grub/cmdline.c
   trunk/filo/main/grub/grub.c
   trunk/filo/util/checksum_elf.c
Log:
New FILO code drop from coresystems' internal repository:

* add "developer commands" to filo (lspci, setpci, io)
* use staged libpayload per default now.
* use libpayload-config.h where appropriate.
* fix an ext3 filesystem issues
* use libpayload functions to implement grub_printf instead of the incomplete
  duplication
* fix broken "weak" symbol handling.
* fix string issue with boot_devices
* fix a couple of problems with colors
* fix endless loop in case of file open error



Modified: trunk/filo/Config.in
===================================================================
--- trunk/filo/Config.in	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/Config.in	2008-10-22 11:19:52 UTC (rev 83)
@@ -330,5 +330,13 @@
 	depends on ARTEC_BOOT
 	default n
 
+config DEVELOPER_TOOLS
+	bool "Developer Tools"
+	depends on USE_GRUB
+	default y
+	help
+	  Add commands useful for hardware development to the GRUB
+	  interface. These are lspci, setpci, io.
+
 endmenu
 

Modified: trunk/filo/Makefile
===================================================================
--- trunk/filo/Makefile	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/Makefile	2008-10-22 11:19:52 UTC (rev 83)
@@ -70,7 +70,7 @@
 
 include $(PLATFORM-y) $(BUILD-y)
 
-LIBPAYLOAD_PREFIX ?= libpayload
+LIBPAYLOAD_PREFIX ?= $(obj)/libpayload
 LIBPAYLOAD = $(LIBPAYLOAD_PREFIX)/lib/libpayload.a
 INCPAYLOAD = $(LIBPAYLOAD_PREFIX)/include
 LIBGCC = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)

Modified: trunk/filo/build.sh
===================================================================
--- trunk/filo/build.sh	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/build.sh	2008-10-22 11:19:52 UTC (rev 83)
@@ -1,11 +1,16 @@
-#!/bin/sh
+#!/bin/bash
 
 CONFIG=defconfig
 
-ALLCLEAN=1
+for make in make gmake gnumake; do
+	if [ "`$make --version 2>/dev/null | grep -c GNU`" -gt 0 ]; then
+		MAKE=$make
+		break
+	fi
+done
 
 OS=`uname -s`
-if [ "$OS" == "Darwin" -o "${OS:0:6}" == "CYGWIN" ]; then
+if [ "$OS" = "Darwin" -o "$OS" = "SunOS" -o "${OS:0:6}" = "CYGWIN" ]; then
     MAKEFLAGS="			\
 	AS=i386-elf-as		\
 	CC=i386-elf-gcc		\
@@ -17,21 +22,21 @@
 	-j			\
 	"
 fi
-if [ "$OS" == "Linux" ]; then
-MAKEFLAGS='CC="gcc -m32" LD="ld -b elf32-i386" HOSTCC="gcc" AS="as --32"'
+if [ "$OS" = "Linux" ]; then
+    MAKEFLAGS='CC="gcc -m32" LD="ld -b elf32-i386" HOSTCC="gcc" AS="as --32"'
 fi
 
-if [ "$ALLCLEAN" != "" -o ! -r libpayload/build/lib/libpayload.a ]; then
-  cd libpayload
-  cp configs/$CONFIG .config
-  make clean
-  make oldconfig
-  eval make $MAKEFLAGS
-  cd ..
-fi
-
-make distclean
+$MAKE distclean
 cp configs/$CONFIG ./.config
-make oldconfig
-eval make $MAKEFLAGS
+$MAKE oldconfig
 
+cd libpayload
+$MAKE distclean
+cp configs/$CONFIG .config
+$MAKE oldconfig
+eval $MAKE $MAKEFLAGS
+eval $MAKE $MAKEFLAGS DESTDIR=../build install 
+cd ..
+
+eval $MAKE $MAKEFLAGS
+

Modified: trunk/filo/configs/defconfig
===================================================================
--- trunk/filo/configs/defconfig	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/configs/defconfig	2008-10-22 11:19:52 UTC (rev 83)
@@ -66,3 +66,4 @@
 # CONFIG_DEBUG_LINUXLOAD is not set
 # CONFIG_DEBUG_IDE is not set
 # CONFIG_DEBUG_ELTORITO is not set
+CONFIG_DEVELOPER_TOOLS=y

Modified: trunk/filo/drivers/ide.c
===================================================================
--- trunk/filo/drivers/ide.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/drivers/ide.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -734,7 +734,7 @@
 		(drive_info[2] != 0x8C73) &&
 		(drive_info[2] != 0xC837) &&
 		(drive_info[2] != 0x0000)) {
-		printf("Invalid IDE Configuration: %hx\n", drive_info[2]);
+		printf("Invalid IDE Configuration: %04x\n", drive_info[2]);
 		return 1;
 	}
 	for(i = 27; i < 47; i++) {

Modified: trunk/filo/drivers/newusb/usb.c
===================================================================
--- trunk/filo/drivers/newusb/usb.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/drivers/newusb/usb.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -17,6 +17,10 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
+#include <libpayload-config.h>
+
+/* Only use this code if libpayload is compiled with USB stack */
+#ifdef CONFIG_USB
 #include <fs.h>
 #include <usb/usb.h>
 #include <usb/usbmsc.h>
@@ -68,3 +72,4 @@
 	int result = -readwrite_blocks(devs[drive], sector, size, cbw_direction_data_in, buffer);
 	return result;
 }
+#endif

Modified: trunk/filo/fs/blockdev.c
===================================================================
--- trunk/filo/fs/blockdev.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/fs/blockdev.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -19,6 +19,7 @@
  */
 
 #include <libpayload.h>
+#include <libpayload-config.h>
 #include <config.h>
 #include <fs.h>
 
@@ -255,7 +256,7 @@
 		disk_size = (uint32_t) - 1;	/* FIXME */
 		break;
 #endif
-#ifdef CONFIG_USB_NEW_DISK
+#if defined(CONFIG_USB_NEW_DISK) && defined(CONFIG_USB)
 	case DISK_NEW_USB:
 		if (usb_new_probe(drive) != 0) {
 			debug("Failed to open USB.\n");
@@ -389,7 +390,7 @@
 				goto readerr;
 			break;
 #endif
-#ifdef CONFIG_USB_NEW_DISK
+#if defined(CONFIG_USB_NEW_DISK) && defined(CONFIG_USB)
 		case DISK_NEW_USB:
 		{
 			int count = (NUM_CACHE-hash>8)?8:(NUM_CACHE-hash);

Modified: trunk/filo/fs/fsys_ext2fs.c
===================================================================
--- trunk/filo/fs/fsys_ext2fs.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/fs/fsys_ext2fs.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -76,7 +76,50 @@
     __u32 s_rev_level;		/* Revision level */
     __u16 s_def_resuid;		/* Default uid for reserved blocks */
     __u16 s_def_resgid;		/* Default gid for reserved blocks */
-    __u32 s_reserved[235];	/* Padding to the end of the block */
+	/*
+	 * These fields are for EXT2_DYNAMIC_REV superblocks only.
+	 *
+	 * Note: the difference between the compatible feature set and
+	 * the incompatible feature set is that if there is a bit set
+	 * in the incompatible feature set that the kernel doesn't
+	 * know about, it should refuse to mount the filesystem.
+	 * 
+	 * e2fsck's requirements are more strict; if it doesn't know
+	 * about a feature in either the compatible or incompatible
+	 * feature set, it must abort and not try to meddle with
+	 * things it doesn't understand...
+	 */
+	__u32	s_first_ino; 		/* First non-reserved inode */
+	__u16   s_inode_size; 		/* size of inode structure */
+	__u16	s_block_group_nr; 	/* block group # of this superblock */
+	__u32	s_feature_compat; 	/* compatible feature set */
+	__u32	s_feature_incompat; 	/* incompatible feature set */
+	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
+	__u8	s_uuid[16];		/* 128-bit uuid for volume */
+	char	s_volume_name[16]; 	/* volume name */
+	char	s_last_mounted[64]; 	/* directory where last mounted */
+	__u32	s_algorithm_usage_bitmap; /* For compression */
+	/*
+	 * Performance hints.  Directory preallocation should only
+	 * happen if the EXT2_COMPAT_PREALLOC flag is on.
+	 */
+	__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
+	__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
+	__u16	s_padding1;
+	/*
+	 * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
+	 */
+	__u8	s_journal_uuid[16];	/* uuid of journal superblock */
+	__u32	s_journal_inum;		/* inode number of journal file */
+	__u32	s_journal_dev;		/* device number of journal file */
+	__u32	s_last_orphan;		/* start of list of inodes to delete */
+	__u32	s_hash_seed[4];		/* HTREE hash seed */
+	__u8	s_def_hash_version;	/* Default hash version to use */
+	__u8	s_reserved_char_pad;
+	__u16	s_reserved_word_pad;
+	__u32	s_default_mount_opts;
+ 	__u32	s_first_meta_bg; 	/* First metablock block group */
+	__u32	s_reserved[190];	/* Padding to the end of the block */
   };
 
 struct ext2_group_desc
@@ -213,6 +256,9 @@
 #define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
 #define EXT2_ADDR_PER_BLOCK_BITS(s)	(log2(EXT2_ADDR_PER_BLOCK(s)))
 
+#define EXT2_INODE_SIZE(s)             (SUPERBLOCK->s_inode_size)
+#define EXT2_INODES_PER_BLOCK(s)       (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
+
 /* linux/ext2_fs.h */
 #define EXT2_BLOCK_SIZE_BITS(s)        (le32_to_cpu((s)->s_log_block_size) + 10)
 /* kind of from ext2/super.c */
@@ -582,12 +628,12 @@
       gdp = GROUP_DESC;
       ino_blk = le32_to_cpu(gdp[desc].bg_inode_table) +
 	(((current_ino - 1) % le32_to_cpu(SUPERBLOCK->s_inodes_per_group))
-	 >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
+	 >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
 #ifdef E2DEBUG
       printf ("ext2fs_dir: itab_blk=%d, i_in_grp=%d, log2=%d\n", 
 	 le32_to_cpu(gdp[desc].bg_inode_table),
 	 ((current_ino - 1) % le32_to_cpu(SUPERBLOCK->s_inodes_per_group)),
-	 log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
+	 log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
       printf ("ext2fs_dir: inode table fsblock=%d\n", ino_blk);
 #endif /* E2DEBUG */
       if (!ext2_rdfsb (ino_blk, INODE))
@@ -598,13 +644,13 @@
       /* reset indirect blocks! */
       mapblock2 = mapblock1 = -1;
 
-      raw_inode = INODE +
-	((current_ino - 1)
-	 & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
+      raw_inode = (struct ext2_inode *)( (unsigned long)INODE +
+        ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1))
+	                                 * EXT2_INODE_SIZE(SUPERBLOCK));
 #ifdef E2DEBUG
       printf ("ext2fs_dir: ipb=%d, sizeof(inode)=%d\n",
-	      (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
-	      sizeof (struct ext2_inode));
+	      EXT2_INODES_PER_BLOCK (SUPERBLOCK),
+	      EXT2_INODE_SIZE(SUPERBLOCK));
       printf ("ext2fs_dir: inode=%x, raw_inode=%x\n", INODE, raw_inode);
       printf ("ext2fs_dir: offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
       dump_inode(raw_inode);

Modified: trunk/filo/include/grub/shared.h
===================================================================
--- trunk/filo/include/grub/shared.h	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/include/grub/shared.h	2008-10-22 11:19:52 UTC (rev 83)
@@ -286,7 +286,6 @@
 /* misc */
 void init_page (void);
 void print_error (void);
-char *convert_to_ascii (char *buf, int c, ...);
 int get_cmdline (char *prompt, char *cmdline, int maxlen,
 		 int echo_char, int history);
 int substring (const char *s1, const char *s2);

Modified: trunk/filo/main/filo.c
===================================================================
--- trunk/filo/main/filo.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/filo.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -16,6 +16,7 @@
  */
 
 #include <libpayload.h>
+#include <libpayload-config.h>
 #include <config.h>
 #include <version.h>
 #include <lib.h>
@@ -59,10 +60,19 @@
     collect_sys_info(&sys_info);
     relocate();
 
-#if defined(CONFIG_USB_DISK) || defined(CONFIG_USB_NEW_DISK)
+#if defined(CONFIG_USB_DISK)
     usb_initialize();
 #endif
+#if defined(CONFIG_USB_NEW_DISK)
+#if defined(CONFIG_USB)
+    /* libpayload USB stack is there */
+    usb_initialize();
+#else
+    printf("No USB stack in libpayload.\n");
+#endif
+#endif
 
+
 #ifdef CONFIG_SUPPORT_SOUND
     sound_init();
 #endif
@@ -91,17 +101,15 @@
     free(file);
 }
 
-
-void __attribute__((weak)) platform_reboot(void)
-{
-	printf("Rebooting not supported.\n");
-}
-
 void reset_handler(void)
 {
-	void platform_reboot(void);
+	void __attribute__((weak)) platform_reboot(void);
 
-	platform_reboot();
+	if (platform_reboot)
+		platform_reboot();
+	else
+		printf("Rebooting not supported.\n");
+
 }
 
 #if CONFIG_USE_GRUB

Modified: trunk/filo/main/grub/builtins.c
===================================================================
--- trunk/filo/main/grub/builtins.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/grub/builtins.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -27,6 +27,7 @@
 #ifdef CONFIG_USE_MD5_PASSWORDS
 #include <grub/md5.h>
 #endif
+#include <pci.h>
 
 /* The default entry.  */
 int default_entry = 0;
@@ -615,8 +616,115 @@
 };
 
 
+#ifdef CONFIG_DEVELOPER_TOOLS
+/* io */
+static int io_func(char *arg, int flags)
+{
+	char *walk = arg;
+	unsigned int port = 0;
+	unsigned int value = 0;
+	unsigned int write_mode = 0;
+	unsigned int maxval=0xff, len=1;
 
+	while ((*walk != 0) && (*walk != '.') && (*walk != '=')) {
+		port *= 16;
+		port += hex2bin(*walk);
+		walk++;
+	}
+	if (port > 0xffff) {
+		grub_printf("port too high\n");
+		errnum = ERR_BAD_ARGUMENT;
+		return 1;
+	}
 
+	if (*walk == '.') {
+		walk++;
+		switch (*walk) {
+		case 'l':
+		case 'L':
+			len = 4;
+			maxval = 0xffffffff;
+			break;
+		case 'w':
+		case 'W':
+			len=2;
+			maxval = 0xffff;
+			break;
+		case 'b':
+		case 'B':
+			len=1;
+			maxval = 0xff;
+			break;
+		default:
+			grub_printf("width must be b, w, or l\n");
+			errnum = ERR_BAD_ARGUMENT;
+			return 1;
+		}
+		walk++;
+	}
+
+	if (*walk == '=') {
+		while (*walk!=0 && *walk != '.') {
+			value *= 16;
+			value += hex2bin(*walk);
+			walk++;
+		}
+
+		if (value > maxval) {
+			grub_printf("value too big.\n");
+			errnum = ERR_BAD_ARGUMENT;
+			return 1;
+		}
+
+		write_mode = 1;
+	}
+
+	if (write_mode) {
+		grub_printf ("out");
+		switch (len) {
+		case 1:
+			grub_printf("b 0x%02x -> 0x%04x\n", value, port);
+			outb(value, port);
+			break;
+		case 2:
+			grub_printf("w 0x%04x -> 0x%04x\n", value, port);
+			outw(value, port);
+			break;
+		case 4:
+			grub_printf("l 0x%08x -> 0x%04x\n", value, port);
+			outl(value, port);
+			break;
+		}
+	} else {
+		grub_printf ("in");
+		switch (len) {
+		case 1:
+			value = inb(port);
+			grub_printf("b 0x%04x: 0x%02x\n", port, value);
+			break;
+		case 2:
+			value = inw(port);
+			grub_printf("w 0x%04x: 0x%04x\n", port, value);
+			break;
+		case 4:
+			value = inl(port);
+			grub_printf("l 0x%04x: 0x%08x\n", port, value);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static struct builtin builtin_io = {
+	"io",
+	io_func,
+	BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST | BUILTIN_NO_ECHO,
+	"io port[.bwl][=val]",
+	"Read/write IO ports."
+};
+#endif
+
 /* kernel */
 static int kernel_func(char *arg, int flags)
 {
@@ -681,6 +789,117 @@
 	"Break a command execution unless the user is authenticated."
 };
 
+#ifdef CONFIG_DEVELOPER_TOOLS
+static int lspci_indent = 0;
+static void lspci_scan_bus(int bus)
+{
+	int slot, func;
+	unsigned int val;
+	unsigned char hdr;
+	int i;
+
+	for (slot = 0; slot < 0x20; slot++) {
+		for (func = 0; func < 8; func++) {
+			pcidev_t dev = PCI_DEV(bus, slot, func);
+
+			val = pci_read_config32(dev, REG_VENDOR_ID);
+
+			/* Nobody home. */
+			if (val == 0xffffffff || val == 0x00000000 ||
+			    val == 0x0000ffff || val == 0xffff0000)
+				continue;
+
+			for (i=0; i<lspci_indent; i++)
+				grub_printf("|  ");
+			grub_printf("|- %x:%x.%x [%x:%x]\n", bus, slot, func,
+					val & 0xffff, val >> 16);
+
+			/* If this is a bridge, then follow it. */
+			hdr = pci_read_config8(dev, REG_HEADER_TYPE);
+			hdr &= 0x7f;
+			if (hdr == HEADER_TYPE_BRIDGE ||
+			    hdr == HEADER_TYPE_CARDBUS) {
+				unsigned int busses;
+
+				busses = pci_read_config32(dev, REG_PRIMARY_BUS);
+				lspci_indent++;
+				lspci_scan_bus((busses >> 8) & 0xff);
+				lspci_indent--;
+			}
+		}
+	}
+}
+
+static void lspci_configspace(pcidev_t dev)
+{
+	unsigned char cspace[256];
+	int i, x, y;
+
+	for (i = 0; i < 256; i ++)
+		cspace[i] = pci_read_config8(dev, i);
+
+	for (y = 0; y < 16; y++) {
+		grub_printf("%x0:", y);
+		for (x = 0; x < 16; x++)
+			grub_printf(" %02x", cspace[(y * 16) + x]);
+		grub_printf("\n");
+	}
+
+	grub_printf("\n");
+}
+
+static int lspci_func(char *arg, int flags)
+{
+	char *walk = arg;
+	int bus, slot, fn;
+
+	if(strlen(walk)) {
+		pcidev_t dev;
+
+		if((walk[1] != ':') && (walk[2] =! ':'))
+			goto out;
+		if(walk[1] == ':') {
+			bus = hex2bin(walk[0]);
+			walk+=2;
+		} else {
+			bus = (hex2bin(walk[0]) * 16) + hex2bin(walk[1]);
+			walk+=3;
+		}
+		if((walk[1] != '.') && (walk[2] =! '.'))
+			goto out;
+
+		if(walk[1] == '.') {
+			slot = hex2bin(walk[0]);
+			walk+=2;
+		} else {
+			slot = (hex2bin(walk[0]) * 16) + hex2bin(walk[1]);
+			walk+=3;
+		}
+		if (!walk[0])
+			goto out;
+
+		fn=hex2bin(walk[0]);
+
+		grub_printf("Dumping %x:%x.%x\n", bus, slot, fn);
+
+		dev = PCI_DEV(bus, slot, fn);
+		lspci_configspace(dev);
+		return 0;
+	}
+out:
+	lspci_scan_bus(0);
+	return 0;
+}
+
+static struct builtin builtin_lspci = {
+	"lspci",
+	lspci_func,
+	BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST | BUILTIN_NO_ECHO,
+	"lspci <device>",
+	"Show PCI devices or dump PCI config space"
+};
+#endif
+
 #ifdef CONFIG_USE_MD5_PASSWORDS
 /* md5crypt */
 static int md5crypt_func(char *arg, int flags)
@@ -817,14 +1036,13 @@
 	"Print MESSAGE, then wait until a key is pressed."
 };
 
-void __attribute__((weak)) platform_poweroff(void)
-{
-	grub_printf("Poweroff not supported.\n");
-}
-
 static int poweroff_func(char *arg, int flags)
 {
-	platform_poweroff();
+	void __attribute__((weak)) platform_poweroff(void);
+	if (platform_poweroff)
+		platform_poweroff();
+	else
+		grub_printf("Poweroff not supported.\n");
 
 	// Will (hopefully) never return;
 	return 0;
@@ -838,11 +1056,38 @@
 	"Power off the system."
 };
 
+#ifdef CONFIG_DEVELOPER_TOOLS
+static int probe_func(char *arg, int flags)
+{
+#if CONFIG_IDE_DISK
+	int i;
+
+	for (i=0; i<8; i++)
+		ide_probe(i);
+#else
+	grub_printf("No IDE driver.\n");
+#endif
+
+	return 0;
+}
+
+static struct builtin builtin_probe = {
+	"probe",
+	probe_func,
+	BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+	"probe",
+	"Probe IDE drives"
+};
+#endif
+
 static int reboot_func(char *arg, int flags)
 {
-	void platform_reboot(void);
+	void __attribute__((weak)) platform_reboot(void);
 
-	platform_reboot();
+	if (platform_reboot)
+		platform_reboot();
+	else
+		grub_printf("Reboot not supported.\n");
 
 	// Will (hopefully) never return;
 	return 0;
@@ -884,10 +1129,8 @@
 	"Set the current \"root device\" to the device DEVICE."
 };
 
-void __attribute__((weak))  serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits)
-{
-	grub_printf("This version of FILO does not have serial console support.\n");
-}
+void __attribute__((weak))  serial_hardware_init(int port, int speed, int
+		word_bits, int parity, int stop_bits);
 
 /* serial */
 static int serial_func(char *arg, int flags)
@@ -987,7 +1230,10 @@
 	}
 
 	/* Initialize the serial unit.  */
-	serial_hardware_init(port, speed, word_len, parity, stop_bit_len);
+	if (serial_hardware_init)
+		serial_hardware_init(port, speed, word_len, parity, stop_bit_len);
+	else
+		grub_printf("This version of FILO does not have serial console support.\n");
 
 	return 0;
 }
@@ -1006,8 +1252,163 @@
 	    " default values are COM1, 9600, 8N1."
 };
 
+#ifdef CONFIG_DEVELOPER_TOOLS
+static int setpci_func(char *arg, int flags)
+{
+	char *walk = arg;
+	int bus, slot, fn;
+	pcidev_t dev;
+	unsigned int reg=0;
+	unsigned int len=1, maxval=0xff, value=0;
+	int write_mode = 0;
 
+	// setpci bus:dev.fn reg.[bwl][=val]
 
+	if(!strlen(arg)) {
+		errnum = ERR_BAD_ARGUMENT;
+		return 1;
+	}
+
+	if((walk[1] != ':') && (walk[2] =! ':')) {
+		errnum = ERR_BAD_ARGUMENT;
+		return 1;
+	}
+
+	if(walk[1] == ':') {
+		bus = hex2bin(walk[0]);
+		walk+=2;
+	} else {
+		bus = (hex2bin(walk[0]) * 16) + hex2bin(walk[1]);
+		walk+=3;
+	}
+	if((walk[1] != '.') && (walk[2] =! '.')) {
+		errnum = ERR_BAD_ARGUMENT;
+		return 1;
+	}
+
+	if(walk[1] == '.') {
+		slot = hex2bin(walk[0]);
+		walk+=2;
+	} else {
+		slot = (hex2bin(walk[0]) * 16) + hex2bin(walk[1]);
+		walk+=3;
+	}
+	if (!walk[0]) {
+		errnum = ERR_BAD_ARGUMENT;
+		return 1;
+	}
+
+	fn=hex2bin(walk[0]);
+
+	dev = PCI_DEV(bus, slot, fn);
+
+	walk++;
+	if (walk[0] != ' ') {
+		grub_printf("No register specified\n");
+		errnum = ERR_BAD_ARGUMENT;
+		return 1;
+	}
+
+	while (*walk!=0 && *walk != '.' && *walk != ':' ) {
+		reg *= 16;
+		reg += hex2bin(*walk);
+		walk++;
+	}
+
+	if (reg > 0xff) {
+		grub_printf("Only 256 byte config space supported.\n");
+		errnum = ERR_BAD_ARGUMENT;
+		return 1;
+	}
+
+	if (*walk == '.') {
+		walk++;
+		switch (*walk) {
+		case 'l':
+		case 'L':
+			len = 4;
+			maxval = 0xffffffff;
+			break;
+		case 'w':
+		case 'W':
+			len=2;
+			maxval = 0xffff;
+			break;
+		case 'b':
+		case 'B':
+			len=1;
+			maxval = 0xff;
+			break;
+		default:
+			grub_printf("width must be b, w, or l\n");
+			errnum = ERR_BAD_ARGUMENT;
+			return 1;
+		}
+		walk++;
+	}
+
+	if (*walk == '=') {
+		while (*walk!=0 && *walk != '.') {
+			value *= 16;
+			value += hex2bin(*walk);
+			walk++;
+		}
+
+		if (value > maxval) {
+			grub_printf("value too big.\n");
+			errnum = ERR_BAD_ARGUMENT;
+			return 1;
+		}
+
+		write_mode = 1;
+	}
+
+	if (write_mode) {
+		grub_printf ("pci_write_config");
+		switch (len) {
+		case 1:
+			grub_printf("8 0x%02x -> %x:%x.%x [%02x]\n", value, bus, slot, fn, reg);
+			pci_write_config8(dev, reg, value);
+			break;
+		case 2:
+			grub_printf("16 0x%04x -> %x:%x.%x [%02x]\n", value, bus, slot, fn, reg);
+			pci_write_config16(dev, reg, value);
+			break;
+		case 4:
+			grub_printf("32 0x%08x -> %x:%x.%x [%02x]\n", value, bus, slot, fn, reg);
+			pci_write_config32(dev, reg, value);
+			break;
+		}
+	} else {
+		grub_printf ("pci_read_config");
+		switch (len) {
+		case 1:
+			value = pci_read_config8(dev, reg);
+			grub_printf("8 %x:%x.%x [%02x] -> %02x\n", bus, slot, fn, reg, value);
+			break;
+		case 2:
+			value = pci_read_config16(dev, reg);
+			grub_printf("16 %x:%x.%x [%02x] -> %04x\n", bus, slot, fn, reg, value);
+			break;
+		case 4:
+			value = pci_read_config32(dev, reg);
+			grub_printf("32 %x:%x.%x [%02x] -> %08x\n", bus, slot, fn, reg, value);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static struct builtin builtin_setpci = {
+	"setpci",
+	setpci_func,
+	BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST | BUILTIN_NO_ECHO,
+	"setpci <device>[.bwl][=value]",
+	"Show/change PCI config space values"
+};
+#endif
+
 /* terminal */
 static int terminal_func(char *arg, int flags)
 {
@@ -1145,7 +1546,7 @@
 	keymap_func,
 	BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST | BUILTIN_NO_ECHO,
 	"keymap LANGCODE",
-	"Select a keymap to use. Currently only 'en' and 'de' are supported."
+	"Select a keymap to use. Currently only 'us' and 'de' are supported."
 };
 
 static int title_func(char *arg, int flags)
@@ -1179,18 +1580,30 @@
 	&builtin_help,
 	&builtin_hiddenmenu,
 	&builtin_initrd,
+#ifdef CONFIG_DEVELOPER_TOOLS
+	&builtin_io,
+#endif
 	&builtin_kernel,
 	&builtin_keymap,
 	&builtin_lock,
+#ifdef CONFIG_DEVELOPER_TOOLS
+	&builtin_lspci,
+#endif
 #ifdef CONFIG_USE_MD5_PASSWORDS
 	&builtin_md5crypt,
 #endif
 	&builtin_password,
 	&builtin_pause,
 	&builtin_poweroff,
+#ifdef CONFIG_DEVELOPER_TOOLS
+	&builtin_probe,
+#endif
 	&builtin_reboot,
 	&builtin_root,
 	&builtin_serial,
+#ifdef CONFIG_DEVELOPER_TOOLS
+	&builtin_setpci,
+#endif
 	&builtin_terminal,
 	&builtin_timeout,
 	&builtin_title,

Modified: trunk/filo/main/grub/char_io.c
===================================================================
--- trunk/filo/main/grub/char_io.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/grub/char_io.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -73,42 +73,6 @@
 		grub_printf("\nError %u: %s\n", errnum, err_list[errnum]);
 }
 
-char *convert_to_ascii(char *buf, int c, ...)
-{
-	unsigned long num = *((&c) + 1), mult = 10;
-	char *ptr = buf;
-
-	if (c == 'x' || c == 'X')
-		mult = 16;
-
-	if ((num & 0x80000000uL) && c == 'd') {
-		num = (~num) + 1;
-		*(ptr++) = '-';
-		buf++;
-	}
-
-	do {
-		int dig = num % mult;
-		*(ptr++) = ((dig > 9) ? dig + 'a' - 10 : '0' + dig);
-	}
-	while (num /= mult);
-
-	/* reorder to correct direction!! */
-	{
-		char *ptr1 = ptr - 1;
-		char *ptr2 = buf;
-		while (ptr1 > ptr2) {
-			int tmp = *ptr1;
-			*ptr1 = *ptr2;
-			*ptr2 = tmp;
-			ptr1--;
-			ptr2++;
-		}
-	}
-
-	return ptr;
-}
-
 void grub_putstr(const char *str)
 {
 	while (*str)
@@ -117,35 +81,17 @@
 
 void grub_printf(const char *format, ...)
 {
-	int *dataptr = (int *) &format;
-	char c, str[16];
+	int ret;
+	va_list args;
+#define OUTPUT_SIZE 256
+	char output[OUTPUT_SIZE];
 
-	dataptr++;
-
-	while ((c = *(format++)) != 0) {
-		if (c != '%')
-			grub_putchar(c);
-		else
-			switch (c = *(format++)) {
-			case 'd':
-			case 'x':
-			case 'X':
-			case 'u':
-				*convert_to_ascii(str, c, *((unsigned long *)
-							    dataptr++)) = 0;
-				grub_putstr(str);
-				break;
-
-			case 'c':
-				grub_putchar((*(dataptr++)) & 0xff);
-				break;
-
-			case 's':
-				grub_putstr((char *) *(dataptr++));
-				break;
-			}
-	}
+	va_start(args, format);
+	ret = vsnprintf(output, OUTPUT_SIZE, format, args);
+	va_end(args);
+	grub_putstr(output);
 	refresh();
+#undef OUTPUT_SIZE
 }
 
 void init_page(void)

Modified: trunk/filo/main/grub/cmdline.c
===================================================================
--- trunk/filo/main/grub/cmdline.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/grub/cmdline.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -139,9 +139,18 @@
 		print_error();
 		errnum = ERR_NONE;
 
+		short col1, col2, col3, col4;
+		pair_content(1, &col1, &col2);
+		pair_content(2, &col3, &col4);
+		/* reset to light-gray-on-black on console */
+		console_setcolor(0x07, 0x70);
+
 		/* Get the command-line with the minimal BASH-like interface. */
-		if (get_cmdline(CONFIG_PROMPT "> ", heap, 2048, 0, 1))
+		if (get_cmdline(CONFIG_PROMPT "> ", heap, 2048, 0, 1)) {
+			init_pair(1, col1, col2);
+			init_pair(2, col3, col4);
 			return;
+		}
 
 		/* If there was no command, grab a new one. */
 		if (!heap[0])
@@ -195,7 +204,7 @@
 			   intervention.  */
 			if (fallback_entryno < 0) {
 				grub_printf("\nPress any key to continue...");
-				(void) getkey();
+				(void) getchar();
 			}
 
 			return 1;

Modified: trunk/filo/main/grub/grub.c
===================================================================
--- trunk/filo/main/grub/grub.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/grub/grub.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -138,6 +138,8 @@
 
 	strcpy(menulst, bootdevice);
 	strncat(menulst, filename, 256);
+	/* Set string to zero: */
+	config_file[0] = 0;
 	copy_path_to_filo_bootline(menulst, config_file, 0);
 	if (file_open(config_file)) {
 		/* We found a config file. Bail out */
@@ -634,6 +636,8 @@
 					if (config_entries)
 						run_menu(heap, NULL, new_num_entries, new_heap, 0);
 					else {
+						/* flush color map */
+						grub_printf(" ");
 						cls();
 						print_cmdline_message(CMDLINE_EDIT_MODE);
 
@@ -800,7 +804,6 @@
 			break;
 	}
 
-	for (;;);
 	show_menu = 1;
 	goto restart;
 }

Modified: trunk/filo/util/checksum_elf.c
===================================================================
--- trunk/filo/util/checksum_elf.c	2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/util/checksum_elf.c	2008-10-22 11:19:52 UTC (rev 83)
@@ -28,6 +28,16 @@
 #else
 #include "byteorder.h"
 #endif
+#if defined(__sun)
+#include <sys/isa_defs.h>
+#define LITTLE_ENDIAN 1
+#define BIG_ENDIAN 2
+#if defined(_LITTLE_ENDIAN)
+#define BYTE_ORDER LITTLE_ENDIAN
+#else
+#define BYTE_ORDER BIG_ENDIAN
+#endif
+#endif
 #define STDINT_H
 #include "elf.h"
 #include "elf_boot.h"





More information about the coreboot mailing list