Index: boot/genarch/ofw.c
===================================================================
--- boot/genarch/ofw.c	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ boot/genarch/ofw.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -115,5 +115,5 @@
 }
 
-int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen)
+int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen)
 {
 	return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen);
@@ -128,4 +128,9 @@
 {
 	return ofw_call("nextprop", 3, 1, NULL, device, previous, buf);
+}
+
+int ofw_package_to_path(const phandle device, char *buf, const int buflen)
+{
+	return ofw_call("package-to-path", 3, 1, NULL, device, buf, buflen);
 }
 
Index: boot/genarch/ofw.h
===================================================================
--- boot/genarch/ofw.h	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ boot/genarch/ofw.h	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -103,5 +103,5 @@
 extern void ofw_write(const char *str, const int len);
 
-extern int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen);
+extern int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen);
 extern int ofw_get_proplen(const phandle device, const char *name);
 extern int ofw_next_property(const phandle device, char *previous, char *buf);
@@ -110,4 +110,6 @@
 extern phandle ofw_get_peer_node(const phandle node);
 extern phandle ofw_find_device(const char *name);
+
+extern int ofw_package_to_path(const phandle device, char *buf, const int buflen);
 
 extern int ofw(ofw_args_t *arg);
Index: boot/genarch/ofw_tree.c
===================================================================
--- boot/genarch/ofw_tree.c	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ boot/genarch/ofw_tree.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -32,4 +32,7 @@
 #include <string.h>
 #include <balloc.h>
+#include <asm.h>
+
+#define MAX_PATH_LEN	256
 
 static ofw_tree_node_t *ofw_tree_node_alloc(void)
@@ -62,8 +65,11 @@
 	ofw_tree_node_t *parent_node, phandle current)
 {
+	static char path[MAX_PATH_LEN+1];
+	static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
 	phandle peer;
 	phandle child;
 	unsigned properties = 0;
-	char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
+	size_t len;
+	int i;
 
 	/*
@@ -77,4 +83,24 @@
 	
 	/*
+	 * Get the disambigued name.
+	 */
+	len = ofw_package_to_path(current, path, MAX_PATH_LEN);
+	if (len == -1)
+		return;
+	
+	path[len] = '\0';
+	for (i = len - 1; i >= 0 && path[i] != '/'; i--)
+		;
+	i++;								/* do not include '/' */
+	
+	len -= i;
+	current_node->da_name = ofw_tree_space_alloc(len + 1);		/* add space for trailing '\0' */
+	if (!current_node->da_name)
+		return;
+	
+	memcpy(current_node->da_name, &path[i], len);
+	current_node->da_name[len] = '\0';
+	
+	/*
 	 * Recursively process the potential peer node.
 	 */
@@ -85,5 +111,5 @@
 		peer_node = ofw_tree_node_alloc();
 		if (peer_node) {
-			ofw_tree_node_process(peer_node, current_node, peer);
+			ofw_tree_node_process(peer_node, parent_node, peer);
 			current_node->peer = peer_node;
 		}
@@ -121,6 +147,4 @@
 		return;
 		
-	int i = 0;
-
 	name[0] = '\0';
 	for (i = 0; ofw_next_property(current, name, name) == 1; i++) {
Index: boot/genarch/ofw_tree.h
===================================================================
--- boot/genarch/ofw_tree.h	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ boot/genarch/ofw_tree.h	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -44,4 +44,6 @@
 	ofw_tree_node_t *child;
 
+	char *da_name;				/**< Disambigued name. */
+
 	unsigned properties;			/**< Number of properties. */
 	ofw_tree_property_t *property;
Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ kernel/arch/sparc64/Makefile.inc	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -61,4 +61,8 @@
 CONFIG_FB = y
 
+## Compile with support for OpenFirmware device tree.
+#
+
+CONFIG_OFW_TREE = y
 
 ifeq ($(MACHINE),enterprise)
Index: kernel/arch/sparc64/src/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sparc64.c	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ kernel/arch/sparc64/src/sparc64.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -46,4 +46,5 @@
 #include <arch/mm/page.h>
 #include <arch/stack.h>
+#include <genarch/ofw/ofw_tree.h>
 #include <userspace.h>
 
@@ -65,4 +66,6 @@
 	ballocs.base = bootinfo.ballocs.base;
 	ballocs.size = bootinfo.ballocs.size;
+	
+	ofw_tree_init(bootinfo.ofw_root);
 }
 
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ kernel/genarch/Makefile.inc	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -93,4 +93,4 @@
 ifeq ($(CONFIG_OFW_TREE), y)
 	GENARCH_SOURCES += \
-		genarch/src/ofw/ofw_tree,c
+		genarch/src/ofw/ofw_tree.c
 endif
Index: kernel/genarch/include/ofw/ofw_tree.h
===================================================================
--- kernel/genarch/include/ofw/ofw_tree.h	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ kernel/genarch/include/ofw/ofw_tree.h	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -31,4 +31,5 @@
 
 #include <arch/types.h>
+#include <typedefs.h>
 
 #define OFW_TREE_PROPERTY_MAX_NAMELEN	32
@@ -43,5 +44,7 @@
 	ofw_tree_node_t *child;
 
-	unsigned properties;			/**< Number of properties. */
+	char *da_name;					/**< Disambigued name. */
+
+	unsigned properties;				/**< Number of properties. */
 	ofw_tree_property_t *property;
 };
@@ -54,3 +57,8 @@
 };
 
+extern void ofw_tree_init(ofw_tree_node_t *root);
+extern void ofw_tree_print(void);
+extern const char *ofw_tree_node_name(const ofw_tree_node_t *node);
+extern ofw_tree_node_t *ofw_tree_lookup(const char *path);
+
 #endif
Index: kernel/genarch/src/ofw/ofw_tree.c
===================================================================
--- kernel/genarch/src/ofw/ofw_tree.c	(revision 61e90ddd605dc4854cbb016a4be65d1cd1e9510c)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
@@ -36,4 +36,119 @@
  */
 
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/memstr.h>
+#include <func.h>
+#include <print.h>
+#include <panic.h>
+
+#define PATH_MAX_LEN	80
+#define NAME_BUF_LEN	50
+
+static ofw_tree_node_t *ofw_root;
+
+void ofw_tree_init(ofw_tree_node_t *root)
+{
+	ofw_root = root;
+}
+
+/** Return value of the 'name' property.
+ *
+ * @param node Node of interest.
+ *
+ * @return Value of the 'name' property belonging to the node.
+ */
+const char *ofw_tree_node_name(const ofw_tree_node_t *node)
+{
+	int i;
+	
+	for (i = 0; i < node->properties; i++) {
+		if (strncmp(node->property[i].name, "name", strlen("name")) == 0) {
+			if (node->property[i].size < 2)
+				panic("Invalid name property.\n");
+			return node->property[i].value;
+		}
+	}
+	
+	panic("Node without name property.\n");
+}
+
+/** Lookup child of given name.
+ *
+ * @param node Node whose child is being looked up.
+ * @param da_name Disambigued name of the child being looked up.
+ *
+ * @return NULL if there is no such child or pointer to the matching child node.
+ */
+static ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *da_name)
+{
+	ofw_tree_node_t *cur;
+	
+	for (cur = node->child; cur; cur = cur->peer) {
+		if (strncmp(cur->da_name, da_name, strlen(da_name)) == 0)
+			return cur;
+	}
+	
+	return NULL;
+}
+
+/** Lookup OpenFirmware node by its path.
+ *
+ * @param path Path to the node.
+ *
+ * @return NULL if there is no such node or pointer to the leaf node.
+ */
+ofw_tree_node_t *ofw_tree_lookup(const char *path)
+{
+	char buf[NAME_BUF_LEN+1];
+	ofw_tree_node_t *node = ofw_root;
+	index_t i, j;
+	
+	if (path[0] != '/')
+		return NULL;
+	
+	for (i = 1; i < strlen(path) && node; i = j + 1) {
+		for (j = i; j < strlen(path) && path[j] != '/'; j++)
+			;
+		if (i == j)	/* skip extra slashes */
+			continue;
+			
+		memcpy(buf, &path[i], j - i);
+		buf[j - i] = '\0';
+		node = ofw_tree_find_child(node, buf);
+	}
+	
+	return node;
+}
+
+/** Recursively print subtree rooted in a node.
+ *
+ * @param node Root of the subtree.
+ * @param path Current path, NULL for the very root of the entire tree.
+ */
+static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path)
+{
+	char p[PATH_MAX_LEN];
+	
+	if (node->parent) {
+		snprintf(p, PATH_MAX_LEN, "%s/%s", path, node->da_name);
+		printf("%s\n", p);
+	} else {
+		snprintf(p, PATH_MAX_LEN, "%s", node->da_name);
+		printf("/\n");
+	}
+
+	if (node->child)
+		ofw_tree_node_print(node->child, p);
+	
+	if (node->peer)
+		ofw_tree_node_print(node->peer, path);
+}
+
+/** Print the structure of the OpenFirmware device tree. */
+void ofw_tree_print(void)
+{
+	ofw_tree_node_print(ofw_root, NULL);
+}
+
 /** @}
  */
