Index: openbios-quilt/arch/ppc/qemu/init.c
===================================================================
--- openbios-quilt.orig/arch/ppc/qemu/init.c	2008-12-21 19:31:01.000000000 +0000
+++ openbios-quilt/arch/ppc/qemu/init.c	2008-12-21 21:35:57.000000000 +0000
@@ -27,6 +27,13 @@
 #include "qemu/qemu.h"
 #include "ofmem.h"
 #include "openbios-version.h"
+#include "libc/byteorder.h"
+#define NO_QEMU_PROTOS
+#include "openbios/fw_cfg.h"
+
+#define CFG_ADDR 0xf0000510
+
+#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
 
 extern void unexpected_excep( int vector );
 extern void ob_pci_init( void );
@@ -62,10 +69,49 @@
 };
 uint32_t isa_io_base;
 
+static volatile uint16_t *fw_cfg_cmd = (void *)CFG_ADDR;
+static volatile uint8_t *fw_cfg_data = (void *)(CFG_ADDR + 2);
+
+static void
+fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
+{
+    unsigned int i;
+
+    *fw_cfg_cmd = cmd;
+    for (i = 0; i < nbytes; i++)
+        buf[i] = *fw_cfg_data;
+}
+
+static uint32_t
+fw_cfg_read_i32(uint16_t cmd)
+{
+    char buf[sizeof(uint32_t)];
+
+    fw_cfg_read(cmd, buf, sizeof(uint32_t));
+
+    return __le32_to_cpu(*(uint32_t *)buf);
+}
+
+static uint16_t
+fw_cfg_read_i16(uint16_t cmd)
+{
+    char buf[sizeof(uint16_t)];
+
+    fw_cfg_read(cmd, buf, sizeof(uint16_t));
+
+    return __le16_to_cpu(*(uint16_t *)buf);
+}
+
 void
 entry( void )
 {
-	arch = &known_arch[ARCH_HEATHROW];
+        uint32_t temp;
+        uint16_t machine_id;
+        char buf[5], qemu_uuid[16];
+
+        machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID);
+
+        arch = &known_arch[machine_id];
 	isa_io_base = arch->io_base;
 
 	serial_init();
@@ -74,6 +120,27 @@
 	printk("=============================================================\n");
 	printk("OpenBIOS %s [%s]\n", OPENBIOS_RELEASE, OPENBIOS_BUILD_DATE );
 
+        fw_cfg_read(FW_CFG_SIGNATURE, buf, 4);
+        buf[4] = '\0';
+
+        printk("Configuration device id %s", buf);
+
+        temp = fw_cfg_read_i32(FW_CFG_ID);
+
+        printk(" version %d machine id %d\n", temp, machine_id);
+
+        temp = fw_cfg_read_i32(FW_CFG_NB_CPUS);
+
+        printk("CPUs: %x\n", temp);
+
+        fw_cfg_read(FW_CFG_UUID, qemu_uuid, 16);
+
+        printk("UUID: " UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], qemu_uuid[2],
+               qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], qemu_uuid[6],
+               qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], qemu_uuid[10],
+               qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], qemu_uuid[14],
+               qemu_uuid[15]);
+
 	ofmem_init();
 	initialize_forth();
 	/* won't return */
Index: openbios-quilt/arch/ppc/qemu/main.c
===================================================================
--- openbios-quilt.orig/arch/ppc/qemu/main.c	2008-12-21 19:31:42.000000000 +0000
+++ openbios-quilt/arch/ppc/qemu/main.c	2008-12-21 21:39:33.000000000 +0000
@@ -33,6 +33,10 @@
 #define ELF_DPRINTF(fmt, args...) do { } while (0)
 #endif
 
+#define NVRAM_ADDR_LO 0x74
+#define NVRAM_ADDR_HI 0x75
+#define NVRAM_DATA    0x77
+
 static void
 transfer_control_to_elf( ulong elf_entry )
 {
@@ -130,6 +134,24 @@
     /* won't come here */
 }
 
+static uint8_t nvram_read(uint16_t offset)
+{
+    outb(offset & 0xff, NVRAM_ADDR_LO);
+    outb(offset >> 8, NVRAM_ADDR_HI);
+    return inb(NVRAM_DATA);
+}
+
+static uint32_t nvram_read_be32(uint16_t offset)
+{
+    uint32_t ret;
+
+    ret = nvram_read(offset) << 24;
+    ret |= nvram_read(offset + 1) << 16;
+    ret |= nvram_read(offset + 2) << 8;
+    ret |= nvram_read(offset + 3);
+    return ret;
+}
+
 static void
 yaboot_startup( void )
 {
@@ -160,6 +182,18 @@
                     param = pop_fstr_copy();
                 }
                 try_path(path, param);
+            } else {
+                char boot_device = nvram_read(0x34);
+                switch (boot_device) {
+                case 'c':
+                    path = strdup("hd:2,\\yaboot");
+                    break;
+                default:
+                case 'd':
+                    path = strdup("cdrom:2,\\yaboot");
+                    break;
+                }
+                try_path(path, "");
             }
         }
         for( i=0; i < sizeof(paths) / sizeof(paths[0]); i++ ) {
@@ -168,6 +202,22 @@
 	printk("*** Boot failure! No secondary bootloader specified ***\n");
 }
 
+static void check_preloaded_kernel(void)
+{
+    unsigned long kernel_image, kernel_size, cmdline;
+    unsigned long initrd_image, initrd_size;
+
+    kernel_size = nvram_read_be32(0x3c);
+    if (kernel_size) {
+        kernel_image = nvram_read_be32(0x38);
+        cmdline = nvram_read_be32(0x40);
+        initrd_image = nvram_read_be32(0x48);
+        initrd_size = nvram_read_be32(0x4c);
+        printk("[ppc] Kernel already loaded (0x%8.8lx + 0x%8.8lx)\n",
+               kernel_image, kernel_size);
+        call_elf(kernel_image);
+    }
+}
 
 /************************************************************************/
 /*	entry								*/
@@ -177,5 +227,6 @@
 boot( void )
 {
 	fword("update-chosen");
+        check_preloaded_kernel();
 	yaboot_startup();
 }
