Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c	2008-08-06 15:31:58.000000000 +0000
+++ qemu/hw/pc.c	2008-08-06 16:22:52.000000000 +0000
@@ -32,6 +32,7 @@
 #include "smbus.h"
 #include "boards.h"
 #include "console.h"
+#include "firmware_abi.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -41,6 +42,8 @@
 #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
 
 #define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
+#define PC_CFG_ROM_PORT 0x1234
+#define PC_CFG_ROM_SIZE 4096
 
 /* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables.  */
 #define ACPI_DATA_SIZE       0x10000
@@ -712,6 +715,86 @@
     nb_ne2k++;
 }
 
+typedef struct CfgROMState {
+    uint8_t cfg_rom[PC_CFG_ROM_SIZE];
+    uint16_t curr_addr;
+} CfgROMState;
+
+static int pc_cfg_rom_set_params(CfgROMState *s,
+                                 const char *arch,
+                                 ram_addr_t below_4g_mem_size,
+                                 ram_addr_t above_4g_mem_size,
+                                 const char *boot_devices)
+{
+    uint32_t start;
+    ohwcfg_v3_t *header = (ohwcfg_v3_t *)s->cfg_rom;
+    struct pc_arch_cfg *pc_header;
+    extern int nographic;
+
+    memset(s->cfg_rom, '\0', PC_CFG_ROM_SIZE);
+
+    // Try to match PPC NVRAM
+    strcpy((char *)header->struct_ident, "QEMU_BIOS");
+    header->struct_version = cpu_to_le32(3); /* structure v3 */
+
+    header->nvram_arch_ptr = cpu_to_le16(sizeof(ohwcfg_v3_t));
+    header->nvram_arch_size = cpu_to_le16(sizeof(struct pc_arch_cfg));
+    strcpy((char *)header->arch, arch);
+    header->nb_cpus = smp_cpus & 0xff;
+    header->RAM0_base = 0;
+    header->RAM0_size = cpu_to_le64((uint64_t)below_4g_mem_size);
+    if (above_4g_mem_size) {
+        header->RAM1_base = 0x100000000ULL;
+        header->RAM1_size = cpu_to_le64((uint64_t)above_4g_mem_size);
+    }
+    strcpy((char *)header->boot_devices, boot_devices);
+    header->nboot_devices = strlen(boot_devices) & 0xff;
+
+    if (nographic)
+        header->graphic_flags = cpu_to_le16(OHW_GF_NOGRAPHICS);
+
+    strncpy((char *)header->uuid, "QEMUQEMUQEMUQEMU", 16);
+
+    header->crc = cpu_to_le16(OHW_compute_crc(header, 0x00, 0xF8));
+
+    // Architecture specific header
+    start = sizeof(ohwcfg_v3_t);
+    pc_header = (struct pc_arch_cfg *)&s->cfg_rom[start];
+    pc_header->valid = 1;
+
+    return 0;
+}
+
+static uint32_t pc_cfg_rom_readw(void *opaque, uint32_t addr)
+{
+    CfgROMState *s = (CfgROMState *)opaque;
+
+    if (s->curr_addr < PC_CFG_ROM_SIZE)
+        return s->cfg_rom[s->curr_addr];
+    return 0;
+}
+
+static void pc_cfg_rom_writew(void *opaque, uint32_t addr, uint32_t value)
+{
+    CfgROMState *s = (CfgROMState *)opaque;
+
+    s->curr_addr = value;
+}
+
+static void *pc_cfg_rom_map(uint32_t addr)
+{
+    CfgROMState *s;
+
+    s = qemu_mallocz(sizeof(CfgROMState));
+    if (!s)
+        return NULL;
+
+    register_ioport_read(addr, 2, 2, pc_cfg_rom_readw, s);
+    register_ioport_write(addr, 2, 2, pc_cfg_rom_writew, s);
+
+    return s;
+}
+
 /* PC hardware initialisation */
 static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
                      const char *boot_device, DisplayState *ds,
@@ -867,6 +950,16 @@
     cpu_register_physical_memory((uint32_t)(-bios_size),
                                  bios_size, bios_offset | IO_MEM_ROM);
 
+    {
+        CfgROMState *cfg_rom;
+
+        /* map configuration ROM */
+        cfg_rom = pc_cfg_rom_map(PC_CFG_ROM_PORT);
+        pc_cfg_rom_set_params(cfg_rom, pci_enabled? "pc" : "isapc",
+                              below_4g_mem_size, above_4g_mem_size,
+                              boot_device);
+    }
+
     bochs_bios_init();
 
     if (linux_boot)
Index: qemu/hw/firmware_abi.h
===================================================================
--- qemu.orig/hw/firmware_abi.h	2008-08-06 15:31:58.000000000 +0000
+++ qemu/hw/firmware_abi.h	2008-08-06 15:32:27.000000000 +0000
@@ -54,8 +54,10 @@
     uint8_t  pad3[5];
     /* 0xD0: boot devices                            */
     uint8_t  boot_devices[0x10];
-    /* 0xE0                                          */
-    uint8_t  pad4[0x1C]; /* 28 */
+    /* 0xE0: UUID                                    */
+    uint8_t  uuid[0x10];
+    /* 0xF0                                          */
+    uint8_t  pad4[0xC]; /* 12 */
     /* 0xFC: checksum                                */
     uint16_t crc;
     uint8_t  pad5[0x02];
@@ -176,6 +178,12 @@
     header->checksum = tmp;
 }
 
+/* PC configuration structure */
+struct pc_arch_cfg {
+    uint8_t valid;
+    uint8_t unused[63];
+};
+
 #else /* __ASSEMBLY__ */
 
 /* Structure offsets for asm use */
Index: qemu/hw/sun4m.c
===================================================================
--- qemu.orig/hw/sun4m.c	2008-08-06 15:31:58.000000000 +0000
+++ qemu/hw/sun4m.c	2008-08-06 15:32:27.000000000 +0000
@@ -213,6 +213,8 @@
     if (nographic)
         header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);
 
+    strncpy((char *)header->uuid, "QEMUQEMUQEMUQEMU", 16);
+
     header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
 
     // Architecture specific header
Index: qemu/hw/sun4u.c
===================================================================
--- qemu.orig/hw/sun4u.c	2008-08-06 15:31:58.000000000 +0000
+++ qemu/hw/sun4u.c	2008-08-06 15:32:27.000000000 +0000
@@ -144,6 +144,8 @@
     if (nographic)
         header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);
 
+    strncpy((char *)header->uuid, "QEMUQEMUQEMUQEMU", 16);
+
     header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
 
     // Architecture specific header
