---
 arch/ppc/build.xml     |    1 
 arch/ppc/qemu/init.c   |   12 ---
 arch/ppc/qemu/qemu.fs  |   45 --------------
 arch/ppc/qemu/tree.c   |   24 -------
 arch/sparc64/tree.fs   |   37 ++++++++++++
 drivers/ide.c          |    2 
 drivers/pci.c          |  149 ++++++++++++++++++++++++++++++++++++++++---------
 drivers/pci.fs         |   21 ------
 drivers/pci_database.h |    1 
 forth/util/pci.fs      |   21 ------
 10 files changed, 163 insertions(+), 150 deletions(-)

Index: openbios-devel/drivers/ide.c
===================================================================
--- openbios-devel.orig/drivers/ide.c	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/drivers/ide.c	2009-01-06 21:53:15.000000000 +0100
@@ -1312,7 +1312,7 @@
 		uint32_t io_port1, uint32_t ctl_port1)
 {
 	int i, j;
-	char nodebuff[32];
+	char nodebuff[128];
 	phandle_t dnode, aliases;
 	int hd_found, cd_found;
 
Index: openbios-devel/drivers/pci.c
===================================================================
--- openbios-devel.orig/drivers/pci.c	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/drivers/pci.c	2009-01-06 21:53:15.000000000 +0100
@@ -40,6 +40,34 @@
 
 const pci_arch_t *arch;
 
+#define IS_NOT_RELOCATABLE	0x80000000
+#define IS_PREFETCHABLE		0x40000000
+#define IS_ALIASED		0x20000000
+
+enum {
+	CONFIGURATION_SPACE = 0,
+	IO_SPACE = 1,
+	MEMORY_SPACE_32 = 2,
+	MEMORY_SPACE_64 = 3,
+};
+
+static inline void pci_encode_phys_addr(cell *phys, int flags, int space_code,
+				 pci_addr dev, uint8_t reg, uint64_t addr)
+{
+
+	/* phys.hi */
+
+	phys[0] = flags | (space_code << 24) | dev | reg;
+
+	/* phys.mid */
+
+	phys[1] = addr >> 32;
+
+	/* phys.lo */
+
+	phys[2] = addr;
+}
+
 static void
 ob_pci_open(int *idx)
 {
@@ -58,11 +86,82 @@
 {
 }
 
+/* ( str len -- phys.lo phys.mid phys.hi ) */
+
+static void
+ob_pci_decode_unit(int *idx)
+{
+	PUSH(0);
+	fword("decode-unit-pci-bus");
+}
+
+/*  ( phys.lo phy.mid phys.hi -- str len ) */
+
+static void
+ob_pci_encode_unit(int *idx)
+{
+	char buf[28];
+	cell hi = POP();
+	cell mid = POP();
+	cell lo = POP();
+	int n, p, t, ss, bus, dev, fn, reg;
+
+	n = hi & IS_NOT_RELOCATABLE;
+	p = hi & IS_PREFETCHABLE;
+	t = hi & IS_ALIASED;
+	ss = (hi >> 24) && 0x03;
+
+	bus = (hi >> 16) & 0xFF;
+	dev = (hi >> 11) & 0x1F;
+	fn = (hi >> 8) & 0x07;
+	reg = hi & 0xFF;
+
+	switch(ss) {
+	case CONFIGURATION_SPACE:
+
+		if (fn == 0)	/* DD */
+        		snprintf(buf, sizeof(buf), "%x", dev);
+		else		/* DD,F */
+        		snprintf(buf, sizeof(buf), "%x,%d", dev, fn);
+		break;
+
+	case IO_SPACE:
+
+		/* [n]i[t]DD,F,RR,NNNNNNNN */
+        	snprintf(buf, sizeof(buf), "%si%s%x,%x,%x,%x",
+			 n ? "n" : "",	/* relocatable */
+			 t ? "t" : "",	/* aliased */
+			 dev, fn, reg, t ? lo & 0x03FF : lo);
+		break;
+
+	case MEMORY_SPACE_32:
+
+		/* [n]m[t][p]DD,F,RR,NNNNNNNN */
+        	snprintf(buf, sizeof(buf), "%sm%s%s%x,%x,%x,%x",
+			 n ? "n" : "",	/* relocatable */
+			 t ? "t" : "",	/* aliased */
+			 p ? "p" : "",	/* prefetchable */
+			 dev, fn, reg, lo );
+		break;
+
+	case MEMORY_SPACE_64:
+
+		/* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN */
+        	snprintf(buf, sizeof(buf), "%sx%s%x,%x,%x,%llx",
+			 n ? "n" : "",	/* relocatable */
+			 p ? "p" : "",	/* prefetchable */
+			 dev, fn, reg, ((uint64_t)mid << 32) | (uint64_t)lo );
+		break;
+	}
+	push_str(buf);
+}
 
 NODE_METHODS(ob_pci_node) = {
 	{ NULL,			ob_pci_initialize	},
 	{ "open",		ob_pci_open		},
 	{ "close",		ob_pci_close		},
+	{ "decode-unit",	ob_pci_decode_unit	},
+	{ "encode-unit",	ob_pci_encode_unit	},
 };
 
 int ide_config_cb2 (const pci_config_t *config)
@@ -119,16 +218,19 @@
 	int status,id;
 	uint16_t vendor_id, device_id;
 	uint8_t rev;
+	uint32_t class_code;
 
 	vendor_id = pci_config_read16(addr, PCI_VENDOR_ID);
 	device_id = pci_config_read16(addr, PCI_DEVICE_ID);
 	rev = pci_config_read8(addr, PCI_REVISION_ID);
+	class_code = pci_config_read16(addr, PCI_CLASS_DEVICE);
 
 	/* create properties as described in 2.5 */
 
 	set_int_property(dev, "vendor-id", vendor_id);
 	set_int_property(dev, "device-id", device_id);
 	set_int_property(dev, "revision-id", rev);
+	set_int_property(dev, "class-code", class_code << 8);
 
 	set_int_property(dev, "interrupts",
 			pci_config_read8(addr, PCI_INTERRUPT_LINE));
@@ -173,10 +275,6 @@
 	if (pci_dev->compat)
 		set_property(dev, "compatible",
 			     pci_dev->compat, pci_compat_len(pci_dev));
-	push_str(pci_dev->name);
-	fword("encode-string");
-	push_str("class");
-	fword("property");
 	if (pci_dev->config_cb)
 		pci_dev->config_cb(config);
 }
@@ -310,17 +408,17 @@
 }
 
 static void ob_scan_pci_bus(int bus, unsigned long *mem_base,
-                            unsigned long *io_base, const char *path)
+                            unsigned long *io_base, char **path)
 {
 	int devnum, fn, is_multi, vid, did;
 	unsigned int htype;
 	pci_addr addr;
-	phandle_t dnode, dbus;
 	pci_config_t config;
         const pci_dev_t *pci_dev;
 	uint32_t ccode;
 	uint8_t class, subclass, iface, rev;
 
+	activate_device("/");
 	for (devnum = 0; devnum < 32; devnum++) {
 		is_multi = 0;
 		for (fn = 0; fn==0 || (is_multi && fn<8); fn++) {
@@ -341,7 +439,8 @@
 			iface = pci_config_read8(addr, PCI_CLASS_PROG);
 			rev = pci_config_read8(addr, PCI_REVISION_ID);
 
-			pci_dev = pci_find_device(class, subclass, iface, vid, did);
+			pci_dev = pci_find_device(class, subclass, iface,
+						  vid, did);
 
 #ifdef CONFIG_DEBUG_PCI
 			printk("%x:%x.%x - %x:%x - ", bus, devnum, fn,
@@ -351,43 +450,41 @@
 			if (fn == 0)
 				is_multi = htype & 0x80;
 
-			activate_device(path);
-
-			dbus=get_cur_dev();
 			if (pci_dev == NULL || pci_dev->name == NULL)
                             snprintf(config.path, sizeof(config.path),
-                                     "%s/pci%x,%x", path, vid, did);
+				     "%s/pci%x,%x", *path, vid, did);
 			else
                             snprintf(config.path, sizeof(config.path),
-                                     "%s/%s", path, pci_dev->name);
+				     "%s/%s", *path, pci_dev->name);
 #ifdef CONFIG_DEBUG_PCI
 			printk("%s - ", config.path);
 #endif
+			config.dev = addr & 0x00FFFFFF;
+
 			REGISTER_NAMED_NODE(ob_pci_node, config.path);
-			dnode=find_dev(config.path);
-			activate_dev( dnode );
+
+			activate_device(config.path);
+
                         ob_pci_configure(addr, &config, mem_base, io_base);
-{
-	int irq_pin, irq_line;
-	static const uint8_t heathrow_pci_irqs[4] = { 0x15, 0x16, 0x17, 0x18 };
-	irq_pin = pci_config_read8(addr, PCI_INTERRUPT_PIN);
-	if (irq_pin > 0) {
-		irq_pin = (devnum + irq_pin - 1) & 3;
-		irq_line = heathrow_pci_irqs[irq_pin];
-	}
-}
 			ob_pci_add_properties(addr, pci_dev, &config);
 			ob_pci_add_reg(addr);
-			device_end();
+
+			if (ccode == 0x0600 || ccode == 0x0604) {
+				/* host or bridge */
+				free(*path);
+				*path = strdup(config.path);
+			}
 
 		}
 	}
+	device_end();
 }
 
 int ob_pci_init(void)
 {
         int bus;
         unsigned long mem_base, io_base;
+	char *path;
 
 #ifdef CONFIG_DEBUG_PCI
 	printk("Initializing PCI devices...\n");
@@ -399,8 +496,10 @@
 
 	mem_base = arch->mem_base;
 	io_base = arch->io_base;
+	path = strdup("");
 	for (bus = 0; bus<0x100; bus++) {
-		ob_scan_pci_bus(bus, &mem_base, &io_base, "/pci");
+		ob_scan_pci_bus(bus, &mem_base, &io_base, &path);
 	}
+	free(path);
 	return 0;
 }
Index: openbios-devel/arch/ppc/build.xml
===================================================================
--- openbios-devel.orig/arch/ppc/build.xml	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/arch/ppc/build.xml	2009-01-06 21:53:15.000000000 +0100
@@ -142,7 +142,6 @@
   <external-object source="target/arch/ppc/qemu/kernel.o"/>
   <object source="qemu/main.c" flags="-Iarch/ppc"/>
   <object source="qemu/methods.c" flags="-Iarch/ppc"/>
-  <object source="qemu/tree.c" flags="-Iarch/ppc"/>
   <object source="qemu/vfd.c" flags="-Iarch/ppc"/>
   <object source="qemu/console.c" flags="-Iarch/ppc"/>
  </library>
Index: openbios-devel/arch/ppc/qemu/init.c
===================================================================
--- openbios-devel.orig/arch/ppc/qemu/init.c	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/arch/ppc/qemu/init.c	2009-01-06 21:53:15.000000000 +0100
@@ -427,18 +427,6 @@
         const struct cpudef *cpu;
 	char buf[64];
 
-	devtree_init();
-
-	/* ISA BASE */
-
-	push_str("/");
-	fword("find-device");
-
-	PUSH(isa_io_base);
-	fword("encode-int");
-	push_str("isa-io-base");
-	fword("property");
-
 	/* memory info */
 
 	push_str("/memory");
Index: openbios-devel/arch/ppc/qemu/qemu.fs
===================================================================
--- openbios-devel.orig/arch/ppc/qemu/qemu.fs	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/arch/ppc/qemu/qemu.fs	2009-01-06 22:12:43.000000000 +0100
@@ -44,51 +44,6 @@
 ; SYSTEM-initializer
 
 
-\ -------------------------------------------------------------------------
-\ device tree fixing
-\ -------------------------------------------------------------------------
-
-\ add decode-address methods
-: (make-decodable) ( phandle -- )
-
-    dup " #address-cells" rot get-package-property 0= if
-      decode-int nip nip
-      over " decode-unit" rot find-method if 2drop else
-        ( save phandle ncells )
-
-        over active-package!
-        case
-          1 of ['] parse-hex " decode-unit" is-xt-func endof
-          3 of
-            " bus-range" active-package get-package-property 0= if
-              decode-int nip nip
-              ['] encode-unit-pci " encode-unit" is-xt-func
-              " decode-unit" is-func-begin
-                ['] (lit) , ,
-                ['] decode-unit-pci-bus ,
-              is-func-end
-            then
-          endof
-        endcase
-      then
-    then
-    drop
-;
-
-: init-qemu-tree ( -- )
-  active-package
-
-  iterate-tree-begin
-  begin ?dup while
-
-    dup (make-decodable)
-
-    iterate-tree
-  repeat
-
-  active-package!
-;
-
 \ use the tty interface if available
 : activate-tty-interface
   " /packages/terminal-emulator" find-dev if drop
Index: openbios-devel/arch/ppc/qemu/tree.c
===================================================================
--- openbios-devel.orig/arch/ppc/qemu/tree.c	2009-01-06 21:52:17.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,24 +0,0 @@
-/*
- *   Creation Date: <2004/08/28 18:38:22 greg>
- *   Time-stamp: <2004/08/28 18:38:22 greg>
- *
- *	<tree.c>
- *
- *	device tree setup
- *
- *   Copyright (C) 2004 Greg Watson
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   version 2
- *
- */
-
-#include "openbios/config.h"
-#include "openbios/bindings.h"
-#include "qemu.h"
-
-void devtree_init( void )
-{
-	fword("init-qemu-tree");
-}
Index: openbios-devel/drivers/pci.fs
===================================================================
--- openbios-devel.orig/drivers/pci.fs	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/drivers/pci.fs	2009-01-06 21:53:15.000000000 +0100
@@ -1,24 +1,5 @@
 [IFDEF] CONFIG_DRIVER_PCI
 
-dev /
-
-\ simple pci bus node
-new-device
-  " pci" device-name
-	3 encode-int " #address-cells" property
-	2 encode-int " #size-cells" property
-	0 encode-int 0 encode-int encode+ " bus-range" property
-	" pci" encode-string " device_type" property
-	
-  external
-  : open ( cr ." opening PCI" cr ) true ;
-  : close ;
-  : decode-unit 0 decode-unit-pci-bus ;
-  : encode-unit encode-unit-pci ;
-finish-device
-
-device-end
-
 : pci-addr-encode ( addr.lo addr.mi addr.hi )
   rot >r swap >r 
   encode-int 
@@ -31,6 +12,4 @@
   rot encode-int encode+ 
   ;
 
-
-
 [THEN]
Index: openbios-devel/forth/util/pci.fs
===================================================================
--- openbios-devel.orig/forth/util/pci.fs	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/forth/util/pci.fs	2009-01-06 21:53:15.000000000 +0100
@@ -93,27 +93,6 @@
 
 \ only forth
 
-
-\ -------------------------------------------------------------------------
-\ PCI encode/decode unit
-\ -------------------------------------------------------------------------
-
-\ we only implement DD and DD,F
-: encode-unit-pci ( phys.lo phy.mid phys.hi -- str len )
-  nip nip ff00 and 8 >> dup 3 >>
-  swap 7 and
-  ( ddddd fff )
-
-  ?dup if
-    pocket tohexstr
-    " ," pocket tmpstrcat
-  else
-    0 0 pocket tmpstrcpy
-  then
-  >r
-  rot pocket tohexstr r> tmpstrcat drop
-;
-
 : decode-unit-pci-bus ( str len bus -- phys.lo phys.mid phys.hi )
   -rot ascii , left-split
   ( addr-R len-R addr-L len-L )
Index: openbios-devel/drivers/pci_database.h
===================================================================
--- openbios-devel.orig/drivers/pci_database.h	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/drivers/pci_database.h	2009-01-06 21:53:15.000000000 +0100
@@ -2,6 +2,7 @@
 
 struct pci_config_t {
 	char path[256];
+	uint32_t dev;		/* bus, dev, fn */
 	uint32_t regions[7];
 	uint32_t sizes[7];
 };
Index: openbios-devel/arch/sparc64/tree.fs
===================================================================
--- openbios-devel.orig/arch/sparc64/tree.fs	2009-01-06 21:52:17.000000000 +0100
+++ openbios-devel/arch/sparc64/tree.fs	2009-01-06 22:13:11.000000000 +0100
@@ -33,6 +33,43 @@
 " /openprom" find-device
   " OBP 3.10.24 1999/01/01 01:01" encode-string " version" property
 
+device-end
+
+\ we only implement DD and DD,F
+: encode-unit-pci ( phys.lo phy.mid phys.hi -- str len )
+  nip nip ff00 and 8 >> dup 3 >>
+  swap 7 and
+  ( ddddd fff )
+
+  ?dup if
+    pocket tohexstr
+    " ," pocket tmpstrcat
+  else
+    0 0 pocket tmpstrcpy
+  then
+  >r
+  rot pocket tohexstr r> tmpstrcat drop
+;
+
+dev /
+
+\ simple pci bus node
+new-device
+  " pci" device-name
+	3 encode-int " #address-cells" property
+	2 encode-int " #size-cells" property
+	0 encode-int 0 encode-int encode+ " bus-range" property
+	" pci" encode-string " device_type" property
+
+  external
+  : open ( cr ." opening PCI" cr ) true ;
+  : close ;
+  : decode-unit 0 decode-unit-pci-bus ;
+  : encode-unit encode-unit-pci ;
+finish-device
+
+device-end
+
 dev /pci
 
 \ simple isa bus node
