Index: openbios-quilt/include/openbios/fw_cfg.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openbios-quilt/include/openbios/fw_cfg.h	2008-08-31 12:42:05.000000000 +0000
@@ -0,0 +1,24 @@
+#ifndef FW_CFG_H
+#define FW_CFG_H
+
+#define FW_CFG_SIGNATURE        0x00
+#define FW_CFG_ID               0x01
+#define FW_CFG_UUID             0x02
+#define FW_CFG_RAM_SIZE         0x03
+#define FW_CFG_NOGRAPHIC        0x04
+#define FW_CFG_NB_CPUS          0x05
+#define FW_CFG_MACHINE_ID       0x06
+#define FW_CFG_MAX_ENTRY        0x10
+
+#define FW_CFG_ARCH_LOCAL       0x8000
+
+#ifndef NO_QEMU_PROTOS
+int fw_cfg_add_bytes(void *opaque, uint16_t key, const uint8_t *data,
+                     uint16_t len);
+int fw_cfg_add_i16(void *opaque, uint16_t key, uint16_t value);
+int fw_cfg_add_i32(void *opaque, uint16_t key, uint32_t value);
+int fw_cfg_add_i64(void *opaque, uint16_t key, uint64_t value);
+void *fw_cfg_init(uint32_t port, target_phys_addr_t addr);
+#endif /* NO_QEMU_PROTOS */
+
+#endif
Index: openbios-quilt/arch/sparc64/entry.S
===================================================================
--- openbios-quilt.orig/arch/sparc64/entry.S	2008-08-30 15:45:58.000000000 +0000
+++ openbios-quilt/arch/sparc64/entry.S	2008-08-31 12:42:58.000000000 +0000
@@ -11,10 +11,11 @@
 #include "asi.h"
 #include "pstate.h"
 #include "lsu.h"
-#define __ASSEMBLY__
-#include "openbios/firmware_abi.h"
+#define NO_QEMU_PROTOS
+#include "openbios/fw_cfg.h"
 
 #define PROM_ADDR 0x1fff0000000
+#define CFG_ADDR  0x1fe02000510
 
         .globl	entry, _entry
 
@@ -52,58 +53,61 @@
         ! Disable I/D MMUs and caches
         stxa    %g0, [%g0] ASI_LSU_CONTROL
 
-        ! Get memory size from NVRAM
-        setx    0x1fe02000074, %g2, %g5
-        mov     OHW_RAM_SIZE, %g2
-        stba    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
-        add     %g5, 1, %g1
-        stba    %g0, [%g1] ASI_PHYS_BYPASS_EC_E
-        add     %g1, 2, %g1
-	lduba	[%g1] ASI_PHYS_BYPASS_EC_E, %g4
-
-        sll     %g4, 8, %g4
-        inc     %g2
-        stba    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
-	lduba	[%g1] ASI_PHYS_BYPASS_EC_E, %g3
+        ! Check signature "QEMU"
+        setx    CFG_ADDR, %g2, %g5
+        mov     FW_CFG_SIGNATURE, %g2
+        stha    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g2
+        cmp     %g2, 'Q'
+        bne     bad_conf
+         nop
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g2
+        cmp     %g2, 'E'
+        bne     bad_conf
+         nop
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g2
+        cmp     %g2, 'M'
+        bne     bad_conf
+         nop
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g2
+        cmp     %g2, 'U'
+        bne     bad_conf
+         nop
+
+        ! Get memory size from configuration device
+        ! NB: little endian format
+        mov     FW_CFG_RAM_SIZE, %g2
+        stha    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g4
+
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+        sllx    %g3, 8, %g3
         or      %g3, %g4, %g4
 
-        sll     %g4, 8, %g4
-        inc     %g2
-        stba    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
-	lduba	[%g1] ASI_PHYS_BYPASS_EC_E, %g3
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+        sllx    %g3, 16, %g3
         or      %g3, %g4, %g4
 
-        sll     %g4, 8, %g4
-        inc     %g2
-        stba    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
-	lduba	[%g1] ASI_PHYS_BYPASS_EC_E, %g3
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+        sllx    %g3, 24, %g3
         or      %g3, %g4, %g4
 
-        sll     %g4, 8, %g4
-        inc     %g2
-        stba    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
-	lduba	[%g1] ASI_PHYS_BYPASS_EC_E, %g3
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+        sllx    %g3, 32, %g3
         or      %g3, %g4, %g4
 
-        sll     %g4, 8, %g4
-        inc     %g2
-        stba    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
-	lduba	[%g1] ASI_PHYS_BYPASS_EC_E, %g3
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+        sllx    %g3, 40, %g3
         or      %g3, %g4, %g4
 
-        sll     %g4, 8, %g4
-        inc     %g2
-        stba    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
-	lduba	[%g1] ASI_PHYS_BYPASS_EC_E, %g3
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+        sllx    %g3, 48, %g3
         or      %g3, %g4, %g4
 
-        sll     %g4, 8, %g4
-        inc     %g2
-        stba    %g2, [%g5] ASI_PHYS_BYPASS_EC_E
-	lduba	[%g1] ASI_PHYS_BYPASS_EC_E, %g3
+        lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
+        sllx    %g3, 56, %g3
         or      %g3, %g4, %g1
-	! %g1 contains end of memory
-
+        ! %g1 contains end of memory
 
         setx    _end, %g7, %g3
         set     0xffff, %g2
@@ -301,8 +305,7 @@
 
         /* We get here when the main context switches back to
          * the boot context.
-         * Return to previous bootloader.
          */
-        ret
+bad_conf:
+        b       bad_conf
          nop
-
Index: openbios-quilt/arch/sparc64/openbios.c
===================================================================
--- openbios-quilt.orig/arch/sparc64/openbios.c	2008-08-30 15:46:13.000000000 +0000
+++ openbios-quilt/arch/sparc64/openbios.c	2008-08-31 12:43:12.000000000 +0000
@@ -24,6 +24,10 @@
 #include "asi.h"
 #include "spitfire.h"
 #include "libc/vsprintf.h"
+#define NO_QEMU_PROTOS
+#include "openbios/fw_cfg.h"
+
+#define BIOS_CFG_IOPORT 0x510
 
 #define REGISTER_NAMED_NODE( name, path )   do {                        \
         bind_new_node( name##_flags_, name##_size_,                     \
@@ -67,6 +71,8 @@
 #define PAGE_MASK_64K  (64 * 1024 - 1)
 #define PAGE_MASK_8K   (8 * 1024 - 1)
 
+#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+
 static void
 mmu_open(void)
 {
@@ -454,6 +460,8 @@
     for (;;);
 }
 
+static uint8_t qemu_uuid[16];
+
 void arch_nvram_get(char *data)
 {
     unsigned short i;
@@ -461,6 +469,9 @@
     uint32_t size;
     const struct cpudef *cpu;
     const char *bootpath;
+    char buf[256];
+    uint32_t temp;
+    uint64_t ram_size;
 
     for (i = 0; i < sizeof(ohwcfg_v3_t); i++) {
         outb(i & 0xff, 0x74);
@@ -468,14 +479,20 @@
         *nvptr++ = inb(0x77);
     }
 
-    printk("Nvram id %s, version %d\n", nv_info.struct_ident,
-           nv_info.struct_version);
-    if (strcmp(nv_info.struct_ident, "QEMU_BIOS") ||
-        nv_info.struct_version != 3 ||
-        OHW_compute_crc(&nv_info, 0x00, 0xF8) != nv_info.crc) {
-        printk("Unknown nvram, freezing!\n");
-        for (;;);
+    outw(__cpu_to_le16(FW_CFG_SIGNATURE), BIOS_CFG_IOPORT);
+    for (i = 0; i < 4; i++) {
+        buf[i] = inb(BIOS_CFG_IOPORT);
     }
+    buf[4] = '\0';
+
+    printk("Configuration device id %s", buf);
+
+    outw(__cpu_to_le16(FW_CFG_ID), BIOS_CFG_IOPORT);
+    for (i = 0; i < 4; i++) {
+        buf[i] = inb(BIOS_CFG_IOPORT);
+    }
+    temp = __le32_to_cpu(*(uint32_t *)buf);
+    printk(" version %d\n", temp);
 
     kernel_image = nv_info.kernel_image;
     kernel_size = nv_info.kernel_size;
@@ -498,16 +515,40 @@
         data[i] = inb(0x77);
     }
 
-    printk("CPUs: %x", nv_info.nb_cpus);
+    outw(__cpu_to_le16(FW_CFG_NB_CPUS), BIOS_CFG_IOPORT);
+    for (i = 0; i < 4; i++) {
+        buf[i] = inb(BIOS_CFG_IOPORT);
+    }
+    temp = __le32_to_cpu(*(uint32_t *)buf);
+
+    printk("CPUs: %x", temp);
+
     cpu = id_cpu();
     //cpu->initfn();
     cpu_generic_init(cpu);
     printk(" x %s\n", cpu->name);
 
-    // Add /idprom
+    // Add /uuid
+    outw(__cpu_to_le16(FW_CFG_UUID), BIOS_CFG_IOPORT);
+    for (i = 0; i < 16; i++) {
+        qemu_uuid[i] = inb(BIOS_CFG_IOPORT);
+    }
+    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]);
+
     push_str("/");
     fword("find-device");
 
+    PUSH((long)&qemu_uuid);
+    PUSH(16);
+    fword("encode-bytes");
+    push_str("uuid");
+    fword("property");
+
+    // Add /idprom
     for (i = 0; i < 32; i++) {
         outb((i + 0x1fd8) & 0xff, 0x74);
         outb((i + 0x1fd8) >> 8, 0x75);
@@ -528,16 +569,22 @@
     push_str("/memory");
     fword("find-device");
 
+    outw(__cpu_to_le16(FW_CFG_RAM_SIZE), BIOS_CFG_IOPORT);
+    for (i = 0; i < 8; i++) {
+        buf[i] = inb(BIOS_CFG_IOPORT);
+    }
+    ram_size = __le64_to_cpu(*(uint64_t *)buf);
+
     // All memory: 0 to RAM_size
     PUSH(0);
     fword("encode-int");
     PUSH(0);
     fword("encode-int");
     fword("encode+");
-    PUSH((int)(nv_info.RAM0_size >> 32));
+    PUSH((int)(ram_size >> 32));
     fword("encode-int");
     fword("encode+");
-    PUSH((int)(nv_info.RAM0_size & 0xffffffff));
+    PUSH((int)(ram_size & 0xffffffff));
     fword("encode-int");
     fword("encode+");
     push_str("reg");
