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"


--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to