Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ HelenOS.config	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -273,5 +273,8 @@
 
 % OpenFirmware tree support
-! [PLATFORM=sparc64] CONFIG_OFW_TREE (y)
+! [PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_OFW_TREE (y)
+
+% OpenFirmware PCI bus support
+! [PLATFORM=sparc64] CONFIG_OFW_PCI (y)
 
 % Multiboot standard support
Index: boot/arch/arm32/loader/asm.h
===================================================================
--- boot/arch/arm32/loader/asm.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/arm32/loader/asm.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -40,13 +40,4 @@
 
 
-/** Copies cnt bytes from dst to src.
- *
- * @param dst Destination address.
- * @param src Source address.
- * @param cnt Count of bytes to be copied.
- */
-#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
-
-
 /** Called when the CPU is switched on.
  *
Index: boot/arch/arm32/loader/main.c
===================================================================
--- boot/arch/arm32/loader/main.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/arm32/loader/main.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -43,4 +43,5 @@
 #include <macros.h>
 #include <string.h>
+#include <memstr.h>
 
 #include "mm.h"
Index: boot/arch/ia64/loader/asm.h
===================================================================
--- boot/arch/ia64/loader/asm.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ia64/loader/asm.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -34,13 +34,10 @@
 #include "main.h"
 
-#define PAGE_WIDTH	14
-#define PAGE_SIZE	(1 << PAGE_WIDTH)
+#define PAGE_WIDTH  14
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
 
-#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
+#define BALLOC_MAX_SIZE  (128 * 1024)
 
 extern void halt(void);
-/*extern void jump_to_kernel(void *entry, uint64_t cfg, bootinfo_t *bootinfo,
-	unsigned int bootinfo_size) __attribute__((noreturn));*/
-
 extern void jump_to_kernel(void *) __attribute__((noreturn));
 
Index: boot/arch/ia64/loader/main.h
===================================================================
--- boot/arch/ia64/loader/main.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ia64/loader/main.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -34,7 +34,5 @@
 
 
-#define CONFIG_INIT_TASKS	32
-
-
+#define CONFIG_INIT_TASKS  32
 
 extern void start(void);
Index: boot/arch/mips32/loader/asm.h
===================================================================
--- boot/arch/mips32/loader/asm.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/mips32/loader/asm.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -33,6 +33,4 @@
 #define PAGE_WIDTH  14
 
-#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
-
 void jump_to_kernel(void *entry, void *bootinfo) __attribute__((noreturn));
 
Index: boot/arch/mips32/loader/main.c
===================================================================
--- boot/arch/mips32/loader/main.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/mips32/loader/main.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -27,9 +27,10 @@
  */
 
-#include "main.h" 
+#include "main.h"
 #include <printf.h>
 #include <align.h>
 #include <macros.h>
 #include <string.h>
+#include <memstr.h>
 #include "msim.h"
 #include "asm.h"
Index: boot/arch/ppc32/loader/Makefile
===================================================================
--- boot/arch/ppc32/loader/Makefile	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/Makefile	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -62,9 +62,11 @@
 SOURCES = \
 	main.c \
-	ofwarch.c \
 	_components.c \
-	../../../genarch/ofw.c \
 	../../../generic/printf.c \
 	../../../generic/string.c \
+	../../../genarch/balloc.c \
+	../../../genarch/ofw.c \
+	../../../genarch/ofw_tree.c \
+	ofwarch.c \
 	asm.S \
 	boot.S
@@ -73,6 +75,6 @@
 	$(KERNELDIR)/kernel.bin \
 	$(USPACEDIR)/srv/ns/ns \
+	$(USPACEDIR)/app/init/init \
 	$(USPACEDIR)/srv/loader/loader \
-	$(USPACEDIR)/app/init/init \
 	$(USPACEDIR)/srv/devmap/devmap \
 	$(USPACEDIR)/srv/bd/rd/rd \
@@ -99,6 +101,6 @@
 	$(USPACEDIR)/app/tester/tester \
 	$(USPACEDIR)/app/trace/trace \
-	$(USPACEDIR)/app/klog/klog \
-	$(USPACEDIR)/app/bdsh/bdsh
+	$(USPACEDIR)/app/bdsh/bdsh \
+	$(USPACEDIR)/app/klog/klog
 
 OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
Index: boot/arch/ppc32/loader/_link.ld.in
===================================================================
--- boot/arch/ppc32/loader/_link.ld.in	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/_link.ld.in	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -19,3 +19,8 @@
 [[COMPONENTS]]
 	}
+	
+	/DISCARD/ : {
+		*(.comment);
+		*(.note*);
+	}
 }
Index: boot/arch/ppc32/loader/asm.S
===================================================================
--- boot/arch/ppc32/loader/asm.S	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/asm.S	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -29,4 +29,5 @@
 #include "asm.h"
 #include "regname.h"
+#include "ofwarch.h"
 
 .macro SMC_COHERENCY addr
@@ -45,6 +46,15 @@
 
 .macro TLB_FLUSH reg
-	tlbie \reg
-	addi \reg, \reg, 0x1000
+	li \reg, 0
+	sync
+	
+	.rept 64
+		tlbie \reg
+		addi \reg, \reg, 0x1000
+	.endr
+	
+	eieio
+	tlbsync
+	sync
 .endm
 
@@ -54,4 +64,5 @@
 .global memcpy
 .global jump_to_kernel
+.global balloc_base
 
 halt:
@@ -62,5 +73,5 @@
 	addi r6, r3, -4
 	addi r4, r4, -4
-	beq	2f
+	beq 2f
 	
 	andi. r0, r6, 3
@@ -69,55 +80,48 @@
 	
 	1:
-	
-	lwz r7, 4(r4)
-	lwzu r8, 8(r4)
-	stw r7, 4(r6)
-	stwu r8, 8(r6)
-	bdnz 1b
-	
-	andi. r5, r5, 7
+		lwz r7, 4(r4)
+		lwzu r8, 8(r4)
+		stw r7, 4(r6)
+		stwu r8, 8(r6)
+		bdnz 1b
+		
+		andi. r5, r5, 7
 	
 	2:
-	
-	cmplwi 0, r5, 4
-	blt 3f
-	
-	lwzu r0, 4(r4)
-	addi r5, r5, -4
-	stwu r0, 4(r6)
+		cmplwi 0, r5, 4
+		blt 3f
+		
+		lwzu r0, 4(r4)
+		addi r5, r5, -4
+		stwu r0, 4(r6)
 	
 	3:
-	
-	cmpwi 0, r5, 0
-	beqlr
-	mtctr r5
-	addi r4, r4, 3
-	addi r6, r6, 3
+		cmpwi 0, r5, 0
+		beqlr
+		mtctr r5
+		addi r4, r4, 3
+		addi r6, r6, 3
 	
 	4:
-	
-	lbzu r0, 1(r4)
-	stbu r0, 1(r6)
-	bdnz 4b
-	blr
+		lbzu r0, 1(r4)
+		stbu r0, 1(r6)
+		bdnz 4b
+		blr
 	
 	5:
-	
-	subfic r0, r0, 4
-	mtctr r0
+		subfic r0, r0, 4
+		mtctr r0
 	
 	6:
-	
-	lbz r7, 4(r4)
-	addi r4, r4, 1
-	stb r7, 4(r6)
-	addi r6, r6, 1
-	bdnz 6b
-	subf r5, r0, r5
-	rlwinm. r7, r5, 32-3, 3, 31
-	beq 2b
-	mtctr r7
-	b 1b
-
+		lbz r7, 4(r4)
+		addi r4, r4, 1
+		stb r7, 4(r6)
+		addi r6, r6, 1
+		bdnz 6b
+		subf r5, r0, r5
+		rlwinm. r7, r5, 32-3, 3, 31
+		beq 2b
+		mtctr r7
+		b 1b
 
 jump_to_kernel:
@@ -128,6 +132,4 @@
 	# r6 = bytes to copy
 	# r7 = real_mode (pa)
-	# r8 = framebuffer (pa)
-	# r9 = scanline
 	
 	# disable interrupts
@@ -153,16 +155,20 @@
 	rfi
 
+.align PAGE_WIDTH
+balloc_base:
+	.fill BALLOC_MAX_SIZE
+
 .section REALMODE, "ax"
+
 .align PAGE_WIDTH
 .global real_mode
-
 real_mode:
 	
 	# copy kernel to proper location
 	#
+	# r3 = bootinfo (pa)
+	# r4 = bootinfo_size
 	# r5 = trans (pa)
 	# r6 = bytes to copy
-	# r8 = framebuffer (pa)
-	# r9 = scanline
 	
 	li r31, PAGE_SIZE >> 2
@@ -343,97 +349,20 @@
 	# flush TLB
 	
-	li r31, 0
-	sync
-	
 	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	TLB_FLUSH r31
-	
-	eieio
-	tlbsync
-	sync
 	
 	# start the kernel
 	#
-	# pc = KERNEL_START_ADDR
+	# pc = PA2KA(BOOT_OFFSET)
 	# r3 = bootinfo (pa)
-	# sprg0 = KA2PA(KERNEL_START_ADDR)
+	# sprg0 = BOOT_OFFSET
 	# sprg3 = physical memory size
 	# sp = 0 (pa)
 	
-	lis r31, KERNEL_START_ADDR@ha
-	addi r31, r31, KERNEL_START_ADDR@l
-	
+	lis r31, PA2KA(BOOT_OFFSET)@ha
+	addi r31, r31, PA2KA(BOOT_OFFSET)@l
 	mtspr srr0, r31
 	
-	subis r31, r31, 0x8000
+	lis r31, BOOT_OFFSET@ha
+	addi r31, r31, BOOT_OFFSET@l
 	mtsprg0 r31
 	
@@ -454,3 +383,5 @@
 .global trans
 trans:
-	.space (TRANS_SIZE * TRANS_ITEM_SIZE)
+	.rept TRANS_SIZE
+	.int 0
+	.endr
Index: boot/arch/ppc32/loader/asm.h
===================================================================
--- boot/arch/ppc32/loader/asm.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/asm.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -30,21 +30,31 @@
 #define BOOT_ppc32_ASM_H_
 
-#define PAGE_SIZE 4096
-#define PAGE_WIDTH 12
+#define PAGE_WIDTH  12
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
 
-#define TRANS_SIZE 1024
-#define TRANS_ITEM_SIZE 4
+#define TRANS_SIZE   1024
+#define BOOT_OFFSET  0x8000
 
-#define KERNEL_START_ADDR 0x80008000
+#define BALLOC_MAX_SIZE  (128 * 1024)
 
 #ifndef __ASM__
 
-#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
+#include "types.h"
+#include "main.h"
+#include "ofwarch.h"
 
-extern void *trans[TRANS_SIZE];
+#define PA2KA(x)  (((uintptr_t) (x)) + 0x80000000)
+
+extern uint8_t balloc_base[BALLOC_MAX_SIZE];
+extern uintptr_t trans[TRANS_SIZE];
 
 extern void halt();
-extern void jump_to_kernel(void *bootinfo, unsigned int bootinfo_size, void *trans, unsigned int kernel_size, void *real_mode, void *fb, unsigned int scanline) __attribute__((noreturn));
+extern void jump_to_kernel(void *bootinfo, unsigned int bootinfo_size,
+    uintptr_t trans[], unsigned int kernel_size, void *real_mode) __attribute__((noreturn));
 extern void real_mode();
+
+#else
+
+#define PA2KA(x)  ((x) + 0x80000000)
 
 #endif
Index: boot/arch/ppc32/loader/main.c
===================================================================
--- boot/arch/ppc32/loader/main.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/main.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -27,21 +27,40 @@
  */
 
-#include "main.h" 
 #include <printf.h>
-#include "asm.h"
-#include "_components.h"
 #include <ofw.h>
 #include <align.h>
 #include <macros.h>
 #include <string.h>
+#include "main.h"
+#include "asm.h"
+#include "_components.h"
 
-#define HEAP_GAP 1024000
+static bootinfo_t bootinfo;
+static component_t components[COMPONENTS];
+static char *release = STRING(RELEASE);
 
-bootinfo_t bootinfo;
+#ifdef REVISION
+	static char *revision = ", revision " STRING(REVISION);
+#else
+	static char *revision = "";
+#endif
 
+#ifdef TIMESTAMP
+	static char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
+#else
+	static char *timestamp = "";
+#endif
+
+/** Print version information. */
+static void version_print(void)
+{
+	printf("HelenOS PPC32 Bootloader\nRelease %s%s%s\n"
+	    "Copyright (c) 2006 HelenOS project\n\n",
+	    release, revision, timestamp);
+}
 
 static void check_align(const void *addr, const char *desc)
 {
-	if ((unsigned int) addr % PAGE_SIZE != 0) {
+	if ((uintptr_t) addr % PAGE_SIZE != 0) {
 		printf("Error: %s not on page boundary, halting.\n", desc);
 		halt();
@@ -49,48 +68,10 @@
 }
 
-
-static void fix_overlap(void *va, void **pa, const char *desc, unsigned int *top)
+static void check_overlap(const void *pa, const char *desc, const uintptr_t top)
 {
-	if ((unsigned int) *pa + PAGE_SIZE < *top) {
-		printf("Warning: %s overlaps kernel physical area\n", desc);
-		
-		void *new_va = (void *) (ALIGN_UP((unsigned int) KERNEL_END + HEAP_GAP, PAGE_SIZE) + *top);
-		void *new_pa = (void *) (HEAP_GAP + *top);
-		*top += PAGE_SIZE;
-		
-		if (ofw_map(new_pa, new_va, PAGE_SIZE, 0) != 0) {
-			printf("Error: Unable to map page aligned memory at %L (physical %L), halting.\n", new_va, new_pa);
-			halt();
-		}
-		
-		if ((unsigned int) new_pa + PAGE_SIZE < KERNEL_SIZE) {
-			printf("Error: %s cannot be relocated, halting.\n", desc);
-			halt();	
-		}
-		
-		printf("Relocating %L -> %L (physical %L -> %L)\n", va, new_va, *pa, new_pa);
-		*pa = new_pa;
-		memcpy(new_va, va, PAGE_SIZE);
+	if ((uintptr_t) pa + PAGE_SIZE < top) {
+		printf("Error: %s overlaps destination physical area\n", desc);
+		halt();
 	}
-}
-
-char *release = STRING(RELEASE);
-
-#ifdef REVISION
-	char *revision = ", revision " STRING(REVISION);
-#else
-	char *revision = "";
-#endif
-
-#ifdef TIMESTAMP
-	char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
-#else
-	char *timestamp = "";
-#endif
-
-/** Print version information. */
-static void version_print(void)
-{
-	printf("HelenOS PPC32 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n\n", release, revision, timestamp);
 }
 
@@ -98,14 +79,5 @@
 {
 	version_print();
-	
-	component_t components[COMPONENTS];
 	init_components(components);
-		
-	unsigned int i;
-	for (i = 0; i < COMPONENTS; i++)
-		check_align(components[i].start, components[i].name);
-	
-	check_align(&real_mode, "bootstrap trampoline");
-	check_align(&trans, "translation table");
 	
 	if (!ofw_memmap(&bootinfo.memmap)) {
@@ -119,32 +91,38 @@
 	}
 	
-	if (!ofw_screen(&bootinfo.screen))
-		printf("Warning: Unable to get screen properties.\n");
+	check_align(&real_mode, "bootstrap trampoline");
+	check_align(trans, "translation table");
+	check_align(balloc_base, "boot allocations");
 	
-	if (!ofw_macio(&bootinfo.macio))
-		printf("Warning: Unable to get macio properties.\n");
+	unsigned int i;
+	for (i = 0; i < COMPONENTS; i++)
+		check_align(components[i].start, components[i].name);
 	
-	printf("Device statistics\n");
+	void *bootinfo_pa = ofw_translate(&bootinfo);
+	void *real_mode_pa = ofw_translate(&real_mode);
+	void *trans_pa = ofw_translate(trans);
+	void *balloc_base_pa = ofw_translate(balloc_base);
 	
-	if (bootinfo.screen.addr)
-		printf(" screen at %L, resolution %dx%d, %d bpp (scanline %d bytes)\n", bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline);
-	
-	if (bootinfo.macio.addr)
-		printf(" macio at %L (size %d bytes)\n", bootinfo.macio.addr, bootinfo.macio.size);
-	
-	void *real_mode_pa = ofw_translate(&real_mode);
-	void *trans_pa = ofw_translate(&trans);
-	void *bootinfo_pa = ofw_translate(&bootinfo);
-	
-	printf("\nMemory statistics (total %d MB)\n", bootinfo.memmap.total >> 20);
+	printf("Memory statistics (total %d MB)\n", bootinfo.memmap.total >> 20);
 	printf(" %L: boot info structure (physical %L)\n", &bootinfo, bootinfo_pa);
 	printf(" %L: bootstrap trampoline (physical %L)\n", &real_mode, real_mode_pa);
-	printf(" %L: translation table (physical %L)\n", &trans, trans_pa);
+	printf(" %L: translation table (physical %L)\n", trans, trans_pa);
+	printf(" %L: boot allocations (physical %L)\n", balloc_base, balloc_base_pa);
 	for (i = 0; i < COMPONENTS; i++)
 		printf(" %L: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size);
 	
-	unsigned int top = 0;
+	uintptr_t top = 0;
 	for (i = 0; i < COMPONENTS; i++)
 		top += ALIGN_UP(components[i].size, PAGE_SIZE);
+	top += ALIGN_UP(BALLOC_MAX_SIZE, PAGE_SIZE);
+	
+	if (top >= TRANS_SIZE * PAGE_SIZE) {
+		printf("Error: boot image is too large\n");
+		halt();
+	}
+	
+	check_overlap(bootinfo_pa, "boot info", top);
+	check_overlap(real_mode_pa, "bootstrap trampoline", top);
+	check_overlap(trans_pa, "translation table", top);
 	
 	unsigned int pages = ALIGN_UP(KERNEL_SIZE, PAGE_SIZE) >> PAGE_WIDTH;
@@ -152,10 +130,15 @@
 	for (i = 0; i < pages; i++) {
 		void *pa = ofw_translate(KERNEL_START + (i << PAGE_WIDTH));
-		fix_overlap(KERNEL_START + (i << PAGE_WIDTH), &pa, "kernel", &top);
-		trans[i] = pa;
+		check_overlap(pa, "kernel", top);
+		trans[i] = (uintptr_t) pa;
 	}
 	
 	bootinfo.taskmap.count = 0;
 	for (i = 1; i < COMPONENTS; i++) {
+		if (bootinfo.taskmap.count == TASKMAP_MAX_RECORDS) {
+			printf("\nSkipping superfluous components.\n");
+			break;
+		}
+		
 		unsigned int component_pages = ALIGN_UP(components[i].size, PAGE_SIZE) >> PAGE_WIDTH;
 		unsigned int j;
@@ -163,12 +146,13 @@
 		for (j = 0; j < component_pages; j++) {
 			void *pa = ofw_translate(components[i].start + (j << PAGE_WIDTH));
-			fix_overlap(components[i].start + (j << PAGE_WIDTH), &pa, components[i].name, &top);
-			trans[pages + j] = pa;
+			check_overlap(pa, components[i].name, top);
+			trans[pages + j] = (uintptr_t) pa;
 			if (j == 0) {
-				bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = (void *) (pages << PAGE_WIDTH);
+				
+				bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = (void *) PA2KA(pages << PAGE_WIDTH);
 				bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size;
 				strncpy(bootinfo.taskmap.tasks[bootinfo.taskmap.count].name,
 				    components[i].name, BOOTINFO_TASK_NAME_BUFLEN);
-
+				
 				bootinfo.taskmap.count++;
 			}
@@ -178,11 +162,22 @@
 	}
 	
-	fix_overlap(&real_mode, &real_mode_pa, "bootstrap trampoline", &top);
-	fix_overlap(&trans, &trans_pa, "translation table", &top);
-	fix_overlap(&bootinfo, &bootinfo_pa, "boot info", &top);
+	uintptr_t balloc_kernel_base = PA2KA(pages << PAGE_WIDTH);
+	unsigned int balloc_pages = ALIGN_UP(BALLOC_MAX_SIZE, PAGE_SIZE) >> PAGE_WIDTH;
+	for (i = 0; i < balloc_pages; i++) {
+		void *pa = ofw_translate(balloc_base + (i << PAGE_WIDTH));
+		check_overlap(pa, "boot allocations", top);
+		trans[pages + i] = (uintptr_t) pa;
+	}
+	
+	pages += balloc_pages;
+	
+	balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base, balloc_kernel_base);
+	printf("\nCanonizing OpenFirmware device tree...");
+	bootinfo.ofw_root = ofw_tree_build();
+	printf("done.\n");
 	
 	ofw_setup_palette();
 	
 	printf("\nBooting the kernel...\n");
-	jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, pages << PAGE_WIDTH, real_mode_pa, (void *) bootinfo.screen.addr, bootinfo.screen.scanline);
+	jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, pages << PAGE_WIDTH, real_mode_pa);
 }
Index: boot/arch/ppc32/loader/main.h
===================================================================
--- boot/arch/ppc32/loader/main.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/main.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -30,23 +30,22 @@
 #define BOOT_ppc32_MAIN_H_
 
-#include "ofw.h"
+#include <ofw.h>
+#include <ofw_tree.h>
+#include <balloc.h>
+#include <types.h>
 
-#define TASKMAP_MAX_RECORDS 32
+#define TASKMAP_MAX_RECORDS  32
 
 /** Size of buffer for storing task name in task_t. */
-#define BOOTINFO_TASK_NAME_BUFLEN 32
+#define BOOTINFO_TASK_NAME_BUFLEN  32
 
-/** Struct holding information about single loaded task. */
 typedef struct {
-	/** Address where the task was placed. */
 	void *addr;
-	/** Size of the task's binary. */
-	unsigned int size;
-	/** Task name. */
+	uint32_t size;
 	char name[BOOTINFO_TASK_NAME_BUFLEN];
 } task_t;
 
 typedef struct {
-	unsigned int count;
+	uint32_t count;
 	task_t tasks[TASKMAP_MAX_RECORDS];
 } taskmap_t;
@@ -55,6 +54,6 @@
 	memmap_t memmap;
 	taskmap_t taskmap;
-	screen_t screen;
-	macio_t macio;
+	ballocs_t ballocs;
+	ofw_tree_node_t *ofw_root;
 } bootinfo_t;
 
@@ -62,5 +61,3 @@
 extern void bootstrap(void);
 
-extern memmap_t memmap;
-
 #endif
Index: boot/arch/ppc32/loader/ofwarch.c
===================================================================
--- boot/arch/ppc32/loader/ofwarch.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/ofwarch.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -31,5 +31,5 @@
 #include <printf.h>
 
-typedef int (* ofw_entry_t)(ofw_args_t *args);
+typedef int (*ofw_entry_t)(ofw_args_t *args);
 
 int ofw(ofw_args_t *args)
@@ -49,28 +49,7 @@
 }
 
-int ofw_macio(macio_t *macio)
-{
-	char device_name[BUF_SIZE];
-	
-	if ((ofw_get_property(ofw_aliases, "macio", device_name, sizeof(device_name)) <= 0)
-	    && (ofw_get_property(ofw_aliases, "mac-io", device_name, sizeof(device_name)) <= 0))
-		return false;
-	
-	phandle device = ofw_find_device(device_name);
-	if (device == -1)
-		return false;
-	
-	pci_reg_t pci_reg;
-	if (ofw_get_property(device, "assigned-addresses", &pci_reg, sizeof(pci_reg)) <= 0)
-		return false;
-	
-	macio->addr = (void *) pci_reg.addr.addr_lo;
-	macio->size = pci_reg.size_lo;
-
-	return true;
-}
-
 int ofw_translate_failed(ofw_arg_t flag)
 {
+	/* PearPC returns buggy flag */
 	return 0;
 }
Index: boot/arch/ppc32/loader/ofwarch.h
===================================================================
--- boot/arch/ppc32/loader/ofwarch.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/ofwarch.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -30,6 +30,6 @@
 #define BOOT_ppc32_OFWARCH_H_
 
-#define OFW_ADDRESS_CELLS	1
-#define OFW_SIZE_CELLS		1
+#define OFW_ADDRESS_CELLS  1
+#define OFW_SIZE_CELLS     1
 
 #endif
Index: boot/arch/ppc32/loader/regname.h
===================================================================
--- boot/arch/ppc32/loader/regname.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/ppc32/loader/regname.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -31,193 +31,196 @@
 
 /* Condition Register Bit Fields */
-#define	cr0	0
-#define	cr1	1
-#define	cr2	2
-#define	cr3	3
-#define	cr4	4
-#define	cr5	5
-#define	cr6	6
-#define	cr7	7
+#define cr0  0
+#define cr1  1
+#define cr2  2
+#define cr3  3
+#define cr4  4
+#define cr5  5
+#define cr6  6
+#define cr7  7
 
 /* General Purpose Registers (GPRs) */
-#define	r0	0
-#define	r1	1
-#define	r2	2
-#define	r3	3
-#define	r4	4
-#define	r5	5
-#define	r6	6
-#define	r7	7
-#define	r8	8
-#define	r9	9
-#define	r10	10
-#define	r11	11
-#define	r12	12
-#define	r13	13
-#define	r14	14
-#define	r15	15
-#define	r16	16
-#define	r17	17
-#define	r18	18
-#define	r19	19
-#define	r20	20
-#define	r21	21
-#define	r22	22
-#define	r23	23
-#define	r24	24
-#define	r25	25
-#define	r26	26
-#define	r27	27
-#define	r28	28
-#define	r29	29
-#define	r30	30
-#define	r31	31
+#define r0   0
+#define r1   1
+#define r2   2
+#define r3   3
+#define r4   4
+#define r5   5
+#define r6   6
+#define r7   7
+#define r8   8
+#define r9   9
+#define r10  10
+#define r11  11
+#define r12  12
+#define r13  13
+#define r14  14
+#define r15  15
+#define r16  16
+#define r17  17
+#define r18  18
+#define r19  19
+#define r20  20
+#define r21  21
+#define r22  22
+#define r23  23
+#define r24  24
+#define r25  25
+#define r26  26
+#define r27  27
+#define r28  28
+#define r29  29
+#define r30  30
+#define r31  31
 
 /* GPR Aliases */
-#define	sp	1
+#define sp  1
 
 /* Floating Point Registers (FPRs) */
-#define	fr0		0
-#define	fr1		1
-#define	fr2		2
-#define	fr3		3
-#define	fr4		4
-#define	fr5		5
-#define	fr6		6
-#define	fr7		7
-#define	fr8		8
-#define	fr9		9
-#define	fr10	10
-#define	fr11	11
-#define	fr12	12
-#define	fr13	13
-#define	fr14	14
-#define	fr15	15
-#define	fr16	16
-#define	fr17	17
-#define	fr18	18
-#define	fr19	19
-#define	fr20	20
-#define	fr21	21
-#define	fr22	22
-#define	fr23	23
-#define	fr24	24
-#define	fr25	25
-#define	fr26	26
-#define	fr27	27
-#define	fr28	28
-#define	fr29	29
-#define	fr30	30
-#define	fr31	31
-
-#define	vr0		0
-#define	vr1		1
-#define	vr2		2
-#define	vr3		3
-#define	vr4		4
-#define	vr5		5
-#define	vr6		6
-#define	vr7		7
-#define	vr8		8
-#define	vr9		9
-#define	vr10	10
-#define	vr11	11
-#define	vr12	12
-#define	vr13	13
-#define	vr14	14
-#define	vr15	15
-#define	vr16	16
-#define	vr17	17
-#define	vr18	18
-#define	vr19	19
-#define	vr20	20
-#define	vr21	21
-#define	vr22	22
-#define	vr23	23
-#define	vr24	24
-#define	vr25	25
-#define	vr26	26
-#define	vr27	27
-#define	vr28	28
-#define	vr29	29
-#define	vr30	30
-#define	vr31	31
-
-#define	evr0	0
-#define	evr1	1
-#define	evr2	2
-#define	evr3	3
-#define	evr4	4
-#define	evr5	5
-#define	evr6	6
-#define	evr7	7
-#define	evr8	8
-#define	evr9	9
-#define	evr10	10
-#define	evr11	11
-#define	evr12	12
-#define	evr13	13
-#define	evr14	14
-#define	evr15	15
-#define	evr16	16
-#define	evr17	17
-#define	evr18	18
-#define	evr19	19
-#define	evr20	20
-#define	evr21	21
-#define	evr22	22
-#define	evr23	23
-#define	evr24	24
-#define	evr25	25
-#define	evr26	26
-#define	evr27	27
-#define	evr28	28
-#define	evr29	29
-#define	evr30	30
-#define	evr31	31
+#define fr0   0
+#define fr1   1
+#define fr2   2
+#define fr3   3
+#define fr4   4
+#define fr5   5
+#define fr6   6
+#define fr7   7
+#define fr8   8
+#define fr9   9
+#define fr10  10
+#define fr11  11
+#define fr12  12
+#define fr13  13
+#define fr14  14
+#define fr15  15
+#define fr16  16
+#define fr17  17
+#define fr18  18
+#define fr19  19
+#define fr20  20
+#define fr21  21
+#define fr22  22
+#define fr23  23
+#define fr24  24
+#define fr25  25
+#define fr26  26
+#define fr27  27
+#define fr28  28
+#define fr29  29
+#define fr30  30
+#define fr31  31
+
+#define vr0   0
+#define vr1   1
+#define vr2   2
+#define vr3   3
+#define vr4   4
+#define vr5   5
+#define vr6   6
+#define vr7   7
+#define vr8   8
+#define vr9   9
+#define vr10  10
+#define vr11  11
+#define vr12  12
+#define vr13  13
+#define vr14  14
+#define vr15  15
+#define vr16  16
+#define vr17  17
+#define vr18  18
+#define vr19  19
+#define vr20  20
+#define vr21  21
+#define vr22  22
+#define vr23  23
+#define vr24  24
+#define vr25  25
+#define vr26  26
+#define vr27  27
+#define vr28  28
+#define vr29  29
+#define vr30  30
+#define vr31  31
+
+#define evr0   0
+#define evr1   1
+#define evr2   2
+#define evr3   3
+#define evr4   4
+#define evr5   5
+#define evr6   6
+#define evr7   7
+#define evr8   8
+#define evr9   9
+#define evr10  10
+#define evr11  11
+#define evr12  12
+#define evr13  13
+#define evr14  14
+#define evr15  15
+#define evr16  16
+#define evr17  17
+#define evr18  18
+#define evr19  19
+#define evr20  20
+#define evr21  21
+#define evr22  22
+#define evr23  23
+#define evr24  24
+#define evr25  25
+#define evr26  26
+#define evr27  27
+#define evr28  28
+#define evr29  29
+#define evr30  30
+#define evr31  31
 
 /* Special Purpose Registers (SPRs) */
-#define	xer		1
-#define lr		8
-#define ctr		9
-#define	dec		22
-#define	sdr1	25
-#define	srr0	26
-#define srr1	27
-#define	sprg0	272
-#define	sprg1	273
-#define	sprg2	274
-#define	sprg3	275
-#define	prv		287
-#define ibat0u	528
-#define ibat0l	529
-#define ibat1u	530
-#define ibat1l	531
-#define ibat2u	532
-#define ibat2l	533
-#define ibat3u	534
-#define ibat3l	535
-#define dbat0u	536
-#define dbat0l	537
-#define dbat1u	538
-#define dbat1l	539
-#define dbat2u	540
-#define dbat2l	541
-#define dbat3u	542
-#define dbat3l	543
-#define hid0	1008
+#define xer      1
+#define lr       8
+#define ctr      9
+#define dec      22
+#define sdr1     25
+#define srr0     26
+#define srr1     27
+#define sprg0    272
+#define sprg1    273
+#define sprg2    274
+#define sprg3    275
+#define prv      287
+#define ibat0u   528
+#define ibat0l   529
+#define ibat1u   530
+#define ibat1l   531
+#define ibat2u   532
+#define ibat2l   533
+#define ibat3u   534
+#define ibat3l   535
+#define dbat0u   536
+#define dbat0l   537
+#define dbat1u   538
+#define dbat1l   539
+#define dbat2u   540
+#define dbat2l   541
+#define dbat3u   542
+#define dbat3l   543
+#define tlbmiss  980
+#define ptehi    981
+#define ptelo    982
+#define hid0     1008
 
 /* MSR bits */
-#define msr_dr	(1 << 4)
-#define msr_ir	(1 << 5)
-#define msr_pr	(1 << 14)
-#define msr_ee	(1 << 15)
+#define msr_dr  (1 << 4)
+#define msr_ir  (1 << 5)
+#define msr_pr  (1 << 14)
+#define msr_ee  (1 << 15)
 
 /* HID0 bits */
-#define hid0_sten	(1 << 24)
-#define hid0_ice	(1 << 15)
-#define hid0_dce	(1 << 14)
-#define hid0_icfi	(1 << 11)
-#define hid0_dci	(1 << 10)
+#define hid0_sten  (1 << 24)
+#define hid0_ice   (1 << 15)
+#define hid0_dce   (1 << 14)
+#define hid0_icfi  (1 << 11)
+#define hid0_dci   (1 << 10)
 
 #endif
Index: boot/arch/sparc64/loader/asm.S
===================================================================
--- boot/arch/sparc64/loader/asm.S	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/asm.S	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -31,6 +31,6 @@
 #include <register.h>
 
-.register       %g2, #scratch
-.register       %g3, #scratch
+.register %g2, #scratch
+.register %g3, #scratch
 
 .text
@@ -43,60 +43,67 @@
 	ba %xcc, halt
 	nop
+
+memcpy:
+	mov %o0, %o3      ! save dst
+	add %o1, 7, %g1
+	and %g1, -8, %g1
+	cmp %o1, %g1
+	be,pn %xcc, 3f
+	add %o0, 7, %g1
+	mov 0, %g3
 	
-memcpy:
-	mov	%o0, %o3		! save dst
-	add	%o1, 7, %g1
-	and	%g1, -8, %g1
-	cmp	%o1, %g1
-	be,pn	%xcc, 3f
-	add	%o0, 7, %g1
-	mov	0, %g3
-0:
-	brz,pn	%o2, 2f
-	mov	0, %g2
-1:
-	ldub	[%g3 + %o1], %g1
-	add	%g2, 1, %g2
-	cmp	%o2, %g2
-	stb	%g1, [%g3 + %o0]
-	bne,pt	%xcc, 1b
-	mov	%g2, %g3
-2:
-	jmp	%o7 + 8			! exit point
-	mov	%o3, %o0
-3:
-	and	%g1, -8, %g1
-	cmp	%o0, %g1
-	bne,pt	%xcc, 0b
-	mov	0, %g3
-	srlx	%o2, 3, %g4
-	brz,pn	%g4, 5f
-	mov	0, %g5
-4:
-	sllx	%g3, 3, %g2
-	add	%g5, 1, %g3
-	ldx	[%o1 + %g2], %g1
-	mov	%g3, %g5
-	cmp	%g4, %g3
-	bne,pt	%xcc, 4b
-	stx	%g1, [%o0 + %g2]
-5:
-	and	%o2, 7, %o2
-	brz,pn	%o2, 2b
-	sllx	%g4, 3, %g1
-	mov	0, %g2
-	add	%g1, %o0, %o0
-	add	%g1, %o1, %g4
-	mov	0, %g3
-6:
-	ldub	[%g2 + %g4], %g1
-	stb	%g1, [%g2 + %o0]
-	add	%g3, 1, %g2
-	cmp	%o2, %g2
-	bne,pt	%xcc, 6b
-	mov	%g2, %g3
-
-	jmp	%o7 + 8			! exit point
-	mov	%o3, %o0
+	0:
+		brz,pn %o2, 2f
+		mov 0, %g2
+	
+	1:
+		ldub [%g3 + %o1], %g1
+		add %g2, 1, %g2
+		cmp %o2, %g2
+		stb %g1, [%g3 + %o0]
+		bne,pt %xcc, 1b
+		mov %g2, %g3
+	
+	2:
+		jmp %o7 + 8   ! exit point
+		mov %o3, %o0
+	
+	3:
+		and %g1, -8, %g1
+		cmp %o0, %g1
+		bne,pt %xcc, 0b
+		mov 0, %g3
+		srlx %o2, 3, %g4
+		brz,pn %g4, 5f
+		mov 0, %g5
+	
+	4:
+		sllx %g3, 3, %g2
+		add %g5, 1, %g3
+		ldx [%o1 + %g2], %g1
+		mov %g3, %g5
+		cmp %g4, %g3
+		bne,pt %xcc, 4b
+		stx %g1, [%o0 + %g2]
+	
+	5:
+		and %o2, 7, %o2
+		brz,pn %o2, 2b
+		sllx %g4, 3, %g1
+		mov 0, %g2
+		add %g1, %o0, %o0
+		add %g1, %o1, %g4
+		mov 0, %g3
+	
+	6:
+		ldub [%g2 + %g4], %g1
+		stb %g1, [%g2 + %o0]
+		add %g3, 1, %g2
+		cmp %o2, %g2
+		bne,pt %xcc, 6b
+		mov %g2, %g3
+	
+	jmp %o7 + 8   ! exit point
+	mov %o3, %o0
 
 jump_to_kernel:
@@ -107,51 +114,55 @@
 	 * 3. Flush instruction pipeline.
 	 */
-
+	
 	/*
 	 * US3 processors have a write-invalidate cache, so explicitly
 	 * invalidating it is not required. Whether to invalidate I-cache
-	 * or not is decided according to the value of the global
-	 * "subarchitecture" variable (set in the bootstrap).
+	 * or not is decided according to the value of the 5th argument
+	 * (subarchitecture).
 	 */
-	set subarchitecture, %g2
-	ldub [%g2], %g2
-	cmp %g2, 3
+	cmp %i4, 3
 	be %xcc, 1f
 	nop
-0:
-	call icache_flush
-	nop
-1:
-	membar #StoreStore
+	
+	0:
+		call icache_flush
+		nop
+	
+	1:
+		membar #StoreStore
 	
 	/*
 	 * Flush the instruction pipeline.
 	 */
-	flush	%i7
-
+	flush %i7
+	
 	mov %o0, %l1
 	mov %o1, %o0
 	mov %o2, %o1
 	mov %o3, %o2
-	jmp %l1				! jump to kernel
+	jmp %l1       ! jump to kernel
 	nop
 
-#define ICACHE_SIZE		8192
-#define ICACHE_LINE_SIZE	32
-#define ICACHE_SET_BIT		(1 << 13)
-#define ASI_ICACHE_TAG		0x67
+#define ICACHE_SIZE       8192
+#define ICACHE_LINE_SIZE  32
+#define ICACHE_SET_BIT    (1 << 13)
+#define ASI_ICACHE_TAG    0x67
 
 # Flush I-cache
 icache_flush:
-	set	((ICACHE_SIZE - ICACHE_LINE_SIZE) | ICACHE_SET_BIT), %g1
-	stxa	%g0, [%g1] ASI_ICACHE_TAG
-0:	membar	#Sync
-	subcc	%g1, ICACHE_LINE_SIZE, %g1
-	bnz,pt	%xcc, 0b
-	stxa	%g0, [%g1] ASI_ICACHE_TAG
-	membar	#Sync
+	set ((ICACHE_SIZE - ICACHE_LINE_SIZE) | ICACHE_SET_BIT), %g1
+	stxa %g0, [%g1] ASI_ICACHE_TAG
+	
+	0:
+		membar #Sync
+		subcc %g1, ICACHE_LINE_SIZE, %g1
+		bnz,pt %xcc, 0b
+	
+	stxa %g0, [%g1] ASI_ICACHE_TAG
+	membar #Sync
 	retl
 	! SF Erratum #51
 	nop
+
 .global ofw
 ofw:
@@ -159,14 +170,14 @@
 	set ofw_cif, %l0
 	ldx [%l0], %l0
-
+	
 	rdpr  %pstate, %l1
 	and  %l1, ~PSTATE_AM_BIT, %l2
 	wrpr  %l2, 0, %pstate
-    
+	
 	jmpl %l0, %o7
 	mov %i0, %o0
-
+	
 	wrpr %l1, 0, %pstate
-
+	
 	ret
 	restore %o0, 0, %o0
Index: boot/arch/sparc64/loader/asm.h
===================================================================
--- boot/arch/sparc64/loader/asm.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/asm.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -34,12 +34,12 @@
 #include "main.h"
 
-#define PAGE_WIDTH	14
-#define PAGE_SIZE	(1 << PAGE_WIDTH)
+#define PAGE_WIDTH  14
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
 
-#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
+#define BALLOC_MAX_SIZE  (128 * 1024)
 
 extern void halt(void);
 extern void jump_to_kernel(void *entry, uint64_t cfg, bootinfo_t *bootinfo,
-	unsigned int bootinfo_size) __attribute__((noreturn));
+    unsigned int bootinfo_size, uint8_t subarchitecture) __attribute__((noreturn));
 
 #endif
Index: boot/arch/sparc64/loader/boot.S
===================================================================
--- boot/arch/sparc64/loader/boot.S	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/boot.S	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -31,7 +31,7 @@
 #include <register.h>
 
-#define INITIAL_STACK_SIZE 	8192
+#define INITIAL_STACK_SIZE  8192
 
-#define NWINDOWS		8
+#define NWINDOWS  8
 
 .register %g2, #scratch
@@ -57,7 +57,9 @@
 	.half 0
 	.half 0
+
 .global silo_ramdisk_image
 silo_ramdisk_image:
 	.word 0
+
 .global silo_ramdisk_size
 silo_ramdisk_size:
@@ -65,5 +67,5 @@
 
 .align 8
-1:	
+1:
 	/*
 	 * Disable interrupts and disable address masking.
@@ -71,15 +73,15 @@
 	wrpr %g0, PSTATE_PRIV_BIT, %pstate
 	
-	wrpr %g0, NWINDOWS - 2, %cansave	! set maximum saveable windows
-	wrpr %g0, 0, %canrestore		! get rid of windows we will never need again
-	wrpr %g0, 0, %otherwin			! make sure the window state is consistent
-	wrpr %g0, NWINDOWS - 1, %cleanwin	! prevent needless clean_window traps for kernel
-
+	wrpr %g0, NWINDOWS - 2, %cansave   ! set maximum saveable windows
+	wrpr %g0, 0, %canrestore           ! get rid of windows we will never need again
+	wrpr %g0, 0, %otherwin             ! make sure the window state is consistent
+	wrpr %g0, NWINDOWS - 1, %cleanwin  ! prevent needless clean_window traps for kernel
+	
 	set initial_stack_top, %sp
 	add %sp, -STACK_BIAS, %sp
-
+	
 	set ofw_cif, %l0
- 
-	call ofw_init		! initialize OpenFirmware
+	
+	call ofw_init   ! initialize OpenFirmware
 	stx %o4, [%l0]
 	
@@ -90,4 +92,5 @@
 initial_stack:
 	.space INITIAL_STACK_SIZE
+
 initial_stack_top:
 	.space STACK_WINDOW_SAVE_AREA_SIZE
Index: boot/arch/sparc64/loader/main.c
===================================================================
--- boot/arch/sparc64/loader/main.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/main.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -1,5 +1,5 @@
 /*
  * Copyright (c) 2005 Martin Decky
- * Copyright (c) 2006 Jakub Jermar 
+ * Copyright (c) 2006 Jakub Jermar
  * All rights reserved.
  *
@@ -28,5 +28,5 @@
  */
 
-#include "main.h" 
+#include "main.h"
 #include <printf.h>
 #include "asm.h"
@@ -39,25 +39,24 @@
 #include <macros.h>
 #include <string.h>
-
-bootinfo_t bootinfo;
-
-component_t components[COMPONENTS];
-
-char *release = STRING(RELEASE);
+#include <memstr.h>
+
+static bootinfo_t bootinfo;
+static component_t components[COMPONENTS];
+static char *release = STRING(RELEASE);
 
 #ifdef REVISION
-	char *revision = ", revision " STRING(REVISION);
+	static char *revision = ", revision " STRING(REVISION);
 #else
-	char *revision = "";
+	static char *revision = "";
 #endif
 
 #ifdef TIMESTAMP
-	char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
+	static char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
 #else
-	char *timestamp = "";
+	static char *timestamp = "";
 #endif
 
 /** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
-uint8_t subarchitecture;
+static uint8_t subarchitecture;
 
 /**
@@ -65,5 +64,5 @@
  * MID_SHIFT bits to the right
  */
-uint16_t mid_mask;
+static uint16_t mid_mask;
 
 /** Print version information. */
@@ -76,11 +75,11 @@
 
 /* the lowest ID (read from the VER register) of some US3 CPU model */
-#define FIRST_US3_CPU 	0x14
+#define FIRST_US3_CPU  0x14
 
 /* the greatest ID (read from the VER register) of some US3 CPU model */
-#define LAST_US3_CPU 	0x19
+#define LAST_US3_CPU   0x19
 
 /* UltraSPARC IIIi processor implementation code */
-#define US_IIIi_CODE	0x15
+#define US_IIIi_CODE   0x15
 
 /**
@@ -91,5 +90,8 @@
 {
 	uint64_t v;
-	asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
+	asm volatile (
+		"rdpr %%ver, %0\n"
+		: "=r" (v)
+	);
 	
 	v = (v << 16) >> 48;
@@ -103,7 +105,6 @@
 		subarchitecture = SUBARCH_US;
 		mid_mask = (1 << 5) - 1;
-	} else {
+	} else
 		printf("\nThis CPU is not supported by HelenOS.");
-	}
 }
 
@@ -113,26 +114,27 @@
 	void *balloc_base;
 	unsigned int top = 0;
-	int i, j;
-
+	unsigned int i;
+	unsigned int j;
+	
 	version_print();
 	
 	detect_subarchitecture();
 	init_components(components);
-
+	
 	if (!ofw_get_physmem_start(&bootinfo.physmem_start)) {
 		printf("Error: unable to get start of physical memory.\n");
 		halt();
 	}
-
+	
 	if (!ofw_memmap(&bootinfo.memmap)) {
 		printf("Error: unable to get memory map, halting.\n");
 		halt();
 	}
-
+	
 	if (bootinfo.memmap.total == 0) {
 		printf("Error: no memory detected, halting.\n");
 		halt();
 	}
-
+	
 	/*
 	 * SILO for some reason adds 0x400000 and subtracts
@@ -143,19 +145,17 @@
 		silo_ramdisk_image += bootinfo.physmem_start;
 		silo_ramdisk_image -= 0x400000;
-		/* Install 1:1 mapping for the ramdisk. */
-		if (ofw_map((void *)((uintptr_t) silo_ramdisk_image),
-		    (void *)((uintptr_t) silo_ramdisk_image),
+		
+		/* Install 1:1 mapping for the RAM disk. */
+		if (ofw_map((void *) ((uintptr_t) silo_ramdisk_image),
+		    (void *) ((uintptr_t) silo_ramdisk_image),
 		    silo_ramdisk_size, -1) != 0) {
-			printf("Failed to map ramdisk.\n");
+			printf("Failed to map RAM disk.\n");
 			halt();
 		}
 	}
 	
-	printf("\nSystem info\n");
-	printf(" memory: %dM starting at %P\n",
+	printf("\nMemory statistics (total %d MB, starting at %P)\n",
 	    bootinfo.memmap.total >> 20, bootinfo.physmem_start);
-
-	printf("\nMemory statistics\n");
-	printf(" kernel entry point at %P\n", KERNEL_VIRTUAL_ADDRESS);
+	printf(" %P: kernel entry point\n", KERNEL_VIRTUAL_ADDRESS);
 	printf(" %P: boot info structure\n", &bootinfo);
 	
@@ -176,4 +176,5 @@
 				break;
 			}
+			
 			bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr =
 			    base + top;
@@ -187,13 +188,15 @@
 		top += components[i].size;
 	}
-
-	j = bootinfo.taskmap.count - 1;	/* do not consider ramdisk */
-
+	
+	/* Do not consider RAM disk */
+	j = bootinfo.taskmap.count - 1;
+	
 	if (silo_ramdisk_image) {
-		/* Treat the ramdisk as the last bootinfo task. */
+		/* Treat the RAM disk as the last bootinfo task. */
 		if (bootinfo.taskmap.count == TASKMAP_MAX_RECORDS) {
-			printf("Skipping ramdisk.\n");
+			printf("Skipping RAM disk.\n");
 			goto skip_ramdisk;
 		}
+		
 		top = ALIGN_UP(top, PAGE_SIZE);
 		bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = 
@@ -202,5 +205,6 @@
 		    silo_ramdisk_size;
 		bootinfo.taskmap.count++;
-		printf("\nCopying ramdisk...");
+		printf("\nCopying RAM disk...");
+		
 		/*
 		 * Claim and map the whole ramdisk as it may exceed the area
@@ -210,11 +214,12 @@
 		(void) ofw_map(bootinfo.physmem_start + base + top, base + top,
 		    silo_ramdisk_size, -1);
-		memmove(base + top, (void *)((uintptr_t)silo_ramdisk_image),
+		memmove(base + top, (void *) ((uintptr_t) silo_ramdisk_image),
 		    silo_ramdisk_size);
+		
 		printf("done.\n");
 		top += silo_ramdisk_size;
 	}
 skip_ramdisk:
-
+	
 	/*
 	 * Now we can proceed to copy the components. We do it in reverse order
@@ -222,8 +227,8 @@
 	 * with base.
 	 */
-	printf("\nCopying bootinfo tasks\n");
+	printf("\nCopying tasks...");
 	for (i = COMPONENTS - 1; i > 0; i--, j--) {
-		printf(" %s...", components[i].name);
-
+		printf("%s ", components[i].name);
+		
 		/*
 		 * At this point, we claim the physical memory that we are
@@ -240,10 +245,11 @@
 		    bootinfo.taskmap.tasks[j].addr,
 		    ALIGN_UP(components[i].size, PAGE_SIZE));
-		    
-		memcpy((void *)bootinfo.taskmap.tasks[j].addr,
+		
+		memcpy((void *) bootinfo.taskmap.tasks[j].addr,
 		    components[i].start, components[i].size);
-		printf("done.\n");
-	}
-
+		
+	}
+	printf(".\n");
+	
 	printf("\nCopying kernel...");
 	(void) ofw_claim_phys(bootinfo.physmem_start + base,
@@ -251,5 +257,5 @@
 	memcpy(base, components[0].start, components[0].size);
 	printf("done.\n");
-
+	
 	/*
 	 * Claim and map the physical memory for the boot allocator.
@@ -261,22 +267,23 @@
 	(void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
 	    BALLOC_MAX_SIZE, -1);
-	balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base);
-
+	balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
+	    (uintptr_t) balloc_base);
+	
 	printf("\nCanonizing OpenFirmware device tree...");
 	bootinfo.ofw_root = ofw_tree_build();
 	printf("done.\n");
-
+	
 #ifdef CONFIG_AP
 	printf("\nChecking for secondary processors...");
-	if (!ofw_cpu())
+	if (!ofw_cpu(mid_mask, bootinfo.physmem_start))
 		printf("Error: unable to get CPU properties\n");
 	printf("done.\n");
 #endif
-
+	
 	ofw_setup_palette();
-
+	
 	printf("\nBooting the kernel...\n");
 	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS,
 	    bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo,
-	    sizeof(bootinfo));
+	    sizeof(bootinfo), subarchitecture);
 }
Index: boot/arch/sparc64/loader/main.h
===================================================================
--- boot/arch/sparc64/loader/main.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/main.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -35,16 +35,16 @@
 #include <types.h>
 
-#define KERNEL_VIRTUAL_ADDRESS 0x400000
+#define KERNEL_VIRTUAL_ADDRESS  0x400000
 
-#define TASKMAP_MAX_RECORDS 32
+#define TASKMAP_MAX_RECORDS  32
 
 /** Size of buffer for storing task name in task_t. */
-#define BOOTINFO_TASK_NAME_BUFLEN 32
+#define BOOTINFO_TASK_NAME_BUFLEN  32
 
-#define BSP_PROCESSOR	1
-#define AP_PROCESSOR	0
+#define BSP_PROCESSOR  1
+#define AP_PROCESSOR   0
 
-#define SUBARCH_US	1
-#define SUBARCH_US3	3
+#define SUBARCH_US   1
+#define SUBARCH_US3  3
 
 typedef struct {
@@ -70,6 +70,4 @@
 extern uint32_t silo_ramdisk_size;
 
-extern bootinfo_t bootinfo;
-
 extern void start(void);
 extern void bootstrap(void);
Index: boot/arch/sparc64/loader/ofwarch.c
===================================================================
--- boot/arch/sparc64/loader/ofwarch.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/ofwarch.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -30,5 +30,5 @@
 /**
  * @file
- * @brief	Architecture dependent parts of OpenFirmware interface.
+ * @brief Architecture dependent parts of OpenFirmware interface.
  */
 
@@ -40,8 +40,4 @@
 #include "main.h"
 #include "asm.h"
-
-/* these tho variables will be set by the detect_subarchitecture function */
-extern uint8_t subarchitecture;
-extern uint16_t mid_mask;
 
 void write(const char *str, const int len)
@@ -65,18 +61,23 @@
  * except for the current CPU.
  *
- * @param child		The first child of the OFW tree node whose children
- * 			represent CPUs to be woken up.
- * @param current_mid	MID of the current CPU, the current CPU will
- *			(of course) not be woken up.
- * @return		Number of CPUs which have the same parent node as
- * 			"child".
+ * @param child         The first child of the OFW tree node whose children
+ *                      represent CPUs to be woken up.
+ * @param current_mid   MID of the current CPU, the current CPU will
+ *                      (of course) not be woken up.
+ * @param physmem_start Starting address of the physical memory.
+ *
+ * @return Number of CPUs which have the same parent node as
+ *         "child".
+ *
  */
-static int wake_cpus_in_node(phandle child, uint64_t current_mid)
+static int wake_cpus_in_node(phandle child, uint64_t current_mid,
+    uintptr_t physmem_start)
 {
 	int cpus;
-	char type_name[BUF_SIZE];
 	
-	for (cpus = 0; child != 0 && child != -1;
+	for (cpus = 0; (child != 0) && (child != -1);
 	    child = ofw_get_peer_node(child), cpus++) {
+		char type_name[BUF_SIZE];
+		
 		if (ofw_get_property(child, "device_type", type_name,
 		    sizeof(type_name)) > 0) {
@@ -88,13 +89,9 @@
 				 * "cpuid" for US-IV
 				 */
-				if (ofw_get_property(
-				    child, "upa-portid",
-				    &mid, sizeof(mid)) <= 0
-				    && ofw_get_property(child, "portid",
-				    &mid, sizeof(mid)) <= 0
-				    && ofw_get_property(child, "cpuid",
-				    &mid, sizeof(mid)) <= 0)
+				if ((ofw_get_property(child, "upa-portid", &mid, sizeof(mid)) <= 0)
+				    && (ofw_get_property(child, "portid", &mid, sizeof(mid)) <= 0)
+				    && (ofw_get_property(child, "cpuid", &mid, sizeof(mid)) <= 0))
 					continue;
-					
+				
 				if (current_mid != mid) {
 					/*
@@ -103,11 +100,10 @@
 					(void) ofw_call("SUNW,start-cpu", 3, 1,
 					    NULL, child, KERNEL_VIRTUAL_ADDRESS,
-					    bootinfo.physmem_start |
-					    AP_PROCESSOR);
+					    physmem_start | AP_PROCESSOR);
 				}
 			}
 		}
 	}
-
+	
 	return cpus;
 }
@@ -116,39 +112,35 @@
  * Finds out the current CPU's MID and wakes up all AP processors.
  */
-int ofw_cpu(void)
+int ofw_cpu(uint16_t mid_mask, uintptr_t physmem_start)
 {
-	int cpus;
-	phandle node;
-	phandle subnode;
-	phandle cpus_parent;
-	phandle cmp;
-	char name[BUF_SIZE];
-
-	/* get the current CPU MID */
+	/* Get the current CPU MID */
 	uint64_t current_mid;
 	
-	asm volatile ("ldxa [%1] %2, %0\n"
-	    : "=r" (current_mid)
-	    : "r" (0), "i" (ASI_ICBUS_CONFIG));
+	asm volatile (
+		"ldxa [%1] %2, %0\n"
+		: "=r" (current_mid)
+		: "r" (0), "i" (ASI_ICBUS_CONFIG)
+	);
+	
 	current_mid >>= ICBUS_CONFIG_MID_SHIFT;
-
 	current_mid &= mid_mask;
-
-	/* wake up CPUs */
 	
-	cpus_parent = ofw_find_device("/ssm@0,0");
-	if (cpus_parent == 0 || cpus_parent == -1) {
+	/* Wake up the CPUs */
+	
+	phandle cpus_parent = ofw_find_device("/ssm@0,0");
+	if ((cpus_parent == 0) || (cpus_parent == -1))
 		cpus_parent = ofw_find_device("/");
-	}
-
-	node = ofw_get_child_node(cpus_parent);
-	cpus = wake_cpus_in_node(node, current_mid);
-	while (node != 0 && node != -1) {
+	
+	phandle node = ofw_get_child_node(cpus_parent);
+	int cpus = wake_cpus_in_node(node, current_mid, physmem_start);
+	while ((node != 0) && (node != -1)) {
+		char name[BUF_SIZE];
+		
 		if (ofw_get_property(node, "name", name,
-			sizeof(name)) > 0) {
+		    sizeof(name)) > 0) {
 			if (strcmp(name, "cmp") == 0) {
-				subnode = ofw_get_child_node(node);
+				phandle subnode = ofw_get_child_node(node);
 				cpus += wake_cpus_in_node(subnode,
-					current_mid);
+					current_mid, physmem_start);
 			}
 		}
@@ -157,23 +149,21 @@
 	
 	return cpus;
-	
 }
 
 /** Get physical memory starting address.
  *
- * @param start		Pointer to variable where the physical memory starting
- *			address will be stored.
+ * @param start Pointer to variable where the physical memory starting
+ *              address will be stored.
  *
- * @return		Non-zero on succes, zero on failure.
+ * @return Non-zero on succes, zero on failure.
+ *
  */
 int ofw_get_physmem_start(uintptr_t *start)
 {
 	uint32_t memreg[4];
-
 	if (ofw_get_property(ofw_memory, "reg", &memreg, sizeof(memreg)) <= 0)
 		return 0;
-
+	
 	*start = (((uint64_t) memreg[0]) << 32) | memreg[1];
 	return 1;
 }
-
Index: boot/arch/sparc64/loader/ofwarch.h
===================================================================
--- boot/arch/sparc64/loader/ofwarch.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/ofwarch.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -33,9 +33,9 @@
 #include "types.h"
 
-#define OFW_ADDRESS_CELLS	2
-#define OFW_SIZE_CELLS		2
+#define OFW_ADDRESS_CELLS  2
+#define OFW_SIZE_CELLS     2
 
-extern int ofw_cpu(void);
-extern int ofw_get_physmem_start(uintptr_t *start); 
+extern int ofw_cpu(uint16_t mid_mask, uintptr_t physmem_start);
+extern int ofw_get_physmem_start(uintptr_t *start);
 
 #endif
Index: boot/arch/sparc64/loader/register.h
===================================================================
--- boot/arch/sparc64/loader/register.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/register.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -30,10 +30,10 @@
 #define BOOT_sparc64_REGISTER_H_
 
-#define PSTATE_IE_BIT   2
-#define PSTATE_PRIV_BIT	4
-#define PSTATE_AM_BIT   8
+#define PSTATE_IE_BIT    2
+#define PSTATE_PRIV_BIT  4
+#define PSTATE_AM_BIT    8
 
-#define ASI_ICBUS_CONFIG		0x4a
-#define ICBUS_CONFIG_MID_SHIFT		17
+#define ASI_ICBUS_CONFIG        0x4a
+#define ICBUS_CONFIG_MID_SHIFT  17
 
 #endif
Index: boot/arch/sparc64/loader/stack.h
===================================================================
--- boot/arch/sparc64/loader/stack.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/arch/sparc64/loader/stack.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -30,7 +30,7 @@
 #define BOOT_sparc64_STACK_H_
 
-#define STACK_ALIGNMENT			16
-#define STACK_BIAS			2047
-#define STACK_WINDOW_SAVE_AREA_SIZE	(16*8)
+#define STACK_ALIGNMENT              16
+#define STACK_BIAS                   2047
+#define STACK_WINDOW_SAVE_AREA_SIZE  (16 * 8)
 
 #endif
Index: boot/genarch/balloc.c
===================================================================
--- boot/genarch/balloc.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/genarch/balloc.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -28,13 +28,16 @@
 
 #include <balloc.h>
+#include <asm.h>
 #include <types.h>
 #include <align.h>
 
 static ballocs_t *ballocs;
+static uintptr_t phys_base;
 
-void balloc_init(ballocs_t *b, uintptr_t base)
+void balloc_init(ballocs_t *ball, uintptr_t base, uintptr_t kernel_base)
 {
-	ballocs = b;
-	ballocs->base = base;
+	ballocs = ball;
+	phys_base = base;
+	ballocs->base = kernel_base;
 	ballocs->size = 0;
 }
@@ -42,16 +45,19 @@
 void *balloc(size_t size, size_t alignment)
 {
-	uintptr_t addr;
-
 	/* Enforce minimal alignment. */
 	alignment = ALIGN_UP(alignment, 4);
 	
-	addr = ballocs->base + ALIGN_UP(ballocs->size, alignment);
-
+	uintptr_t addr = phys_base + ALIGN_UP(ballocs->size, alignment);
+	
 	if (ALIGN_UP(ballocs->size, alignment) + size > BALLOC_MAX_SIZE)
 		return NULL;
-		
+	
 	ballocs->size = ALIGN_UP(ballocs->size, alignment) + size;
 	
 	return (void *) addr;
 }
+
+void *balloc_rebase(void *ptr)
+{
+	return (void *) ((uintptr_t) ptr - phys_base + ballocs->base);
+}
Index: boot/genarch/balloc.h
===================================================================
--- boot/genarch/balloc.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/genarch/balloc.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -32,6 +32,4 @@
 #include <types.h>
 
-#define BALLOC_MAX_SIZE		(128 * 1024)
-
 typedef struct {
 	uintptr_t base;
@@ -39,6 +37,7 @@
 } ballocs_t;
 
-extern void balloc_init(ballocs_t *b, uintptr_t base);
+extern void balloc_init(ballocs_t *ball, uintptr_t base, uintptr_t kernel_base);
 extern void *balloc(size_t size, size_t alignment);
+extern void *balloc_rebase(void *ptr);
 
 #endif
Index: boot/genarch/ofw.c
===================================================================
--- boot/genarch/ofw.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/genarch/ofw.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -33,4 +33,9 @@
 #include <types.h>
 
+#define RED(i)    (((i) >> 5) & ((1 << 3) - 1))
+#define GREEN(i)  (((i) >> 3) & ((1 << 2) - 1))
+#define BLUE(i)   ((i) & ((1 << 3) - 1))
+#define CLIP(i)   ((i) <= 255 ? (i) : 255)
+
 uintptr_t ofw_cif;
 
@@ -85,12 +90,13 @@
 /** Perform a call to OpenFirmware client interface.
  *
- * @param service	String identifying the service requested.
- * @param nargs		Number of input arguments.
- * @param nret		Number of output arguments. This includes the return
- * 			value.
- * @param rets		Buffer for output arguments or NULL. The buffer must
- * 			accommodate nret - 1 items.
- *
- * @return		Return value returned by the client interface.
+ * @param service String identifying the service requested.
+ * @param nargs   Number of input arguments.
+ * @param nret    Number of output arguments. This includes the return
+ *                value.
+ * @param rets    Buffer for output arguments or NULL. The buffer must
+ *                accommodate nret - 1 items.
+ *
+ * @return Return value returned by the client interface.
+ *
  */
 unsigned long
@@ -221,5 +227,5 @@
 }
 
-void *ofw_claim_virt(const void *virt, const int len)
+void *ofw_claim_virt(const void *virt, const unsigned int len)
 {
 	ofw_arg_t retaddr;
@@ -234,41 +240,54 @@
 }
 
-void *ofw_claim_phys(const void *phys, const int len)
-{
-	ofw_arg_t retaddr[2];
-	int shift;
-
+static void *ofw_claim_phys_internal(const void *phys, const unsigned int len, const unsigned int alignment)
+{
+	/*
+	 * Note that the return value check will help
+	 * us to discover conflicts between OpenFirmware
+	 * allocations and our use of physical memory.
+	 * It is better to detect collisions here
+	 * than to cope with weird errors later.
+	 *
+	 * So this is really not to make the loader
+	 * more generic; it is here for debugging
+	 * purposes.
+	 */
+	
 	if (sizeof(unative_t) == 8) {
-		shift = 32;
+		ofw_arg_t retaddr[2];
+		int shift = 32;
+		
 		if (ofw_call("call-method", 6, 3, retaddr, "claim",
-		    ofw_memory_prop, 0, len, ((uintptr_t) phys) >> shift,
+		    ofw_memory_prop, alignment, len, ((uintptr_t) phys) >> shift,
 		    ((uintptr_t) phys) & ((uint32_t) -1)) != 0) {
-			/*
-			 * Note that this will help us to discover
-			 * conflicts between OpenFirmware allocations
-			 * and our use of physical memory.
-			 * It is better to detect collisions here
-			 * than to cope with weird errors later.
-			 *
-			 * So this is really not to make the loader
-			 * more generic; it is here for debugging
-			 * purposes.
-			 */
 			puts("Error: memory method claim() failed, halting.\n");
 			halt();
 		}
+		
+		return (void *) ((retaddr[0] << shift) | retaddr[1]);
 	} else {
-		shift = 0;
-		/*
-		 * FIXME: the number of arguments is probably different...
-		 */
-		puts("Error: 32-bit ofw_claim_phys not implemented.\n");
-		halt();
-	}
-
-	return (void *) ((retaddr[0] << shift) | retaddr[1]);
-}
-
-int ofw_map(const void *phys, const void *virt, const int size, const int mode)
+		ofw_arg_t retaddr[1];
+		
+		if (ofw_call("call-method", 5, 2, retaddr, "claim",
+		    ofw_memory_prop, alignment, len, (uintptr_t) phys) != 0) {
+			puts("Error: memory method claim() failed, halting.\n");
+			halt();
+		}
+		
+		return (void *) retaddr[0];
+	}
+}
+
+void *ofw_claim_phys(const void *phys, const unsigned int len)
+{
+	return ofw_claim_phys_internal(phys, len, 0);
+}
+
+void *ofw_claim_phys_any(const unsigned int len, const unsigned int alignment)
+{
+	return ofw_claim_phys_internal(NULL, len, alignment);
+}
+
+int ofw_map(const void *phys, const void *virt, const unsigned int size, const int mode)
 {
 	uintptr_t phys_hi, phys_lo;
@@ -314,9 +333,9 @@
 
 		/*
- 		 * This is a hot fix of the issue which occurs on machines
- 		 * where there are holes in the physical memory (such as
- 		 * SunBlade 1500). Should we detect a hole in the physical
- 		 * memory, we will ignore any memory detected behind
- 		 * the hole and pretend the hole does not exist.
+		 * This is a hot fix of the issue which occurs on machines
+		 * where there are holes in the physical memory (such as
+		 * SunBlade 1500). Should we detect a hole in the physical
+		 * memory, we will ignore any memory detected behind
+		 * the hole and pretend the hole does not exist.
 		 */
 		if ((map->count > 0) && (map->zones[map->count - 1].start +
@@ -335,48 +354,4 @@
 }
 
-int ofw_screen(screen_t *screen)
-{
-	char device_name[BUF_SIZE];
-	uint32_t virtaddr;
-	
-	if (ofw_get_property(ofw_aliases, "screen", device_name,
-	    sizeof(device_name)) <= 0)
-		return false;
-	
-	phandle device = ofw_find_device(device_name);
-	if (device == -1)
-		return false;
-	
-	if (ofw_get_property(device, "address", &virtaddr,
-	    sizeof(virtaddr)) <= 0)
-		return false;
-
-	screen->addr = (void *) ((uintptr_t) virtaddr);
-
-	if (ofw_get_property(device, "width", &screen->width,
-	    sizeof(screen->width)) <= 0)
-		return false;
-	
-	if (ofw_get_property(device, "height", &screen->height,
-	    sizeof(screen->height)) <= 0)
-		return false;
-	
-	if (ofw_get_property(device, "depth", &screen->bpp,
-	    sizeof(screen->bpp)) <= 0)
-		return false;
-	
-	if (ofw_get_property(device, "linebytes", &screen->scanline,
-	    sizeof(screen->scanline)) <= 0)
-		return false;
-	
-	return true;
-}
-
-#define RED(i)    (((i) >> 5) & ((1 << 3) - 1))
-#define GREEN(i)  (((i) >> 3) & ((1 << 2) - 1))
-#define BLUE(i)   ((i) & ((1 << 3) - 1))
-#define CLIP(i)   ((i) <= 255 ? (i) : 255)
-
-
 /**
  * Sets up the palette for the 8-bit color depth configuration so that the
@@ -392,10 +367,10 @@
 	char device_name[BUF_SIZE];
 	
-	/* resolve alias */
+	/* Resolve alias */
 	if (ofw_get_property(ofw_aliases, "screen", device_name,
 	    sizeof(device_name)) <= 0)
 		return false;
 	
-	/* for depth greater than 8 it makes no sense to set up the palette */
+	/* For depth greater than 8 it makes no sense to set up the palette */
 	uint32_t depth;
 	phandle device = ofw_find_device(device_name);
@@ -407,10 +382,10 @@
 		return false;
 	
-	/* required in order to be able to make a method call */
+	/* Required in order to be able to make a method call */
 	ihandle screen = ofw_open(device_name);
 	if (screen == -1)
 		return false;
 	
-	/* setup the palette so that the (inverted) 3:2:3 scheme is usable */
+	/* Setup the palette so that the (inverted) 3:2:3 scheme is usable */
 	unsigned int i;
 	for (i = 0; i < 256; i++)
Index: boot/genarch/ofw.h
===================================================================
--- boot/genarch/ofw.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/genarch/ofw.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -33,9 +33,9 @@
 #include <stdarg.h>
 
-#define BUF_SIZE		1024
+#define BUF_SIZE  1024
 
-#define MEMMAP_MAX_RECORDS 	32
+#define MEMMAP_MAX_RECORDS  32
 
-#define MAX_OFW_ARGS            12
+#define MAX_OFW_ARGS  12
 
 typedef unative_t ofw_arg_t;
@@ -47,8 +47,8 @@
  */
 typedef struct {
-	ofw_arg_t service;		/**< Command name. */
-	ofw_arg_t nargs;		/**< Number of in arguments. */
-	ofw_arg_t nret;			/**< Number of out arguments. */
-	ofw_arg_t args[MAX_OFW_ARGS];	/**< List of arguments. */
+	ofw_arg_t service;             /**< Command name. */
+	ofw_arg_t nargs;               /**< Number of in arguments. */
+	ofw_arg_t nret;                /**< Number of out arguments. */
+	ofw_arg_t args[MAX_OFW_ARGS];  /**< List of arguments. */
 } ofw_args_t;
 
@@ -63,17 +63,4 @@
 	memzone_t zones[MEMMAP_MAX_RECORDS];
 } memmap_t;
-
-typedef struct {
-	void *addr;
-	uint32_t width;
-	uint32_t height;
-	uint32_t bpp;
-	uint32_t scanline;
-} screen_t;
-
-typedef struct {
-	void *addr;
-	uint32_t size;
-} macio_t;
 
 typedef struct {
@@ -118,10 +105,9 @@
 extern void *ofw_translate(const void *virt);
 extern int ofw_translate_failed(ofw_arg_t flag);
-extern void *ofw_claim_virt(const void *virt, const int len);
-extern void *ofw_claim_phys(const void *virt, const int len);
-extern int ofw_map(const void *phys, const void *virt, const int size, const int mode);
+extern void *ofw_claim_virt(const void *virt, const unsigned int len);
+extern void *ofw_claim_phys(const void *virt, const unsigned int len);
+extern void *ofw_claim_phys_any(const unsigned int len, const unsigned int alignment);
+extern int ofw_map(const void *phys, const void *virt, const unsigned int size, const int mode);
 extern int ofw_memmap(memmap_t *map);
-extern int ofw_screen(screen_t *screen);
-extern int ofw_macio(macio_t *macio);
 extern int ofw_setup_palette(void);
 extern void ofw_quiesce(void);
Index: boot/genarch/ofw_tree.c
===================================================================
--- boot/genarch/ofw_tree.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/genarch/ofw_tree.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -29,10 +29,12 @@
 #include <ofw_tree.h>
 #include <ofw.h>
+#include <ofwarch.h>
 #include <types.h>
 #include <string.h>
 #include <balloc.h>
 #include <asm.h>
-
-#define MAX_PATH_LEN	256
+#include <memstr.h>
+
+#define MAX_PATH_LEN  256
 
 static ofw_tree_node_t *ofw_tree_node_alloc(void)
@@ -49,6 +51,4 @@
 static void *ofw_tree_space_alloc(size_t size)
 {
-	char *addr;
-
 	/*
 	 * What we do here is a nasty hack :-)
@@ -61,7 +61,8 @@
 	 * behind the requested memory.
 	 */
-	addr = balloc(size + 1, size);
+	char *addr = balloc(size + 1, size);
 	if (addr)
 		addr[size] = '\0';
+	
 	return addr;
 }
@@ -75,26 +76,19 @@
  * order to prevent stack from overflowing.
  *
- * @param current_node	Pointer to uninitialized ofw_tree_node structure that
- * 			will become the memory represenation of 'current'.
- * @param parent_node	Parent ofw_tree_node structure or NULL in case of root
- * 			node.
- * @param current	OpenFirmware phandle to the current device tree node.
+ * @param current_node Pointer to uninitialized ofw_tree_node structure that
+ *                     will become the memory represenation of 'current'.
+ * @param parent_node  Parent ofw_tree_node structure or NULL in case of root
+ *                     node.
+ * @param current      OpenFirmware phandle to the current device tree node.
+ *
  */
 static void ofw_tree_node_process(ofw_tree_node_t *current_node,
     ofw_tree_node_t *parent_node, phandle current)
 {
-	static char path[MAX_PATH_LEN + 1];
-	static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
-	static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];
-	phandle peer;
-	phandle child;
-	size_t len;
-	int i;
-
 	while (current_node) {
 		/*
 		 * Initialize node.
 		 */
-		current_node->parent = parent_node;
+		current_node->parent = (ofw_tree_node_t *) balloc_rebase(parent_node);
 		current_node->peer = NULL;
 		current_node->child = NULL;
@@ -103,45 +97,51 @@
 		current_node->property = NULL;
 		current_node->device = NULL;
-	
+		
 		/*
 		 * Get the disambigued name.
 		 */
-		len = ofw_package_to_path(current, path, MAX_PATH_LEN);
+		static char path[MAX_PATH_LEN + 1];
+		size_t 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 '/' */
-	
+		
+		/* Find last slash */
+		int i;
+		for (i = len - 1; (i >= 0) && (path[i] != '/'); i--);
+		
+		/* Do not include the slash */
+		i++;
 		len -= i;
-
-		/* add space for trailing '\0' */
-		current_node->da_name = ofw_tree_space_alloc(len + 1);
-		if (!current_node->da_name)
-			return;
-	
-		memcpy(current_node->da_name, &path[i], len);
-		current_node->da_name[len] = '\0';
-	
+		
+		/* Add space for trailing '\0' */
+		char *da_name = ofw_tree_space_alloc(len + 1);
+		if (!da_name)
+			return;
+		
+		memcpy(da_name, &path[i], len);
+		da_name[len] = '\0';
+		current_node->da_name = (char *) balloc_rebase(da_name);
+		
 		/*
 		 * Recursively process the potential child node.
 		 */
-		child = ofw_get_child_node(current);
-		if (child != 0 && child != -1) {
-			ofw_tree_node_t *child_node;
-		
-			child_node = ofw_tree_node_alloc();
+		phandle child = ofw_get_child_node(current);
+		if ((child != 0) && (child != -1)) {
+			ofw_tree_node_t *child_node = ofw_tree_node_alloc();
 			if (child_node) {
 				ofw_tree_node_process(child_node, current_node,
 				    child);
-				current_node->child = child_node;
+				current_node->child =
+				    (ofw_tree_node_t *) balloc_rebase(child_node);
 			}
 		}
-	
+		
 		/*
 		 * Count properties.
 		 */
+		static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
+		static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];
 		name[0] = '\0';
 		while (ofw_next_property(current, name, name2) == 1) {
@@ -149,50 +149,46 @@
 			memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
 		}
-
+		
 		if (!current_node->properties)
 			return;
-	
+		
 		/*
 		 * Copy properties.
 		 */
-		current_node->property =
+		ofw_tree_property_t *property =
 		    ofw_tree_properties_alloc(current_node->properties);
-		if (!current_node->property)
+		if (!property)
 			return;
 		
 		name[0] = '\0';
 		for (i = 0; ofw_next_property(current, name, name2) == 1; i++) {
-			size_t size;
-		
 			if (i == current_node->properties)
 				break;
-		
+			
 			memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
-			memcpy(current_node->property[i].name, name,
-			    OFW_TREE_PROPERTY_MAX_NAMELEN);
-			current_node->property[i].name[
-			    OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0';
-
-			size = ofw_get_proplen(current, name);
-			current_node->property[i].size = size;
+			memcpy(property[i].name, name, OFW_TREE_PROPERTY_MAX_NAMELEN);
+			property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0';
+			
+			size_t size = ofw_get_proplen(current, name);
+			property[i].size = size;
+			
 			if (size) {
-				void *buf;
-			
-				buf = ofw_tree_space_alloc(size);
-				if (current_node->property[i].value = buf) {
+				void *buf = ofw_tree_space_alloc(size);
+				if (buf) {
 					/*
 					 * Copy property value to memory node.
 					 */
-					(void) ofw_get_property(current, name,
-					    buf, size);
+					(void) ofw_get_property(current, name, buf, size);
+					property[i].value = balloc_rebase(buf);
 				}
-			} else {
-				current_node->property[i].value = NULL;
-			}
-		}
-
+			} else
+				property[i].value = NULL;
+		}
+		
 		/* Just in case we ran out of memory. */
 		current_node->properties = i;
-
+		current_node->property = (ofw_tree_property_t *) balloc_rebase(property);
+		
+		
 		/*
 		 * Iteratively process the next peer node.
@@ -202,11 +198,9 @@
 		 * risk of overflowing the stack is too real.
 		 */
-		peer = ofw_get_peer_node(current);
-		if (peer != 0 && peer != -1) {
-			ofw_tree_node_t *peer_node;
-		
-			peer_node = ofw_tree_node_alloc();
-			if (peer_node) { 
-				current_node->peer = peer_node;
+		phandle peer = ofw_get_peer_node(current);
+		if ((peer != 0) && (peer != -1)) {
+			ofw_tree_node_t *peer_node = ofw_tree_node_alloc();
+			if (peer_node) {
+				current_node->peer = (ofw_tree_node_t *) balloc_rebase(peer_node);
 				current_node = peer_node;
 				current = peer;
@@ -217,4 +211,5 @@
 			}
 		}
+		
 		/*
 		 * No more peers on this level.
@@ -226,16 +221,13 @@
 /** Construct memory representation of OpenFirmware device tree.
  *
- * @return		NULL on failure or pointer to the root node.
+ * @return NULL on failure or kernel pointer to the root node.
+ *
  */
 ofw_tree_node_t *ofw_tree_build(void)
 {
-	ofw_tree_node_t *root;
-	phandle ssm_node;
-	ofw_tree_node_t *ssm;
-	
-	root = ofw_tree_node_alloc();
+	ofw_tree_node_t *root = ofw_tree_node_alloc();
 	if (root)
 		ofw_tree_node_process(root, NULL, ofw_root);
-
+	
 	/*
 	 * The firmware client interface does not automatically include the
@@ -243,15 +235,15 @@
 	 * solution is to explicitly stick "ssm" to the OFW tree.
 	 */
-	ssm_node = ofw_find_device("/ssm@0,0");
+	phandle ssm_node = ofw_find_device("/ssm@0,0");
 	if (ssm_node != -1) {
-		ssm = ofw_tree_node_alloc();
+		ofw_tree_node_t *ssm = ofw_tree_node_alloc();
 		if (ssm) {
 			ofw_tree_node_process(ssm, root,
 			    ofw_find_device("/ssm@0,0"));
 			ssm->peer = root->child;
-			root->child = ssm;
+			root->child = (ofw_tree_node_t *) balloc_rebase(ssm);
 		}
 	}
 	
-	return root;
-}
+	return (ofw_tree_node_t *) balloc_rebase(root);
+}
Index: boot/genarch/ofw_tree.h
===================================================================
--- boot/genarch/ofw_tree.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/genarch/ofw_tree.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -33,31 +33,28 @@
 #include <ofw.h>
 
-#define OFW_TREE_PROPERTY_MAX_NAMELEN	32
-
-typedef struct ofw_tree_node ofw_tree_node_t;
-typedef struct ofw_tree_property ofw_tree_property_t;
-
-/** Memory representation of OpenFirmware device tree node. */
-struct ofw_tree_node {
-	ofw_tree_node_t *parent;
-	ofw_tree_node_t *peer;
-	ofw_tree_node_t *child;
-
-	uint32_t node_handle;			/**< Old OpenFirmware node handle. */
-
-	char *da_name;				/**< Disambigued name. */
-
-	unsigned properties;			/**< Number of properties. */
-	ofw_tree_property_t *property;
-	
-	void *device;				/**< Member used solely by the kernel. */
-};
+#define OFW_TREE_PROPERTY_MAX_NAMELEN  32
 
 /** Memory representation of OpenFirmware device tree node property. */
-struct ofw_tree_property {
+typedef struct {
 	char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
 	size_t size;
 	void *value;
-};
+} ofw_tree_property_t;
+
+/** Memory representation of OpenFirmware device tree node. */
+typedef struct ofw_tree_node {
+	struct ofw_tree_node *parent;
+	struct ofw_tree_node *peer;
+	struct ofw_tree_node *child;
+	
+	uint32_t node_handle;           /**< Old OpenFirmware node handle. */
+	
+	char *da_name;                  /**< Disambigued name. */
+	
+	unsigned int properties;        /**< Number of properties. */
+	ofw_tree_property_t *property;
+	
+	void *device;                   /**< Member used solely by the kernel. */
+} ofw_tree_node_t;
 
 extern ofw_tree_node_t *ofw_tree_build(void);
Index: boot/generic/memstr.h
===================================================================
--- boot/generic/memstr.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
+++ boot/generic/memstr.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2009 Martin Decky
+ * 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_MEMSTR_H_
+#define BOOT_MEMSTR_H_
+
+extern void memcpy(void *dst, const void *src, unsigned int cnt);
+
+#endif
+
+/** @}
+ */
Index: boot/generic/printf.c
===================================================================
--- boot/generic/printf.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/generic/printf.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
Index: boot/generic/printf.h
===================================================================
--- boot/generic/printf.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/generic/printf.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
Index: boot/generic/stdarg.h
===================================================================
--- boot/generic/stdarg.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ boot/generic/stdarg.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -38,7 +38,7 @@
 typedef __builtin_va_list va_list;
 
-#define va_start(ap, last)              __builtin_va_start(ap, last)
-#define va_arg(ap, type)                __builtin_va_arg(ap, type)
-#define va_end(ap)                      __builtin_va_end(ap)
+#define va_start(ap, last)   __builtin_va_start(ap, last)
+#define va_arg(ap, type)     __builtin_va_arg(ap, type)
+#define va_end(ap)           __builtin_va_end(ap)
 
 #endif
Index: kernel/arch/ia64/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -129,5 +129,5 @@
 	
 	outdev_initialize("skiout", &skiout, &skiout_ops);
-	stdout = &skiout;
+	stdout_wire(&skiout);
 	
 	sysinfo_set_item_val("fb", NULL, false);
Index: kernel/arch/ppc32/include/asm/regname.h
===================================================================
--- kernel/arch/ppc32/include/asm/regname.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/ppc32/include/asm/regname.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32	
+/** @addtogroup ppc32
  * @{
  */
@@ -37,196 +37,196 @@
 
 /* Condition Register Bit Fields */
-#define	cr0	0
-#define	cr1	1
-#define	cr2	2
-#define	cr3	3
-#define	cr4	4
-#define	cr5	5
-#define	cr6	6
-#define	cr7	7
+#define cr0  0
+#define cr1  1
+#define cr2  2
+#define cr3  3
+#define cr4  4
+#define cr5  5
+#define cr6  6
+#define cr7  7
 
 /* General Purpose Registers (GPRs) */
-#define	r0	0
-#define	r1	1
-#define	r2	2
-#define	r3	3
-#define	r4	4
-#define	r5	5
-#define	r6	6
-#define	r7	7
-#define	r8	8
-#define	r9	9
-#define	r10	10
-#define	r11	11
-#define	r12	12
-#define	r13	13
-#define	r14	14
-#define	r15	15
-#define	r16	16
-#define	r17	17
-#define	r18	18
-#define	r19	19
-#define	r20	20
-#define	r21	21
-#define	r22	22
-#define	r23	23
-#define	r24	24
-#define	r25	25
-#define	r26	26
-#define	r27	27
-#define	r28	28
-#define	r29	29
-#define	r30	30
-#define	r31	31
+#define r0   0
+#define r1   1
+#define r2   2
+#define r3   3
+#define r4   4
+#define r5   5
+#define r6   6
+#define r7   7
+#define r8   8
+#define r9   9
+#define r10  10
+#define r11  11
+#define r12  12
+#define r13  13
+#define r14  14
+#define r15  15
+#define r16  16
+#define r17  17
+#define r18  18
+#define r19  19
+#define r20  20
+#define r21  21
+#define r22  22
+#define r23  23
+#define r24  24
+#define r25  25
+#define r26  26
+#define r27  27
+#define r28  28
+#define r29  29
+#define r30  30
+#define r31  31
 
 /* GPR Aliases */
-#define	sp	1
+#define sp  1
 
 /* Floating Point Registers (FPRs) */
-#define	fr0		0
-#define	fr1		1
-#define	fr2		2
-#define	fr3		3
-#define	fr4		4
-#define	fr5		5
-#define	fr6		6
-#define	fr7		7
-#define	fr8		8
-#define	fr9		9
-#define	fr10	10
-#define	fr11	11
-#define	fr12	12
-#define	fr13	13
-#define	fr14	14
-#define	fr15	15
-#define	fr16	16
-#define	fr17	17
-#define	fr18	18
-#define	fr19	19
-#define	fr20	20
-#define	fr21	21
-#define	fr22	22
-#define	fr23	23
-#define	fr24	24
-#define	fr25	25
-#define	fr26	26
-#define	fr27	27
-#define	fr28	28
-#define	fr29	29
-#define	fr30	30
-#define	fr31	31
-
-#define	vr0		0
-#define	vr1		1
-#define	vr2		2
-#define	vr3		3
-#define	vr4		4
-#define	vr5		5
-#define	vr6		6
-#define	vr7		7
-#define	vr8		8
-#define	vr9		9
-#define	vr10	10
-#define	vr11	11
-#define	vr12	12
-#define	vr13	13
-#define	vr14	14
-#define	vr15	15
-#define	vr16	16
-#define	vr17	17
-#define	vr18	18
-#define	vr19	19
-#define	vr20	20
-#define	vr21	21
-#define	vr22	22
-#define	vr23	23
-#define	vr24	24
-#define	vr25	25
-#define	vr26	26
-#define	vr27	27
-#define	vr28	28
-#define	vr29	29
-#define	vr30	30
-#define	vr31	31
-
-#define	evr0	0
-#define	evr1	1
-#define	evr2	2
-#define	evr3	3
-#define	evr4	4
-#define	evr5	5
-#define	evr6	6
-#define	evr7	7
-#define	evr8	8
-#define	evr9	9
-#define	evr10	10
-#define	evr11	11
-#define	evr12	12
-#define	evr13	13
-#define	evr14	14
-#define	evr15	15
-#define	evr16	16
-#define	evr17	17
-#define	evr18	18
-#define	evr19	19
-#define	evr20	20
-#define	evr21	21
-#define	evr22	22
-#define	evr23	23
-#define	evr24	24
-#define	evr25	25
-#define	evr26	26
-#define	evr27	27
-#define	evr28	28
-#define	evr29	29
-#define	evr30	30
-#define	evr31	31
+#define fr0   0
+#define fr1   1
+#define fr2   2
+#define fr3   3
+#define fr4   4
+#define fr5   5
+#define fr6   6
+#define fr7   7
+#define fr8   8
+#define fr9   9
+#define fr10  10
+#define fr11  11
+#define fr12  12
+#define fr13  13
+#define fr14  14
+#define fr15  15
+#define fr16  16
+#define fr17  17
+#define fr18  18
+#define fr19  19
+#define fr20  20
+#define fr21  21
+#define fr22  22
+#define fr23  23
+#define fr24  24
+#define fr25  25
+#define fr26  26
+#define fr27  27
+#define fr28  28
+#define fr29  29
+#define fr30  30
+#define fr31  31
+
+#define vr0   0
+#define vr1   1
+#define vr2   2
+#define vr3   3
+#define vr4   4
+#define vr5   5
+#define vr6   6
+#define vr7   7
+#define vr8   8
+#define vr9   9
+#define vr10  10
+#define vr11  11
+#define vr12  12
+#define vr13  13
+#define vr14  14
+#define vr15  15
+#define vr16  16
+#define vr17  17
+#define vr18  18
+#define vr19  19
+#define vr20  20
+#define vr21  21
+#define vr22  22
+#define vr23  23
+#define vr24  24
+#define vr25  25
+#define vr26  26
+#define vr27  27
+#define vr28  28
+#define vr29  29
+#define vr30  30
+#define vr31  31
+
+#define evr0   0
+#define evr1   1
+#define evr2   2
+#define evr3   3
+#define evr4   4
+#define evr5   5
+#define evr6   6
+#define evr7   7
+#define evr8   8
+#define evr9   9
+#define evr10  10
+#define evr11  11
+#define evr12  12
+#define evr13  13
+#define evr14  14
+#define evr15  15
+#define evr16  16
+#define evr17  17
+#define evr18  18
+#define evr19  19
+#define evr20  20
+#define evr21  21
+#define evr22  22
+#define evr23  23
+#define evr24  24
+#define evr25  25
+#define evr26  26
+#define evr27  27
+#define evr28  28
+#define evr29  29
+#define evr30  30
+#define evr31  31
 
 /* Special Purpose Registers (SPRs) */
-#define	xer		1
-#define lr		8
-#define ctr		9
-#define	dec		22
-#define	sdr1	25
-#define	srr0	26
-#define srr1	27
-#define	sprg0	272
-#define	sprg1	273
-#define	sprg2	274
-#define	sprg3	275
-#define	prv		287
-#define ibat0u	528
-#define ibat0l	529
-#define ibat1u	530
-#define ibat1l	531
-#define ibat2u	532
-#define ibat2l	533
-#define ibat3u	534
-#define ibat3l	535
-#define dbat0u	536
-#define dbat0l	537
-#define dbat1u	538
-#define dbat1l	539
-#define dbat2u	540
-#define dbat2l	541
-#define dbat3u	542
-#define dbat3l	543
-#define tlbmiss	980
-#define ptehi	981
-#define ptelo	982
-#define hid0	1008
+#define xer      1
+#define lr       8
+#define ctr      9
+#define dec      22
+#define sdr1     25
+#define srr0     26
+#define srr1     27
+#define sprg0    272
+#define sprg1    273
+#define sprg2    274
+#define sprg3    275
+#define prv      287
+#define ibat0u   528
+#define ibat0l   529
+#define ibat1u   530
+#define ibat1l   531
+#define ibat2u   532
+#define ibat2l   533
+#define ibat3u   534
+#define ibat3l   535
+#define dbat0u   536
+#define dbat0l   537
+#define dbat1u   538
+#define dbat1l   539
+#define dbat2u   540
+#define dbat2l   541
+#define dbat3u   542
+#define dbat3l   543
+#define tlbmiss  980
+#define ptehi    981
+#define ptelo    982
+#define hid0     1008
 
 /* MSR bits */
-#define msr_dr	(1 << 4)
-#define msr_ir	(1 << 5)
-#define msr_pr	(1 << 14)
-#define msr_ee	(1 << 15)
+#define msr_dr  (1 << 4)
+#define msr_ir  (1 << 5)
+#define msr_pr  (1 << 14)
+#define msr_ee  (1 << 15)
 
 /* HID0 bits */
-#define hid0_sten	(1 << 24)
-#define hid0_ice	(1 << 15)
-#define hid0_dce	(1 << 14)
-#define hid0_icfi	(1 << 11)
-#define hid0_dci	(1 << 10)
+#define hid0_sten  (1 << 24)
+#define hid0_ice   (1 << 15)
+#define hid0_dce   (1 << 14)
+#define hid0_icfi  (1 << 11)
+#define hid0_dci   (1 << 10)
 
 #endif
Index: kernel/arch/ppc32/include/boot/boot.h
===================================================================
--- kernel/arch/ppc32/include/boot/boot.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/ppc32/include/boot/boot.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -41,12 +41,13 @@
 #define TEMP_STACK_SIZE  0x1000
 
-#define TASKMAP_MAX_RECORDS  32
-#define MEMMAP_MAX_RECORDS   32
+#define TASKMAP_MAX_RECORDS        32
+#define MEMMAP_MAX_RECORDS         32
+#define BOOTINFO_TASK_NAME_BUFLEN  32
 
 #ifndef __ASM__
 
-#define BOOTINFO_TASK_NAME_BUFLEN 32
-
 #include <arch/types.h>
+#include <config.h>
+#include <genarch/ofw/ofw_tree.h>
 
 typedef struct {
@@ -73,21 +74,8 @@
 
 typedef struct {
-	uintptr_t addr;
-	unsigned int width;
-	unsigned int height;
-	unsigned int bpp;
-	unsigned int scanline;
-} screen_t;
-
-typedef struct {
-	uintptr_t addr;
-	unsigned int size;
-} macio_t;
-
-typedef struct {
 	memmap_t memmap;
 	taskmap_t taskmap;
-	screen_t screen;
-	macio_t macio;
+	ballocs_t ballocs;
+	ofw_tree_node_t *ofw_root;
 } bootinfo_t;
 
Index: kernel/arch/ppc32/src/mm/tlb.c
===================================================================
--- kernel/arch/ppc32/src/mm/tlb.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/ppc32/src/mm/tlb.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -45,9 +45,4 @@
 static unsigned int seed = 10;
 static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
-
-
-#define TLB_FLUSH \
-	"tlbie %0\n" \
-	"addi %0, %0, 0x1000\n"
 
 
@@ -451,75 +446,8 @@
 		"sync\n"
 		
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
-		TLB_FLUSH
+		".rept 64\n"
+		"tlbie %0\n"
+		"addi %0, %0, 0x1000\n"
+		".endr\n"
 		
 		"eieio\n"
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/ppc32/src/ppc32.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -41,4 +41,6 @@
 #include <genarch/fb/fb.h>
 #include <genarch/fb/visuals.h>
+#include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/pci.h>
 #include <userspace.h>
 #include <proc/uarg.h>
@@ -49,4 +51,5 @@
 #include <macros.h>
 #include <string.h>
+#include <print.h>
 
 #define IRQ_COUNT  64
@@ -63,9 +66,15 @@
 	
 	for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) {
-		init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr);
+		init.tasks[i].addr = bootinfo.taskmap.tasks[i].addr;
 		init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
 		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
 		    bootinfo.taskmap.tasks[i].name);
 	}
+	
+	/* Copy boot allocations info. */
+	ballocs.base = bootinfo.ballocs.base;
+	ballocs.size = bootinfo.ballocs.size;
+	
+	ofw_tree_init(bootinfo.ofw_root);
 }
 
@@ -74,44 +83,76 @@
 	/* Initialize dispatch table */
 	interrupt_init();
-
+	
 	/* Start decrementer */
 	start_decrementer();
 }
 
+static bool display_register(ofw_tree_node_t *node, void *arg)
+{
+	uintptr_t fb_addr = 0;
+	uint32_t fb_width = 0;
+	uint32_t fb_height = 0;
+	uint32_t fb_scanline = 0;
+	unsigned int visual = VISUAL_UNKNOWN;
+	
+	ofw_tree_property_t *prop = ofw_tree_getprop(node, "address");
+	if ((prop) && (prop->value))
+		fb_addr = *((uintptr_t *) prop->value);
+	
+	prop = ofw_tree_getprop(node, "width");
+	if ((prop) && (prop->value))
+		fb_width = *((uint32_t *) prop->value);
+	
+	prop = ofw_tree_getprop(node, "height");
+	if ((prop) && (prop->value))
+		fb_height = *((uint32_t *) prop->value);
+	
+	prop = ofw_tree_getprop(node, "depth");
+	if ((prop) && (prop->value)) {
+		uint32_t fb_bpp = *((uint32_t *) prop->value);
+		switch (fb_bpp) {
+		case 8:
+			visual = VISUAL_INDIRECT_8;
+			break;
+		case 16:
+			visual = VISUAL_RGB_5_5_5_BE;
+			break;
+		case 24:
+			visual = VISUAL_BGR_8_8_8;
+			break;
+		case 32:
+			visual = VISUAL_RGB_0_8_8_8;
+			break;
+		default:
+			visual = VISUAL_UNKNOWN;
+		}
+	}
+	
+	prop = ofw_tree_getprop(node, "linebytes");
+	if ((prop) && (prop->value))
+		fb_scanline = *((uint32_t *) prop->value);
+	
+	if ((fb_addr) && (fb_width > 0) && (fb_height > 0)
+	    && (fb_scanline > 0) && (visual != VISUAL_UNKNOWN)) {
+		fb_properties_t fb_prop = {
+			.addr = fb_addr,
+			.offset = 0,
+			.x = fb_width,
+			.y = fb_height,
+			.scan = fb_scanline,
+			.visual = visual,
+		};
+		fb_init(&fb_prop);
+	}
+	
+	/* Consider only a single device for now */
+	return false;
+}
+
 void arch_post_mm_init(void)
 {
 	if (config.cpu_active == 1) {
-
 #ifdef CONFIG_FB
-		/* Initialize framebuffer */
-		if (bootinfo.screen.addr) {
-			unsigned int visual;
-			
-			switch (bootinfo.screen.bpp) {
-			case 8:
-				visual = VISUAL_INDIRECT_8;
-				break;
-			case 16:
-				visual = VISUAL_RGB_5_5_5_BE;
-				break;
-			case 24:
-				visual = VISUAL_BGR_8_8_8;
-				break;
-			case 32:
-				visual = VISUAL_RGB_0_8_8_8;
-				break;
-			default:
-				panic("Unsupported bits per pixel.");
-			}
-			fb_properties_t prop = {
-				.addr = bootinfo.screen.addr,
-				.offset = 0,
-				.x = bootinfo.screen.width,
-				.y = bootinfo.screen.height,
-				.scan = bootinfo.screen.scanline,
-				.visual = visual,
-			};
-			fb_init(&prop);
-		}
+		ofw_tree_walk_by_device_type("display", display_register, NULL);
 #endif
 		
@@ -132,21 +173,27 @@
 }
 
-void arch_post_smp_init(void)
-{
-	if (bootinfo.macio.addr) {
+static bool macio_register(ofw_tree_node_t *node, void *arg)
+{
+	ofw_pci_reg_t *assigned_address = NULL;
+	
+	ofw_tree_property_t *prop = ofw_tree_getprop(node, "assigned-addresses");
+	if ((prop) && (prop->value))
+		assigned_address = ((ofw_pci_reg_t *) prop->value);
+	
+	if (assigned_address) {
 		/* Initialize PIC */
 		cir_t cir;
 		void *cir_arg;
-		pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg);
-
+		pic_init(assigned_address[0].addr, PAGE_SIZE, &cir, &cir_arg);
+		
 #ifdef CONFIG_MAC_KBD
-		uintptr_t pa = bootinfo.macio.addr + 0x16000;
+		uintptr_t pa = assigned_address[0].addr + 0x16000;
 		uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
 		size_t offset = pa - aligned_addr;
 		size_t size = 2 * PAGE_SIZE;
-			
+		
 		cuda_t *cuda = (cuda_t *)
 		    (hw_map(aligned_addr, offset + size) + offset);
-			
+		
 		/* Initialize I/O controller */
 		cuda_instance_t *cuda_instance =
@@ -163,4 +210,12 @@
 #endif
 	}
+	
+	/* Consider only a single device for now */
+	return false;
+}
+
+void arch_post_smp_init(void)
+{
+	ofw_tree_walk_by_device_type("mac-io", macio_register, NULL);
 }
 
Index: kernel/arch/sparc64/include/drivers/fhc.h
===================================================================
--- kernel/arch/sparc64/include/drivers/fhc.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/sparc64/include/drivers/fhc.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
Index: kernel/arch/sparc64/src/drivers/fhc.c
===================================================================
--- kernel/arch/sparc64/src/drivers/fhc.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/sparc64/src/drivers/fhc.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -46,4 +46,5 @@
 #include <arch/types.h>
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/fhc.h>
 #include <sysinfo/sysinfo.h>
 
Index: kernel/arch/sparc64/src/drivers/kbd.c
===================================================================
--- kernel/arch/sparc64/src/drivers/kbd.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/sparc64/src/drivers/kbd.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -35,15 +35,6 @@
 #include <arch/drivers/kbd.h>
 #include <genarch/ofw/ofw_tree.h>
-
-#ifdef CONFIG_SUN_KBD
-#include <genarch/kbrd/kbrd.h>
-#endif
-#ifdef CONFIG_Z8530
-#include <genarch/drivers/z8530/z8530.h>
-#endif
-#ifdef CONFIG_NS16550
-#include <genarch/drivers/ns16550/ns16550.h>
-#endif
-
+#include <genarch/ofw/fhc.h>
+#include <genarch/ofw/ebus.h>
 #include <console/console.h>
 #include <ddi/irq.h>
@@ -56,4 +47,16 @@
 
 #ifdef CONFIG_SUN_KBD
+#include <genarch/kbrd/kbrd.h>
+#endif
+
+#ifdef CONFIG_Z8530
+#include <genarch/drivers/z8530/z8530.h>
+#endif
+
+#ifdef CONFIG_NS16550
+#include <genarch/drivers/ns16550/ns16550.h>
+#endif
+
+#ifdef CONFIG_SUN_KBD
 
 #ifdef CONFIG_Z8530
Index: kernel/arch/sparc64/src/drivers/pci.c
===================================================================
--- kernel/arch/sparc64/src/drivers/pci.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/sparc64/src/drivers/pci.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -37,4 +37,5 @@
 #include <arch/drivers/pci.h>
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/upa.h>
 #include <arch/trap/interrupt.h>
 #include <mm/page.h>
Index: kernel/arch/sparc64/src/drivers/scr.c
===================================================================
--- kernel/arch/sparc64/src/drivers/scr.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/sparc64/src/drivers/scr.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -35,4 +35,7 @@
 #include <arch/drivers/scr.h>
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/pci.h>
+#include <genarch/ofw/sbus.h>
+#include <genarch/ofw/upa.h>
 #include <genarch/fb/fb.h>
 #include <genarch/fb/visuals.h>
Index: kernel/arch/sparc64/src/drivers/sgcn.c
===================================================================
--- kernel/arch/sparc64/src/drivers/sgcn.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/arch/sparc64/src/drivers/sgcn.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -380,6 +380,6 @@
 	sysinfo_set_item_val("fb.kind", NULL, 4);
 
-	outdev_initialize("sgcnout", &sgcnout, &sgcnout_ops);	
-	stdout = &sgcnout;
+	outdev_initialize("sgcnout", &sgcnout, &sgcnout_ops);
+	stdout_wire(&sgcnout);
 }
 
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/Makefile.inc	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -130,10 +130,14 @@
 ifeq ($(CONFIG_OFW_TREE),y)
 	GENARCH_SOURCES += \
-		genarch/src/ofw/ofw_tree.c \
+		genarch/src/ofw/ofw_tree.c
+endif
+
+ifeq ($(CONFIG_OFW_PCI),y)
+	GENARCH_SOURCES += \
 		genarch/src/ofw/ebus.c \
 		genarch/src/ofw/fhc.c \
 		genarch/src/ofw/pci.c  \
 		genarch/src/ofw/sbus.c \
-		genarch/src/ofw/upa.c 
+		genarch/src/ofw/upa.c
 endif
 
Index: kernel/genarch/include/fb/fb.h
===================================================================
--- kernel/genarch/include/fb/fb.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/include/fb/fb.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -68,5 +68,5 @@
 
 void fb_redraw(void);
-void fb_init(fb_properties_t *props);
+bool fb_init(fb_properties_t *props);
 
 #endif
Index: kernel/genarch/include/fb/visuals.h
===================================================================
--- kernel/genarch/include/fb/visuals.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/include/fb/visuals.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -37,4 +37,5 @@
 
 typedef enum {
+	VISUAL_UNKNOWN = 0,
 	VISUAL_INDIRECT_8,
 	VISUAL_RGB_5_5_5_LE,
Index: kernel/genarch/include/ofw/ebus.h
===================================================================
--- kernel/genarch/include/ofw/ebus.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
+++ kernel/genarch/include/ofw/ebus.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2006 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.
+ */
+
+#ifndef KERN_EBUS_H_
+#define KERN_EBUS_H_
+
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/types.h>
+#include <ddi/irq.h>
+#include <typedefs.h>
+
+typedef struct {
+	uint32_t space;
+	uint32_t addr;
+	uint32_t size;
+} __attribute__ ((packed)) ofw_ebus_reg_t;
+
+typedef struct {
+	uint32_t child_space;
+	uint32_t child_base;
+	uint32_t parent_space;
+	
+	/* Group phys.mid and phys.lo together */
+	uint64_t parent_base;
+	uint32_t size;
+} __attribute__ ((packed)) ofw_ebus_range_t;
+
+typedef struct {
+	uint32_t space;
+	uint32_t addr;
+	uint32_t intr;
+	uint32_t controller_handle;
+	uint32_t controller_ino;
+} __attribute__ ((packed)) ofw_ebus_intr_map_t;
+
+typedef struct {
+	uint32_t space_mask;
+	uint32_t addr_mask;
+	uint32_t intr_mask;
+} __attribute__ ((packed)) ofw_ebus_intr_mask_t;
+
+extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *,
+    uintptr_t *);
+extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *,
+    uint32_t, int *, cir_t *, void **);
+
+#endif
Index: kernel/genarch/include/ofw/fhc.h
===================================================================
--- kernel/genarch/include/ofw/fhc.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
+++ kernel/genarch/include/ofw/fhc.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2006 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.
+ */
+
+#ifndef KERN_FHC_H_
+#define KERN_FHC_H_
+
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/types.h>
+#include <ddi/irq.h>
+#include <typedefs.h>
+
+typedef struct {
+	uint64_t addr;
+	uint32_t size;
+} __attribute__ ((packed)) ofw_fhc_reg_t;
+
+typedef struct {
+	uint64_t child_base;
+	uint64_t parent_base;
+	uint32_t size;
+} __attribute__ ((packed)) ofw_fhc_range_t;
+
+typedef struct {
+	uint64_t addr;
+	uint32_t size;
+} __attribute__ ((packed)) ofw_central_reg_t;
+
+typedef struct {
+	uint64_t child_base;
+	uint64_t parent_base;
+	uint32_t size;
+} __attribute__ ((packed)) ofw_central_range_t;
+
+extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *,
+    uintptr_t *);
+extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *,
+    uintptr_t *);
+
+extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *,
+    uint32_t, int *, cir_t *, void **);
+
+#endif
Index: kernel/genarch/include/ofw/ofw_tree.h
===================================================================
--- kernel/genarch/include/ofw/ofw_tree.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/include/ofw/ofw_tree.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -31,23 +31,26 @@
 
 #include <arch/types.h>
-#include <ddi/irq.h>
 #include <typedefs.h>
 
-#define OFW_TREE_PROPERTY_MAX_NAMELEN	32
+#define OFW_TREE_PROPERTY_MAX_NAMELEN  32
 
-typedef struct ofw_tree_node ofw_tree_node_t;
-typedef struct ofw_tree_property ofw_tree_property_t;
+/** Memory representation of OpenFirmware device tree node property. */
+typedef struct {
+	char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
+	size_t size;
+	void *value;
+} ofw_tree_property_t;
 
 /** Memory representation of OpenFirmware device tree node. */
-struct ofw_tree_node {
-	ofw_tree_node_t *parent;
-	ofw_tree_node_t *peer;
-	ofw_tree_node_t *child;
-
-	uint32_t node_handle;		/**< Old OpenFirmware node handle. */
-
-	char *da_name;			/**< Disambigued name. */
-
-	unsigned properties;		/**< Number of properties. */
+typedef struct ofw_tree_node {
+	struct ofw_tree_node *parent;
+	struct ofw_tree_node *peer;
+	struct ofw_tree_node *child;
+	
+	uint32_t node_handle;           /**< Old OpenFirmware node handle. */
+	
+	char *da_name;                  /**< Disambigued name. */
+	
+	unsigned int properties;        /**< Number of properties. */
 	ofw_tree_property_t *property;
 	
@@ -57,147 +60,29 @@
 	 */
 	void *device;
-};
+} ofw_tree_node_t;
 
-/** Memory representation of OpenFirmware device tree node property. */
-struct ofw_tree_property {
-	char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
-	size_t size;
-	void *value;
-};
-
-/*
- * Definition of 'reg' and 'ranges' properties for various buses.
- */
- 
-struct ofw_fhc_reg {
-	uint64_t addr;
-	uint32_t size;
-} __attribute__ ((packed));
-typedef struct ofw_fhc_reg ofw_fhc_reg_t;
-			
-struct ofw_fhc_range {
-	uint64_t child_base;
-	uint64_t parent_base;
-	uint32_t size;
-} __attribute__ ((packed));
-typedef struct ofw_fhc_range ofw_fhc_range_t;
-
-struct ofw_central_reg {
-	uint64_t addr;
-	uint32_t size;
-} __attribute__ ((packed));
-typedef struct ofw_central_reg ofw_central_reg_t;
-
-struct ofw_central_range {
-	uint64_t child_base;
-	uint64_t parent_base;
-	uint32_t size;
-} __attribute__ ((packed));
-typedef struct ofw_central_range ofw_central_range_t;
-
-struct ofw_ebus_reg {
-	uint32_t space;
-	uint32_t addr;
-	uint32_t size;
-} __attribute__ ((packed));
-typedef struct ofw_ebus_reg ofw_ebus_reg_t;
-
-struct ofw_ebus_range {
-	uint32_t child_space;
-	uint32_t child_base;
-	uint32_t parent_space;
-	uint64_t parent_base;	/* group phys.mid and phys.lo together */
-	uint32_t size;
-} __attribute__ ((packed));
-typedef struct ofw_ebus_range ofw_ebus_range_t;
-
-struct ofw_ebus_intr_map {
-	uint32_t space;
-	uint32_t addr;
-	uint32_t intr;
-	uint32_t controller_handle;
-	uint32_t controller_ino;
-} __attribute__ ((packed));
-typedef struct ofw_ebus_intr_map ofw_ebus_intr_map_t;
-
-struct ofw_ebus_intr_mask {
-	uint32_t space_mask;
-	uint32_t addr_mask;
-	uint32_t intr_mask;
-} __attribute__ ((packed));
-typedef struct ofw_ebus_intr_mask ofw_ebus_intr_mask_t;
-
-struct ofw_pci_reg {
-	uint32_t space;		/* needs to be masked to obtain pure space id */
-	uint64_t addr;		/* group phys.mid and phys.lo together */
-	uint64_t size;
-} __attribute__ ((packed));
-typedef struct ofw_pci_reg ofw_pci_reg_t;
-
-struct ofw_pci_range {
-	uint32_t space;
-	uint64_t child_base;	/* group phys.mid and phys.lo together */
-	uint64_t parent_base;
-	uint64_t size;
-} __attribute__ ((packed));
-typedef struct ofw_pci_range ofw_pci_range_t;
-
-struct ofw_sbus_reg {
-	uint64_t addr;
-	uint32_t size;
-} __attribute__ ((packed));
-typedef struct ofw_sbus_reg ofw_sbus_reg_t;
-
-struct ofw_sbus_range {
-	uint64_t child_base;
-	uint64_t parent_base;
-	uint32_t size;
-} __attribute__ ((packed));
-typedef struct ofw_sbus_range ofw_sbus_range_t;
-
-struct ofw_upa_reg {
-	uint64_t addr;
-	uint64_t size;
-} __attribute__ ((packed));
-typedef struct ofw_upa_reg ofw_upa_reg_t;
+/* Walker for visiting OpenFirmware device tree nodes. */
+typedef bool (* ofw_tree_walker_t)(ofw_tree_node_t *, void *);
 
 extern void ofw_tree_init(ofw_tree_node_t *);
 extern void ofw_tree_print(void);
+
 extern const char *ofw_tree_node_name(const ofw_tree_node_t *);
 extern ofw_tree_node_t *ofw_tree_lookup(const char *);
 extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *,
     const char *);
+extern void ofw_tree_walk_by_device_type(const char *, ofw_tree_walker_t,
+    void *);
+
 extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *, const char *);
 extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *,
     const char *);
+
 extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *,
     const char *);
-extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node,
-    const char *name);
+extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *,
+    const char *);
 extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *,
     uint32_t);
 
-extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *,
-    uintptr_t *);
-extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *,
-    uintptr_t *);
-extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *,
-    uintptr_t *);
-extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *,
-    uintptr_t *);
-extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *,
-    uintptr_t *);
-extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *,
-    uintptr_t *);
-
-extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *,
-    ofw_pci_reg_t *);
-
-extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *,
-    uint32_t, int *, cir_t *, void **);
-extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *,
-    uint32_t, int *, cir_t *, void **);
-extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *,
-    int, int *, cir_t *, void **);
-
 #endif
Index: kernel/genarch/include/ofw/pci.h
===================================================================
--- kernel/genarch/include/ofw/pci.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
+++ kernel/genarch/include/ofw/pci.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2006 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.
+ */
+
+#ifndef KERN_PCI_H_
+#define KERN_PCI_H_
+
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/types.h>
+#include <ddi/irq.h>
+#include <typedefs.h>
+
+typedef struct {
+	/* Needs to be masked to obtain pure space id */
+	uint32_t space;
+	
+	/* Group phys.mid and phys.lo together */
+	uint64_t addr;
+	uint64_t size;
+} __attribute__ ((packed)) ofw_pci_reg_t;
+
+typedef struct {
+	uint32_t space;
+	
+	/* Group phys.mid and phys.lo together */
+	uint64_t child_base;
+	uint64_t parent_base;
+	uint64_t size;
+} __attribute__ ((packed)) ofw_pci_range_t;
+
+extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *,
+    uintptr_t *);
+
+extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *,
+    ofw_pci_reg_t *);
+
+extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *,
+    int, int *, cir_t *, void **);
+
+#endif
Index: kernel/genarch/include/ofw/sbus.h
===================================================================
--- kernel/genarch/include/ofw/sbus.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
+++ kernel/genarch/include/ofw/sbus.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 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.
+ */
+
+#ifndef KERN_SBUS_H_
+#define KERN_SBUS_H_
+
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/types.h>
+#include <ddi/irq.h>
+#include <typedefs.h>
+
+typedef struct {
+	uint64_t addr;
+	uint32_t size;
+} __attribute__ ((packed)) ofw_sbus_reg_t;
+
+typedef struct {
+	uint64_t child_base;
+	uint64_t parent_base;
+	uint32_t size;
+} __attribute__ ((packed)) ofw_sbus_range_t;
+
+extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *,
+    uintptr_t *);
+
+#endif
Index: kernel/genarch/include/ofw/upa.h
===================================================================
--- kernel/genarch/include/ofw/upa.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
+++ kernel/genarch/include/ofw/upa.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2006 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.
+ */
+
+#ifndef KERN_UPA_H_
+#define KERN_UPA_H_
+
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/types.h>
+#include <ddi/irq.h>
+#include <typedefs.h>
+
+typedef struct {
+	uint64_t addr;
+	uint64_t size;
+} __attribute__ ((packed)) ofw_upa_reg_t;
+
+extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *,
+    uintptr_t *);
+
+#endif
Index: kernel/genarch/src/drivers/dsrln/dsrlnout.c
===================================================================
--- kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -66,5 +66,5 @@
 	
 	outdev_initialize("dsrlnout", &dsrlnout_console, &dsrlnout_ops);
-	stdout = &dsrlnout_console;
+	stdout_wire(&dsrlnout_console);
 	
 	sysinfo_set_item_val("fb", NULL, true);
Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -567,5 +567,5 @@
 	
 	outdev_initialize("ega", &ega_console, &ega_ops);
-	stdout = &ega_console;
+	stdout_wire(&ega_console);
 	
 	sysinfo_set_item_val("fb", NULL, true);
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/fb/fb.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -458,6 +458,11 @@
  *
  */
-void fb_init(fb_properties_t *props)
-{
+bool fb_init(fb_properties_t *props)
+{
+	ASSERT(props);
+	ASSERT(props->x > 0);
+	ASSERT(props->y > 0);
+	ASSERT(props->scan > 0);
+	
 	switch (props->visual) {
 	case VISUAL_INDIRECT_8:
@@ -506,5 +511,6 @@
 		break;
 	default:
-		panic("Unsupported visual.");
+		LOG("Unsupported visual.");
+		return false;
 	}
 	
@@ -536,21 +542,33 @@
 	size_t glyphsize = FONT_GLYPHS * glyphbytes;
 	
+	fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
+	if (!fb_addr) {
+		LOG("Unable to map framebuffer.");
+		return false;
+	}
+	
 	backbuf = (uint16_t *) malloc(bbsize, 0);
-	if (!backbuf)
-		panic("Unable to allocate backbuffer.");
+	if (!backbuf) {
+		LOG("Unable to allocate backbuffer.");
+		return false;
+	}
 	
 	glyphs = (uint8_t *) malloc(glyphsize, 0);
-	if (!glyphs)
-		panic("Unable to allocate glyphs.");
+	if (!glyphs) {
+		free(backbuf);
+		LOG("Unable to allocate glyphs.");
+		return false;
+	}
 	
 	bgscan = malloc(bgscanbytes, 0);
-	if (!bgscan)
-		panic("Unable to allocate background pixel.");
+	if (!bgscan) {
+		free(glyphs);
+		free(backbuf);
+		LOG("Unable to allocate background pixel.");
+		return false;
+	}
 	
 	memsetw(backbuf, cols * rows, 0);
-	
 	glyphs_render();
-	
-	fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
 	
 	sysinfo_set_item_val("fb", NULL, true);
@@ -565,5 +583,7 @@
 	
 	outdev_initialize("fb", &fb_console, &fb_ops);
-	stdout = &fb_console;
+	stdout_wire(&fb_console);
+	
+	return true;
 }
 
Index: kernel/genarch/src/ofw/ebus.c
===================================================================
--- kernel/genarch/src/ofw/ebus.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/ofw/ebus.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -37,6 +37,7 @@
 
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/ebus.h>
+#include <genarch/ofw/pci.h>
 #include <arch/memstr.h>
-#include <arch/trap/interrupt.h>
 #include <string.h>
 #include <panic.h>
Index: kernel/genarch/src/ofw/fhc.c
===================================================================
--- kernel/genarch/src/ofw/fhc.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/ofw/fhc.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -37,4 +37,5 @@
 
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/fhc.h>
 #include <arch/drivers/fhc.h>
 #include <arch/memstr.h>
Index: kernel/genarch/src/ofw/ofw_tree.c
===================================================================
--- kernel/genarch/src/ofw/ofw_tree.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -32,5 +32,5 @@
 /**
  * @file
- * @brief	OpenFirmware device tree navigation.
+ * @brief OpenFirmware device tree navigation.
  *
  */
@@ -40,9 +40,9 @@
 #include <mm/slab.h>
 #include <string.h>
+#include <panic.h>
 #include <print.h>
-#include <panic.h>
-
-#define PATH_MAX_LEN	80
-#define NAME_BUF_LEN	50
+
+#define PATH_MAX_LEN  256
+#define NAME_BUF_LEN  50
 
 static ofw_tree_node_t *ofw_root;
@@ -55,12 +55,13 @@
 /** Get OpenFirmware node property.
  *
- * @param node		Node in which to lookup the property.
- * @param name		Name of the property.
- *
- * @return		Pointer to the property structure or NULL if no such
- * 			property.
- */
-ofw_tree_property_t *
-ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
+ * @param node Node in which to lookup the property.
+ * @param name Name of the property.
+ *
+ * @return Pointer to the property structure or NULL if no such
+ *         property.
+ *
+ */
+ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node,
+    const char *name)
 {
 	unsigned int i;
@@ -70,5 +71,5 @@
 			return &node->property[i];
 	}
-
+	
 	return NULL;
 }
@@ -76,18 +77,15 @@
 /** Return value of the 'name' property.
  *
- * @param node		Node of interest.
- *
- * @return		Value of the 'name' property belonging to the node.
+ * @param node Node of interest.
+ *
+ * @return Value of the 'name' property belonging to the node
+ *         or NULL if the property is invalid.
+ *
  */
 const char *ofw_tree_node_name(const ofw_tree_node_t *node)
 {
-	ofw_tree_property_t *prop;
-	
-	prop = ofw_tree_getprop(node, "name");
-	if (!prop)
-		panic("Node without name property.");
-		
-	if (prop->size < 2)
-		panic("Invalid name property.");
+	ofw_tree_property_t *prop = ofw_tree_getprop(node, "name");
+	if ((!prop) || (prop->size < 2))
+		return NULL;
 	
 	return prop->value;
@@ -96,11 +94,13 @@
 /** Lookup child of given name.
  *
- * @param node		Node whose child is being looked up.
- * @param name		Name of the child being looked up.
- *
- * @return		NULL if there is no such child or pointer to the
- * 			matching child node.
- */
-ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name)
+ * @param node Node whose child is being looked up.
+ * @param name Name of the child being looked up.
+ *
+ * @return NULL if there is no such child or pointer to the
+ *         matching child node.
+ *
+ */
+ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node,
+    const char *name)
 {
 	ofw_tree_node_t *cur;
@@ -125,5 +125,5 @@
 			return cur;
 	}
-		
+	
 	return NULL;
 }
@@ -131,24 +131,27 @@
 /** Lookup first child of given device type.
  *
- * @param node		Node whose child is being looked up.
- * @param name		Device type of the child being looked up.
- *
- * @return		NULL if there is no such child or pointer to the
- * 			matching child node.
- */
-ofw_tree_node_t *
-ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
-{
-	ofw_tree_node_t *cur;
-	ofw_tree_property_t *prop;
+ * @param node  Node whose child is being looked up.
+ * @param dtype Device type of the child being looked up.
+ *
+ * @return NULL if there is no such child or pointer to the
+ *         matching child node.
+ *
+ */
+ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node,
+    const char *dtype)
+{
+	ofw_tree_node_t *cur;
 	
 	for (cur = node->child; cur; cur = cur->peer) {
-		prop = ofw_tree_getprop(cur, "device_type");
-		if (!prop || !prop->value)
+		ofw_tree_property_t *prop =
+		    ofw_tree_getprop(cur, "device_type");
+		
+		if ((!prop) || (!prop->value))
 			continue;
-		if (str_cmp(prop->value, name) == 0)
-			return cur;
-	}
-			
+		
+		if (str_cmp(prop->value, dtype) == 0)
+			return cur;
+	}
+	
 	return NULL;
 }
@@ -159,23 +162,23 @@
  * are looked up iteratively to avoid stack overflow.
  *
- * @param root		Root of the searched subtree.
- * @param handle	OpenFirmware handle.
- *
- * @return		NULL if there is no such node or pointer to the matching
- * 			node.
- */
-ofw_tree_node_t *
-ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle)
-{
-	ofw_tree_node_t *cur;
-
-	for (cur = root; cur; cur = cur->peer) {		
+ * @param root   Root of the searched subtree.
+ * @param handle OpenFirmware handle.
+ *
+ * @return NULL if there is no such node or pointer to the matching
+ *         node.
+ *
+ */
+ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root,
+    uint32_t handle)
+{
+	ofw_tree_node_t *cur;
+	
+	for (cur = root; cur; cur = cur->peer) {
 		if (cur->node_handle == handle)
 			return cur;
-
+		
 		if (cur->child) {
-			ofw_tree_node_t *node;
-			
-			node = ofw_tree_find_node_by_handle(cur->child, handle);
+			ofw_tree_node_t *node
+			    = ofw_tree_find_node_by_handle(cur->child, handle);
 			if (node)
 				return node;
@@ -183,55 +186,60 @@
 	}
 	
-	return NULL;	
+	return NULL;
 }
 
 /** Lookup first peer of given device type.
  *
- * @param node		Node whose peer is being looked up.
- * @param name		Device type of the child being looked up.
- *
- * @return		NULL if there is no such child or pointer to the
- * 			matching child node.
- */
-ofw_tree_node_t *
-ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
-{
-	ofw_tree_node_t *cur;
-	ofw_tree_property_t *prop;
+ * @param node  Node whose peer is being looked up.
+ * @param dtype Device type of the child being looked up.
+ *
+ * @return NULL if there is no such child or pointer to the
+ *         matching child node.
+ *
+ */
+ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node,
+    const char *dtype)
+{
+	ofw_tree_node_t *cur;
 	
 	for (cur = node->peer; cur; cur = cur->peer) {
-		prop = ofw_tree_getprop(cur, "device_type");
-		if (!prop || !prop->value)
+		ofw_tree_property_t *prop =
+		    ofw_tree_getprop(cur, "device_type");
+		
+		if ((!prop) || (!prop->value))
 			continue;
+		
+		if (str_cmp(prop->value, dtype) == 0)
+			return cur;
+	}
+	
+	return NULL;
+}
+
+/** Lookup first peer of given name.
+ *
+ * @param node Node whose peer is being looked up.
+ * @param name Name of the child being looked up.
+ *
+ * @return NULL if there is no such peer or pointer to the matching
+ *         peer node.
+ *
+ */
+ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node,
+    const char *name)
+{
+	ofw_tree_node_t *cur;
+	
+	for (cur = node->peer; cur; cur = cur->peer) {
+		ofw_tree_property_t *prop
+		    = ofw_tree_getprop(cur, "name");
+		
+		if ((!prop) || (!prop->value))
+			continue;
+		
 		if (str_cmp(prop->value, name) == 0)
 			return cur;
 	}
-			
-	return NULL;
-}
-
-
-/** Lookup first peer of given name.
- *
- * @param node		Node whose peer is being looked up.
- * @param name		Name of the child being looked up.
- *
- * @return		NULL if there is no such peer or pointer to the matching
- * 			peer node.
- */
-ofw_tree_node_t *
-ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name)
-{
-	ofw_tree_node_t *cur;
-	ofw_tree_property_t *prop;
-	
-	for (cur = node->peer; cur; cur = cur->peer) {
-		prop = ofw_tree_getprop(cur, "name");
-		if (!prop || !prop->value)
-			continue;
-		if (str_cmp(prop->value, name) == 0)
-			return cur;
-	}
-			
+	
 	return NULL;
 }
@@ -239,19 +247,19 @@
 /** 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.
+ * @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];
+	if (path[0] != '/')
+		return NULL;
+	
 	ofw_tree_node_t *node = ofw_root;
 	size_t i;
 	size_t j;
 	
-	if (path[0] != '/')
-		return NULL;
-	
 	for (i = 1; (i < str_size(path)) && (node); i = j + 1) {
 		for (j = i; (j < str_size(path)) && (path[j] != '/'); j++);
@@ -261,4 +269,5 @@
 			continue;
 		
+		char buf[NAME_BUF_LEN + 1];
 		memcpy(buf, &path[i], j - i);
 		buf[j - i] = 0;
@@ -269,33 +278,88 @@
 }
 
-/** Print OpenFirmware device subtree rooted in a node.
+/** Walk the OpenFirmware device subtree rooted in a node.
  *
  * Child nodes are processed recursively and peer nodes are processed
  * iteratively in order to avoid stack overflow.
  *
- * @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;
-	const ofw_tree_node_t *cur;
-
-	p = (char *) malloc(PATH_MAX_LEN, 0);
-
+ * @param node   Root of the subtree.
+ * @param dtype  Device type to look for.
+ * @param walker Routine to be invoked on found device.
+ * @param arg    User argument to the walker.
+ *
+ * @return True if the walk should continue.
+ *
+ */
+static bool ofw_tree_walk_by_device_type_internal(ofw_tree_node_t *node,
+    const char *dtype, ofw_tree_walker_t walker, void *arg)
+{
+	ofw_tree_node_t *cur;
+	
 	for (cur = node; cur; cur = cur->peer) {
-		if (cur->parent) {
-			snprintf(p, PATH_MAX_LEN, "%s/%s", path, cur->da_name);
-			printf("%s\n", p);
+		ofw_tree_property_t *prop =
+		    ofw_tree_getprop(cur, "device_type");
+		
+		if ((prop) && (prop->value) && (str_cmp(prop->value, dtype) == 0)) {
+			bool ret = walker(cur, arg);
+			if (!ret)
+				return false;
+		}
+		
+		if (cur->child) {
+			bool ret =
+			    ofw_tree_walk_by_device_type_internal(cur->child, dtype, walker, arg);
+			if (!ret)
+				return false;
+		}
+	}
+	
+	return true;
+}
+
+/** Walk the OpenFirmware device tree and find devices by type.
+ *
+ * Walk the whole OpenFirmware device tree and if any node has
+ * the property "device_type" equal to dtype, run a walker on it.
+ * If the walker returns false, the walk does not continue.
+ *
+ * @param dtype  Device type to look for.
+ * @param walker Routine to be invoked on found device.
+ * @param arg    User argument to the walker.
+ *
+ */
+void ofw_tree_walk_by_device_type(const char *dtype, ofw_tree_walker_t walker,
+    void *arg)
+{
+	(void) ofw_tree_walk_by_device_type_internal(ofw_root, dtype, walker, arg);
+}
+
+/** Print OpenFirmware device subtree rooted in a node.
+ *
+ * Child nodes are processed recursively and peer nodes are processed
+ * iteratively in order to avoid stack overflow.
+ *
+ * @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(ofw_tree_node_t *node, const char *path)
+{
+	char *cur_path = (char *) malloc(PATH_MAX_LEN, 0);
+	ofw_tree_node_t *cur;
+	
+	for (cur = node; cur; cur = cur->peer) {
+		if ((cur->parent) && (path)) {
+			snprintf(cur_path, PATH_MAX_LEN, "%s/%s", path, cur->da_name);
+			printf("%s\n", cur_path);
 		} else {
-			snprintf(p, PATH_MAX_LEN, "%s", cur->da_name);
+			snprintf(cur_path, PATH_MAX_LEN, "%s", cur->da_name);
 			printf("/\n");
 		}
-
+		
 		if (cur->child)
-			ofw_tree_node_print(cur->child, p);
-	}
-
-	free(p);
+			ofw_tree_node_print(cur->child, cur_path);
+	}
+	
+	free(cur_path);
 }
 
Index: kernel/genarch/src/ofw/pci.c
===================================================================
--- kernel/genarch/src/ofw/pci.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/ofw/pci.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -37,4 +37,5 @@
 
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/pci.h>
 #include <arch/drivers/pci.h>
 #include <arch/trap/interrupt.h>
Index: kernel/genarch/src/ofw/sbus.c
===================================================================
--- kernel/genarch/src/ofw/sbus.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/ofw/sbus.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -37,4 +37,5 @@
 
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/sbus.h>
 #include <macros.h>
 
Index: kernel/genarch/src/ofw/upa.c
===================================================================
--- kernel/genarch/src/ofw/upa.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/genarch/src/ofw/upa.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -37,4 +37,5 @@
 
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/upa.h>
 #include <arch/memstr.h>
 #include <func.h>
Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/generic/include/console/chardev.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -36,4 +36,5 @@
 #define KERN_CHARDEV_H_
 
+#include <adt/list.h>
 #include <arch/types.h>
 #include <synch/waitq.h>
@@ -75,5 +76,5 @@
 } outdev_operations_t;
 
-/** Character input device. */
+/** Character output device. */
 typedef struct outdev {
 	char *name;
@@ -81,4 +82,8 @@
 	/** Protects everything below. */
 	SPINLOCK_DECLARE(lock);
+	
+	/** Fields suitable for multiplexing. */
+	link_t link;
+	link_t list;
 	
 	/** Implementation of outdev operations. */
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/generic/include/console/console.h	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -44,4 +44,5 @@
 
 extern indev_t *stdin_wire(void);
+extern void stdout_wire(outdev_t *outdev);
 extern void console_init(void);
 
Index: kernel/generic/src/console/chardev.c
===================================================================
--- kernel/generic/src/console/chardev.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/generic/src/console/chardev.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -33,4 +33,5 @@
  */
 
+#include <adt/list.h>
 #include <console/chardev.h>
 #include <synch/waitq.h>
@@ -134,4 +135,6 @@
 	outdev->name = name;
 	spinlock_initialize(&outdev->lock, "outdev");
+	link_initialize(&outdev->link);
+	list_initialize(&outdev->list);
 	outdev->op = op;
 }
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 207e208e62266d2670cc05533ded75ef5cccb345)
+++ kernel/generic/src/console/console.c	(revision bc7d44c8c94c3e6939ba5054dd1878bd7e3674f7)
@@ -76,8 +76,17 @@
 static parea_t klog_parea;
 
+static indev_t stdin_sink;
+static outdev_t stdout_source;
+
 static indev_operations_t stdin_ops = {
 	.poll = NULL
 };
 
+static void stdout_write(outdev_t *dev, wchar_t ch, bool silent);
+
+static outdev_operations_t stdout_ops = {
+	.write = stdout_write
+};
+
 /** Silence output */
 bool silent = false;
@@ -90,10 +99,29 @@
 {
 	if (stdin == NULL) {
-		stdin = malloc(sizeof(indev_t), FRAME_ATOMIC);
-		if (stdin != NULL)
-			indev_initialize("stdin", stdin, &stdin_ops);
+		indev_initialize("stdin", &stdin_sink, &stdin_ops);
+		stdin = &stdin_sink;
 	}
 	
 	return stdin;
+}
+
+void stdout_wire(outdev_t *outdev)
+{
+	if (stdout == NULL) {
+		outdev_initialize("stdout", &stdout_source, &stdout_ops);
+		stdout = &stdout_source;
+	}
+	
+	list_append(&outdev->link, &stdout->list);
+}
+
+static void stdout_write(outdev_t *dev, wchar_t ch, bool silent)
+{
+	link_t *cur;
+	
+	for (cur = dev->list.next; cur != &dev->list; cur = cur->next) {
+		outdev_t *sink = list_get_instance(cur, outdev_t, link);
+		sink->op->write(sink, ch, silent);
+	}
 }
 
