Index: boot/arch/sparc64/loader/Makefile
===================================================================
--- boot/arch/sparc64/loader/Makefile	(revision cfa70adda5479cb3ac144ad8b0e43184319bd909)
+++ boot/arch/sparc64/loader/Makefile	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -52,4 +52,5 @@
 	main.c \
 	../../../generic/printf.c \
+	../../../generic/string.c \
 	../../../genarch/ofw.c \
 	ofwarch.c \
Index: boot/arch/sparc64/loader/main.c
===================================================================
--- boot/arch/sparc64/loader/main.c	(revision cfa70adda5479cb3ac144ad8b0e43184319bd909)
+++ boot/arch/sparc64/loader/main.c	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -67,5 +67,9 @@
 		printf("Error: unable to get keyboard properties\n");
 
+	if (!ofw_cpu(&bootinfo.cpu))
+		printf("Error: unable to get cpu properties\n");
+
 	printf("\nDevice statistics\n");
+	printf(" cpu: %dMHz\n", bootinfo.cpu.clock_frequency/1000000);
 	printf(" memory: %dM\n", bootinfo.memmap.total>>20);
 	printf(" screen at %P, resolution %dx%d, %d bpp (scanline %d bytes)\n", (uintptr_t) bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline);
Index: boot/arch/sparc64/loader/main.h
===================================================================
--- boot/arch/sparc64/loader/main.h	(revision cfa70adda5479cb3ac144ad8b0e43184319bd909)
+++ boot/arch/sparc64/loader/main.h	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -46,8 +46,13 @@
 
 typedef struct {
+	uint32_t clock_frequency;
+} cpu_t;
+
+typedef struct {
 	taskmap_t taskmap;
 	memmap_t memmap;
 	screen_t screen;
 	keyboard_t keyboard;
+	cpu_t cpu;
 } bootinfo_t;
 
Index: boot/arch/sparc64/loader/ofwarch.c
===================================================================
--- boot/arch/sparc64/loader/ofwarch.c	(revision cfa70adda5479cb3ac144ad8b0e43184319bd909)
+++ boot/arch/sparc64/loader/ofwarch.c	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -35,4 +35,6 @@
 #include <ofw.h>
 #include <printf.h>
+#include <string.h>
+#include "main.h"
 
 int bpp2align[] = {
@@ -80,2 +82,30 @@
 	return true;
 }
+
+int ofw_cpu(cpu_t *cpu)
+{
+	char type_name[BUF_SIZE];
+
+	phandle node;
+	node = ofw_get_child_node(ofw_root);
+	if (node == 0 || node == -1) {
+		printf("Could not find any child nodes of the root node.\n");
+		return;
+	}
+	
+	for (; node != 0 && node != -1; node = ofw_get_peer_node(node)) {
+		if (ofw_get_property(node, "device_type", type_name, sizeof(type_name)) > 0) {
+			if (strncmp(type_name, "cpu", 3) == 0) {
+				uint32_t mhz;
+				
+				if (ofw_get_property(node, "clock-frequency", &mhz, sizeof(mhz)) <= 0)
+					continue;
+					
+				cpu->clock_frequency = mhz;
+				return 1;
+			}
+		}
+	};
+
+	return 0;
+}
Index: boot/arch/sparc64/loader/ofwarch.h
===================================================================
--- boot/arch/sparc64/loader/ofwarch.h	(revision cfa70adda5479cb3ac144ad8b0e43184319bd909)
+++ boot/arch/sparc64/loader/ofwarch.h	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -30,4 +30,6 @@
 #define BOOT_sparc64_OFWARCH_H_
 
+#include "main.h"
+
 #define OFW_ADDRESS_CELLS	2
 #define OFW_SIZE_CELLS		2
@@ -35,3 +37,5 @@
 extern int bpp2align[];
 
+extern int ofw_cpu(cpu_t *cpu);
+
 #endif
Index: boot/genarch/ofw.c
===================================================================
--- boot/genarch/ofw.c	(revision cfa70adda5479cb3ac144ad8b0e43184319bd909)
+++ boot/genarch/ofw.c	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -146,4 +146,13 @@
 }
 
+phandle ofw_get_child_node(const phandle node)
+{
+	return ofw_call("child", 1, 1, NULL, node);
+}
+
+phandle ofw_get_peer_node(const phandle node)
+{
+	return ofw_call("peer", 1, 1, NULL, node);
+}
 
 static ihandle ofw_open(const char *name)
Index: boot/genarch/ofw.h
===================================================================
--- boot/genarch/ofw.h	(revision cfa70adda5479cb3ac144ad8b0e43184319bd909)
+++ boot/genarch/ofw.h	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -91,10 +91,20 @@
 extern uintptr_t ofw_cif;
 
+
+extern phandle ofw_chosen;
+extern ihandle ofw_stdout;
+extern phandle ofw_root;
+extern ihandle ofw_mmu;
+extern phandle ofw_memory;
 extern phandle ofw_aliases;
 
 extern void ofw_init(void);
+
 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 phandle ofw_get_child_node(const phandle node);
+extern phandle ofw_get_peer_node(const phandle node);
 extern phandle ofw_find_device(const char *name);
 
Index: boot/generic/gentypes.h
===================================================================
--- boot/generic/gentypes.h	(revision cfa70adda5479cb3ac144ad8b0e43184319bd909)
+++ boot/generic/gentypes.h	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -34,3 +34,5 @@
 #define true 1
 
+typedef unsigned long size_t;
+
 #endif
Index: boot/generic/string.c
===================================================================
--- boot/generic/string.c	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
+++ boot/generic/string.c	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2001-2004 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic	
+ * @{
+ */
+
+#include <string.h>
+
+/**
+ * @file
+ * @brief	String manipulation functions.
+ */
+
+/** Return number of characters in a string.
+ *
+ * @param str NULL terminated string.
+ *
+ * @return Number of characters in str.
+ */
+size_t strlen(const char *str)
+{
+	int i;
+	
+	for (i = 0; str[i]; i++)
+		;
+	
+	return i;
+}
+
+/** Compare two NULL terminated strings
+ *
+ * Do a char-by-char comparison of two NULL terminated strings.
+ * The strings are considered equal iff they consist of the same
+ * characters on the minimum of their lengths and specified maximal
+ * length.
+ *
+ * @param src First string to compare.
+ * @param dst Second string to compare.
+ * @param len Maximal length for comparison.
+ *
+ * @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller.
+ *
+ */
+int strncmp(const char *src, const char *dst, size_t len)
+{
+	int i;
+	
+	i = 0;
+	for (;*src && *dst && i < len;src++,dst++,i++) {
+		if (*src < *dst)
+			return -1;
+		if (*src > *dst)
+			return 1;
+	}
+	if (i == len || *src == *dst)
+		return 0;
+	if (!*src)
+		return -1;
+	return 1;
+}
+
+/** Copy NULL terminated string.
+ *
+ * Copy at most 'len' characters from string 'src' to 'dest'.
+ * If 'src' is shorter than 'len', '\0' is inserted behind the
+ * last copied character.
+ *
+ * @param src Source string.
+ * @param dest Destination buffer.
+ * @param len Size of destination buffer.
+ */
+void strncpy(char *dest, const char *src, size_t len)
+{
+	int i;
+	for (i = 0; i < len; i++) {
+		if (!(dest[i] = src[i]))
+			return;
+	}
+	dest[i-1] = '\0';
+}
+
+/** Convert ascii representation to unative_t
+ *
+ * Supports 0x for hexa & 0 for octal notation.
+ * Does not check for overflows, does not support negative numbers
+ *
+ * @param text Textual representation of number
+ * @return Converted number or 0 if no valid number ofund 
+ */
+unative_t atoi(const char *text)
+{
+	int base = 10;
+	unative_t result = 0;
+
+	if (text[0] == '0' && text[1] == 'x') {
+		base = 16;
+		text += 2;
+	} else if (text[0] == '0')
+		base = 8;
+
+	while (*text) {
+		if (base != 16 && \
+		    ((*text >= 'A' && *text <= 'F' )
+		     || (*text >='a' && *text <='f')))
+			break;
+		if (base == 8 && *text >='8')
+			break;
+
+		if (*text >= '0' && *text <= '9') {
+			result *= base;
+			result += *text - '0';
+		} else if (*text >= 'A' && *text <= 'F') {
+			result *= base;
+			result += *text - 'A' + 10;
+		} else if (*text >= 'a' && *text <= 'f') {
+			result *= base;
+			result += *text - 'a' + 10;
+		} else
+			break;
+		text++;
+	}
+
+	return result;
+}
+
+/** @}
+ */
Index: boot/generic/string.h
===================================================================
--- boot/generic/string.h	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
+++ boot/generic/string.h	(revision 34d9469e3b197174b8bbc9c194e03a69d4ef5c36)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2001-2004 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef BOOT_STRING_H_
+#define BOOT_STRING_H_
+
+#include <types.h>
+
+extern size_t strlen(const char *str);
+extern int strncmp(const char *src, const char *dst, size_t len);
+extern void strncpy(char *dest, const char *src, size_t len);
+extern unative_t atoi(const char *text);
+
+#endif
+
+/** @}
+ */
