Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ HelenOS.config	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -82,5 +82,5 @@
 ! [PLATFORM=sparc64&MACHINE=serengeti] PROCESSOR (choice)
 
-% Ramdisk format
+% RAM disk format
 @ "tmpfs" TMPFS image
 @ "fat" FAT16 image
@@ -219,25 +219,26 @@
 
 % Compiler
-@ "gcc_cross" GCC Cross-compiler
-@ "gcc_native" GCC Native
-@ "icc_native" ICC Native
-@ "suncc_native" Sun Studio C Compiler
+@ "gcc_cross" GNU C Compiler (cross-compiler)
+@ "gcc_native" GNU C Compiler (native)
+@ "icc" Intel C Compiler
+@ "suncc" Sun Studio C Compiler
+@ "clang" Clang
 ! [PLATFORM=amd64|PLATFORM=ia32] COMPILER (choice)
 
 % Compiler
-@ "gcc_cross" GCC Cross-compiler
-@ "gcc_native" GCC Native
-@ "icc_native" ICC Native
+@ "gcc_cross" GNU C Compiler (cross-compiler)
+@ "gcc_native" GNU C Compiler (native)
+@ "icc" Intel C Compiler
 ! [PLATFORM=ia64] COMPILER (choice)
 
 % Compiler
-@ "gcc_cross" GCC Cross-compiler
-@ "gcc_native" GCC Native
-@ "suncc_native" Sun Studio C Compiler
+@ "gcc_cross" GNU C Compiler (cross-compiler)
+@ "gcc_native" GNU C Compiler (native)
+@ "suncc" Sun Studio C Compiler
 ! [PLATFORM=sparc64] COMPILER (choice)
 
 % Compiler
-@ "gcc_cross" GCC Cross-compiler
-@ "gcc_native" GCC Native
+@ "gcc_cross" GNU C Compiler (cross-compiler)
+@ "gcc_native" GNU C Compiler (native)
 ! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice)
 
@@ -273,5 +274,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
@@ -474,5 +478,5 @@
 ! [PLATFORM=sparc64&MACHINE=generic] CONFIG_AOUT_ISOFS_B (y)
 
-% External ramdisk
+% External RAM disk
 ! [PLATFORM=sparc64] CONFIG_RD_EXTERNAL (y/n)
 
Index: Makefile
===================================================================
--- Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -30,5 +30,5 @@
 #
 
-.PHONY: all config distclean clean cscope
+.PHONY: all config config_default distclean clean cscope
 
 all: Makefile.config config.h config.defs
@@ -37,8 +37,14 @@
 	$(MAKE) -C boot
 
-Makefile.config config.h config.defs: HelenOS.config
+Makefile.config: config_default
+
+config.h: config_default
+
+config.defs: config_default
+
+config_default: HelenOS.config
 	tools/config.py HelenOS.config default
 
-config:
+config: HelenOS.config
 	tools/config.py HelenOS.config
 
Index: boot/Makefile
===================================================================
--- boot/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -47,3 +47,3 @@
 
 generic_clean:
-	-rm generic/*.o genarch/*.o
+	rm -f generic/*.o genarch/*.o
Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/amd64/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -52,8 +52,11 @@
 	$(USPACEDIR)/srv/fs/fat/fat \
 	$(USPACEDIR)/srv/bd/ata_bd/ata_bd \
-	$(USPACEDIR)/srv/bd/file_bd/file_bd
+	$(USPACEDIR)/srv/bd/file_bd/file_bd \
+	$(USPACEDIR)/srv/part/mbr_part/mbr_part
 
 RD_APPS = \
+	$(USPACEDIR)/app/edit/edit \
 	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
 	$(USPACEDIR)/app/tetris/tetris \
 	$(USPACEDIR)/app/tester/tester \
@@ -94,10 +97,10 @@
 
 clean:
-	-for file in $(RD_SRVS) ; do \
+	for file in $(RD_SRVS) ; do \
 		rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
 	done
-	-for file in $(RD_APPS) ; do \
+	for file in $(RD_APPS) ; do \
 		rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
 	done
-	-rm -fr $(TMP)
-	-rm -f $(BASE)/image.iso
+	rm -fr $(TMP)
+	rm -f $(BASE)/image.iso
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/arm32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -29,14 +29,9 @@
 build: $(BASE)/image.boot
 
-$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot
-	cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot
-
-depend:
-	-rm arch/$(BARCH)/loader/image.boot
-
-arch/$(BARCH)/loader/image.boot:
-	make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
+$(BASE)/image.boot:
+	$(MAKE) -C arch/$(BARCH)/loader
+	cp arch/$(BARCH)/loader/image.boot $@
 
 clean:
-	make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-	-rm -f $(BASE)/image.boot
+	$(MAKE) -C arch/$(BARCH)/loader clean
+	rm -f $(BASE)/image.boot
Index: boot/arch/arm32/loader/Makefile
===================================================================
--- boot/arch/arm32/loader/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/arm32/loader/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,128 +28,20 @@
 #
 
-include ../../../../version
--include ../../../../Makefile.config
+include Makefile.common
 
-## Toolchain configuration
-#
+.PHONY: all clean
 
-ifndef CROSS_PREFIX
-	CROSS_PREFIX = /usr/local
-endif
-
-BFD_NAME = elf32-littlearm
-BFD_ARCH = arm
-TARGET = arm-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin
-
-ifeq ($(COMPILER),gcc_native)
-	CC = gcc
-	AS = as
-	LD = ld
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-endif
-
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
-	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
-	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
-endif
-
-CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../.. -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -pipe
-
-SOURCES = \
-	main.c \
-	boot.S \
-	asm.S \
-	mm.c \
-	print/print.c \
-	_components.c \
-	../../../generic/printf.c \
-	../../../generic/string.c \
-	../../../genarch/division.c
-
-COMPONENTS = \
-	$(KERNELDIR)/kernel.bin \
-	$(USPACEDIR)/srv/ns/ns \
-	$(USPACEDIR)/srv/loader/loader \
-	$(USPACEDIR)/app/init/init \
-	$(USPACEDIR)/srv/devmap/devmap \
-	$(USPACEDIR)/srv/bd/rd/rd \
-	$(USPACEDIR)/srv/vfs/vfs
-ifeq ($(RDFMT),tmpfs)
-	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
-endif
-ifeq ($(RDFMT),fat)
-	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
-endif
-
-RD_SRVS = \
-	$(USPACEDIR)/srv/fb/fb \
-	$(USPACEDIR)/srv/kbd/kbd \
-	$(USPACEDIR)/srv/console/console \
-	$(USPACEDIR)/srv/fs/devfs/devfs \
-	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
-	$(USPACEDIR)/srv/fs/fat/fat \
-	$(USPACEDIR)/srv/bd/file_bd/file_bd
-ifeq ($(MACHINE),testarm)
-	RD_SRVS += \
-		$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
-endif
-
-RD_APPS = \
-	$(USPACEDIR)/app/getvc/getvc \
-	$(USPACEDIR)/app/tetris/tetris \
-	$(USPACEDIR)/app/tester/tester \
-	$(USPACEDIR)/app/trace/trace \
-	$(USPACEDIR)/app/klog/klog \
-	$(USPACEDIR)/app/bdsh/bdsh
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
-
-.PHONY: all clean depend
-
-all: image.boot
-
--include Makefile.depend
-
-image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
-	$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@
-
-depend:
-	-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
+all: ../../../../version ../../../../Makefile.config ../../../../config.h ../../../../config.defs
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-for file in $(RD_SRVS) ; do \
+	for file in $(RD_SRVS) ; do \
 		rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
 	done
-	-for file in $(RD_APPS) ; do \
+	for file in $(RD_APPS) ; do \
 		rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
 	done
-	-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.boot Makefile.depend
-
-_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
-	for file in $(RD_SRVS) ; do \
-		cp $$file $(USPACEDIR)/dist/srv/ ; \
-	done
-	for file in $(RD_APPS) ; do \
-		cp $$file $(USPACEDIR)/dist/app/ ; \
-	done
-ifeq ($(RDFMT),tmpfs)
-	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
-endif
-ifeq ($(RDFMT),fat)
-	../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
-endif
-	../../../../tools/mkhord.py 4096 initrd.fs initrd.img
-	rm initrd.fs
-	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 4096 "unsigned int" $(COMPONENTS) ./initrd.img
-
-%.o: %.S
-	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(COMPS).h $(COMPS).c $(LINK) $(INITRD).img $(INITRD).fs
+	find . -name '*.o' -follow -exec rm \{\} \;
+	find . -name '*.co' -follow -exec rm \{\} \;
Index: boot/arch/arm32/loader/Makefile.build
===================================================================
--- boot/arch/arm32/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/arm32/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,102 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include ../../../../version
+include ../../../../Makefile.config
+include ../../../../config.defs
+include Makefile.common
+include Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	main.c \
+	boot.S \
+	asm.S \
+	mm.c \
+	print/print.c \
+	_components.c \
+	../../../generic/printf.c \
+	../../../generic/string.c \
+	../../../genarch/division.c
+
+COMPONENTS = \
+	$(KERNELDIR)/kernel.bin \
+	$(USPACEDIR)/srv/ns/ns \
+	$(USPACEDIR)/srv/loader/loader \
+	$(USPACEDIR)/app/init/init \
+	$(USPACEDIR)/srv/devmap/devmap \
+	$(USPACEDIR)/srv/bd/rd/rd \
+	$(USPACEDIR)/srv/vfs/vfs
+ifeq ($(RDFMT),tmpfs)
+	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
+endif
+ifeq ($(RDFMT),fat)
+	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
+endif
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+COMPONENT_OBJECTS := $(addsuffix .co,$(basename $(notdir $(COMPONENTS)))) $(INITRD).co
+
+.PHONY: all
+
+all: $(OUTPUT)
+
+-include $(DEPEND)
+
+$(OUTPUT): $(OBJECTS) $(COMPONENT_OBJECTS) $(LINK)
+	$(LD) -no-check-sections -N -T $(LINK) $(COMPONENT_OBJECTS) $(OBJECTS) -o $@
+
+%.o: %.S $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	for file in $(RD_SRVS) ; do \
+		cp $$file $(USPACEDIR)/dist/srv/ ; \
+	done
+	for file in $(RD_APPS) ; do \
+		cp $$file $(USPACEDIR)/dist/app/ ; \
+	done
+ifeq ($(RDFMT),tmpfs)
+	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+ifeq ($(RDFMT),fat)
+	../../../../tools/mkfat.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+	../../../../tools/mkhord.py 4096 $(INITRD).fs $(INITRD).img
+	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 4096 "unsigned int" $(COMPONENTS) ./$(INITRD).img
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: boot/arch/arm32/loader/Makefile.common
===================================================================
--- boot/arch/arm32/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/arm32/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = image.boot
+
+LINK = _link.ld
+COMPS = _components
+INITRD = initrd
+
+KERNELDIR = ../../../../kernel
+USPACEDIR = ../../../../uspace
+
+RD_SRVS = \
+	$(USPACEDIR)/srv/fb/fb \
+	$(USPACEDIR)/srv/kbd/kbd \
+	$(USPACEDIR)/srv/console/console \
+	$(USPACEDIR)/srv/fs/devfs/devfs \
+	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
+	$(USPACEDIR)/srv/fs/fat/fat \
+	$(USPACEDIR)/srv/bd/file_bd/file_bd \
+	$(USPACEDIR)/srv/part/mbr_part/mbr_part \
+	$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
+
+RD_APPS = \
+	$(USPACEDIR)/app/edit/edit \
+	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
+	$(USPACEDIR)/app/tetris/tetris \
+	$(USPACEDIR)/app/tester/tester \
+	$(USPACEDIR)/app/trace/trace \
+	$(USPACEDIR)/app/klog/klog \
+	$(USPACEDIR)/app/bdsh/bdsh
Index: boot/arch/arm32/loader/Makefile.toolchain
===================================================================
--- boot/arch/arm32/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/arm32/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2006 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.
+#
+
+## Toolchain configuration
+#
+
+ifndef CROSS_PREFIX
+	CROSS_PREFIX = /usr/local
+endif
+
+BFD_NAME = elf32-littlearm
+BFD_ARCH = arm
+TARGET = arm-linux-gnu
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm32/bin
+
+ifeq ($(COMPILER),gcc_native)
+	CC = gcc
+	AS = as
+	LD = ld
+	OBJCOPY = objcopy
+	OBJDUMP = objdump
+endif
+
+ifeq ($(COMPILER),gcc_cross)
+	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
+	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
+	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
+	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
+	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
+endif
+
+CFLAGS = \
+	-DRELEASE=$(RELEASE) -I. -I../../../generic -I../../.. \
+	-imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin \
+	-Werror-implicit-function-declaration -Wmissing-prototypes -Werror \
+	-O3 -pipe
+
+DEPEND_DEFS = $(CONFIG_DEFS)
Index: boot/arch/arm32/loader/asm.h
===================================================================
--- boot/arch/arm32/loader/asm.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/arm32/loader/asm.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/arm32/loader/main.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -43,4 +43,5 @@
 #include <macros.h>
 #include <string.h>
+#include <memstr.h>
 
 #include "mm.h"
Index: boot/arch/ia32/Makefile.inc
===================================================================
--- boot/arch/ia32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ia32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,106 +1,1 @@
-#
-# Copyright (c) 2006 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.
-#
-
-TMP = distroot
-
-INIT_TASKS = \
-	$(USPACEDIR)/srv/ns/ns \
-	$(USPACEDIR)/srv/loader/loader \
-	$(USPACEDIR)/app/init/init \
-	$(USPACEDIR)/srv/devmap/devmap \
-	$(USPACEDIR)/srv/bd/rd/rd \
-	$(USPACEDIR)/srv/vfs/vfs
-ifeq ($(RDFMT),tmpfs)
-	INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
-endif
-ifeq ($(RDFMT),fat)
-	INIT_TASKS += $(USPACEDIR)/srv/fs/fat/fat
-endif
-
-RD_SRVS = \
-	$(USPACEDIR)/srv/pci/pci \
-	$(USPACEDIR)/srv/fb/fb \
-	$(USPACEDIR)/srv/kbd/kbd \
-	$(USPACEDIR)/srv/console/console \
-	$(USPACEDIR)/srv/fs/devfs/devfs \
-	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
-	$(USPACEDIR)/srv/fs/fat/fat \
-	$(USPACEDIR)/srv/bd/ata_bd/ata_bd \
-	$(USPACEDIR)/srv/bd/file_bd/file_bd
-
-RD_APPS = \
-	$(USPACEDIR)/app/getvc/getvc \
-	$(USPACEDIR)/app/tetris/tetris \
-	$(USPACEDIR)/app/tester/tester \
-	$(USPACEDIR)/app/trace/trace \
-	$(USPACEDIR)/app/klog/klog \
-	$(USPACEDIR)/app/bdsh/bdsh \
-	$(USPACEDIR)/app/lspci/lspci \
-	$(USPACEDIR)/app/shutters/shutters \
-	$(USPACEDIR)/app/test_serial/test_serial
-
-build: $(BASE)/image.iso
-
-$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS)
-	mkdir -p $(TMP)/boot/grub
-	cp arch/$(BARCH)/grub/stage2_eltorito $(TMP)/boot/grub/
-ifneq ($(RDFMT),tmpfs)
-	cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" > $(TMP)/boot/grub/menu.lst
-endif
-ifneq ($(RDFMT),fat)
-	cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" > $(TMP)/boot/grub/menu.lst
-endif
-	cp $(KERNELDIR)/kernel.bin $(TMP)/boot/
-	for task in $(INIT_TASKS) ; do \
-		cp $$task $(TMP)/boot/ ; \
-	done
-	for file in $(RD_SRVS) ; do \
-		cp $$file $(USPACEDIR)/dist/srv/ ; \
-	done
-	for file in $(RD_APPS) ; do \
-		cp $$file $(USPACEDIR)/dist/app/ ; \
-	done
-ifeq ($(RDFMT),tmpfs)
-	$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
-endif
-ifeq ($(RDFMT),fat)
-	$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
-endif
-	$(BASE)/tools/mkhord.py 4096 $(TMP)/boot/initrd.fs $(TMP)/boot/initrd.img
-	rm $(TMP)/boot/initrd.fs
-	mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $@ $(TMP)/
-
-clean:
-	-for file in $(RD_SRVS) ; do \
-		rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
-	done
-	-for file in $(RD_APPS) ; do \
-		rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
-	done
-	-rm -fr $(TMP)
-	-rm -f $(BASE)/image.iso
+../amd64/Makefile.inc
Index: boot/arch/ia64/Makefile.inc
===================================================================
--- boot/arch/ia64/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ia64/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -29,14 +29,9 @@
 build: $(BASE)/image.boot
 
-$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot
-	cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot
+$(BASE)/image.boot:
+	$(MAKE) -C arch/$(BARCH)/loader
+	cp arch/$(BARCH)/loader/image.boot $@
 
-depend:
-	-rm arch/$(BARCH)/loader/image.boot
-
-arch/$(BARCH)/loader/image.boot:
-	make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-
-clean: generic_clean
-	make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-	-rm -f $(BASE)/image.boot
+clean:
+	$(MAKE) -C arch/$(BARCH)/loader clean
+	rm -f $(BASE)/image.boot $(BASE)/hello.efi $(BASE)/image.bin
Index: boot/arch/ia64/loader/Makefile
===================================================================
--- boot/arch/ia64/loader/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ia64/loader/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,145 +28,22 @@
 #
 
-include ../../../../version
--include ../../../../Makefile.config
+include Makefile.common
 
-## Toolchain configuration
-#
+.PHONY: all clean
 
-ifndef CROSS_PREFIX
-	CROSS_PREFIX = /usr/local
-endif
-
-BFD_NAME = elf64-ia64-little
-BFD_ARCH = ia64
-TARGET = ia64-pc-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin
-
-ifeq ($(COMPILER),gcc_native)
-	CC = gcc
-	AS = as
-	LD = ld
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-	GEFI_PREFIX =
-endif
-
-ifeq ($(COMPILER),icc_native)
-	CC = icc
-	AS = as
-	LD = ld
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-endif
-
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
-	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
-	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
-	GEFI_PREFIX = $(TOOLCHAIN_DIR)/$(TARGET)-
-endif
-
-#-mno-pic means do not use gp + imm22 to address data
-CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -I../../../../kernel/generic/include -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -fno-unwind-tables -mfixed-range=f32-f127 -mno-pic -pipe
-
-SOURCES = \
-	main.c \
-	../../../generic/printf.c \
-	../../../generic/string.c \
-	../../../genarch/balloc.c \
-	_components.c \
-	asm.S \
-	boot.S
-
-NOCOMPONENTS = \
-	$(KERNELDIR)/kernel.bin 
-COMPONENTS = \
-	$(KERNELDIR)/kernel.bin \
-	$(USPACEDIR)/srv/ns/ns \
-	$(USPACEDIR)/srv/loader/loader \
-	$(USPACEDIR)/app/init/init \
-	$(USPACEDIR)/srv/devmap/devmap \
-	$(USPACEDIR)/srv/bd/rd/rd \
-	$(USPACEDIR)/srv/vfs/vfs
-ifeq ($(RDFMT),tmpfs)
-	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
-endif
-ifeq ($(RDFMT),fat)
-	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
-endif
-
-RD_SRVS = \
-	$(USPACEDIR)/srv/fb/fb \
-	$(USPACEDIR)/srv/kbd/kbd \
-	$(USPACEDIR)/srv/console/console \
-	$(USPACEDIR)/srv/fs/devfs/devfs \
-	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
-	$(USPACEDIR)/srv/fs/fat/fat \
-	$(USPACEDIR)/srv/bd/file_bd/file_bd
-
-RD_APPS = \
-	$(USPACEDIR)/app/getvc/getvc \
-	$(USPACEDIR)/app/tetris/tetris \
-	$(USPACEDIR)/app/tester/tester \
-	$(USPACEDIR)/app/trace/trace \
-	$(USPACEDIR)/app/klog/klog \
-	$(USPACEDIR)/app/bdsh/bdsh
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
-
-.PHONY: all clean depend
-
-all: hello.efi disasm
-
--include Makefile.depend
-
-hello.efi: image.boot
-	make -C gefi/HelenOS PREFIX=$(GEFI_PREFIX)
-	cp gefi/HelenOS/hello.efi ../../../../
-	cp gefi/HelenOS/image.bin ../../../../
-
-image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
-	$(LD) -Map image.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@
-
-depend:
-	-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
+all: ../../../../version ../../../../Makefile.config ../../../../config.h ../../../../config.defs
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-for file in $(RD_SRVS) ; do \
+	$(MAKE) -C gefi clean
+	$(MAKE) -C gefi/HelenOS clean
+	for file in $(RD_SRVS) ; do \
 		rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
 	done
-	-for file in $(RD_APPS) ; do \
+	for file in $(RD_APPS) ; do \
 		rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
 	done
-	-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) image.boot image.map image.disasm initrd.img image.boot Makefile.depend ../../../../image.bin ../../../../hello.efi
-	make -C gefi clean
-	make -C gefi/HelenOS clean
-
-_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
-	for file in $(RD_SRVS) ; do \
-		cp $$file $(USPACEDIR)/dist/srv/ ; \
-	done
-	for file in $(RD_APPS) ; do \
-		cp $$file $(USPACEDIR)/dist/app/ ; \
-	done
-ifeq ($(RDFMT),tmpfs)
-	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
-endif
-ifeq ($(RDFMT),fat)
-	../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
-endif
-	../../../../tools/mkhord.py 16384 initrd.fs initrd.img
-	rm initrd.fs
-	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned long" $(COMPONENTS) ./initrd.img
-
-%.o: %.S
-	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-disasm: image.boot
-	$(OBJDUMP) -d image.boot > image.disasm
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(HELLO) $(COMPS).h $(COMPS).c $(LINK) $(INITRD).img $(INITRD).fs
+	find . -name '*.o' -follow -exec rm \{\} \;
+	find . -name '*.co' -follow -exec rm \{\} \;
Index: boot/arch/ia64/loader/Makefile.build
===================================================================
--- boot/arch/ia64/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/ia64/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include ../../../../version
+include ../../../../Makefile.config
+include ../../../../config.defs
+include Makefile.common
+include Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	main.c \
+	../../../generic/printf.c \
+	../../../generic/string.c \
+	../../../genarch/balloc.c \
+	_components.c \
+	asm.S \
+	boot.S
+
+COMPONENTS = \
+	$(KERNELDIR)/kernel.bin \
+	$(USPACEDIR)/srv/ns/ns \
+	$(USPACEDIR)/srv/loader/loader \
+	$(USPACEDIR)/app/init/init \
+	$(USPACEDIR)/srv/devmap/devmap \
+	$(USPACEDIR)/srv/bd/rd/rd \
+	$(USPACEDIR)/srv/vfs/vfs
+ifeq ($(RDFMT),tmpfs)
+	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
+endif
+ifeq ($(RDFMT),fat)
+	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
+endif
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+COMPONENT_OBJECTS := $(addsuffix .co,$(basename $(notdir $(COMPONENTS)))) $(INITRD).co
+
+.PHONY: all
+
+all: $(OUTPUT)
+
+-include $(DEPEND)
+
+$(OUTPUT): $(OBJECTS) $(COMPONENT_OBJECTS) $(LINK)
+	$(LD) -no-check-sections -N -T $(LINK) $(COMPONENT_OBJECTS) $(OBJECTS) -o $@
+	$(MAKE) -C gefi/HelenOS PREFIX=$(GEFI_PREFIX)
+	cp gefi/HelenOS/hello.efi ../../../../
+	cp gefi/HelenOS/image.bin ../../../../
+
+%.o: %.S $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	for file in $(RD_SRVS) ; do \
+		cp $$file $(USPACEDIR)/dist/srv/ ; \
+	done
+	for file in $(RD_APPS) ; do \
+		cp $$file $(USPACEDIR)/dist/app/ ; \
+	done
+ifeq ($(RDFMT),tmpfs)
+	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+ifeq ($(RDFMT),fat)
+	../../../../tools/mkfat.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+	../../../../tools/mkhord.py 16384 $(INITRD).fs $(INITRD).img
+	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned long" $(COMPONENTS) ./$(INITRD).img
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: boot/arch/ia64/loader/Makefile.common
===================================================================
--- boot/arch/ia64/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/ia64/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = image.boot
+HELLO = hello.efi
+
+LINK = _link.ld
+COMPS = _components
+INITRD = initrd
+
+KERNELDIR = ../../../../kernel
+USPACEDIR = ../../../../uspace
+
+RD_SRVS = \
+	$(USPACEDIR)/srv/fb/fb \
+	$(USPACEDIR)/srv/kbd/kbd \
+	$(USPACEDIR)/srv/console/console \
+	$(USPACEDIR)/srv/fs/devfs/devfs \
+	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
+	$(USPACEDIR)/srv/fs/fat/fat \
+	$(USPACEDIR)/srv/bd/file_bd/file_bd \
+	$(USPACEDIR)/srv/part/mbr_part/mbr_part
+
+RD_APPS = \
+	$(USPACEDIR)/app/edit/edit \
+	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
+	$(USPACEDIR)/app/tetris/tetris \
+	$(USPACEDIR)/app/tester/tester \
+	$(USPACEDIR)/app/trace/trace \
+	$(USPACEDIR)/app/klog/klog \
+	$(USPACEDIR)/app/bdsh/bdsh
Index: boot/arch/ia64/loader/Makefile.toolchain
===================================================================
--- boot/arch/ia64/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/ia64/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,75 @@
+#
+# Copyright (c) 2006 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.
+#
+
+## Toolchain configuration
+#
+
+ifndef CROSS_PREFIX
+	CROSS_PREFIX = /usr/local
+endif
+
+BFD_NAME = elf64-ia64-little
+BFD_ARCH = ia64
+TARGET = ia64-pc-linux-gnu
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin
+
+ifeq ($(COMPILER),gcc_native)
+	CC = gcc
+	AS = as
+	LD = ld
+	OBJCOPY = objcopy
+	OBJDUMP = objdump
+	GEFI_PREFIX =
+endif
+
+ifeq ($(COMPILER),icc)
+	CC = icc
+	AS = as
+	LD = ld
+	OBJCOPY = objcopy
+	OBJDUMP = objdump
+	GEFI_PREFIX =
+endif
+
+ifeq ($(COMPILER),gcc_cross)
+	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
+	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
+	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
+	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
+	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
+	GEFI_PREFIX = $(TOOLCHAIN_DIR)/$(TARGET)-
+endif
+
+CFLAGS = \
+	-DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch \
+	-I../../../../kernel/generic/include -imacros ../../../../config.h \
+	-nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration \
+	-Wmissing-prototypes -Werror -O3 -fno-unwind-tables -mfixed-range=f32-f127 \
+	-mno-pic -pipe
+
+DEPEND_DEFS = $(CONFIG_DEFS)
Index: boot/arch/ia64/loader/asm.h
===================================================================
--- boot/arch/ia64/loader/asm.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ia64/loader/asm.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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/gefi/HelenOS/Makefile
===================================================================
--- boot/arch/ia64/loader/gefi/HelenOS/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ia64/loader/gefi/HelenOS/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -69,3 +69,3 @@
 
 gefi:
-	make -C .. prefix=$(PREFIX)
+	$(MAKE) -C .. prefix=$(PREFIX)
Index: boot/arch/ia64/loader/main.h
===================================================================
--- boot/arch/ia64/loader/main.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ia64/loader/main.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -34,7 +34,5 @@
 
 
-#define CONFIG_INIT_TASKS	32
-
-
+#define CONFIG_INIT_TASKS  32
 
 extern void start(void);
Index: boot/arch/mips32/Makefile.inc
===================================================================
--- boot/arch/mips32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/mips32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -29,14 +29,9 @@
 build: $(BASE)/image.boot
 
-$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot
-	cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot
-
-depend:
-	-rm arch/$(BARCH)/loader/image.boot
-
-arch/$(BARCH)/loader/image.boot:
-	make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
+$(BASE)/image.boot:
+	$(MAKE) -C arch/$(BARCH)/loader
+	cp arch/$(BARCH)/loader/image.boot $@
 
 clean:
-	make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-	-rm -f $(BASE)/image.boot
+	$(MAKE) -C arch/$(BARCH)/loader clean
+	rm -f $(BASE)/image.boot
Index: boot/arch/mips32/loader/Makefile
===================================================================
--- boot/arch/mips32/loader/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/mips32/loader/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,140 +28,20 @@
 #
 
-include ../../../../version
--include ../../../../Makefile.config
+include Makefile.common
 
-## Toolchain configuration
-#
+.PHONY: all clean
 
-ifndef CROSS_PREFIX
-	CROSS_PREFIX = /usr/local
-endif
-
-BFD_ARCH = mips
-TARGET = mipsel-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin
-
-ifeq ($(MACHINE),lgxemul)
-	BFD_NAME = elf32-tradlittlemips
-	BFD = ecoff-littlemips
-endif
-ifeq ($(MACHINE),bgxemul)
-	BFD_NAME = elf32-tradbigmips
-	BFD = ecoff-bigmips
-	TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin
-	TARGET = mips-linux-gnu
-endif
-ifeq ($(MACHINE),msim)
-	BFD_NAME = elf32-tradlittlemips
-	BFD = binary
-endif
-
-ifeq ($(COMPILER),gcc_native)
-	CC = gcc
-	AS = as
-	LD = ld
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-endif
-
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
-	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
-	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
-endif
-
-CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mhard-float -mips3 -pipe
-
-SOURCES = \
-	main.c \
-	msim.c \
-	_components.c \
-	../../../generic/printf.c \
-	../../../generic/string.c \
-	asm.S \
-	boot.S
-
-COMPONENTS = \
-	$(KERNELDIR)/kernel.bin \
-	$(USPACEDIR)/srv/ns/ns \
-	$(USPACEDIR)/srv/loader/loader \
-	$(USPACEDIR)/app/init/init \
-	$(USPACEDIR)/srv/devmap/devmap \
-	$(USPACEDIR)/srv/bd/rd/rd \
-	$(USPACEDIR)/srv/vfs/vfs
-ifeq ($(RDFMT),tmpfs)
-	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
-endif
-ifeq ($(RDFMT),fat)
-	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
-endif
-
-RD_SRVS = \
-	$(USPACEDIR)/srv/fb/fb \
-	$(USPACEDIR)/srv/kbd/kbd \
-	$(USPACEDIR)/srv/console/console \
-	$(USPACEDIR)/srv/fs/devfs/devfs \
-	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
-	$(USPACEDIR)/srv/fs/fat/fat \
-	$(USPACEDIR)/srv/bd/file_bd/file_bd \
-	$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
-
-RD_APPS = \
-	$(USPACEDIR)/app/getvc/getvc \
-	$(USPACEDIR)/app/tetris/tetris \
-	$(USPACEDIR)/app/tester/tester \
-	$(USPACEDIR)/app/trace/trace \
-	$(USPACEDIR)/app/bdsh/bdsh \
-	$(USPACEDIR)/app/klog/klog
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
-
-.PHONY: all clean depend
-
-all: image.boot
-
--include Makefile.depend
-
-image.boot: image.raw
-	$(OBJCOPY) -O $(BFD) $< $@
-
-image.raw: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
-	$(LD) -no-check-sections -N -T _link.ld -o $@ $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
-
-depend:
-	-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
+all: ../../../../version ../../../../Makefile.config ../../../../config.h ../../../../config.defs
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-for file in $(RD_SRVS) ; do \
+	for file in $(RD_SRVS) ; do \
 		rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
 	done
-	-for file in $(RD_APPS) ; do \
+	for file in $(RD_APPS) ; do \
 		rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
 	done
-	-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.raw image.boot Makefile.depend
-
-_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
-	for file in $(RD_SRVS) ; do \
-		cp $$file $(USPACEDIR)/dist/srv/ ; \
-	done
-	for file in $(RD_APPS) ; do \
-		cp $$file $(USPACEDIR)/dist/app/ ; \
-	done
-ifeq ($(RDFMT),tmpfs)
-	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
-endif
-ifeq ($(RDFMT),fat)
-	../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
-endif
-	../../../../tools/mkhord.py 16384 initrd.fs initrd.img
-	rm initrd.fs
-	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned int" $(COMPONENTS) ./initrd.img
-
-%.o: %.S
-	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(RAW) $(COMPS).h $(COMPS).c $(LINK) $(INITRD).img $(INITRD).fs
+	find . -name '*.o' -follow -exec rm \{\} \;
+	find . -name '*.co' -follow -exec rm \{\} \;
Index: boot/arch/mips32/loader/Makefile.build
===================================================================
--- boot/arch/mips32/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/mips32/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include ../../../../version
+include ../../../../Makefile.config
+include ../../../../config.defs
+include Makefile.common
+include Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	main.c \
+	msim.c \
+	_components.c \
+	../../../generic/printf.c \
+	../../../generic/string.c \
+	asm.S \
+	boot.S
+
+COMPONENTS = \
+	$(KERNELDIR)/kernel.bin \
+	$(USPACEDIR)/srv/ns/ns \
+	$(USPACEDIR)/srv/loader/loader \
+	$(USPACEDIR)/app/init/init \
+	$(USPACEDIR)/srv/devmap/devmap \
+	$(USPACEDIR)/srv/bd/rd/rd \
+	$(USPACEDIR)/srv/vfs/vfs
+ifeq ($(RDFMT),tmpfs)
+	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
+endif
+ifeq ($(RDFMT),fat)
+	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
+endif
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+COMPONENT_OBJECTS := $(addsuffix .co,$(basename $(notdir $(COMPONENTS)))) $(INITRD).co
+
+.PHONY: all
+
+all: $(OUTPUT)
+
+-include $(DEPEND)
+
+$(OUTPUT): $(RAW)
+	$(OBJCOPY) -O $(BFD) $< $@
+
+$(RAW): $(OBJECTS) $(COMPONENT_OBJECTS) $(LINK)
+	$(LD) -no-check-sections -N -T $(LINK) $(COMPONENT_OBJECTS) $(OBJECTS) -o $@
+
+%.o: %.S $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	for file in $(RD_SRVS) ; do \
+		cp $$file $(USPACEDIR)/dist/srv/ ; \
+	done
+	for file in $(RD_APPS) ; do \
+		cp $$file $(USPACEDIR)/dist/app/ ; \
+	done
+ifeq ($(RDFMT),tmpfs)
+	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+ifeq ($(RDFMT),fat)
+	../../../../tools/mkfat.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+	../../../../tools/mkhord.py 16384 $(INITRD).fs $(INITRD).img
+	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned int" $(COMPONENTS) ./$(INITRD).img
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: boot/arch/mips32/loader/Makefile.common
===================================================================
--- boot/arch/mips32/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/mips32/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+RAW = image.raw
+OUTPUT = image.boot
+
+LINK = _link.ld
+COMPS = _components
+INITRD = initrd
+
+KERNELDIR = ../../../../kernel
+USPACEDIR = ../../../../uspace
+
+RD_SRVS = \
+	$(USPACEDIR)/srv/fb/fb \
+	$(USPACEDIR)/srv/kbd/kbd \
+	$(USPACEDIR)/srv/console/console \
+	$(USPACEDIR)/srv/fs/devfs/devfs \
+	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
+	$(USPACEDIR)/srv/fs/fat/fat \
+	$(USPACEDIR)/srv/bd/file_bd/file_bd \
+	$(USPACEDIR)/srv/part/mbr_part/mbr_part \
+	$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
+
+RD_APPS = \
+	$(USPACEDIR)/app/edit/edit \
+	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
+	$(USPACEDIR)/app/tetris/tetris \
+	$(USPACEDIR)/app/tester/tester \
+	$(USPACEDIR)/app/trace/trace \
+	$(USPACEDIR)/app/klog/klog \
+	$(USPACEDIR)/app/bdsh/bdsh
Index: boot/arch/mips32/loader/Makefile.toolchain
===================================================================
--- boot/arch/mips32/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/mips32/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2006 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.
+#
+
+## Toolchain configuration
+#
+
+ifndef CROSS_PREFIX
+	CROSS_PREFIX = /usr/local
+endif
+
+BFD_ARCH = mips
+TARGET = mipsel-linux-gnu
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32/bin
+
+ifeq ($(MACHINE),lgxemul)
+	BFD_NAME = elf32-tradlittlemips
+	BFD = ecoff-littlemips
+endif
+
+ifeq ($(MACHINE),bgxemul)
+	BFD_NAME = elf32-tradbigmips
+	BFD = ecoff-bigmips
+	TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32eb/bin
+	TARGET = mips-linux-gnu
+endif
+
+ifeq ($(MACHINE),msim)
+	BFD_NAME = elf32-tradlittlemips
+	BFD = binary
+endif
+
+ifeq ($(COMPILER),gcc_native)
+	CC = gcc
+	AS = as
+	LD = ld
+	OBJCOPY = objcopy
+	OBJDUMP = objdump
+endif
+
+ifeq ($(COMPILER),gcc_cross)
+	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
+	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
+	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
+	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
+	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
+endif
+
+CFLAGS = \
+	-DRELEASE=$(RELEASE) -I. -I../../../generic \
+	-imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin \
+	-Werror-implicit-function-declaration -Wmissing-prototypes -Werror \
+	-O3 -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mhard-float \
+	-mips3 -pipe
+
+DEPEND_DEFS = $(CONFIG_DEFS)
Index: boot/arch/mips32/loader/asm.h
===================================================================
--- boot/arch/mips32/loader/asm.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/mips32/loader/asm.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/mips32/loader/main.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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/Makefile.inc
===================================================================
--- boot/arch/ppc32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -31,5 +31,5 @@
 build: $(BASE)/image.iso
 
-$(BASE)/image.iso: depend arch/$(BARCH)/loader/image.boot
+$(BASE)/image.iso: arch/$(BARCH)/loader/image.boot
 	mkdir -p $(TMP)/boot
 	mkdir -p $(TMP)/ppc
@@ -41,12 +41,9 @@
 	mkisofs -hfs -part -map arch/$(BARCH)/yaboot/maps -no-desktop -hfs-volid "HelenOS" -hfs-bless $(TMP)/boot -r -o $@ $(TMP)/
 
-depend:
-	-rm arch/$(BARCH)/loader/image.boot
-
 arch/$(BARCH)/loader/image.boot:
-	$(MAKE) -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
+	$(MAKE) -C arch/$(BARCH)/loader
 
 clean: generic_clean
-	$(MAKE) -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-	-rm -fr $(TMP)
-	-rm -f $(BASE)/image.iso
+	$(MAKE) -C arch/$(BARCH)/loader clean
+	rm -fr $(TMP)
+	rm -f $(BASE)/image.iso
Index: boot/arch/ppc32/loader/Makefile
===================================================================
--- boot/arch/ppc32/loader/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,123 +28,20 @@
 #
 
-include ../../../../version
--include ../../../../Makefile.config
+include Makefile.common
 
-## Toolchain configuration
-#
+.PHONY: all clean
 
-ifndef CROSS_PREFIX
-	CROSS_PREFIX = /usr/local
-endif
-
-BFD_NAME = elf32-powerpc
-BFD_ARCH = powerpc:common
-TARGET = ppc-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin
-
-ifeq ($(COMPILER),gcc_native)
-	CC = gcc
-	AS = as
-	LD = ld
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-endif
-
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
-	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
-	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
-endif
-
-CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc -msoft-float -m32 -pipe
-
-SOURCES = \
-	main.c \
-	ofwarch.c \
-	_components.c \
-	../../../genarch/ofw.c \
-	../../../generic/printf.c \
-	../../../generic/string.c \
-	asm.S \
-	boot.S
-
-COMPONENTS = \
-	$(KERNELDIR)/kernel.bin \
-	$(USPACEDIR)/srv/ns/ns \
-	$(USPACEDIR)/srv/loader/loader \
-	$(USPACEDIR)/app/init/init \
-	$(USPACEDIR)/srv/devmap/devmap \
-	$(USPACEDIR)/srv/bd/rd/rd \
-	$(USPACEDIR)/srv/vfs/vfs
-ifeq ($(RDFMT),tmpfs)
-	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
-endif
-ifeq ($(RDFMT),fat)
-	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
-endif
-
-RD_SRVS = \
-	$(USPACEDIR)/srv/fb/fb \
-	$(USPACEDIR)/srv/kbd/kbd \
-	$(USPACEDIR)/srv/console/console \
-	$(USPACEDIR)/srv/fs/devfs/devfs \
-	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
-	$(USPACEDIR)/srv/fs/fat/fat \
-	$(USPACEDIR)/srv/bd/file_bd/file_bd
-
-RD_APPS = \
-	$(USPACEDIR)/app/getvc/getvc \
-	$(USPACEDIR)/app/tetris/tetris \
-	$(USPACEDIR)/app/tester/tester \
-	$(USPACEDIR)/app/trace/trace \
-	$(USPACEDIR)/app/klog/klog \
-	$(USPACEDIR)/app/bdsh/bdsh
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
-
-.PHONY: all clean depend
-
-all: image.boot
-
--include Makefile.depend
-
-image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
-	$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@
-
-depend:
-	-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
+all: ../../../../version ../../../../Makefile.config ../../../../config.h ../../../../config.defs
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-for file in $(RD_SRVS) ; do \
+	for file in $(RD_SRVS) ; do \
 		rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
 	done
-	-for file in $(RD_APPS) ; do \
+	for file in $(RD_APPS) ; do \
 		rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
 	done
-	-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.boot Makefile.depend
-
-_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
-	for file in $(RD_SRVS) ; do \
-		cp $$file $(USPACEDIR)/dist/srv/ ; \
-	done
-	for file in $(RD_APPS) ; do \
-		cp $$file $(USPACEDIR)/dist/app/ ; \
-	done
-ifeq ($(RDFMT),tmpfs)
-	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
-endif
-ifeq ($(RDFMT),fat)
-	../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
-endif
-	../../../../tools/mkhord.py 4096 initrd.fs initrd.img
-	rm initrd.fs
-	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 4096 "unsigned int" $(COMPONENTS) ./initrd.img
-
-%.o: %.S
-	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(COMPS).h $(COMPS).c $(LINK) $(INITRD).img $(INITRD).fs
+	find . -name '*.o' -follow -exec rm \{\} \;
+	find . -name '*.co' -follow -exec rm \{\} \;
Index: boot/arch/ppc32/loader/Makefile.build
===================================================================
--- boot/arch/ppc32/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/ppc32/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include ../../../../version
+include ../../../../Makefile.config
+include ../../../../config.defs
+include Makefile.common
+include Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	main.c \
+	_components.c \
+	../../../generic/printf.c \
+	../../../generic/string.c \
+	../../../genarch/balloc.c \
+	../../../genarch/ofw.c \
+	../../../genarch/ofw_tree.c \
+	ofwarch.c \
+	asm.S \
+	boot.S
+
+COMPONENTS = \
+	$(KERNELDIR)/kernel.bin \
+	$(USPACEDIR)/srv/ns/ns \
+	$(USPACEDIR)/app/init/init \
+	$(USPACEDIR)/srv/loader/loader \
+	$(USPACEDIR)/srv/devmap/devmap \
+	$(USPACEDIR)/srv/bd/rd/rd \
+	$(USPACEDIR)/srv/vfs/vfs
+ifeq ($(RDFMT),tmpfs)
+	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
+endif
+ifeq ($(RDFMT),fat)
+	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
+endif
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+COMPONENT_OBJECTS := $(addsuffix .co,$(basename $(notdir $(COMPONENTS)))) $(INITRD).co
+
+.PHONY: all
+
+all: $(OUTPUT)
+
+-include $(DEPEND)
+
+$(OUTPUT): $(OBJECTS) $(COMPONENT_OBJECTS) $(LINK)
+	$(LD) -no-check-sections -N -T $(LINK) $(COMPONENT_OBJECTS) $(OBJECTS) -o $@
+
+%.o: %.S $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	for file in $(RD_SRVS) ; do \
+		cp $$file $(USPACEDIR)/dist/srv/ ; \
+	done
+	for file in $(RD_APPS) ; do \
+		cp $$file $(USPACEDIR)/dist/app/ ; \
+	done
+ifeq ($(RDFMT),tmpfs)
+	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+ifeq ($(RDFMT),fat)
+	../../../../tools/mkfat.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+	../../../../tools/mkhord.py 4096 $(INITRD).fs $(INITRD).img
+	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 4096 "unsigned int" $(COMPONENTS) ./$(INITRD).img
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: boot/arch/ppc32/loader/Makefile.common
===================================================================
--- boot/arch/ppc32/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/ppc32/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = image.boot
+
+LINK = _link.ld
+COMPS = _components
+INITRD = initrd
+
+KERNELDIR = ../../../../kernel
+USPACEDIR = ../../../../uspace
+
+RD_SRVS = \
+	$(USPACEDIR)/srv/fb/fb \
+	$(USPACEDIR)/srv/kbd/kbd \
+	$(USPACEDIR)/srv/console/console \
+	$(USPACEDIR)/srv/fs/devfs/devfs \
+	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
+	$(USPACEDIR)/srv/fs/fat/fat \
+	$(USPACEDIR)/srv/bd/file_bd/file_bd \
+	$(USPACEDIR)/srv/part/mbr_part/mbr_part
+
+RD_APPS = \
+	$(USPACEDIR)/app/edit/edit \
+	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
+	$(USPACEDIR)/app/tetris/tetris \
+	$(USPACEDIR)/app/tester/tester \
+	$(USPACEDIR)/app/trace/trace \
+	$(USPACEDIR)/app/klog/klog \
+	$(USPACEDIR)/app/bdsh/bdsh
Index: boot/arch/ppc32/loader/Makefile.toolchain
===================================================================
--- boot/arch/ppc32/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/ppc32/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2006 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.
+#
+
+## Toolchain configuration
+#
+
+ifndef CROSS_PREFIX
+	CROSS_PREFIX = /usr/local
+endif
+
+BFD_NAME = elf32-powerpc
+BFD_ARCH = powerpc:common
+TARGET = ppc-linux-gnu
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc32/bin
+
+ifeq ($(COMPILER),gcc_native)
+	CC = gcc
+	AS = as
+	LD = ld
+	OBJCOPY = objcopy
+	OBJDUMP = objdump
+endif
+
+ifeq ($(COMPILER),gcc_cross)
+	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
+	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
+	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
+	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
+	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
+endif
+
+CFLAGS = \
+	-DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch \
+	-imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin \
+	-Werror-implicit-function-declaration -Wmissing-prototypes -Werror \
+	-O3 -mcpu=powerpc -msoft-float -m32 -pipe
+
+DEPEND_DEFS = $(CONFIG_DEFS)
Index: boot/arch/ppc32/loader/_link.ld.in
===================================================================
--- boot/arch/ppc32/loader/_link.ld.in	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/_link.ld.in	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -19,3 +19,8 @@
 [[COMPONENTS]]
 	}
+	
+	/DISCARD/ : {
+		*(.comment);
+		*(.note*);
+	}
 }
Index: boot/arch/ppc32/loader/asm.S
===================================================================
--- boot/arch/ppc32/loader/asm.S	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/asm.S	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/asm.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/main.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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,24 @@
 	}
 	
-	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;
+	}
 	
-	ofw_setup_palette();
+	pages += balloc_pages;
 	
-	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);
+	printf("Setting up screens...");
+	ofw_setup_screens();
+	printf("done.\n");
+	
+	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");
+	
+	printf("Booting the kernel...\n");
+	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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/main.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/ofwarch.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/ofwarch.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/ppc32/loader/regname.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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/Makefile.inc
===================================================================
--- boot/arch/sparc64/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -37,5 +37,5 @@
 build: $(BASE)/image.iso
 
-$(BASE)/image.iso: depend arch/$(BARCH)/loader/image.boot
+$(BASE)/image.iso: arch/$(BARCH)/loader/image.boot
 	mkdir -p $(TMP)/boot
 	mkdir -p $(TMP)/HelenOS
@@ -54,12 +54,9 @@
 	mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $@ $(TMP)/
 
-depend:
-	-rm arch/$(BARCH)/loader/image.boot
-
 arch/$(BARCH)/loader/image.boot:
-	$(MAKE) -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
+	$(MAKE) -C arch/$(BARCH)/loader
 
 clean: generic_clean
-	$(MAKE) -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-	-rm -fr $(TMP)
-	-rm -f $(BASE)/image.iso
+	$(MAKE) -C arch/$(BARCH)/loader clean
+	rm -fr $(TMP)
+	rm -f $(BASE)/image.iso
Index: boot/arch/sparc64/loader/Makefile
===================================================================
--- boot/arch/sparc64/loader/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,151 +28,20 @@
 #
 
-include ../../../../version
--include ../../../../Makefile.config
+include Makefile.common
 
-## Toolchain configuration
-#
+.PHONY: all clean
 
-ifndef CROSS_PREFIX
-	CROSS_PREFIX = /usr/local
-endif
-
-BFD_NAME = elf64-sparc
-BFD_ARCH = sparc
-TARGET = sparc64-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin
-
-ifeq ($(COMPILER),gcc_native)
-	CC = gcc
-	AS = as
-	LD = ld
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-endif
-
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
-	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
-	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
-endif
-
-CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=ultrasparc -m64 -mno-fpu -pipe
-
-SOURCES = \
-	main.c \
-	_components.c \
-	../../../generic/printf.c \
-	../../../generic/string.c \
-	../../../genarch/balloc.c \
-	../../../genarch/ofw.c \
-	../../../genarch/ofw_tree.c \
-	ofwarch.c \
-	asm.S \
-	boot.S
-
-#
-# All components that go to image.boot without the ramdisk.
-#
-COMPONENTS = \
-	$(KERNELDIR)/kernel.bin \
-	$(USPACEDIR)/srv/ns/ns \
-	$(USPACEDIR)/app/init/init \
-	$(USPACEDIR)/srv/loader/loader \
-	$(USPACEDIR)/srv/devmap/devmap \
-	$(USPACEDIR)/srv/bd/rd/rd \
-	$(USPACEDIR)/srv/vfs/vfs
-ifeq ($(RDFMT),tmpfs)
-	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
-endif
-ifeq ($(RDFMT),fat)
-	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
-endif
-
-#
-# Final list of all components that go to image.boot.
-#
-ALL_COMPONENTS = $(COMPONENTS)
-ifeq ($(CONFIG_RD_EXTERNAL),n)
-	ALL_COMPONENTS += ./initrd.img
-endif
-
-RD_SRVS = \
-	$(USPACEDIR)/srv/fb/fb \
-	$(USPACEDIR)/srv/kbd/kbd \
-	$(USPACEDIR)/srv/console/console \
-	$(USPACEDIR)/srv/pci/pci \
-	$(USPACEDIR)/srv/fs/devfs/devfs \
-	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
-	$(USPACEDIR)/srv/bd/file_bd/file_bd
-
-ifeq ($(MACHINE),generic)
-RD_SRVS += \
-	$(USPACEDIR)/srv/fs/fat/fat \
-	$(USPACEDIR)/srv/cir/fhc/fhc \
-	$(USPACEDIR)/srv/cir/obio/obio
-endif
-
-RD_APPS = \
-	$(USPACEDIR)/app/getvc/getvc \
-	$(USPACEDIR)/app/tetris/tetris \
-	$(USPACEDIR)/app/trace/trace \
-	$(USPACEDIR)/app/bdsh/bdsh \
-	$(USPACEDIR)/app/klog/klog \
-	$(USPACEDIR)/app/lspci/lspci
-
-ifeq ($(MACHINE),generic)
-RD_APPS += \
-	$(USPACEDIR)/app/tester/tester
-endif
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-ALL_COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(ALL_COMPONENTS))))
-
-.PHONY: all clean depend
-
-all: image.boot disasm
-
--include Makefile.depend
-
-image.boot: depend _components.h _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS)
-	$(LD) -Map image.map -no-check-sections -N -T _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) -o $@
-
-depend:
-	-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
+all: ../../../../version ../../../../Makefile.config ../../../../config.h ../../../../config.defs
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-for file in $(RD_SRVS) ; do \
+	for file in $(RD_SRVS) $(RD_SRVS_GENERIC) ; do \
 		rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
 	done
-	-for file in $(RD_APPS) ; do \
+	for file in $(RD_APPS) $(RD_APPS_GENERIC) ; do \
 		rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
 	done
-	-rm -f _components.h _components.c _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) initrd.img image.boot image.map image.disasm Makefile.depend
-
-_components.h _components.c _link.ld $(ALL_COMPONENT_OBJECTS): $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
-	for file in $(RD_SRVS) ; do \
-		cp $$file $(USPACEDIR)/dist/srv/ ; \
-	done
-	for file in $(RD_APPS) ; do \
-		cp $$file $(USPACEDIR)/dist/app/ ; \
-	done
-ifeq ($(RDFMT),tmpfs)
-	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
-endif
-ifeq ($(RDFMT),fat)
-	../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
-endif
-	../../../../tools/mkhord.py 16384 initrd.fs initrd.img
-	rm initrd.fs
-	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(ALL_COMPONENTS)
-
-%.o: %.S
-	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-disasm: image.boot
-	$(OBJDUMP) -d image.boot > image.disasm
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(COMPS).h $(COMPS).c $(LINK) $(INITRD).img $(INITRD).fs
+	find . -name '*.o' -follow -exec rm \{\} \;
+	find . -name '*.co' -follow -exec rm \{\} \;
Index: boot/arch/sparc64/loader/Makefile.build
===================================================================
--- boot/arch/sparc64/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/sparc64/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,118 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include ../../../../version
+include ../../../../Makefile.config
+include ../../../../config.defs
+include Makefile.common
+include Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	main.c \
+	_components.c \
+	../../../generic/printf.c \
+	../../../generic/string.c \
+	../../../genarch/balloc.c \
+	../../../genarch/ofw.c \
+	../../../genarch/ofw_tree.c \
+	ofwarch.c \
+	asm.S \
+	boot.S
+
+COMPONENTS = \
+	$(KERNELDIR)/kernel.bin \
+	$(USPACEDIR)/srv/ns/ns \
+	$(USPACEDIR)/app/init/init \
+	$(USPACEDIR)/srv/loader/loader \
+	$(USPACEDIR)/srv/devmap/devmap \
+	$(USPACEDIR)/srv/bd/rd/rd \
+	$(USPACEDIR)/srv/vfs/vfs
+ifeq ($(RDFMT),tmpfs)
+	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
+endif
+ifeq ($(RDFMT),fat)
+	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
+endif
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+ifeq ($(CONFIG_RD_EXTERNAL),n)
+	COMPONENT_OBJECTS := $(addsuffix .co,$(basename $(notdir $(COMPONENTS)))) $(INITRD).co
+else
+	COMPONENT_OBJECTS := $(addsuffix .co,$(basename $(notdir $(COMPONENTS))))
+endif
+
+ifeq ($(MACHINE),generic)
+	RD_SRVS += $(RD_SRVS_GENERIC)
+	RD_APPS += $(RD_APPS_GENERIC)
+endif
+
+
+.PHONY: all
+
+all: $(OUTPUT)
+
+-include $(DEPEND)
+
+$(OUTPUT): $(OBJECTS) $(COMPONENT_OBJECTS) $(LINK)
+	$(LD) -no-check-sections -N -T $(LINK) $(COMPONENT_OBJECTS) $(OBJECTS) -o $@
+
+%.o: %.S $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	for file in $(RD_SRVS) ; do \
+		cp $$file $(USPACEDIR)/dist/srv/ ; \
+	done
+	for file in $(RD_APPS) ; do \
+		cp $$file $(USPACEDIR)/dist/app/ ; \
+	done
+ifeq ($(RDFMT),tmpfs)
+	../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+ifeq ($(RDFMT),fat)
+	../../../../tools/mkfat.py $(USPACEDIR)/dist/ $(INITRD).fs
+endif
+	../../../../tools/mkhord.py 16384 $(INITRD).fs $(INITRD).img
+ifeq ($(CONFIG_RD_EXTERNAL),n)
+	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(COMPONENTS) ./$(INITRD).img
+else
+	../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(COMPONENTS)
+endif
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: boot/arch/sparc64/loader/Makefile.common
===================================================================
--- boot/arch/sparc64/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/sparc64/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = image.boot
+
+LINK = _link.ld
+COMPS = _components
+INITRD = initrd
+
+KERNELDIR = ../../../../kernel
+USPACEDIR = ../../../../uspace
+
+RD_SRVS = \
+	$(USPACEDIR)/srv/fb/fb \
+	$(USPACEDIR)/srv/kbd/kbd \
+	$(USPACEDIR)/srv/console/console \
+	$(USPACEDIR)/srv/fs/devfs/devfs \
+	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
+	$(USPACEDIR)/srv/bd/file_bd/file_bd \
+	$(USPACEDIR)/srv/part/mbr_part/mbr_part
+
+RD_APPS = \
+	$(USPACEDIR)/app/edit/edit \
+	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
+	$(USPACEDIR)/app/tetris/tetris \
+	$(USPACEDIR)/app/trace/trace \
+	$(USPACEDIR)/app/klog/klog \
+	$(USPACEDIR)/app/bdsh/bdsh
+
+RD_SRVS_GENERIC = \
+	$(USPACEDIR)/srv/fs/fat/fat \
+	$(USPACEDIR)/srv/cir/fhc/fhc \
+	$(USPACEDIR)/srv/cir/obio/obio
+
+RD_APPS_GENERIC = \
+	$(USPACEDIR)/app/tester/tester
Index: boot/arch/sparc64/loader/Makefile.toolchain
===================================================================
--- boot/arch/sparc64/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/arch/sparc64/loader/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2006 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.
+#
+
+## Toolchain configuration
+#
+
+ifndef CROSS_PREFIX
+	CROSS_PREFIX = /usr/local
+endif
+
+BFD_NAME = elf64-sparc
+BFD_ARCH = sparc
+TARGET = sparc64-linux-gnu
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin
+
+ifeq ($(COMPILER),gcc_native)
+	CC = gcc
+	AS = as
+	LD = ld
+	OBJCOPY = objcopy
+	OBJDUMP = objdump
+endif
+
+ifeq ($(COMPILER),gcc_cross)
+	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
+	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
+	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
+	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
+	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
+endif
+
+CFLAGS = \
+	-DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch \
+	-imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin \
+	-Werror-implicit-function-declaration -Wmissing-prototypes -Werror \
+	-O3 -mcpu=ultrasparc -m64 -mno-fpu -pipe
+
+DEPEND_DEFS = $(CONFIG_DEFS)
Index: boot/arch/sparc64/loader/asm.S
===================================================================
--- boot/arch/sparc64/loader/asm.S	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/asm.S	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/asm.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/boot.S	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/main.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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,17 @@
 		top += components[i].size;
 	}
-
-	j = bootinfo.taskmap.count - 1;	/* do not consider ramdisk */
-
+	
+	printf("\n");
+	
+	/* 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 +207,6 @@
 		    silo_ramdisk_size;
 		bootinfo.taskmap.count++;
-		printf("\nCopying ramdisk...");
+		printf("Copying RAM disk...");
+		
 		/*
 		 * Claim and map the whole ramdisk as it may exceed the area
@@ -210,11 +216,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 +229,8 @@
 	 * with base.
 	 */
-	printf("\nCopying bootinfo tasks\n");
+	printf("Copying 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,16 +247,17 @@
 		    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("\nCopying kernel...");
+		
+	}
+	printf(".\n");
+	
+	printf("Copying kernel...");
 	(void) ofw_claim_phys(bootinfo.physmem_start + base,
 	    ALIGN_UP(components[0].size, PAGE_SIZE));
 	memcpy(base, components[0].start, components[0].size);
 	printf("done.\n");
-
+	
 	/*
 	 * Claim and map the physical memory for the boot allocator.
@@ -261,22 +269,25 @@
 	(void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
 	    BALLOC_MAX_SIZE, -1);
-	balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base);
-
-	printf("\nCanonizing OpenFirmware device tree...");
+	balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
+	    (uintptr_t) balloc_base);
+	
+	printf("Setting up screens...");
+	ofw_setup_screens();
+	printf("done.\n");
+	
+	printf("Canonizing OpenFirmware device tree...");
 	bootinfo.ofw_root = ofw_tree_build();
 	printf("done.\n");
-
+	
 #ifdef CONFIG_AP
-	printf("\nChecking for secondary processors...");
-	if (!ofw_cpu())
+	printf("Checking for secondary processors...");
+	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");
+	
+	printf("Booting 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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/main.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/ofwarch.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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,20 +61,26 @@
  * 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[OFW_TREE_PROPERTY_MAX_VALUELEN];
+		
 		if (ofw_get_property(child, "device_type", type_name,
-		    sizeof(type_name)) > 0) {
+		    OFW_TREE_PROPERTY_MAX_VALUELEN) > 0) {
+			type_name[OFW_TREE_PROPERTY_MAX_VALUELEN - 1] = 0;
 			if (strcmp(type_name, "cpu") == 0) {
 				uint32_t mid;
@@ -88,13 +90,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 +101,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 +113,36 @@
  * 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[OFW_TREE_PROPERTY_MAX_VALUELEN];
+		
 		if (ofw_get_property(node, "name", name,
-			sizeof(name)) > 0) {
+		    OFW_TREE_PROPERTY_MAX_VALUELEN) > 0) {
+			name[OFW_TREE_PROPERTY_MAX_VALUELEN - 1] = 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 +151,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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/ofwarch.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/register.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/arch/sparc64/loader/stack.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/genarch/balloc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/genarch/balloc.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/genarch/ofw.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -32,4 +32,10 @@
 #include <asm.h>
 #include <types.h>
+#include <string.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;
@@ -41,5 +47,4 @@
 ihandle ofw_memory_prop;
 phandle ofw_memory;
-phandle ofw_aliases;
 
 void ofw_init(void)
@@ -69,5 +74,5 @@
 		halt();
 	}
-
+	
 	ofw_memory = ofw_find_device("/memory");
 	if (ofw_memory == -1) {
@@ -75,22 +80,17 @@
 		halt();
 	}
-	
-	ofw_aliases = ofw_find_device("/aliases");
-	if (ofw_aliases == -1) {
-		puts("\r\nError: Unable to find /aliases device, halted.\r\n");
-		halt();
-	}
 }
 
 /** 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
@@ -127,6 +127,5 @@
 }
 
-int
-ofw_get_property(const phandle device, const char *name, void *buf,
+int ofw_get_property(const phandle device, const char *name, void *buf,
     const int buflen)
 {
@@ -161,5 +160,4 @@
 }
 
-
 unsigned int ofw_get_size_cells(const phandle device)
 {
@@ -221,5 +219,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 +232,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 +325,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,87 +346,89 @@
 }
 
-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
- * 3:2:3 color scheme can be used. Checks that setting the palette makes sense
- * (appropriate nodes exist in the OBP tree and the color depth is not greater
+static void ofw_setup_screen(phandle handle)
+{
+	/* Check for device type */
+	char device_type[OFW_TREE_PROPERTY_MAX_VALUELEN];
+	if (ofw_get_property(handle, "device_type", device_type, OFW_TREE_PROPERTY_MAX_VALUELEN) <= 0)
+		return;
+	
+	device_type[OFW_TREE_PROPERTY_MAX_VALUELEN - 1] = '\0';
+	if (strcmp(device_type, "display") != 0)
+		return;
+	
+	/* Check for 8 bit depth */
+	uint32_t depth;
+	if (ofw_get_property(handle, "depth", &depth, sizeof(uint32_t)) <= 0)
+		depth = 0;
+	
+	/* Get device path */
+	static char path[OFW_TREE_PATH_MAX_LEN + 1];
+	size_t len = ofw_package_to_path(handle, path, OFW_TREE_PATH_MAX_LEN);
+	if (len == -1)
+		return;
+	
+	path[len] = '\0';
+	
+	/* Open the display to initialize it */
+	ihandle screen = ofw_open(path);
+	if (screen == -1)
+		return;
+	
+	if (depth == 8) {
+		/* Setup the palette so that the (inverted) 3:2:3 scheme is usable */
+		unsigned int i;
+		for (i = 0; i < 256; i++) {
+			ofw_call("call-method", 6, 1, NULL, "color!", screen,
+			    255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37));
+		}
+	}
+}
+
+static void ofw_setup_screens_internal(phandle current)
+{
+	while ((current != 0) && (current != -1)) {
+		ofw_setup_screen(current);
+		
+		/*
+		 * Recursively process the potential child node.
+		 */
+		phandle child = ofw_get_child_node(current);
+		if ((child != 0) && (child != -1))
+			ofw_setup_screens_internal(child);
+		
+		/*
+		 * Iteratively process the next peer node.
+		 * Note that recursion is a bad idea here.
+		 * Due to the topology of the OpenFirmware device tree,
+		 * the nesting of peer nodes could be to wide and the
+		 * risk of overflowing the stack is too real.
+		 */
+		phandle peer = ofw_get_peer_node(current);
+		if ((peer != 0) && (peer != -1)) {
+			current = peer;
+			/*
+			 * Process the peer in next iteration.
+			 */
+			continue;
+		}
+		
+		/*
+		 * No more peers on this level.
+		 */
+		break;
+	}
+}
+
+/** Setup all screens which can be detected.
+ *
+ * Open all screens which can be detected and set up the palette for the 8-bit
+ * color depth configuration so that the 3:2:3 color scheme can be used.
+ * Check that setting the palette makes sense (the color depth is not greater
  * than 8).
  *
- * @return true if the palette has been set, false otherwise
- *
  */
-int ofw_setup_palette(void)
-{
-	char device_name[BUF_SIZE];
-	
-	/* 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 */
-	uint32_t depth;
-	phandle device = ofw_find_device(device_name);
-	if (device == -1)
-		return false;
-	if (ofw_get_property(device, "depth", &depth, sizeof(uint32_t)) <= 0)
-		return false;
-	if (depth != 8)
-		return false;
-	
-	/* 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 */
-	unsigned int i;
-	for (i = 0; i < 256; i++)
-		ofw_call("call-method", 6, 1, NULL, "color!", screen,
-		    255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37));
-	return true;
+void ofw_setup_screens(void)
+{
+	ofw_setup_screens_internal(ofw_root);
 }
 
Index: boot/genarch/ofw.h
===================================================================
--- boot/genarch/ofw.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/genarch/ofw.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -33,9 +33,10 @@
 #include <stdarg.h>
 
-#define BUF_SIZE		1024
+#define MEMMAP_MAX_RECORDS  32
+#define MAX_OFW_ARGS        12
 
-#define MEMMAP_MAX_RECORDS 	32
-
-#define MAX_OFW_ARGS            12
+#define OFW_TREE_PATH_MAX_LEN           256
+#define OFW_TREE_PROPERTY_MAX_NAMELEN   32
+#define OFW_TREE_PROPERTY_MAX_VALUELEN  64
 
 typedef unative_t ofw_arg_t;
@@ -47,8 +48,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 +64,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 {
@@ -96,5 +84,4 @@
 extern ihandle ofw_mmu;
 extern phandle ofw_memory;
-extern phandle ofw_aliases;
 
 extern void ofw_init(void);
@@ -118,11 +105,10 @@
 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_setup_screens(void);
 extern void ofw_quiesce(void);
 
Index: boot/genarch/ofw_tree.c
===================================================================
--- boot/genarch/ofw_tree.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/genarch/ofw_tree.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -29,10 +29,10 @@
 #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>
 
 static ofw_tree_node_t *ofw_tree_node_alloc(void)
@@ -49,6 +49,4 @@
 static void *ofw_tree_space_alloc(size_t size)
 {
-	char *addr;
-
 	/*
 	 * What we do here is a nasty hack :-)
@@ -61,7 +59,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 +74,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 +95,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[OFW_TREE_PATH_MAX_LEN + 1];
+		size_t len = ofw_package_to_path(current, path, OFW_TREE_PATH_MAX_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 +147,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 - 1] = '\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 +196,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 +209,5 @@
 			}
 		}
+		
 		/*
 		 * No more peers on this level.
@@ -226,16 +219,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 +233,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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/genarch/ofw_tree.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -33,31 +33,27 @@
 #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. */
-};
 
 /** 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 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ boot/generic/memstr.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/generic/printf.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
Index: boot/generic/printf.h
===================================================================
--- boot/generic/printf.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/generic/printf.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
Index: boot/generic/stdarg.h
===================================================================
--- boot/generic/stdarg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/generic/stdarg.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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: boot/tools/pack.py
===================================================================
--- boot/tools/pack.py	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ boot/tools/pack.py	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -72,5 +72,5 @@
 		plainname = os.path.splitext(basename)[0]
 		path = os.path.dirname(task)
-		object = plainname + ".o"
+		object = plainname + ".co"
 		symbol = "_binary_" + basename.replace(".", "_")
 		macro = plainname.upper()
Index: contrib/arch/HelenOS.adl
===================================================================
--- contrib/arch/HelenOS.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/HelenOS.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+system architecture HelenOS version 0.4.1 {
+	/* SPARTAN kernel */
+	inst kernel kernel;
+	
+	/* Naming Service */
+	inst ns ns;
+	
+	/* Loader (clonable service) */
+	inst loader loader;
+	
+	/* Device mapper */
+	inst devmap devmap;
+	
+	/* Block device */
+	inst bd bd;
+	
+	/* VFS server */
+	inst vfs vfs;
+	
+	/* Console */
+	inst console console;
+	
+	/* Kernel log */
+	inst klog klog;
+	
+	[/uspace/lib/libc/bind%ns]
+	[/uspace/lib/libc/bind%loader]
+	[/uspace/lib/libc/bind%devmap]
+	[/uspace/lib/libc/bind%bd]
+	[/uspace/lib/libc/bind%vfs]
+	[/uspace/lib/libc/bind%console]
+	[/uspace/lib/libc/bind%klog]
+	
+	bind ns:kbd to console:kbd;
+	bind ns:fb to console:fb;
+	bind ns:console to console:console;
+	bind ns:vfs to vfs:vfs;
+	bind ns:devmap_driver to devmap:devmap_driver;
+	bind ns:devmap_client to devmap:devmap_client;
+	bind ns:loader to loader:loader;
+	
+	bind loader:ns to ns:ns;
+	
+	bind devmap:ns to ns:ns;
+	bind devmap:rd to bd:rd;
+	bind devmap:console to console:console;
+	
+	bind bd:ns to ns:ns;
+	bind bd:devmap_driver to devmap:devmap_driver;
+	
+	bind vfs:ns to ns:ns;
+	bind vfs:rd to bd:rd;
+	bind vfs:devmap_client to devmap:devmap_client;
+	bind vfs:device to console:console;
+	
+	bind console:ns to ns:ns;
+	bind console:devmap_driver to devmap:devmap_driver;
+	bind console:sys_console to kernel:sys_console;
+	
+	bind klog:ns to ns:ns;
+};
Index: contrib/arch/hadlbppp.py
===================================================================
--- contrib/arch/hadlbppp.py	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/hadlbppp.py	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,1849 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+"""
+HelenOS Architecture Description Language and Behavior Protocols preprocessor
+"""
+
+import sys
+import os
+
+INC, POST_INC, BLOCK_COMMENT, LINE_COMMENT, SYSTEM, ARCH, HEAD, BODY, NULL, \
+	INST, VAR, FIN, BIND, TO, SUBSUME, DELEGATE, IFACE, EXTENDS, PRE_BODY, \
+	PROTOTYPE, PAR_LEFT, PAR_RIGHT, SIGNATURE, PROTOCOL, INITIALIZATION, \
+	FINALIZATION, FRAME, PROVIDES, REQUIRES = range(29)
+
+def usage(prname):
+	"Print usage syntax"
+	
+	print "%s <--bp|--ebp|--adl|--dot|--nop>+ <OUTPUT>" % prname
+	print
+	print "--bp   Dump original Behavior Protocols (dChecker, BPSlicer)"
+	print "--ebp  Dump Extended Behavior Protocols (bp2promela)"
+	print "--adl  Dump Architecture Description Language (modified SOFA ADL/CDL)"
+	print "--dot  Dump Dot architecture diagram (GraphViz)"
+	print "--nop  Do not dump anything (just input files syntax check)"
+	print
+
+def tabs(cnt):
+	"Return given number of tabs"
+	
+	return ("\t" * cnt)
+
+def cond_append(tokens, token, trim):
+	"Conditionally append token to tokens with trim"
+	
+	if (trim):
+		token = token.strip(" \t")
+	
+	if (token != ""):
+		tokens.append(token)
+	
+	return tokens
+
+def split_tokens(string, delimiters, trim = False, separate = False):
+	"Split string to tokens by delimiters, keep the delimiters"
+	
+	tokens = []
+	last = 0
+	i = 0
+	
+	while (i < len(string)):
+		for delim in delimiters:
+			if (len(delim) > 0):
+				
+				if (string[i:(i + len(delim))] == delim):
+					if (separate):
+						tokens = cond_append(tokens, string[last:i], trim)
+						tokens = cond_append(tokens, delim, trim)
+						last = i + len(delim)
+					elif (i > 0):
+						tokens = cond_append(tokens, string[last:i], trim)
+						last = i
+					
+					i += len(delim) - 1
+					break
+		
+		i += 1
+	
+	tokens = cond_append(tokens, string[last:len(string)], trim)
+	
+	return tokens
+
+def identifier(token):
+	"Check whether the token is an identifier"
+	
+	if (len(token) == 0):
+		return False
+	
+	for i, char in enumerate(token):
+		if (i == 0):
+			if ((not char.isalpha()) and (char != "_")):
+				return False
+		else:
+			if ((not char.isalnum()) and (char != "_")):
+				return False
+	
+	return True
+
+def descriptor(token):
+	"Check whether the token is an interface descriptor"
+	
+	parts = token.split(":")
+	if (len(parts) != 2):
+		return False
+	
+	return (identifier(parts[0]) and identifier(parts[1]))
+
+def word(token):
+	"Check whether the token is a word"
+	
+	if (len(token) == 0):
+		return False
+	
+	for i, char in enumerate(token):
+		if ((not char.isalnum()) and (char != "_") and (char != ".")):
+			return False
+	
+	return True
+
+def tentative_bp(name, tokens):
+	"Preprocess tentative statements in Behavior Protocol"
+	
+	result = []
+	i = 0
+	
+	while (i < len(tokens)):
+		if (tokens[i] == "tentative"):
+			if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
+				i += 2
+				start = i
+				level = 1
+				
+				while ((i < len(tokens)) and (level > 0)):
+					if (tokens[i] == "{"):
+						level += 1
+					elif (tokens[i] == "}"):
+						level -= 1
+					
+					i += 1
+				
+				if (level == 0):
+					result.append("(")
+					result.extend(tentative_bp(name, tokens[start:(i - 1)]))
+					result.append(")")
+					result.append("+")
+					result.append("NULL")
+					if (i < len(tokens)):
+						result.append(tokens[i])
+				else:
+					print "%s: Syntax error in tentative statement" % name
+			else:
+				print "%s: Expected '{' for tentative statement" % name
+		else:
+			result.append(tokens[i])
+		
+		i += 1
+	
+	return result
+
+def alternative_bp(name, tokens):
+	"Preprocess alternative statements in Behavior Protocol"
+	
+	result = []
+	i = 0
+	
+	while (i < len(tokens)):
+		if (tokens[i] == "alternative"):
+			if ((i + 1 < len(tokens)) and (tokens[i + 1] == "(")):
+				i += 2
+				reps = []
+				
+				while ((i < len(tokens)) and (tokens[i] != ")")):
+					reps.append(tokens[i])
+					if ((i + 1 < len(tokens)) and (tokens[i + 1] == ";")):
+						i += 2
+					else:
+						i += 1
+				
+				if (len(reps) >= 2):
+					if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
+						i += 2
+						
+						start = i
+						level = 1
+						
+						while ((i < len(tokens)) and (level > 0)):
+							if (tokens[i] == "{"):
+								level += 1
+							elif (tokens[i] == "}"):
+								level -= 1
+							
+							i += 1
+						
+						if (level == 0):
+							first = True
+							
+							for rep in reps[1:]:
+								retokens = []
+								for token in tokens[start:(i - 1)]:
+									parts = token.split(".")
+									if ((len(parts) == 2) and (parts[0] == reps[0])):
+										retokens.append("%s.%s" % (rep, parts[1]))
+									else:
+										retokens.append(token)
+								
+								if (first):
+									first = False
+								else:
+									result.append("+")
+								
+								result.append("(")
+								result.extend(alternative_bp(name, retokens))
+								result.append(")")
+							
+							if (i < len(tokens)):
+								result.append(tokens[i])
+						else:
+							print "%s: Syntax error in alternative statement" % name
+					else:
+						print "%s: Expected '{' for alternative statement body" % name
+				else:
+					print "%s: At least one pattern and one replacement required for alternative statement" % name
+			else:
+				print "%s: Expected '(' for alternative statement head" % name
+		else:
+			result.append(tokens[i])
+		
+		i += 1
+	
+	return result
+
+def split_bp(protocol):
+	"Convert Behavior Protocol to tokens"
+	
+	return split_tokens(protocol, ["\n", " ", "\t", "(", ")", "{", "}", "*", ";", "+", "||", "|", "!", "?"], True, True)
+
+def extend_bp(name, tokens, iface):
+	"Convert interface Behavior Protocol to generic protocol"
+	
+	result = []
+	i = 0
+	
+	while (i < len(tokens)):
+		result.append(tokens[i])
+		
+		if (tokens[i] == "?"):
+			if (i + 1 < len(tokens)):
+				i += 1
+				parts = tokens[i].split(".")
+				
+				if (len(parts) == 1):
+					result.append("%s.%s" % (iface, tokens[i]))
+				else:
+					result.append(tokens[i])
+			else:
+				print "%s: Unexpected end of protocol" % name
+		
+		i += 1
+	
+	return result
+
+def merge_bp(initialization, finalization, protocols):
+	"Merge several Behavior Protocols"
+	
+	indep = []
+	
+	if (len(protocols) > 1):
+		first = True
+		
+		for protocol in protocols:
+			if (first):
+				first = False
+			else:
+				indep.append("|")
+			
+			indep.append("(")
+			indep.extend(protocol)
+			indep.append(")")
+	elif (len(protocols) == 1):
+		indep = protocols[0]
+	
+	inited = []
+	
+	if (initialization != None):
+		if (len(indep) > 0):
+			inited.append("(")
+			inited.extend(initialization)
+			inited.append(")")
+			inited.append(";")
+			inited.append("(")
+			inited.extend(indep)
+			inited.append(")")
+		else:
+			inited = initialization
+	else:
+		inited = indep
+	
+	finited = []
+	
+	if (finalization != None):
+		if (len(inited) > 0):
+			finited.append("(")
+			finited.extend(inited)
+			finited.append(")")
+			finited.append(";")
+			finited.append("(")
+			finited.extend(finalization)
+			finited.append(")")
+		else:
+			finited = finalization
+	else:
+		finited = inited
+	
+	return finited
+
+def parse_bp(name, tokens, base_indent):
+	"Parse Behavior Protocol"
+	
+	tokens = tentative_bp(name, tokens)
+	tokens = alternative_bp(name, tokens)
+	
+	indent = base_indent
+	output = ""
+	
+	for token in tokens:
+		if (token == "\n"):
+			continue
+		
+		if ((token == ";") or (token == "+") or (token == "||") or (token == "|")):
+			output += " %s" % token
+		elif (token == "("):
+			output += "\n%s%s" % (tabs(indent), token)
+			indent += 1
+		elif (token == ")"):
+			if (indent < base_indent):
+				print "%s: Too many parentheses" % name
+			
+			indent -= 1
+			output += "\n%s%s" % (tabs(indent), token)
+		elif (token == "{"):
+			output += " %s" % token
+			indent += 1
+		elif (token == "}"):
+			if (indent < base_indent):
+				print "%s: Too many parentheses" % name
+			
+			indent -= 1
+			output += "\n%s%s" % (tabs(indent), token)
+		elif (token == "*"):
+			output += "%s" % token
+		elif ((token == "!") or (token == "?") or (token == "NULL")):
+			output += "\n%s%s" % (tabs(indent), token)
+		else:
+			output += "%s" % token
+	
+	if (indent > base_indent):
+		print "%s: Missing parentheses" % name
+	
+	output = output.strip()
+	if (output == ""):
+		return "NULL"
+	
+	return output
+
+def parse_ebp(component, name, tokens, base_indent):
+	"Parse Behavior Protocol and generate Extended Behavior Protocol output"
+	
+	return "component %s {\n\tbehavior {\n\t\t%s\n\t}\n}" % (component, parse_bp(name, tokens, base_indent + 2))
+
+def get_iface(name):
+	"Get interface by name"
+	
+	global iface_properties
+	
+	if (name in iface_properties):
+		return iface_properties[name]
+	
+	return None
+
+def inherited_protocols(iface):
+	"Get protocols inherited by an interface"
+	
+	result = []
+	
+	if ('extends' in iface):
+		supiface = get_iface(iface['extends'])
+		if (not supiface is None):
+			if ('protocol' in supiface):
+				result.append(supiface['protocol'])
+			result.extend(inherited_protocols(supiface))
+		else:
+			print "%s: Extends unknown interface '%s'" % (iface['name'], iface['extends'])
+	
+	return result
+
+def dump_frame(directed_binds, frame, outdir, var, archf):
+	"Dump Behavior Protocol of a given frame"
+	
+	global opt_bp
+	global opt_ebp
+	
+	if (opt_ebp):
+		fname = "%s.ebp" % frame['name']
+	else:
+		fname = "%s.bp" % frame['name']
+	
+	if (archf != None):
+		archf.write("instantiate %s from \"%s\"\n" % (var, fname))
+	
+	outname = os.path.join(outdir, fname)
+	
+	protocols = []
+	if ('protocol' in frame):
+		protocols.append(frame['protocol'])
+	
+	if ('initialization' in frame):
+		initialization = frame['initialization']
+	else:
+		initialization = None
+	
+	if ('finalization' in frame):
+		finalization = frame['finalization']
+	else:
+		finalization = None
+	
+	if ('provides' in frame):
+		for provides in frame['provides']:
+			iface = get_iface(provides['iface'])
+			if (not iface is None):
+				binds = directed_binds['%s.%s' % (var, provides['iface'])]
+				if (not binds is None):
+					cnt = len(binds)
+				else:
+					cnt = 1
+				
+				if ('protocol' in iface):
+					proto = extend_bp(outname, iface['protocol'], iface['name'])
+					for _ in range(0, cnt):
+						protocols.append(proto)
+				
+				for protocol in inherited_protocols(iface):
+					proto = extend_bp(outname, protocol, iface['name'])
+					for _ in range(0, cnt):
+						protocols.append(proto)
+			else:
+				print "%s: Provided interface '%s' is undefined" % (frame['name'], provides['iface'])
+	
+	if (opt_bp):
+		outf = file(outname, "w")
+		outf.write(parse_bp(outname, merge_bp(initialization, finalization, protocols), 0))
+		outf.close()
+	
+	if (opt_ebp):
+		outf = file(outname, "w")
+		outf.write(parse_ebp(frame['name'], outname, merge_bp(initialization, finalization, protocols), 0))
+		outf.close()
+
+def get_system_arch():
+	"Get system architecture"
+	
+	global arch_properties
+	
+	for arch, properties in arch_properties.items():
+		if ('system' in properties):
+			return properties
+	
+	return None
+
+def get_arch(name):
+	"Get architecture by name"
+	
+	global arch_properties
+	
+	if (name in arch_properties):
+		return arch_properties[name]
+	
+	return None
+
+def get_frame(name):
+	"Get frame by name"
+	
+	global frame_properties
+	
+	if (name in frame_properties):
+		return frame_properties[name]
+	
+	return None
+
+def create_null_bp(fname, outdir, archf):
+	"Create null frame protocol"
+	
+	global opt_bp
+	global opt_ebp
+	
+	if (archf != None):
+		archf.write("frame \"%s\"\n" % fname)
+	
+	outname = os.path.join(outdir, fname)
+	
+	if (opt_bp):
+		outf = file(outname, "w")
+		outf.write("NULL")
+		outf.close()
+	
+	if (opt_ebp):
+		outf = file(outname, "w")
+		outf.write("component null {\n\tbehavior {\n\t\tNULL\n\t}\n}")
+		outf.close()
+
+def flatten_binds(binds, delegates, subsumes):
+	"Remove bindings which are replaced by delegation or subsumption"
+	
+	result = []
+	stable = True
+	
+	for bind in binds:
+		keep = True
+		
+		for delegate in delegates:
+			if (bind['to'] == delegate['to']):
+				keep = False
+				result.append({'from': bind['from'], 'to': delegate['rep']})
+		
+		for subsume in subsumes:
+			if (bind['from'] == subsume['from']):
+				keep = False
+				result.append({'from': subsume['rep'], 'to': bind['to']})
+		
+		if (keep):
+			result.append(bind)
+		else:
+			stable = False
+	
+	if (stable):
+		return result
+	else:
+		return flatten_binds(result, delegates, subsumes)
+
+def direct_binds(binds):
+	"Convert bindings matrix to set of sources by destination"
+	
+	result = {}
+	
+	for bind in binds:
+		if (not bind['to'] in result):
+			result[bind['to']] = set()
+		
+		result[bind['to']].add(bind['from'])
+	
+	return result
+
+def merge_arch(prefix, arch, outdir):
+	"Merge subarchitecture into architecture"
+	
+	insts = []
+	binds = []
+	delegates = []
+	subsumes = []
+	
+	if ('inst' in arch):
+		for inst in arch['inst']:
+			subarch = get_arch(inst['type'])
+			if (not subarch is None):
+				(subinsts, subbinds, subdelegates, subsubsumes) = merge_arch("%s_%s" % (prefix, subarch['name']), subarch, outdir)
+				insts.extend(subinsts)
+				binds.extend(subbinds)
+				delegates.extend(subdelegates)
+				subsumes.extend(subsubsumes)
+			else:
+				subframe = get_frame(inst['type'])
+				if (not subframe is None):
+					insts.append({'var': "%s_%s" % (prefix, inst['var']), 'frame': subframe})
+				else:
+					print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
+	
+	if ('bind' in arch):
+		for bind in arch['bind']:
+			binds.append({'from': "%s_%s.%s" % (prefix, bind['from'][0], bind['from'][1]), 'to': "%s_%s.%s" % (prefix, bind['to'][0], bind['to'][1])})
+	
+	if ('delegate' in arch):
+		for delegate in arch['delegate']:
+			delegates.append({'to': "%s.%s" % (prefix, delegate['from']), 'rep': "%s_%s.%s" % (prefix, delegate['to'][0], delegate['to'][1])})
+	
+	if ('subsume' in arch):
+		for subsume in arch['subsume']:
+			subsumes.append({'from': "%s.%s" % (prefix, subsume['to']), 'rep': "%s_%s.%s" % (prefix, subsume['from'][0], subsume['from'][1])})
+	
+	return (insts, binds, delegates, subsumes)
+
+def dump_archbp(outdir):
+	"Dump system architecture Behavior Protocol"
+	
+	global opt_bp
+	global opt_ebp
+	
+	arch = get_system_arch()
+	
+	if (arch is None):
+		print "Unable to find system architecture"
+		return
+	
+	insts = []
+	binds = []
+	delegates = []
+	subsumes = []
+	
+	if ('inst' in arch):
+		for inst in arch['inst']:
+			subarch = get_arch(inst['type'])
+			if (not subarch is None):
+				(subinsts, subbinds, subdelegates, subsubsumes) = merge_arch(subarch['name'], subarch, outdir)
+				insts.extend(subinsts)
+				binds.extend(subbinds)
+				delegates.extend(subdelegates)
+				subsumes.extend(subsubsumes)
+			else:
+				subframe = get_frame(inst['type'])
+				if (not subframe is None):
+					insts.append({'var': inst['var'], 'frame': subframe})
+				else:
+					print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
+	
+	if ('bind' in arch):
+		for bind in arch['bind']:
+			binds.append({'from': "%s.%s" % (bind['from'][0], bind['from'][1]), 'to': "%s.%s" % (bind['to'][0], bind['to'][1])})
+	
+	if ('delegate' in arch):
+		for delegate in arch['delegate']:
+			print "Unable to delegate interface in system architecture"
+			break
+	
+	if ('subsume' in arch):
+		for subsume in arch['subsume']:
+			print "Unable to subsume interface in system architecture"
+			break
+	
+	directed_binds = direct_binds(flatten_binds(binds, delegates, subsumes))
+	
+	outname = os.path.join(outdir, "%s.archbp" % arch['name'])
+	if ((opt_bp) or (opt_ebp)):
+		outf = file(outname, "w")
+	else:
+		outf = None
+	
+	create_null_bp("null.bp", outdir, outf)
+	
+	for inst in insts:
+		dump_frame(directed_binds, inst['frame'], outdir, inst['var'], outf)
+	
+	for dst, src in directed_binds.items():
+		if (outf != None):
+			outf.write("bind %s to %s\n" % (", ".join(src), dst))
+	
+	if (outf != None):
+		outf.close()
+
+def preproc_adl(raw, inarg):
+	"Preprocess %% statements in ADL"
+	
+	return raw.replace("%%", inarg)
+
+def parse_adl(base, root, inname, nested, indent):
+	"Parse Architecture Description Language"
+	
+	global output
+	global context
+	global architecture
+	global interface
+	global frame
+	global protocol
+	global initialization
+	global finalization
+	
+	global iface_properties
+	global frame_properties
+	global arch_properties
+	
+	global arg0
+	
+	if (nested):
+		parts = inname.split("%")
+		
+		if (len(parts) > 1):
+			inarg = parts[1]
+		else:
+			inarg = "%%"
+		
+		if (parts[0][0:1] == "/"):
+			path = os.path.join(base, ".%s" % parts[0])
+			nested_root = os.path.dirname(path)
+		else:
+			path = os.path.join(root, parts[0])
+			nested_root = root
+		
+		if (not os.path.isfile(path)):
+			print "%s: Unable to include file %s" % (inname, path)
+			return ""
+	else:
+		inarg = "%%"
+		path = inname
+		nested_root = root
+	
+	inf = file(path, "r")
+	
+	raw = preproc_adl(inf.read(), inarg)
+	tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
+	
+	for token in tokens:
+		
+		# Includes
+		
+		if (INC in context):
+			context.remove(INC)
+			parse_adl(base, nested_root, token, True, indent)
+			context.add(POST_INC)
+			continue
+		
+		if (POST_INC in context):
+			if (token != "]"):
+				print "%s: Expected ]" % inname
+			
+			context.remove(POST_INC)
+			continue
+		
+		# Comments and newlines
+		
+		if (BLOCK_COMMENT in context):
+			if (token == "*/"):
+				context.remove(BLOCK_COMMENT)
+			
+			continue
+		
+		if (LINE_COMMENT in context):
+			if (token == "\n"):
+				context.remove(LINE_COMMENT)
+			
+			continue
+		
+		# Any context
+		
+		if (token == "/*"):
+			context.add(BLOCK_COMMENT)
+			continue
+		
+		if (token == "#"):
+			context.add(LINE_COMMENT)
+			continue
+		
+		if (token == "["):
+			context.add(INC)
+			continue
+		
+		if (token == "\n"):
+			continue
+		
+		# "frame"
+		
+		if (FRAME in context):
+			if (NULL in context):
+				if (token != ";"):
+					print "%s: Expected ';' in frame '%s'" % (inname, frame)
+				else:
+					output += "%s\n" % token
+				
+				context.remove(NULL)
+				context.remove(FRAME)
+				frame = None
+				continue
+			
+			if (BODY in context):
+				if (FINALIZATION in context):
+					if (token == "{"):
+						indent += 1
+					elif (token == "}"):
+						indent -= 1
+					
+					if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
+						bp = split_bp(finalization)
+						finalization = None
+						
+						if (not frame in frame_properties):
+							frame_properties[frame] = {}
+						
+						if ('finalization' in frame_properties[frame]):
+							print "%s: Finalization protocol for frame '%s' already defined" % (inname, frame)
+						else:
+							frame_properties[frame]['finalization'] = bp
+						
+						output += "\n%s" % tabs(2)
+						output += parse_bp(inname, bp, 2)
+						
+						context.remove(FINALIZATION)
+						if (indent == -1):
+							output += "\n%s" % token
+							context.remove(BODY)
+							context.add(NULL)
+							indent = 0
+							continue
+						else:
+							indent = 2
+					else:
+						finalization += token
+						continue
+				
+				if (INITIALIZATION in context):
+					if (token == "{"):
+						indent += 1
+					elif (token == "}"):
+						indent -= 1
+					
+					if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
+						bp = split_bp(initialization)
+						initialization = None
+						
+						if (not frame in frame_properties):
+							frame_properties[frame] = {}
+						
+						if ('initialization' in frame_properties[frame]):
+							print "%s: Initialization protocol for frame '%s' already defined" % (inname, frame)
+						else:
+							frame_properties[frame]['initialization'] = bp
+						
+						output += "\n%s" % tabs(2)
+						output += parse_bp(inname, bp, 2)
+						
+						context.remove(INITIALIZATION)
+						if (indent == -1):
+							output += "\n%s" % token
+							context.remove(BODY)
+							context.add(NULL)
+							indent = 0
+							continue
+						else:
+							indent = 2
+					else:
+						initialization += token
+						continue
+				
+				if (PROTOCOL in context):
+					if (token == "{"):
+						indent += 1
+					elif (token == "}"):
+						indent -= 1
+					
+					if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
+						bp = split_bp(protocol)
+						protocol = None
+						
+						if (not frame in frame_properties):
+							frame_properties[frame] = {}
+						
+						if ('protocol' in frame_properties[frame]):
+							print "%s: Protocol for frame '%s' already defined" % (inname, frame)
+						else:
+							frame_properties[frame]['protocol'] = bp
+						
+						output += "\n%s" % tabs(2)
+						output += parse_bp(inname, bp, 2)
+						
+						context.remove(PROTOCOL)
+						if (indent == -1):
+							output += "\n%s" % token
+							context.remove(BODY)
+							context.add(NULL)
+							indent = 0
+							continue
+						else:
+							indent = 2
+					else:
+						protocol += token
+						continue
+				
+				if (REQUIRES in context):
+					if (FIN in context):
+						if (token != ";"):
+							print "%s: Expected ';' in frame '%s'" % (inname, frame)
+						else:
+							output += "%s" % token
+						
+						context.remove(FIN)
+						continue
+					
+					if (VAR in context):
+						if (not identifier(token)):
+							print "%s: Variable name expected in frame '%s'" % (inname, frame)
+						else:
+							if (not frame in frame_properties):
+								frame_properties[frame] = {}
+							
+							if (not 'requires' in frame_properties[frame]):
+								frame_properties[frame]['requires'] = []
+							
+							frame_properties[frame]['requires'].append({'iface': arg0, 'var': token})
+							arg0 = None
+							
+							output += "%s" % token
+						
+						context.remove(VAR)
+						context.add(FIN)
+						continue
+					
+					if ((token == "}") or (token[-1] == ":")):
+						context.remove(REQUIRES)
+					else:
+						if (not identifier(token)):
+							print "%s: Interface name expected in frame '%s'" % (inname, frame)
+						else:
+							arg0 = token
+							output += "\n%s%s " % (tabs(indent), token)
+						
+						context.add(VAR)
+						continue
+				
+				if (PROVIDES in context):
+					if (FIN in context):
+						if (token != ";"):
+							print "%s: Expected ';' in frame '%s'" % (inname, frame)
+						else:
+							output += "%s" % token
+						
+						context.remove(FIN)
+						continue
+					
+					if (VAR in context):
+						if (not identifier(token)):
+							print "%s: Variable name expected in frame '%s'" % (inname, frame)
+						else:
+							if (not frame in frame_properties):
+								frame_properties[frame] = {}
+							
+							if (not 'provides' in frame_properties[frame]):
+								frame_properties[frame]['provides'] = []
+							
+							frame_properties[frame]['provides'].append({'iface': arg0, 'var': token})
+							arg0 = None
+							
+							output += "%s" % token
+						
+						context.remove(VAR)
+						context.add(FIN)
+						continue
+					
+					if ((token == "}") or (token[-1] == ":")):
+						context.remove(PROVIDES)
+					else:
+						if (not identifier(token)):
+							print "%s: Interface name expected in frame '%s'" % (inname, frame)
+						else:
+							arg0 = token
+							output += "\n%s%s " % (tabs(indent), token)
+						
+						context.add(VAR)
+						continue
+				
+				if (token == "}"):
+					if (indent != 2):
+						print "%s: Wrong number of parentheses in frame '%s'" % (inname, frame)
+					else:
+						indent = 0
+						output += "\n%s" % token
+					
+					context.remove(BODY)
+					context.add(NULL)
+					continue
+				
+				if (token == "provides:"):
+					output += "\n%s%s" % (tabs(indent - 1), token)
+					context.add(PROVIDES)
+					continue
+				
+				if (token == "requires:"):
+					output += "\n%s%s" % (tabs(indent - 1), token)
+					context.add(REQUIRES)
+					continue
+				
+				if (token == "initialization:"):
+					output += "\n%s%s" % (tabs(indent - 1), token)
+					indent = 0
+					context.add(INITIALIZATION)
+					initialization = ""
+					continue
+				
+				if (token == "finalization:"):
+					output += "\n%s%s" % (tabs(indent - 1), token)
+					indent = 0
+					context.add(FINALIZATION)
+					finalization = ""
+					continue
+				
+				if (token == "protocol:"):
+					output += "\n%s%s" % (tabs(indent - 1), token)
+					indent = 0
+					context.add(PROTOCOL)
+					protocol = ""
+					continue
+				
+				print "%s: Unknown token '%s' in frame '%s'" % (inname, token, frame)
+				continue
+			
+			if (HEAD in context):
+				if (token == "{"):
+					output += "%s" % token
+					indent += 2
+					context.remove(HEAD)
+					context.add(BODY)
+					continue
+				
+				if (token == ";"):
+					output += "%s\n" % token
+					context.remove(HEAD)
+					context.remove(FRAME)
+					continue
+				
+				print "%s: Unknown token '%s' in frame head '%s'" % (inname, token, frame)
+				
+				continue
+			
+			if (not identifier(token)):
+				print "%s: Expected frame name" % inname
+			else:
+				frame = token
+				output += "%s " % token
+				
+				if (not frame in frame_properties):
+					frame_properties[frame] = {}
+				
+				frame_properties[frame]['name'] = frame
+			
+			context.add(HEAD)
+			continue
+		
+		# "interface"
+		
+		if (IFACE in context):
+			if (NULL in context):
+				if (token != ";"):
+					print "%s: Expected ';' in interface '%s'" % (inname, interface)
+				else:
+					output += "%s\n" % token
+				
+				context.remove(NULL)
+				context.remove(IFACE)
+				interface = None
+				continue
+			
+			if (BODY in context):
+				if (PROTOCOL in context):
+					if (token == "{"):
+						indent += 1
+					elif (token == "}"):
+						indent -= 1
+					
+					if (indent == -1):
+						bp = split_bp(protocol)
+						protocol = None
+						
+						if (not interface in iface_properties):
+							iface_properties[interface] = {}
+						
+						if ('protocol' in iface_properties[interface]):
+							print "%s: Protocol for interface '%s' already defined" % (inname, interface)
+						else:
+							iface_properties[interface]['protocol'] = bp
+						
+						output += "\n%s" % tabs(2)
+						output += parse_bp(inname, bp, 2)
+						output += "\n%s" % token
+						indent = 0
+						
+						context.remove(PROTOCOL)
+						context.remove(BODY)
+						context.add(NULL)
+					else:
+						protocol += token
+					
+					continue
+				
+				if (PROTOTYPE in context):
+					if (FIN in context):
+						if (token != ";"):
+							print "%s: Expected ';' in interface '%s'" % (inname, interface)
+						else:
+							output += "%s" % token
+						
+						context.remove(FIN)
+						context.remove(PROTOTYPE)
+						continue
+					
+					if (PAR_RIGHT in context):
+						if (token == ")"):
+							output += "%s" % token
+							context.remove(PAR_RIGHT)
+							context.add(FIN)
+						else:
+							output += " %s" % token
+						
+						continue
+					
+					if (SIGNATURE in context):
+						output += "%s" % token
+						if (token == ")"):
+							context.remove(SIGNATURE)
+							context.add(FIN)
+						
+						context.remove(SIGNATURE)
+						context.add(PAR_RIGHT)
+						continue
+					
+					if (PAR_LEFT in context):
+						if (token != "("):
+							print "%s: Expected '(' in interface '%s'" % (inname, interface)
+						else:
+							output += "%s" % token
+						
+						context.remove(PAR_LEFT)
+						context.add(SIGNATURE)
+						continue
+					
+					if (not identifier(token)):
+						print "%s: Method identifier expected in interface '%s'" % (inname, interface)
+					else:
+						output += "%s" % token
+					
+					context.add(PAR_LEFT)
+					continue
+				
+				if (token == "}"):
+					if (indent != 2):
+						print "%s: Wrong number of parentheses in interface '%s'" % (inname, interface)
+					else:
+						indent = 0
+						output += "\n%s" % token
+					
+					context.remove(BODY)
+					context.add(NULL)
+					continue
+				
+				if ((token == "ipcarg_t") or (token == "unative_t")):
+					output += "\n%s%s " % (tabs(indent), token)
+					context.add(PROTOTYPE)
+					continue
+				
+				if (token == "protocol:"):
+					output += "\n%s%s" % (tabs(indent - 1), token)
+					indent = 0
+					context.add(PROTOCOL)
+					protocol = ""
+					continue
+				
+				print "%s: Unknown token '%s' in interface '%s'" % (inname, token, interface)
+				continue
+			
+			if (HEAD in context):
+				if (PRE_BODY in context):
+					if (token == "{"):
+						output += "%s" % token
+						indent += 2
+						context.remove(PRE_BODY)
+						context.remove(HEAD)
+						context.add(BODY)
+						continue
+					
+					if (token == ";"):
+						output += "%s\n" % token
+						context.remove(PRE_BODY)
+						context.remove(HEAD)
+						context.remove(IFACE)
+						continue
+						
+					print "%s: Expected '{' or ';' in interface head '%s'" % (inname, interface)
+					continue
+				
+				if (EXTENDS in context):
+					if (not identifier(token)):
+						print "%s: Expected inherited interface name in interface head '%s'" % (inname, interface)
+					else:
+						output += "%s " % token
+						if (not interface in iface_properties):
+							iface_properties[interface] = {}
+						
+						iface_properties[interface]['extends'] = token
+					
+					context.remove(EXTENDS)
+					context.add(PRE_BODY)
+					continue
+				
+				if (token == "extends"):
+					output += "%s " % token
+					context.add(EXTENDS)
+					continue
+					
+				if (token == "{"):
+					output += "%s" % token
+					indent += 2
+					context.remove(HEAD)
+					context.add(BODY)
+					continue
+				
+				if (token == ";"):
+					output += "%s\n" % token
+					context.remove(HEAD)
+					context.remove(IFACE)
+					continue
+				
+				print "%s: Expected 'extends', '{' or ';' in interface head '%s'" % (inname, interface)
+				continue
+			
+			if (not identifier(token)):
+				print "%s: Expected interface name" % inname
+			else:
+				interface = token
+				output += "%s " % token
+				
+				if (not interface in iface_properties):
+					iface_properties[interface] = {}
+				
+				iface_properties[interface]['name'] = interface
+			
+			context.add(HEAD)
+			continue
+		
+		# "architecture"
+		
+		if (ARCH in context):
+			if (NULL in context):
+				if (token != ";"):
+					print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
+				else:
+					output += "%s\n" % token
+				
+				context.remove(NULL)
+				context.remove(ARCH)
+				context.discard(SYSTEM)
+				architecture = None
+				continue
+			
+			if (BODY in context):
+				if (DELEGATE in context):
+					if (FIN in context):
+						if (token != ";"):
+							print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
+						else:
+							output += "%s" % token
+						
+						context.remove(FIN)
+						context.remove(DELEGATE)
+						continue
+					
+					if (VAR in context):
+						if (not descriptor(token)):
+							print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
+						else:
+							if (not architecture in arch_properties):
+								arch_properties[architecture] = {}
+							
+							if (not 'delegate' in arch_properties[architecture]):
+								arch_properties[architecture]['delegate'] = []
+							
+							arch_properties[architecture]['delegate'].append({'from': arg0, 'to': token.split(":")})
+							arg0 = None
+							
+							output += "%s" % token
+						
+						context.add(FIN)
+						context.remove(VAR)
+						continue
+					
+					if (TO in context):
+						if (token != "to"):
+							print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
+						else:
+							output += "%s " % token
+						
+						context.add(VAR)
+						context.remove(TO)
+						continue
+					
+					if (not identifier(token)):
+						print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
+					else:
+						output += "%s " % token
+						arg0 = token
+					
+					context.add(TO)
+					continue
+				
+				if (SUBSUME in context):
+					if (FIN in context):
+						if (token != ";"):
+							print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
+						else:
+							output += "%s" % token
+						
+						context.remove(FIN)
+						context.remove(SUBSUME)
+						continue
+					
+					if (VAR in context):
+						if (not identifier(token)):
+							print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
+						else:
+							if (not architecture in arch_properties):
+								arch_properties[architecture] = {}
+							
+							if (not 'subsume' in arch_properties[architecture]):
+								arch_properties[architecture]['subsume'] = []
+							
+							arch_properties[architecture]['subsume'].append({'from': arg0.split(":"), 'to': token})
+							arg0 = None
+							
+							output += "%s" % token
+						
+						context.add(FIN)
+						context.remove(VAR)
+						continue
+					
+					if (TO in context):
+						if (token != "to"):
+							print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
+						else:
+							output += "%s " % token
+						
+						context.add(VAR)
+						context.remove(TO)
+						continue
+					
+					if (not descriptor(token)):
+						print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
+					else:
+						output += "%s " % token
+						arg0 = token
+					
+					context.add(TO)
+					continue
+				
+				if (BIND in context):
+					if (FIN in context):
+						if (token != ";"):
+							print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
+						else:
+							output += "%s" % token
+						
+						context.remove(FIN)
+						context.remove(BIND)
+						continue
+					
+					if (VAR in context):
+						if (not descriptor(token)):
+							print "%s: Expected second interface descriptor in architecture '%s'" % (inname, architecture)
+						else:
+							if (not architecture in arch_properties):
+								arch_properties[architecture] = {}
+							
+							if (not 'bind' in arch_properties[architecture]):
+								arch_properties[architecture]['bind'] = []
+							
+							arch_properties[architecture]['bind'].append({'from': arg0.split(":"), 'to': token.split(":")})
+							arg0 = None
+							
+							output += "%s" % token
+						
+						context.add(FIN)
+						context.remove(VAR)
+						continue
+					
+					if (TO in context):
+						if (token != "to"):
+							print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
+						else:
+							output += "%s " % token
+						
+						context.add(VAR)
+						context.remove(TO)
+						continue
+					
+					if (not descriptor(token)):
+						print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
+					else:
+						output += "%s " % token
+						arg0 = token
+					
+					context.add(TO)
+					continue
+				
+				if (INST in context):
+					if (FIN in context):
+						if (token != ";"):
+							print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
+						else:
+							output += "%s" % token
+						
+						context.remove(FIN)
+						context.remove(INST)
+						continue
+					
+					if (VAR in context):
+						if (not identifier(token)):
+							print "%s: Expected instance name in architecture '%s'" % (inname, architecture)
+						else:
+							if (not architecture in arch_properties):
+								arch_properties[architecture] = {}
+							
+							if (not 'inst' in arch_properties[architecture]):
+								arch_properties[architecture]['inst'] = []
+							
+							arch_properties[architecture]['inst'].append({'type': arg0, 'var': token})
+							arg0 = None
+							
+							output += "%s" % token
+						
+						context.add(FIN)
+						context.remove(VAR)
+						continue
+					
+					if (not identifier(token)):
+						print "%s: Expected frame/architecture type in architecture '%s'" % (inname, architecture)
+					else:
+						output += "%s " % token
+						arg0 = token
+					
+					context.add(VAR)
+					continue
+				
+				if (token == "}"):
+					if (indent != 1):
+						print "%s: Wrong number of parentheses in architecture '%s'" % (inname, architecture)
+					else:
+						indent -= 1
+						output += "\n%s" % token
+					
+					context.remove(BODY)
+					context.add(NULL)
+					continue
+				
+				if (token == "inst"):
+					output += "\n%s%s " % (tabs(indent), token)
+					context.add(INST)
+					continue
+				
+				if (token == "bind"):
+					output += "\n%s%s " % (tabs(indent), token)
+					context.add(BIND)
+					continue
+				
+				if (token == "subsume"):
+					output += "\n%s%s " % (tabs(indent), token)
+					context.add(SUBSUME)
+					continue
+				
+				if (token == "delegate"):
+					output += "\n%s%s " % (tabs(indent), token)
+					context.add(DELEGATE)
+					continue
+				
+				print "%s: Unknown token '%s' in architecture '%s'" % (inname, token, architecture)
+				continue
+			
+			if (HEAD in context):
+				if (token == "{"):
+					output += "%s" % token
+					indent += 1
+					context.remove(HEAD)
+					context.add(BODY)
+					continue
+				
+				if (token == ";"):
+					output += "%s\n" % token
+					context.remove(HEAD)
+					context.remove(ARCH)
+					context.discard(SYSTEM)
+					continue
+				
+				if (not word(token)):
+					print "%s: Expected word in architecture head '%s'" % (inname, architecture)
+				else:
+					output += "%s " % token
+				
+				continue
+			
+			if (not identifier(token)):
+				print "%s: Expected architecture name" % inname
+			else:
+				architecture = token
+				output += "%s " % token
+				
+				if (not architecture in arch_properties):
+					arch_properties[architecture] = {}
+				
+				arch_properties[architecture]['name'] = architecture
+				
+				if (SYSTEM in context):
+					arch_properties[architecture]['system'] = True
+			
+			context.add(HEAD)
+			continue
+		
+		# "system architecture"
+		
+		if (SYSTEM in context):
+			if (token != "architecture"):
+				print "%s: Expected 'architecture'" % inname
+			else:
+				output += "%s " % token
+			
+			context.add(ARCH)
+			continue
+		
+		if (token == "frame"):
+			output += "\n%s " % token
+			context.add(FRAME)
+			continue
+		
+		if (token == "interface"):
+			output += "\n%s " % token
+			context.add(IFACE)
+			continue
+		
+		if (token == "system"):
+			output += "\n%s " % token
+			context.add(SYSTEM)
+			continue
+		
+		if (token == "architecture"):
+			output += "\n%s " % token
+			context.add(ARCH)
+			continue
+		
+		print "%s: Unknown token '%s'" % (inname, token)
+	
+	inf.close()
+
+def open_adl(base, root, inname, outdir, outname):
+	"Open Architecture Description file"
+	
+	global output
+	global context
+	global architecture
+	global interface
+	global frame
+	global protocol
+	global initialization
+	global finalization
+	
+	global arg0
+	
+	global opt_adl
+	
+	output = ""
+	context = set()
+	architecture = None
+	interface = None
+	frame = None
+	protocol = None
+	initialization = None
+	finalization = None
+	arg0 = None
+	
+	parse_adl(base, root, inname, False, 0)
+	output = output.strip()
+	
+	if ((output != "") and (opt_adl)):
+		outf = file(outname, "w")
+		outf.write(output)
+		outf.close()
+
+def recursion(base, root, output, level):
+	"Recursive directory walk"
+	
+	for name in os.listdir(root):
+		canon = os.path.join(root, name)
+		
+		if (os.path.isfile(canon)):
+			fcomp = split_tokens(canon, ["."])
+			cname = canon.split("/")
+			
+			if (fcomp[-1] == ".adl"):
+				output_path = os.path.join(output, cname[-1])
+				open_adl(base, root, canon, output, output_path)
+		
+		if (os.path.isdir(canon)):
+			recursion(base, canon, output, level + 1)
+
+def merge_dot_frame(prefix, name, frame, outf, indent):
+	"Dump Dot frame"
+	
+	outf.write("%ssubgraph cluster_%s {\n" % (tabs(indent), prefix))
+	outf.write("%s\tlabel=\"%s\";\n" % (tabs(indent), name))
+	outf.write("%s\tstyle=filled;\n" % tabs(indent))
+	outf.write("%s\tcolor=red;\n" % tabs(indent))
+	outf.write("%s\tfillcolor=yellow;\n" % tabs(indent))
+	outf.write("%s\t\n" % tabs(indent))
+	
+	if ('provides' in frame):
+		outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, style=filled, color=green, fillcolor=yellow];\n" % (tabs(indent), prefix))
+	
+	if ('requires' in frame):
+		outf.write("%s\t%s__requires [label=\"\", shape=circle, style=filled, color=red, fillcolor=yellow];\n" % (tabs(indent), prefix))
+	
+	outf.write("%s}\n" % tabs(indent))
+	outf.write("%s\n" % tabs(indent))
+
+def merge_dot_arch(prefix, name, arch, outf, indent):
+	"Dump Dot subarchitecture"
+	
+	outf.write("%ssubgraph cluster_%s {\n" % (tabs(indent), prefix))
+	outf.write("%s\tlabel=\"%s\";\n" % (tabs(indent), name))
+	outf.write("%s\tcolor=red;\n" % tabs(indent))
+	outf.write("%s\t\n" % tabs(indent))
+	
+	if ('inst' in arch):
+		for inst in arch['inst']:
+			subarch = get_arch(inst['type'])
+			if (not subarch is None):
+				merge_dot_arch("%s_%s" % (prefix, inst['var']), inst['var'], subarch, outf, indent + 1)
+			else:
+				subframe = get_frame(inst['type'])
+				if (not subframe is None):
+					merge_dot_frame("%s_%s" % (prefix, inst['var']), inst['var'], subframe, outf, indent + 1)
+				else:
+					print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
+	
+	if ('bind' in arch):
+		labels = {}
+		for bind in arch['bind']:
+			if (bind['from'][1] != bind['to'][1]):
+				label = "%s:%s" % (bind['from'][1], bind['to'][1])
+			else:
+				label = bind['from'][1]
+			
+			if (not (bind['from'][0], bind['to'][0]) in labels):
+				labels[(bind['from'][0], bind['to'][0])] = []
+			
+			labels[(bind['from'][0], bind['to'][0])].append(label)
+		
+		for bind in arch['bind']:
+			if (not (bind['from'][0], bind['to'][0]) in labels):
+				continue
+			
+			attrs = []
+			
+			if (bind['from'][0] != bind['to'][0]):
+				attrs.append("ltail=cluster_%s_%s" % (prefix, bind['from'][0]))
+				attrs.append("lhead=cluster_%s_%s" % (prefix, bind['to'][0]))
+			
+			attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
+			del labels[(bind['from'][0], bind['to'][0])]
+			
+			outf.write("%s\t%s_%s__requires -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, bind['from'][0], prefix, bind['to'][0], ", ".join(attrs)))
+	
+	if ('delegate' in arch):
+		outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, color=green];\n" % (tabs(indent), prefix))
+		
+		labels = {}
+		for delegate in arch['delegate']:
+			if (delegate['from'] != delegate['to'][1]):
+				label = "%s:%s" % (delegate['from'], delegate['to'][1])
+			else:
+				label = delegate['from']
+			
+			if (not delegate['to'][0] in labels):
+				labels[delegate['to'][0]] = []
+			
+			labels[delegate['to'][0]].append(label)
+		
+		for delegate in arch['delegate']:
+			if (not delegate['to'][0] in labels):
+				continue
+			
+			attrs = []
+			attrs.append("color=gray")
+			attrs.append("lhead=cluster_%s_%s" % (prefix, delegate['to'][0]))
+			attrs.append("label=\"%s\"" % "\\n".join(labels[delegate['to'][0]]))
+			del labels[delegate['to'][0]]
+			
+			outf.write("%s\t%s__provides -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, prefix, delegate['to'][0], ", ".join(attrs)))
+	
+	if ('subsume' in arch):
+		outf.write("%s\t%s__requires [label=\"\", shape=circle, color=red];\n" % (tabs(indent), prefix))
+		
+		labels = {}
+		for subsume in arch['subsume']:
+			if (subsume['from'][1] != subsume['to']):
+				label = "%s:%s" % (subsume['from'][1], subsume['to'])
+			else:
+				label = subsume['to']
+			
+			if (not subsume['from'][0] in labels):
+				labels[subsume['from'][0]] = []
+			
+			labels[subsume['from'][0]].append(label)
+		
+		for subsume in arch['subsume']:
+			if (not subsume['from'][0] in labels):
+				continue
+			
+			attrs = []
+			attrs.append("color=gray")
+			attrs.append("ltail=cluster_%s_%s" % (prefix, subsume['from'][0]))
+			attrs.append("label=\"%s\"" % "\\n".join(labels[subsume['from'][0]]))
+			del labels[subsume['from'][0]]
+			
+			outf.write("%s\t%s_%s__requires -> %s__requires [%s];\n" % (tabs(indent), prefix, subsume['from'][0], prefix, ", ".join(attrs)))
+	
+	outf.write("%s}\n" % tabs(indent))
+	outf.write("%s\n" % tabs(indent))
+
+def dump_dot(outdir):
+	"Dump Dot architecture"
+	
+	global opt_dot
+	
+	arch = get_system_arch()
+	
+	if (arch is None):
+		print "Unable to find system architecture"
+		return
+	
+	if (opt_dot):
+		outname = os.path.join(outdir, "%s.dot" % arch['name'])
+		outf = file(outname, "w")
+		
+		outf.write("digraph {\n")
+		outf.write("\tlabel=\"%s\";\n" % arch['name'])
+		outf.write("\tcompound=true;\n")
+		outf.write("\tsplines=\"polyline\";\n")
+		outf.write("\tedge [fontsize=8];\n")
+		outf.write("\t\n")
+		
+		if ('inst' in arch):
+			for inst in arch['inst']:
+				subarch = get_arch(inst['type'])
+				if (not subarch is None):
+					merge_dot_arch(inst['var'], inst['var'], subarch, outf, 1)
+				else:
+					subframe = get_frame(inst['type'])
+					if (not subframe is None):
+						merge_dot_frame("%s" % inst['var'], inst['var'], subframe, outf, 1)
+					else:
+						print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
+		
+		if ('bind' in arch):
+			labels = {}
+			for bind in arch['bind']:
+				if (bind['from'][1] != bind['to'][1]):
+					label = "%s:%s" % (bind['from'][1], bind['to'][1])
+				else:
+					label = bind['from'][1]
+				
+				if (not (bind['from'][0], bind['to'][0]) in labels):
+					labels[(bind['from'][0], bind['to'][0])] = []
+				
+				labels[(bind['from'][0], bind['to'][0])].append(label)
+			
+			for bind in arch['bind']:
+				if (not (bind['from'][0], bind['to'][0]) in labels):
+					continue
+				
+				attrs = []
+				
+				if (bind['from'][0] != bind['to'][0]):
+					attrs.append("ltail=cluster_%s" % bind['from'][0])
+					attrs.append("lhead=cluster_%s" % bind['to'][0])
+				
+				attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
+				del labels[(bind['from'][0], bind['to'][0])]
+				
+				outf.write("\t%s__requires -> %s__provides [%s];\n" % (bind['from'][0], bind['to'][0], ", ".join(attrs)))
+		
+		if ('delegate' in arch):
+			for delegate in arch['delegate']:
+				print "Unable to delegate interface in system architecture"
+				break
+		
+		if ('subsume' in arch):
+			for subsume in arch['subsume']:
+				print "Unable to subsume interface in system architecture"
+				break
+		
+		outf.write("}\n")
+		
+		outf.close()
+
+def main():
+	global iface_properties
+	global frame_properties
+	global arch_properties
+	global opt_bp
+	global opt_ebp
+	global opt_adl
+	global opt_dot
+	
+	if (len(sys.argv) < 3):
+		usage(sys.argv[0])
+		return
+	
+	opt_bp = False
+	opt_ebp = False
+	opt_adl = False
+	opt_dot = False
+	
+	for arg in sys.argv[1:(len(sys.argv) - 1)]:
+		if (arg == "--bp"):
+			opt_bp = True
+		elif (arg == "--ebp"):
+			opt_ebp = True
+		elif (arg == "--adl"):
+			opt_adl = True
+		elif (arg == "--dot"):
+			opt_dot = True
+		elif (arg == "--nop"):
+			pass
+		else:
+			print "Error: Unknown command line option '%s'" % arg
+			return
+	
+	if ((opt_bp) and (opt_ebp)):
+		print "Error: Cannot dump both original Behavior Protocols and Extended Behavior Protocols"
+		return
+	
+	path = os.path.abspath(sys.argv[-1])
+	if (not os.path.isdir(path)):
+		print "Error: <OUTPUT> is not a directory"
+		return
+	
+	iface_properties = {}
+	frame_properties = {}
+	arch_properties = {}
+	
+	recursion(".", ".", path, 0)
+	dump_archbp(path)
+	dump_dot(path)
+
+if __name__ == '__main__':
+	main()
Index: contrib/arch/kernel/kernel.adl
===================================================================
--- contrib/arch/kernel/kernel.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/kernel/kernel.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,315 @@
+/*****************************
+ * Kernel syscall interfaces *
+ *****************************/
+
+interface sys_klog {
+		/* Print using kernel facility */
+		unative_t sys_klog(int fd, const void *buf, size_t size);
+	protocol:
+		?sys_klog*
+};
+
+interface sys_console {
+		/* Enable kernel console */
+		unative_t sys_debug_enable_console(void);
+		
+		/* Disable kernel console */
+		unative_t sys_debug_disable_console(void);
+	protocol:
+		(
+			?sys_debug_enable_console +
+			?sys_debug_disable_console
+		)*
+};
+
+interface sys_tls {
+		/* Set thread-local storage pointer (on architectures where kernel mode is required) */
+		unative_t sys_tls_set(unative_t addr);
+	protocol:
+		?sys_tls_set*
+};
+
+interface sys_thread {
+		/* Create new thread */
+		unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id);
+		
+		/* Terminate current thread */
+		unative_t sys_thread_exit(int uspace_status);
+		
+		/* Get current thread id */
+		unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);
+	protocol:
+		(
+			?sys_thread_create +
+			?sys_thread_get_id +
+			?sys_thread_exit
+		)*
+};
+
+interface sys_task {
+		/* Set name fo the current task */
+		unative_t sys_task_set_name(const char *uspace_name, size_t name_len);
+		
+		/* Get current task id */
+		unative_t sys_task_get_id(task_id_t *uspace_task_id);
+	protocol:
+		(
+			?sys_task_set_name +
+			?sys_task_get_id
+		)*
+};
+
+interface sys_program {
+		/* Spawn a new instance of clonable loader service */
+		unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len);
+	protocol:
+		?sys_program_spawn_loader*
+};
+
+interface sys_futex {
+		/* Sleep in a futex wait queue */
+		unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags);
+		
+		/* Wakeup one thread waiting in futex wait queue */
+		unative_t sys_futex_wakeup(uintptr_t uaddr);
+	protocol:
+		(
+			?sys_futex_sleep_timeout +
+			?sys_futex_wakeup
+		)*
+};
+
+interface sys_smc {
+		/* Enforce self-modifying code cache coherency */
+		unative_t sys_smc_coherence(uintptr_t va, size_t size);
+	protocol:
+		?sys_smc_coherence*
+};
+
+interface sys_as {
+		/* Create new address space area */
+		unative_t sys_as_area_create(uintptr_t address, size_t size, int flags);
+		
+		/* Resize an address space area */
+		unative_t sys_as_area_resize(uinptr_t address, size_t size, int flags);
+		
+		/* Change flags of an address space area */
+		unative_t sys_as_area_change_flags(uintptr_t address, int flags);
+		
+		/* Destroy an address space area */
+		unative_t sys_as_area_destroy(uintptr_t address);
+	protocol:
+		(
+			?sys_as_area_create +
+			?sys_as_area_resize +
+			?sys_as_area_change_flags +
+			?sys_as_area_destroy
+		)*
+};
+
+interface sys_ipc {
+		/* Fast synchronous IPC call */
+		unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method, unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data);
+		
+		/* Slow synchronous IPC call */
+		unative_t sys_ipc_call_sync_slow(unative_t phoneid, ipc_data_t *question, ipc_data_t *answer);
+		
+		/* Fast asynchronous IPC call */
+		unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method, unative_t arg1, unative_t arg2, unative_t arg3, unative_t arg4);
+		
+		/* Slow asynchronous IPC call */
+		unative_t sys_ipc_call_async_slow(unative_t phoneid, ipc_data_t *data);
+		
+		/* Fast forward a received IPC call to another destination */
+		unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, unative_t method, unative_t arg1, unative_t arg2, int mode);
+		
+		/* Slow forward a received IPC call to another destination */
+		unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid, ipc_data_t *data, int mode);
+		
+		/* Fast answer an IPC call */
+		unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval, unative_t arg1, unative_t arg2, unative_t arg3, unative_t arg4);
+		
+		/* Slow answer an IPC call */
+		unative_t sys_ipc_answer_slow(unative_t callid, ipc_data_t *data);
+		
+		/* Hang up a phone */
+		unative_t sys_ipc_hangup(int phoneid);
+		
+		/* Wait for an incoming IPC call or answer */
+		unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, int flags);
+		
+		/* Interrupt one thread of the current task from waiting on IPC call */
+		unative_t sys_ipc_poke(void);
+	protocol:
+		(
+			?sys_ipc_call_sync_fast +
+			?sys_ipc_call_sync_slow +
+			?sys_ipc_call_async_fast +
+			?sys_ipc_call_async_slow +
+			?sys_ipc_forward_fast +
+			?sys_ipc_forward_slow +
+			?sys_ipc_answer_fast +
+			?sys_ipc_answer_slow +
+			?sys_ipc_hangup +
+			?sys_ipc_wait_for_call +
+			?sys_ipc_poke
+		)*
+};
+
+interface sys_event {
+		/* Subscribe to kernel event notifications */
+		unative_t sys_event_subscribe(unative_t evno, unative_t method);
+	protocol:
+		?sys_event_subscribe*
+};
+
+interface sys_cap {
+		/* Grant capabilities to a task */
+		unative_t sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps);
+		
+		/* Revoke capabilities from a task */
+		unative_t sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps);
+	protocol:
+		(
+			?sys_cap_grant +
+			?sys_cap_rewoke
+		)*
+};
+
+interface sys_ddi {
+		/* Enable access I/O address space for the current task */
+		unative_t sys_enable_iospace(ddi_ioarg_t *uspace_io_arg);
+		
+		/* Map physical memory to the current task's address space */
+		unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base, unative_t pages, unative_t flags);
+		
+		/* Enable or disable preemption */
+		unative_t sys_preempt_control(int enable);
+		
+		/* Assign unique device number */
+		unative_t sys_device_assign_devno(void);
+		
+		/* Connect an IRQ handler to the current task */
+		unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method, irq_code_t *ucode);
+		
+		/* Disconnect an IRQ handler from the current task */
+		unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno);
+	protocol:
+		(
+			?sys_enable_iospace +
+			?sys_physmem_map +
+			?sys_device_assign_devno +
+			?sys_preempt_control +
+			?sys_ipc_register_irq +
+			?sys_ipc_unregister_irq
+		)*
+};
+
+interface sys_sysinfo {
+		/* Check for sysinfo key validity */
+		unative_t sys_sysinfo_valid(unative_t ptr, unative_t len);
+		
+		/* Get sysinfo key value */
+		unative_t sys_sysinfo_value(unatice_t ptr, unative_t len);
+	protocol:
+		(
+			?sys_sysinfo_valid +
+			?sys_sysinfo_value
+		)*
+};
+
+interface sys_debug {
+		/* Connect to the kernel debugging answerbox of a given task */
+		unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg);
+	protocol:
+		?sys_ipc_connect_kbox*
+};
+
+
+/*****************************************************
+ * Primitive kernel components (exported subsystems) *
+ *****************************************************/
+
+frame sys_console {
+	provides:
+		sys_klog sys_klog;
+		sys_console sys_console;
+};
+
+frame sys_proc {
+	provides:
+		sys_tls sys_tls;
+		sys_thread sys_thread;
+		sys_task sys_task;
+		sys_program sys_program;
+};
+
+frame sys_synch {
+	provides:
+		sys_futex sys_futex;
+		sys_smc sys_smc;
+};
+
+frame sys_mm {
+	provides:
+		sys_as sys_as;
+};
+
+frame sys_ipc {
+	provides:
+		sys_ipc sys_ipc;
+		sys_event sys_event;
+};
+
+frame sys_security {
+	provides:
+		sys_cap sys_cap;
+};
+
+frame sys_ddi {
+	provides:
+		sys_ddi sys_ddi;
+};
+
+frame sys_sysinfo {
+	provides:
+		sys_sysinfo sys_sysinfo;
+};
+
+frame sys_debug {
+	provides:
+		sys_debug sys_debug;
+};
+
+
+/******************************
+ * Composite kernel component *
+ ******************************/
+
+architecture kernel {
+	inst sys_console sys_console;
+	inst sys_proc sys_proc;
+	inst sys_synch sys_synch;
+	inst sys_mm sys_mm;
+	inst sys_ipc sys_ipc;
+	inst sys_security sys_security;
+	inst sys_ddi sys_ddi;
+	inst sys_sysinfo sys_sysinfo;
+	inst sys_debug sys_debug;
+	
+	delegate sys_klog to sys_console:sys_klog;
+	delegate sys_console to sys_console:sys_console;
+	delegate sys_tls to sys_proc:sys_tls;
+	delegate sys_thread to sys_proc:sys_thread;
+	delegate sys_task to sys_proc:sys_task;
+	delegate sys_program to sys_proc:sys_program;
+	delegate sys_futex to sys_synch:sys_futex;
+	delegate sys_smc to sys_synch:sys_smc;
+	delegate sys_as to sys_mm:sys_as;
+	delegate sys_ipc to sys_ipc:sys_ipc;
+	delegate sys_event to sys_ipc:sys_event;
+	delegate sys_cap to sys_security:sys_cap;
+	delegate sys_ddi to sys_ddi:sys_ddi;
+	delegate sys_sysinfo to sys_sysinfo:sys_sysinfo;
+	delegate sys_debug to sys_debug:sys_debug;
+};
Index: contrib/arch/uspace/app/klog/klog.adl
===================================================================
--- contrib/arch/uspace/app/klog/klog.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/app/klog/klog.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,9 @@
+frame klog {
+	requires:
+		naming_service ns;
+		[/uspace/lib/libc/requires]
+	initialization:
+		!ns.ipc_m_share_in /* SERVICE_MEM_KLOG */
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/lib/libblock/fnc.block_fini
===================================================================
--- contrib/arch/uspace/lib/libblock/fnc.block_fini	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libblock/fnc.block_fini	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!%%.ipc_m_phone_hungup
+)
Index: contrib/arch/uspace/lib/libblock/fnc.block_init
===================================================================
--- contrib/arch/uspace/lib/libblock/fnc.block_init	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libblock/fnc.block_init	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,9 @@
+(
+	[/uspace/lib/libc/fnc.devmap_device_connect] ;
+	tentative {
+		!%%.ipc_m_share_out ;
+		tentative {
+			!%%.get_block_size
+		}
+	}
+)
Index: contrib/arch/uspace/lib/libblock/fnc.block_seqread
===================================================================
--- contrib/arch/uspace/lib/libblock/fnc.block_seqread	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libblock/fnc.block_seqread	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,5 @@
+(
+	tentative {
+		!%%.read_blocks*
+	}
+)
Index: contrib/arch/uspace/lib/libc/bind
===================================================================
--- contrib/arch/uspace/lib/libc/bind	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/bind	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,15 @@
+/* Bind %% to kernel interfaces */
+bind %%:sys_klog to kernel:sys_klog;
+bind %%:sys_tls to kernel:sys_tls;
+bind %%:sys_thread to kernel:sys_thread;
+bind %%:sys_task to kernel:sys_task;
+bind %%:sys_program to kernel:sys_program;
+bind %%:sys_futex to kernel:sys_futex;
+bind %%:sys_smc to kernel:sys_smc;
+bind %%:sys_as to kernel:sys_as;
+bind %%:sys_ipc to kernel:sys_ipc;
+bind %%:sys_event to kernel:sys_event;
+bind %%:sys_cap to kernel:sys_cap;
+bind %%:sys_ddi to kernel:sys_ddi;
+bind %%:sys_sysinfo to kernel:sys_sysinfo;
+bind %%:sys_debug to kernel:sys_debug;
Index: contrib/arch/uspace/lib/libc/fnc.devmap_device_connect
===================================================================
--- contrib/arch/uspace/lib/libc/fnc.devmap_device_connect	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/fnc.devmap_device_connect	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!ns.ipc_m_connect_me_to /* device via devmap */
+)
Index: contrib/arch/uspace/lib/libc/fnc.devmap_device_get_count
===================================================================
--- contrib/arch/uspace/lib/libc/fnc.devmap_device_get_count	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/fnc.devmap_device_get_count	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,6 @@
+(
+	[fnc.devmap_get_phone] ;
+	tentative {
+		!devmap_client.device_get_count
+	}
+)
Index: contrib/arch/uspace/lib/libc/fnc.devmap_device_get_devices
===================================================================
--- contrib/arch/uspace/lib/libc/fnc.devmap_device_get_devices	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/fnc.devmap_device_get_devices	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,9 @@
+(
+	[fnc.devmap_get_phone] ;
+	tentative {
+		!devmap_client.device_get_devices {
+			!devmap_client.ipc_m_data_read /* buffer */
+		}
+	}
+)
+
Index: contrib/arch/uspace/lib/libc/fnc.devmap_device_get_handle
===================================================================
--- contrib/arch/uspace/lib/libc/fnc.devmap_device_get_handle	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/fnc.devmap_device_get_handle	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,8 @@
+(
+	[fnc.devmap_get_phone] ;
+	tentative {
+		!devmap_client.device_get_handle {
+			!devmap_client.ipc_m_data_write /* name */
+		}
+	}
+)
Index: contrib/arch/uspace/lib/libc/fnc.devmap_device_register
===================================================================
--- contrib/arch/uspace/lib/libc/fnc.devmap_device_register	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/fnc.devmap_device_register	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,8 @@
+(
+	[fnc.devmap_get_phone] ;
+	tentative {
+		!devmap_driver.device_register {
+			!devmap_driver.ipc_m_data_write /* name */
+		}
+	}
+)
Index: contrib/arch/uspace/lib/libc/fnc.devmap_driver_register
===================================================================
--- contrib/arch/uspace/lib/libc/fnc.devmap_driver_register	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/fnc.devmap_driver_register	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,11 @@
+(
+	[fnc.devmap_get_phone] ;
+	tentative {
+		!devmap_driver.driver_register {
+			!devmap_driver.ipc_m_data_write /* name */
+		} ;
+		tentative {
+			!devmap_driver.ipc_m_connect_to_me
+		}
+	}
+)
Index: contrib/arch/uspace/lib/libc/fnc.devmap_get_phone
===================================================================
--- contrib/arch/uspace/lib/libc/fnc.devmap_get_phone	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/fnc.devmap_get_phone	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,5 @@
+(
+	tentative {
+		!ns.ipc_m_connect_me_to /* devmap */
+	}
+)
Index: contrib/arch/uspace/lib/libc/protocol
===================================================================
--- contrib/arch/uspace/lib/libc/protocol	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/protocol	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,41 @@
+/* Protocol according to which libc uses kernel syscalls */
+(
+	!sys_klog.sys_klog +
+	!sys_tls.sys_tls_set +
+	!sys_thread.sys_thread_create +
+	!sys_thread.sys_thread_get_id +
+	!sys_thread.sys_thread_exit +
+	!sys_task.sys_task_set_name +
+	!sys_task.sys_task_get_id +
+	!sys_program.sys_program_spawn_loader +
+	!sys_futex.sys_futex_sleep_timeout +
+	!sys_futex.sys_futex_wakeup +
+	!sys_smc.sys_smc_coherence +
+	!sys_as.sys_as_area_create +
+	!sys_as.sys_as_area_resize +
+	!sys_as.sys_as_area_change_flags +
+	!sys_as.sys_as_area_destroy +
+	!sys_ipc.sys_ipc_call_sync_fast +
+	!sys_ipc.sys_ipc_call_sync_slow +
+	!sys_ipc.sys_ipc_call_async_fast +
+	!sys_ipc.sys_ipc_call_async_slow +
+	!sys_ipc.sys_ipc_forward_fast +
+	!sys_ipc.sys_ipc_forward_slow +
+	!sys_ipc.sys_ipc_answer_fast +
+	!sys_ipc.sys_ipc_answer_slow +
+	!sys_ipc.sys_ipc_hangup +
+	!sys_ipc.sys_ipc_wait_for_call +
+	!sys_ipc.sys_ipc_poke +
+	!sys_event.sys_event_subscribe +
+	!sys_cap.sys_cap_grant +
+	!sys_cap.sys_cap_rewoke +
+	!sys_ddi.sys_enable_iospace +
+	!sys_ddi.sys_physmem_map +
+	!sys_ddi.sys_device_assign_devno +
+	!sys_ddi.sys_preempt_control +
+	!sys_ddi.sys_ipc_register_irq +
+	!sys_ddi.sys_ipc_unregister_irq +
+	!sys_sysinfo.sys_sysinfo_valid +
+	!sys_sysinfo.sys_sysinfo_value +
+	!sys_debug.sys_ipc_connect_kbox
+)*
Index: contrib/arch/uspace/lib/libc/requires
===================================================================
--- contrib/arch/uspace/lib/libc/requires	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/requires	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,15 @@
+/* Kernel interfaces required by libc */
+sys_klog sys_klog;
+sys_tls sys_tls;
+sys_thread sys_thread;
+sys_task sys_task;
+sys_program sys_program;
+sys_futex sys_futex;
+sys_smc sys_smc;
+sys_as sys_as;
+sys_ipc sys_ipc;
+sys_event sys_event;
+sys_cap sys_cap;
+sys_ddi sys_ddi;
+sys_sysinfo sys_sysinfo;
+sys_debug sys_debug;
Index: contrib/arch/uspace/lib/libc/subsume
===================================================================
--- contrib/arch/uspace/lib/libc/subsume	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libc/subsume	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,15 @@
+/* Subsume %% to kernel interfaces */
+subsume %%:sys_klog to sys_klog;
+subsume %%:sys_tls to sys_tls;
+subsume %%:sys_thread to sys_thread;
+subsume %%:sys_task to sys_task;
+subsume %%:sys_program to sys_program;
+subsume %%:sys_futex to sys_futex;
+subsume %%:sys_smc to sys_smc;
+subsume %%:sys_as to sys_as;
+subsume %%:sys_ipc to sys_ipc;
+subsume %%:sys_event to sys_event;
+subsume %%:sys_cap to sys_cap;
+subsume %%:sys_ddi to sys_ddi;
+subsume %%:sys_sysinfo to sys_sysinfo;
+subsume %%:sys_debug to sys_debug;
Index: contrib/arch/uspace/lib/libfs/fnc.fs_register
===================================================================
--- contrib/arch/uspace/lib/libfs/fnc.fs_register	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libfs/fnc.fs_register	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,7 @@
+(
+	!vfs.register {
+		!vfs.ipc_m_data_write /* vfs_into_t */
+	} ;
+	!vfs.ipc_m_connect_to_me ;
+	!vfs.ipc_m_share_in
+)
Index: contrib/arch/uspace/lib/libfs/fnc.libfs_lookup
===================================================================
--- contrib/arch/uspace/lib/libfs/fnc.libfs_lookup	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libfs/fnc.libfs_lookup	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,5 @@
+(
+	alternative (fs; tmpfs_nested; fat_nested; devfs_nested) {
+		!fs.lookup
+	}
+)*
Index: contrib/arch/uspace/lib/libfs/fnc.libfs_mount
===================================================================
--- contrib/arch/uspace/lib/libfs/fnc.libfs_mount	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libfs/fnc.libfs_mount	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,11 @@
+(
+	?ipc_m_connection_clone ;
+	?ipc_m_data_write /* mount options */ {
+		alternative (fs; tmpfs_nested; fat_nested; devfs_nested) {
+			!fs.ipc_m_connect_to_me ;
+			!fs.mounted {
+				!fs.ipc_m_data_write /* forward */
+			}
+		}
+	}
+)
Index: contrib/arch/uspace/lib/libfs/fnc.libfs_open_node
===================================================================
--- contrib/arch/uspace/lib/libfs/fnc.libfs_open_node	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libfs/fnc.libfs_open_node	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	NULL
+)
Index: contrib/arch/uspace/lib/libfs/fnc.libfs_stat
===================================================================
--- contrib/arch/uspace/lib/libfs/fnc.libfs_stat	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/lib/libfs/fnc.libfs_stat	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	?ipc_m_data_read
+)
Index: contrib/arch/uspace/srv/bd/bd.adl
===================================================================
--- contrib/arch/uspace/srv/bd/bd.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/bd/bd.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,26 @@
+interface bd extends service {
+		/* Share out data buffer */
+		ipcarg_t ipc_m_share_out(in ipcarg_t as_area_base, in ipcarg_t as_area_size, in ipcarg_t flags, out ipcarg_t dst_as_area_base);
+		
+		/* Get block size */
+		ipcarg_t get_block_size(out ipcarg_t block_size);
+		
+		/* Read blocks via shared data buffer */
+		ipcarg_t read_blocks(in ipcarg_t index_lower, in ipcarg_t index_upper, in ipcarg_t count);
+		
+		/* Write blocks via shared data buffer */
+		ipcarg_t write_blocks(in ipcarg_t index_lower, in ipcarg_t index_upper, in ipcarg_t count);
+	protocol:
+		[bd.bp]
+};
+
+architecture bd {
+	inst rd rd;
+	
+	[/uspace/lib/libc/subsume%rd]
+	
+	delegate rd to rd:rd;
+	
+	subsume rd:ns to ns;
+	subsume rd:devmap_driver to devmap_driver;
+};
Index: contrib/arch/uspace/srv/bd/bd.bp
===================================================================
--- contrib/arch/uspace/srv/bd/bd.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/bd/bd.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,8 @@
+?ipc_m_connect_me_to ;
+?ipc_m_share_out ;
+(
+	?get_block_size +
+	?read_blocks +
+	?write_blocks
+)* ;
+?ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/bd/rd/rd.adl
===================================================================
--- contrib/arch/uspace/srv/bd/rd/rd.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/bd/rd/rd.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,15 @@
+interface rd extends bd;
+
+frame rd {
+	provides:
+		rd rd;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+		devmap_driver devmap_driver;
+	initialization:
+		[/uspace/lib/libc/fnc.devmap_driver_register] ;
+		[/uspace/lib/libc/fnc.devmap_device_register]
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/console/console.adl
===================================================================
--- contrib/arch/uspace/srv/console/console.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/console.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,107 @@
+interface console extends service {
+		/* Read characters from console */
+		ipcarg_t read(out_copy stream data);
+		
+		/* Write characters to console */
+		ipcarg_t write(in_copy stream data);
+		
+		/* Get last event from event queue */
+		ipcarg_t get_event(out ipcarg_t type, out ipcarg_t key, out ipcarg_t mods, out ipcarg_t char);
+		
+		/* Flush output buffer */
+		ipcarg_t sync(void);
+		
+		/* Clear console */
+		ipcarg_t clear(void);
+		
+		/* Move cursor to given position */
+		ipcarg_t goto(in ipcarg_t col, in ipcarg_t row);
+		
+		/* Get console dimensions (in character cells) */
+		ipcarg_t get_size(out ipcarg_t cols, in ipcarg_t rows);
+		
+		/* Get color capabilities */
+		ipcarg_t get_color_cap(void);
+		
+		/* Set abstract text style */
+		ipcarg_t set_style(in ipcarg_t style);
+		
+		/* Set EGA-based text color */
+		ipcarg_t set_color(in ipcarg_t fb_color, in ipcarg_t bg_color, in ipcarg_t attr);
+		
+		/* Set RGB-based text color */
+		ipcarg_t set_rgb_color(in ipcarg_t fb_color, in ipcarg_t bg_color);
+		
+		/* Set cursor visibility */
+		ipcarg_t cursor_visibility(in ipcarg_t visible);
+		
+		/* Switch to kernel debugging console (if available) */
+		ipcarg_t kcon_enable(void);
+	protocol:
+		[console.bp]
+};
+
+frame ui_dispatcher {
+	provides:
+		console console;
+		event event;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+		devmap_driver devmap_driver;
+		sys_console sys_console;
+		kbd kbd;
+		fb fb;
+	initialization:
+		!ns.ipc_m_connect_me_to /* kbd */ ;
+		!kbd.ipc_m_connect_to_me ;
+		!ns.ipc_m_connect_me_to /* fb */ ;
+		[/uspace/lib/libc/fnc.devmap_driver_register] ;
+		!fb.get_resolution ;
+		(
+			[fnc.vp_create] +
+			[fnc.vp_switch]
+		)* ;
+		[fnc.make_pixmap]* ;
+		[fnc.make_anim] ;
+		[fnc.vp_switch] ;
+		!fb.flush ;
+		!fb.get_csize ;
+		!fb.get_color_cap ;
+		!fb.ipc_m_share_out ;
+		[/uspace/lib/libc/fnc.devmap_device_register]* ;
+		!sys_console.sys_debug_disable_console ;
+		[fnc.gcons_redraw_console] ;
+		[fnc.set_rgb_color] ;
+		[fnc.screen_clear] ;
+		[fnc.curs_goto] ;
+		[fnc.curs_visibility]
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
+
+architecture console {
+	inst ui_dispatcher ui_dispatcher;
+	inst kbd kbd;
+	inst fb fb;
+	
+	bind ui_dispatcher:kbd to kbd:kbd;
+	bind ui_dispatcher:fb to fb:fb;
+	
+	bind kbd:event to ui_dispatcher:event;
+	
+	delegate console to ui_dispatcher:console;
+	delegate kbd to kbd:kbd;
+	delegate fb to fb:fb;
+	
+	[/uspace/lib/libc/subsume%ui_dispatcher]
+	[/uspace/lib/libc/subsume%kbd]
+	[/uspace/lib/libc/subsume%fb]
+	
+	subsume ui_dispatcher:ns to ns;
+	subsume ui_dispatcher:devmap_driver to devmap_driver;
+	subsume ui_dispatcher:sys_console to sys_console;
+	
+	subsume kbd:ns to ns;
+	subsume fb:ns to ns;
+};
Index: contrib/arch/uspace/srv/console/console.bp
===================================================================
--- contrib/arch/uspace/srv/console/console.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/console.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,70 @@
+?ipc_m_connect_me_to ;
+[fnc.gcons_notify_connect] ;
+(
+	?read {
+		[fnc.cons_read]
+	} +
+	
+	?write {
+		[fnc.cons_write]
+	} +
+	
+	?sync {
+		[fnc.fb_pending_flush] ;
+		tentative {
+			!fb.flush ;
+			[fnc.curs_goto]
+		}
+	} +
+	
+	?clear {
+		tentative {
+			!fb.flush
+		}
+	} +
+	
+	?goto {
+		tentative {
+			!fb.curs_goto
+		}
+	} +
+	
+	?set_style {
+		[fnc.fb_pending_flush] ;
+		tentative {
+			[fnc.set_style]
+		}
+	} +
+	
+	?set_color {
+		[fnc.fb_pending_flush] ;
+		tentative {
+			[fnc.set_color]
+		}
+	} +
+	
+	?set_rgb_color {
+		[fnc.fb_pending_flush] ;
+		tentative {
+			[fnc.set_rgb_color]
+		}
+	} +
+	
+	?cursor_visibility {
+		[fnc.fb_pending_flush] ;
+		tentative {
+			[fnc.curs_visibility]
+		}
+	} +
+	
+	?kcon_enable {
+		!sys_console.sys_debug_enable_console
+	} +
+	
+	?get_event +
+	?get_size +
+	?get_color_cap
+)* ;
+?ipc_m_phone_hungup {
+	[fnc.gcons_notify_disconnect]
+}
Index: contrib/arch/uspace/srv/console/fnc.cell_mark_changed
===================================================================
--- contrib/arch/uspace/srv/console/fnc.cell_mark_changed	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.cell_mark_changed	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,5 @@
+(
+	tentative {
+		[fnc.fb_pending_flush]
+	}
+)
Index: contrib/arch/uspace/srv/console/fnc.clear
===================================================================
--- contrib/arch/uspace/srv/console/fnc.clear	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.clear	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.clear
+)
Index: contrib/arch/uspace/srv/console/fnc.cons_read
===================================================================
--- contrib/arch/uspace/srv/console/fnc.cons_read	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.cons_read	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	?ipc_m_data_read
+)
Index: contrib/arch/uspace/srv/console/fnc.cons_write
===================================================================
--- contrib/arch/uspace/srv/console/fnc.cons_write	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.cons_write	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,5 @@
+(
+	?ipc_m_data_write ;
+	[fnc.write_char]* ;
+	[fnc.gcons_notify_char]
+)
Index: contrib/arch/uspace/srv/console/fnc.curs_goto
===================================================================
--- contrib/arch/uspace/srv/console/fnc.curs_goto	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.curs_goto	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.cursor_goto
+)
Index: contrib/arch/uspace/srv/console/fnc.curs_visibility
===================================================================
--- contrib/arch/uspace/srv/console/fnc.curs_visibility	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.curs_visibility	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.cursor_visibility
+)
Index: contrib/arch/uspace/srv/console/fnc.draw_pixmap
===================================================================
--- contrib/arch/uspace/srv/console/fnc.draw_pixmap	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.draw_pixmap	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,6 @@
+(
+	!fb.prepare_shm ;
+	!fb.ipc_m_share_out ;
+	!fb.draw_ppm ;
+	!fb.drop_shm
+)
Index: contrib/arch/uspace/srv/console/fnc.fb_pending_flush
===================================================================
--- contrib/arch/uspace/srv/console/fnc.fb_pending_flush	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.fb_pending_flush	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.draw_text_data
+)
Index: contrib/arch/uspace/srv/console/fnc.gcons_notify_char
===================================================================
--- contrib/arch/uspace/srv/console/fnc.gcons_notify_char	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.gcons_notify_char	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,6 @@
+(
+	tentative {
+		[fnc.redraw_state] ;
+		[fnc.vp_switch]
+	}
+)
Index: contrib/arch/uspace/srv/console/fnc.gcons_notify_connect
===================================================================
--- contrib/arch/uspace/srv/console/fnc.gcons_notify_connect	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.gcons_notify_connect	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,6 @@
+(
+	tentative {
+		[fnc.redraw_state] ;
+		[fnc.vp_switch]
+	}
+)
Index: contrib/arch/uspace/srv/console/fnc.gcons_notify_disconnect
===================================================================
--- contrib/arch/uspace/srv/console/fnc.gcons_notify_disconnect	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.gcons_notify_disconnect	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,6 @@
+(
+	tentative {
+		[fnc.redraw_state] ;
+		[fnc.vp_switch]
+	}
+)
Index: contrib/arch/uspace/srv/console/fnc.gcons_redraw_console
===================================================================
--- contrib/arch/uspace/srv/console/fnc.gcons_redraw_console	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.gcons_redraw_console	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,11 @@
+(
+	tentative {
+		[fnc.vp_switch] ;
+		[fnc.set_rgb_color] ;
+		[fnc.clear] ;
+		[fnc.draw_pixmap] ;
+		[fnc.draw_pixmap] ;
+		[fnc.redraw_state]* ;
+		[fnc.vp_switch]
+	}
+)
Index: contrib/arch/uspace/srv/console/fnc.make_anim
===================================================================
--- contrib/arch/uspace/srv/console/fnc.make_anim	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.make_anim	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,6 @@
+(
+	!fb.anim_create ;
+	[fnc.make_pixmap]* ;
+	!fb.anim_add_pixmap ;
+	!fb.anim_start
+)
Index: contrib/arch/uspace/srv/console/fnc.make_pixmap
===================================================================
--- contrib/arch/uspace/srv/console/fnc.make_pixmap	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.make_pixmap	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,6 @@
+(
+	!fb.prepare_shm ;
+	!fb.ipc_m_share_out ;
+	!fb.shm2pixmap ;
+	!fb.drop_shm
+)
Index: contrib/arch/uspace/srv/console/fnc.redraw_state
===================================================================
--- contrib/arch/uspace/srv/console/fnc.redraw_state	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.redraw_state	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,9 @@
+(
+	[fnc.vp_switch] ;
+	tentative {
+		!fb.vp_draw_pixmap
+	} ;
+	tentative {
+		!fb.putchar*
+	}
+)
Index: contrib/arch/uspace/srv/console/fnc.screen_clear
===================================================================
--- contrib/arch/uspace/srv/console/fnc.screen_clear	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.screen_clear	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.clear
+)
Index: contrib/arch/uspace/srv/console/fnc.set_color
===================================================================
--- contrib/arch/uspace/srv/console/fnc.set_color	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.set_color	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.set_color
+)
Index: contrib/arch/uspace/srv/console/fnc.set_rgb_color
===================================================================
--- contrib/arch/uspace/srv/console/fnc.set_rgb_color	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.set_rgb_color	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.set_rgb_color
+)
Index: contrib/arch/uspace/srv/console/fnc.set_style
===================================================================
--- contrib/arch/uspace/srv/console/fnc.set_style	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.set_style	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.set_style
+)
Index: contrib/arch/uspace/srv/console/fnc.vp_create
===================================================================
--- contrib/arch/uspace/srv/console/fnc.vp_create	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.vp_create	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.viewport_create
+)
Index: contrib/arch/uspace/srv/console/fnc.vp_switch
===================================================================
--- contrib/arch/uspace/srv/console/fnc.vp_switch	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.vp_switch	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fb.viewport_switch
+)
Index: contrib/arch/uspace/srv/console/fnc.write_char
===================================================================
--- contrib/arch/uspace/srv/console/fnc.write_char	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/console/fnc.write_char	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,15 @@
+(
+	(
+		[fnc.fb_pending_flush] +
+		[fnc.cell_mark_changed]
+	) ;
+	tentative {
+		[fnc.fb_pending_flush] ;
+		tentative {
+			!fb.scroll
+		}
+	} ;
+	tentative {
+		[fnc.curs_goto]
+	}
+)
Index: contrib/arch/uspace/srv/devmap/devmap.adl
===================================================================
--- contrib/arch/uspace/srv/devmap/devmap.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/devmap/devmap.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,71 @@
+interface devmap_driver {
+		/* Establish connection (iface is DEVMAP_DRIVER) */
+		ipcarg_t ipc_m_connect_me_to(in ipcarg_t iface);
+		
+		/* Register as a new driver */
+		ipcarg_t driver_register(in_copy string name);
+		
+		/* Unregister all devices and the driver itself */
+		ipcarg_t driver_unregister(void);
+		
+		/* Register new device and return handle */
+		ipcarg_t device_register(in_copy string name, out ipcarg_t handle);
+		
+		/* Unregister device */
+		ipcarg_t device_unregister(in ipcarg_t handle);
+		
+		/* Resolve device name to handle */
+		ipcarg_t device_get_handle(in ipcarg_t flags, in_copy string name);
+		
+		/* Get device name for a given handle */
+		ipcarg_t device_get_name(in ipcarg_t handle);
+		
+		/* Close connection */
+		ipcarg_t ipc_m_phone_hungup(void);
+	protocol:
+		[devmap_driver.bp]
+};
+
+interface devmap_client {
+		/* Establish connection (iface is DEVMAP_CLIENT) or forward to device (iface is DEVMAP_CONNECT_TO_DEVICE) */
+		ipcarg_t ipc_m_connect_me_to(in ipcarg_t iface, in ipcarg_t handle);
+		
+		/* Resolve device name to handle */
+		ipcarg_t device_get_handle(in ipcarg_t flags, in_copy string name);
+		
+		/* Get device name for a given handle */
+		ipcarg_t device_get_name(in ipcarg_t handle);
+		
+		/* Clone NULL device */
+		ipcarg_t device_null_create(out ipcarg_t index);
+		
+		/* Destroy NULL device */
+		ipcarg_t device_null_destroy(in ipcarg_t index);
+		
+		/* Get number of devices */
+		ipcarg_t device_get_count(out ipcarg_t count);
+		
+		/* Get an array of (device_name, handle) pairs */
+		ipcarg_t device_get_devices(out_copy stream data);
+		
+		/* Close connection */
+		ipcarg_t ipc_m_phone_hungup(void);
+	protocol:
+		[devmap_client.bp]
+	
+};
+
+frame devmap {
+	provides:
+		devmap_driver devmap_driver;
+		devmap_client devmap_client;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+		rd rd;
+		console console;
+	initialization:
+		!ns.ipc_m_connect_to_me /* devmap */
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/devmap/devmap_client.bp
===================================================================
--- contrib/arch/uspace/srv/devmap/devmap_client.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/devmap/devmap_client.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,23 @@
+?ipc_m_connect_me_to ;
+
+alternative (service; rd; console) {
+	!service.ipc_m_connect_me_to /* forward */
+}
++
+(
+	(
+		?device_get_handle {
+			?ipc_m_data_write /* device name */
+		} +
+		
+		?device_get_name +
+		?device_null_create +
+		?device_null_destroy +
+		?device_get_count +
+		
+		?device_get_devices {
+			?ipc_m_data_read /* buffer */
+		}
+	)*
+) ;
+?ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/devmap/devmap_driver.bp
===================================================================
--- contrib/arch/uspace/srv/devmap/devmap_driver.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/devmap/devmap_driver.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,25 @@
+?ipc_m_connect_me_to ;
+?driver_register {
+	tentative {
+		?ipc_m_data_write /* driver name */
+	}
+} ;
+(
+	?device_register {
+		tentative {
+			?ipc_m_data_write /* device name */
+		} ;
+		tentative {
+			?ipc_m_connect_to_me /* callback */
+		}
+	} +
+	
+	?device_get_handle {
+		?ipc_m_data_write /* device name */
+	} +
+	
+	?device_get_name +
+	?device_unregister +
+	?driver_unregister
+)* ;
+?ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/fb/fb.adl
===================================================================
--- contrib/arch/uspace/srv/fb/fb.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fb/fb.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,111 @@
+interface fb extends service {
+		/* Get screen resolution */
+		ipcarg_t get_resolution(out ipcarg_t width, out ipcarg_t height);
+		
+		/* Yield screen */
+		ipcarg_t screen_yield(void);
+		
+		/* Reclaim screen */
+		ipcarg_t screen_reclaim(void);
+		
+		/* Set mouse cursor position on screen */
+		ipcarg_t pointer_move(in ipcarg_t x, in ipcarg_t y);
+		
+		/* Create new viewport */
+		ipcarg_t viewport_create(in ipcarg_t origin, in ipcarg_t dimension);
+		
+		/* Get viewport size in character cells */
+		ipcarg_t get_csize(out ipcarg_t width, out ipcarg_t height);
+		
+		/* Clear viewport character buffer */
+		ipcarg_t clear(void);
+		
+		/* Scroll viewport character buffer */
+		ipcarg_t scroll(in ipcarg_t lines);
+		
+		/* Set active viewport */
+		ipcarg_t viewport_switch(in ipcarg_t index);
+		
+		/* Delete viewport */
+		ipcarg_t viewport_delete(in ipcarg_t index);
+		
+		/* Get color capabilities of the screen */
+		ipcarg_t get_color_cap(void);
+		
+		/* Set abstract text style */
+		ipcarg_t set_style(in ipcarg_t style);
+		
+		/* Set EGA-based text color */
+		ipcarg_t set_color(in ipcarg_t fg_color, in ipcarg_t bg_color, in ipcarg_t atrr);
+		
+		/* Set RGB-based text color */
+		ipcarg_t set_rgb_color(in ipcarg_t fg_color, in ipcarg_t bg_color);
+		
+		/* Put a character to a given position in viewport character buffer */
+		ipcarg_t putchar(in ipcarg_t char, in ipcarg_t col, in ipcarg_t row);
+		
+		/* Set character cursor visibility in viewport */
+		ipcarg_t cursor_visibility(in ipcarg_t visible);
+		
+		/* Set character cursor position in viewport */
+		ipcarg_t cursor_goto(in ipcarg_t col, in ipcarg_t row);
+		
+		/* Prepare memory sharing of bitmaps */
+		ipcarg_t prepare_shm(in ipcarg_t as_area_base);
+		
+		/* Share bitmap or text data */
+		ipcarg_t ipc_m_share_out(in ipcarg_t as_area_base, in ipcarg_t as_area_size, out ipcarg_t dst_as_area);
+		
+		/* Drop memory sharing */
+		ipcarg_t drop_shm(void);
+		
+		/* Draw PPM data from shared memory to viewport */
+		ipcarg_t draw_ppm(in ipcarg_t x, in ipcarg_t y);
+		
+		/* Put characters from shared memory to viewport */
+		ipcarg_t draw_text_data(in ipcarg_t x, in ipcarg_t y, in ipcarg_t width, in ipcarg_t height);
+		
+		/* Convert PPM data from shared memory to pixmap */
+		ipcarg_t shm2pixmap(void);
+		
+		/* Save viewport contents to a pixmap */
+		ipcarg_t vp2pixmap(in ipcarg_t vp_index);
+		
+		/* Draw pixmap to viewport */
+		ipcarg_t vp_draw_pixmap(in ipcarg_t vp_index, in ipcarg_t pm_index);
+		
+		/* Discard pixmap */
+		ipcarg_t drop_pixmap(in ipcarg_t pm_index);
+		
+		/* Create new (empty) animation for a viewport */
+		ipcarg_t anim_create(in ipcarg_t vp_index);
+		
+		/* Append a pixmap to an animation */
+		ipcarg_t anim_addpixmap(in ipcarg_t anim_index, in ipcarg_t pm_index);
+		
+		/* Change a viewport associated with an animation */
+		ipcarg_t anim_chgvp(in ipcarg_t anim_index, in ipcarg_t vp_index);
+		
+		/* Start animation playback */
+		ipcarg_t anim_start(in ipcarg_t anim_index);
+		
+		/* Stop animation playback */
+		ipcarg_t anim_stop(in ipcarg_t anim_index);
+		
+		/* Delete animation */
+		ipcarg_t anim_drop(in ipcarg_t anim_index);
+	protocol:
+		[fb.bp]
+};
+
+frame fb {
+	provides:
+		fb fb;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+	initialization:
+		!ns.ipc_m_connect_to_me /* fb */
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/fb/fb.bp
===================================================================
--- contrib/arch/uspace/srv/fb/fb.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fb/fb.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+?ipc_m_connect_me_to ;
+(
+	(
+		?prepare_shm ;
+		?ipc_m_share_out
+	) +
+	?ipc_m_share_out +
+	?drop_shm +
+	?get_resolution +
+	?screen_yield +
+	?screen_reclaim +
+	?pointer_move +
+	?viewport_create +
+	?get_csize +
+	?clear +
+	?scroll +
+	?viewport_switch +
+	?viewport_delete +
+	?get_color_cap +
+	?set_style +
+	?set_color +
+	?set_rgb_color +
+	?putchar +
+	?cursor_visibility +
+	?cursor_goto +
+	?draw_ppm +
+	?draw_text_data +
+	?shm2pixmap +
+	?vp2pixmap +
+	?vp_draw_pixmap +
+	?drop_pixmap +
+	?anim_create +
+	?anim_addpixmap +
+	?anim_chgvp +
+	?anim_start +
+	?anim_stop +
+	?anim_drop
+)* ;
+?ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/fs/devfs/devfs.adl
===================================================================
--- contrib/arch/uspace/srv/fs/devfs/devfs.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fs/devfs/devfs.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,21 @@
+interface devfs extends fs {
+	protocol:
+		[devfs.bp]
+};
+
+frame devfs {
+	provides:
+		devfs devfs;
+	requires:
+		[/uspace/lib/libc/requires]
+		vfs vfs;
+		ns ns;
+		devmap_client devmap_client;
+		service device;
+	initialization:
+		[/uspace/lib/libc/fnc.devmap_get_phone] ;
+		!ns.ipc_m_connect_me_to /* vfs */ ;
+		[/uspace/lib/libfs/fnc.fs_register]
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/fs/devfs/devfs.bp
===================================================================
--- contrib/arch/uspace/srv/fs/devfs/devfs.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fs/devfs/devfs.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,62 @@
+(
+	?ipc_m_connect_me_to ;
+	(
+		?mounted {
+			?ipc_m_data_write /* mount options */
+		} +
+		
+		?lookup {
+			tentative {
+				[/uspace/lib/libc/fnc.devmap_device_get_handle] ;
+				tentative {
+					[/uspace/lib/libc/fnc.devmap_device_connect]
+				}
+			}
+		} +
+		
+		?open_node {
+			tentative {
+				[/uspace/lib/libc/fnc.devmap_device_connect]
+			}
+		} +
+		
+		?read {
+			tentative {
+				?ipc_m_data_read /* payload */ {
+					!device.read {
+						!device.ipc_m_data_read /* forward */
+					}
+				} +
+				(
+					[/uspace/lib/libc/fnc.devmap_device_get_count] ;
+					[/uspace/lib/libc/fnc.devmap_device_get_devices]
+				)
+			}
+		} +
+		
+		?write {
+			tentative {
+				?ipc_m_data_write /* payload */ {
+					!device.write {
+						!device.ipc_m_data_write /* forward */
+					}
+				}
+			}
+		} +
+		
+		?stat {
+			?ipc_m_data_read /* struct data */
+		} +
+		
+		?close {
+			!device.ipc_m_phone_hungup
+		} +
+		
+		?mount +
+		?truncate +
+		?destroy +
+		?sync
+	)* ;
+	?ipc_m_phone_hungup
+)* ;
+!vfs.ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/fs/fat/fat.adl
===================================================================
--- contrib/arch/uspace/srv/fs/fat/fat.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fs/fat/fat.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,22 @@
+interface fat extends fs {
+	protocol:
+		[fat.bp]
+};
+
+frame fat {
+	provides:
+		fat fat;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+		rd rd;
+		vfs vfs;
+		tmpfs tmpfs_nested;
+		fat fat_nested;
+		devfs devfs_nested;
+	initialization:
+		!ns.ipc_m_connect_me_to /* vfs */ ;
+		[/uspace/lib/libfs/fnc.fs_register]
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/fs/fat/fat.bp
===================================================================
--- contrib/arch/uspace/srv/fs/fat/fat.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fs/fat/fat.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,48 @@
+!ns.ipc_m_connect_me_to /* vfs */ ;
+[/uspace/lib/libfs/fnc.fs_register] ;
+(
+	?ipc_m_connect_me_to ;
+	(
+		?mounted {
+			?ipc_m_data_write /* mount options */ ;
+			tentative {
+				[/uspace/lib/libblock/fnc.block_init%rd]
+			}
+		} +
+		
+		?mount {
+			[/uspace/lib/libfs/fnc.libfs_mount]
+		} +
+		
+		?lookup {
+			[/uspace/lib/libfs/fnc.libfs_lookup]
+		} +
+		
+		?open_node {
+			[/uspace/lib/libfs/fnc.libfs_open_node]
+		} +
+		
+		?read {
+			tentative {
+				?ipc_m_data_read /* payload */
+			}
+		} +
+		
+		?write {
+			tentative {
+				?ipc_m_data_write /* payload */
+			}
+		} +
+		
+		?stat {
+			[/uspace/lib/libfs/fnc.libfs_stat]
+		} +
+		
+		?truncate +
+		?close +
+		?destroy +
+		?sync
+	)* ;
+	?ipc_m_phone_hungup
+)* ;
+!vfs.ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/fs/tmpfs/fnc.tmpfs_restore
===================================================================
--- contrib/arch/uspace/srv/fs/tmpfs/fnc.tmpfs_restore	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fs/tmpfs/fnc.tmpfs_restore	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,7 @@
+(
+	[/uspace/lib/libblock/fnc.block_init%rd] ;
+	tentative {
+		[/uspace/lib/libblock/fnc.block_seqread%rd]* ;
+		[/uspace/lib/libblock/fnc.block_fini%rd]
+	}
+)
Index: contrib/arch/uspace/srv/fs/tmpfs/tmpfs.adl
===================================================================
--- contrib/arch/uspace/srv/fs/tmpfs/tmpfs.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fs/tmpfs/tmpfs.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,22 @@
+interface tmpfs extends fs {
+	protocol:
+		[tmpfs.bp]
+};
+
+frame tmpfs {
+	provides:
+		tmpfs tmpfs;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+		rd rd;
+		vfs vfs;
+		tmpfs tmpfs_nested;
+		fat fat_nested;
+		devfs devfs_nested;
+	initialization:
+		!ns.ipc_m_connect_me_to /* vfs */ ;
+		[/uspace/lib/libfs/fnc.fs_register]
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/fs/tmpfs/tmpfs.bp
===================================================================
--- contrib/arch/uspace/srv/fs/tmpfs/tmpfs.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/fs/tmpfs/tmpfs.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,46 @@
+(
+	?ipc_m_connect_me_to ;
+	(
+		?mounted {
+			?ipc_m_data_write /* mount options */ ;
+			tentative {
+				[fnc.tmpfs_restore]
+			}
+		} +
+		
+		?mount {
+			[/uspace/lib/libfs/fnc.libfs_mount]
+		} +
+		
+		?lookup {
+			[/uspace/lib/libfs/fnc.libfs_lookup]
+		} +
+		
+		?open_node {
+			[/uspace/lib/libfs/fnc.libfs_open_node]
+		} +
+		
+		?read {
+			tentative {
+				?ipc_m_data_read /* payload */
+			}
+		} +
+		
+		?write {
+			tentative {
+				?ipc_m_data_write /* payload */
+			}
+		} +
+		
+		?stat {
+			[/uspace/lib/libfs/fnc.libfs_stat]
+		} +
+		
+		?truncate +
+		?close +
+		?destroy +
+		?sync
+	)* ;
+	?ipc_m_phone_hungup
+)* ;
+!vfs.ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/kbd/event.bp
===================================================================
--- contrib/arch/uspace/srv/kbd/event.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/kbd/event.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,7 @@
+?ipc_m_connect_me_to ;
+?event {
+	tentative {
+		!sys_console.sys_enable_console
+	}
+}* ;
+?ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/kbd/kbd.adl
===================================================================
--- contrib/arch/uspace/srv/kbd/kbd.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/kbd/kbd.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,33 @@
+interface kbd extends service {
+		/* Callback connection */
+		ipcarg_t ipc_m_connect_to_me(void);
+		
+		/* Yield hardware */
+		ipcarg_t yield(void);
+		
+		/* Reclaim hardware */
+		ipcarg_t reclaim(void);
+	protocol:
+		[kbd.bp]
+};
+
+interface event {
+		/* Send keyboard event */
+		ipcarg_t event(in ipcarg_t type, in ipcarg_t key, in ipcarg_t mods, in ipcarg_t char);
+	protocol:
+		[event.bp]
+};
+
+frame kbd {
+	provides:
+		kbd kbd;
+	requires:
+		[/uspace/lib/libc/requires]
+		event event;
+		ns ns;
+	initialization:
+		!ns.ipc_m_connect_to_me /* kbd */ ;
+		!event.event*
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/kbd/kbd.bp
===================================================================
--- contrib/arch/uspace/srv/kbd/kbd.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/kbd/kbd.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,7 @@
+?ipc_m_connect_me_to ;
+(
+	?ipc_m_connect_to_me +
+	?yield +
+	?reclam
+)* ;
+?ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/loader/loader.adl
===================================================================
--- contrib/arch/uspace/srv/loader/loader.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/loader/loader.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,34 @@
+interface loader extends service {
+		/* Set task pathname */
+		ipcarg_t set_pathname(in_copy string pathname);
+		
+		/* Set task arguments */
+		ipcarg_t set_args(in_copy stream args);
+		
+		/* Set task initial files */
+		ipcarg_t set_files(in_copy stream files);
+		
+		/* Get task ID */
+		ipcarg_t get_taskid(out_copy stream id);
+		
+		/* Load binary */
+		ipcarg_t load(void);
+		
+		/* Run binary */
+		ipcarg_t run(void);
+	protocol:
+		[loader.bp]
+};
+
+frame loader {
+	provides:
+		loader loader;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+	initialization:
+		!ns.id_intro ;
+		!ns.ipc_m_connect_to_me /* loader */
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/loader/loader.bp
===================================================================
--- contrib/arch/uspace/srv/loader/loader.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/loader/loader.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,23 @@
+(
+	?get_taskid {
+		?ipc_m_data_read /* task ID */
+	} +
+	
+	?set_pathname {
+		?ipc_m_data_write /* pathname */
+	} +
+	
+	?set_args {
+		?ipc_m_data_write /* arguments */
+	} +
+	
+	?set_files {
+		?ipc_m_data_write /* files */
+	} +
+	
+	?load
+)* ;
+(
+	?run +
+	?ipc_m_phone_hungup
+)
Index: contrib/arch/uspace/srv/ns/ns.adl
===================================================================
--- contrib/arch/uspace/srv/ns/ns.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/ns/ns.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,43 @@
+interface ns {
+		/* Register a clonable service or a generic service */
+		ipcarg_t ipc_m_connect_to_me(in ipcarg_t service);
+		
+		/* Connect to a clonable service or a generic service */
+		ipcarg_t ipc_m_connect_me_to(in ipcarg_t service, in ipcarg_t arg2, in ipcarg_t arg3, in ipcarg_t flags);
+		
+		/* Share real-time clock page or klog page */
+		ipcarg_t ipc_m_share_in(in ipcarg_t as_area_base, in ipcarg_t as_area_size, in ipcarg_t service);
+		
+		/* For IPC testing purposes */
+		ipcarg_t ping(void);
+		
+		/* Wait for task exit and get exit status and return value */
+		ipcarg_t task_wait(in ipcarg_t id_lower, in ipcarg_t id_upper, out ipcarg_t status, out ipcarg_t retval);
+		
+		/* Introduce a new loader task id in such a way it cannot be spoofed */
+		ipcarg_t id_intro(in ipcarg_t id_lower, in ipcarg_t id_upper);
+		
+		/* Set task return value */
+		ipcarg_t retval(in ipcarg_t retval);
+		
+		/* Implicit connection close */
+		ipcarg_t ipc_m_phone_hungup(void);
+	protocol:
+		[ns.bp]
+};
+
+frame ns {
+	provides:
+		ns ns;
+	requires:
+		[/uspace/lib/libc/requires]
+		kbd kbd;
+		fb fb;
+		console console;
+		vfs vfs;
+		devmap_driver devmap_driver;
+		devmap_client devmap_client;
+		loader loader;
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/ns/ns.bp
===================================================================
--- contrib/arch/uspace/srv/ns/ns.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/ns/ns.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,25 @@
+/* Every task has an implicit connection to the Naming Service,
+   thus there is no explicit ?ipc_m_connect_me_to */
+
+(
+	?ipc_m_connect_to_me {
+		tentative {
+			!loader.ipc_m_connect_to_me /* forward */
+		}
+	} +
+	
+	?ipc_m_connect_me_to {
+		tentative {
+			alternative (service; kbd; fb; console; vfs; devmap_driver; devmap_client) {
+				!service.ipc_m_connect_me_to /* forward */
+			}
+		}
+	} +
+	
+	?ipc_m_share_in +
+	?ping +
+	?task_wait +
+	?id_intro +
+	?retval
+)* ;
+?ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/ns/service.adl
===================================================================
--- contrib/arch/uspace/srv/ns/service.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/ns/service.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,8 @@
+interface service {
+		/* Establish connection with the service
+		   (this call is forwarded from Naming Service or Device Mapper) */
+		ipcarg_t ipc_m_connect_me_to(void);
+		
+		/* Close connection */
+		ipcarg_t ipc_m_phone_hungup(void);
+};
Index: contrib/arch/uspace/srv/pci/pci.adl
===================================================================
--- contrib/arch/uspace/srv/pci/pci.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/pci/pci.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,16 @@
+interface pci extends service {
+	protocol:
+		[pci.bp]
+};
+
+frame pci {
+	provides:
+		pci pci;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+	initialization:
+		!ns.ipc_m_connect_to_me /* pci */
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: contrib/arch/uspace/srv/pci/pci.bp
===================================================================
--- contrib/arch/uspace/srv/pci/pci.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/pci/pci.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,2 @@
+?ipc_m_connect_me_to ;
+?ipc_m_phone_hungup
Index: contrib/arch/uspace/srv/vfs/fnc.vfs_grab_phone
===================================================================
--- contrib/arch/uspace/srv/vfs/fnc.vfs_grab_phone	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/vfs/fnc.vfs_grab_phone	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fs.ipc_m_connect_me_to
+)
Index: contrib/arch/uspace/srv/vfs/fnc.vfs_lookup_internal
===================================================================
--- contrib/arch/uspace/srv/vfs/fnc.vfs_lookup_internal	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/vfs/fnc.vfs_lookup_internal	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,5 @@
+(
+	[fnc.vfs_grab_phone] ;
+	!fs.lookup ;
+	[fnc.vfs_release_phone]
+)
Index: contrib/arch/uspace/srv/vfs/fnc.vfs_open_node_internal
===================================================================
--- contrib/arch/uspace/srv/vfs/fnc.vfs_open_node_internal	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/vfs/fnc.vfs_open_node_internal	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,5 @@
+(
+	[fnc.vfs_grab_phone] ;
+	!fs.open_node ;
+	[fnc.vfs_release_phone]
+)
Index: contrib/arch/uspace/srv/vfs/fnc.vfs_release_phone
===================================================================
--- contrib/arch/uspace/srv/vfs/fnc.vfs_release_phone	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/vfs/fnc.vfs_release_phone	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,3 @@
+(
+	!fs.ipc_m_phone_hungup
+)
Index: contrib/arch/uspace/srv/vfs/vfs.adl
===================================================================
--- contrib/arch/uspace/srv/vfs/vfs.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/vfs/vfs.adl	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,139 @@
+interface vfs extends service {
+		/* Register a filesystem driver */
+		ipcarg_t register(in_copy string name);
+		
+		/* Mount filesystem */
+		ipcarg_t mount(in ipcarg_t device, in ipcarg_t flags, in_copy string point, in_copy string opts, in_copy string fs);
+		
+		/* Open file */
+		ipcarg_t open(in ipcarg_t lflag, in ipcarg_t oflag, in ipcarg_t mode, in_copy string path, out ipcarg_t fd);
+		
+		/* Open file using node */
+		ipcarg_t open_node(in ipcarg_t fs_handle, in ipcarg_t dev_handle, in ipcarg_t index, in ipcarg_t oflag, out ipcarg_t fd);
+		
+		/* Read data from file */
+		ipcarg_t read(in ipcarg_t fd, out_copy stream data);
+		
+		/* Write data to file */
+		ipcarg_t write(in ipcarg_t fd, in_copy stream data);
+		
+		/* Seek in file */
+		ipcarg_t seek(in ipcarg_t fd, in ipcarg_t offset, in ipcarg_t whence);
+		
+		/* Truncate file */
+		ipcarg_t truncate(in ipcarg_t fd, in ipcarg_t size);
+		
+		/* Get file metadata */
+		ipcarg_t fstat(in ipcarg_t fd, out_copy stream stat);
+		
+		/* Get directory entry metadata */
+		ipcarg_t stat(in_copy string path, out_copy stream stat);
+		
+		/* Create directory */
+		ipcarg_t mkdir(in ipcarg_t mode, in_copy string path);
+		
+		/* Delete directory entry */
+		ipcarg_t unlink(in ipcarg_t lflag, in_copy string path);
+		
+		/* Rename directory entry */
+		ipcarg_t rename(in_copy string old, in_copy string new);
+		
+		/* Flush file buffers */
+		ipcarg_t sync(in ipcarg_t fd);
+		
+		/* In-protocol status value */
+		ipcarg_t ipc_m_ping(void);
+		
+		/* Close connection */
+		ipcarg_t ipc_m_phone_hungup(void);
+	protocol:
+		[vfs.bp]
+};
+
+interface fs extends service {
+		/* Notify filesystem that it was mounted */
+		ipcarg_t mounted(in ipcarg_t dev_handle, in_copy string opts);
+		
+		/* Mount filesystem */
+		ipcarg_t mount(in ipcarg_t device, in ipcarg_t flags, in_copy string point, in_copy string opts, ...);
+		
+		/* Open file by node */
+		ipcarg_t open_node(in ipcarg_t lflag, in ipcarg_t oflag, in ipcarg_t mode, ...);
+		
+		/* Lookup file */
+		ipcarg_t lookup(in ipcarg_t lflag, in ipcarg_t oflag, in ipcarg_t mode, ...);
+		
+		/* Read data from file */
+		ipcarg_t read(in ipcarg_t dev_handle, in ipcarg_t fs_index, in ipcarg_t offset, out_copy stream data);
+		
+		/* Write data to file */
+		ipcarg_t write(in ipcarg_t dev_handle, in ipcarg_t fs_index, in ipcarg_t offset, in_copy stream data);
+		
+		/* Truncate file */
+		ipcarg_t truncate(in ipcarg_t dev_handle, in ipcarg_t fs_index, in ipcarg_t size);
+		
+		/* Get directory entry metadata */
+		ipcarg_t stat(in ipcarg_t dev_handle, in ipcarg_t fs_index, out_copy stream stat);
+		
+		/* Flush file buffers */
+		ipcarg_t sync(in ipcarg_t dev_handle, in ipcarg_t fs_index);
+		
+		/* Notify on file close */
+		ipcarg_t close(in ipcarg_t dev_handle, in ipcarg_t fs_index);
+};
+
+frame io_dispatcher {
+	provides:
+		vfs vfs;
+	requires:
+		[/uspace/lib/libc/requires]
+		ns ns;
+		tmpfs tmpfs;
+		fat fat;
+		devfs devfs;
+	initialization:
+		!ns.ipc_m_connect_to_me /* vfs */
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
+
+architecture vfs {
+	inst io_dispatcher io_dispatcher;
+	inst tmpfs tmpfs;
+	inst fat fat;
+	inst devfs devfs;
+	
+	bind io_dispatcher:tmpfs to tmpfs:tmpfs;
+	bind io_dispatcher:fat to fat:fat;
+	bind io_dispatcher:devfs to devfs:devfs;
+	
+	bind tmpfs:vfs to io_dispatcher:vfs;
+	bind fat:vfs to io_dispatcher:vfs;
+	bind devfs:vfs to io_dispatcher:vfs;
+	
+	bind tmpfs:tmpfs_nested to tmpfs:tmpfs;
+	bind tmpfs:fat_nested to fat:fat;
+	bind tmpfs:devfs_nested to devfs:devfs;
+	
+	bind fat:tmpfs_nested to tmpfs:tmpfs;
+	bind fat:fat_nested to fat:fat;
+	bind fat:devfs_nested to devfs:devfs;
+	
+	delegate vfs to io_dispatcher:vfs;
+	
+	[/uspace/lib/libc/subsume%io_dispatcher]
+	[/uspace/lib/libc/subsume%tmpfs]
+	[/uspace/lib/libc/subsume%fat]
+	[/uspace/lib/libc/subsume%devfs]
+	
+	subsume io_dispatcher:ns to ns;
+	subsume tmpfs:ns to ns;
+	subsume fat:ns to ns;
+	subsume devfs:ns to ns;
+	
+	subsume tmpfs:rd to rd;
+	subsume fat:rd to rd;
+	
+	subsume devfs:devmap_client to devmap_client;
+	subsume devfs:device to device;
+};
Index: contrib/arch/uspace/srv/vfs/vfs.bp
===================================================================
--- contrib/arch/uspace/srv/vfs/vfs.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/arch/uspace/srv/vfs/vfs.bp	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,212 @@
+?ipc_m_connect_me_to ;
+(
+	?register {
+		?ipc_m_data_write /* fs name */ ;
+		tentative {
+			/* callback connection */
+			?ipc_m_connect_to_me ;
+			?ipc_m_share_in
+		}
+	} +
+	
+	?mount {
+		?ipc_m_data_write /* mount point */ ;
+		tentative {
+			?ipc_m_data_write /* mount options */ ;
+			tentative {
+				?ipc_m_data_write /* fs name */ ;
+				tentative {
+					?ipc_m_ping ;
+					tentative {
+						(
+							/* root fs */
+							alternative (fs; tmpfs; fat; devfs) {
+								!fs.mounted {
+									!fs.ipc_m_data_write /* mount options */
+								}
+							}
+						) +
+						(
+							/* non-root fs */
+							tentative {
+								alternative (fs; tmpfs; fat; devfs) {
+									[fnc.vfs_lookup_internal] ;
+									tentative {
+										[fnc.vfs_grab_phone] ;
+										[fnc.vfs_grab_phone] ;
+										!fs.mount ;
+										!fs.ipc_m_connection_clone ;
+										[fnc.vfs_release_phone] ;
+										tentative {
+											!fs.vfs_m_data_write /* mount options */
+										} ;
+										[fnc.vfs_release_phone]
+									}
+								}
+							}
+						)
+					}
+				}
+			}
+		}
+	} +
+	
+	?open {
+		tentative {
+			?ipc_m_data_write /* path */ ;
+			tentative {
+				alternative (fs; tmpfs; fat; devfs) {
+					[fnc.vfs_lookup_internal] ;
+					tentative {
+						[fnc.vfs_grab_phone] ;
+						!fs.truncate ;
+						[fnc.vfs_release_phone]
+					}
+				}
+			}
+		}
+	} +
+	
+	?open_node {
+		alternative (fs; tmpfs; fat; devfs) {
+			[fnc.vfs_open_node_internal] ;
+			tentative {
+				[fnc.vfs_grab_phone] ;
+				!fs.truncate ;
+				[fnc.vfs_release_phone]
+			}
+		}
+	} +
+	
+	?close {
+		tentative {
+			alternative (fs; tmpfs; fat; devfs) {
+				[fnc.vfs_grab_phone] ;
+				!fs.close ;
+				[fnc.vfs_release_phone]
+			}
+		}
+	} +
+	
+	?read {
+		tentative {
+			?ipc_m_data_read {
+				alternative (fs; tmpfs; fat; devfs) {
+					[fnc.vfs_grab_phone] ;
+					!fs.read {
+						!fs.ipc_m_data_read /* forward payload */
+					} ;
+					[fnc.vfs_release_phone]
+				}
+			}
+		}
+	} +
+	
+	?write {
+		tentative {
+			?ipc_m_data_write {
+				alternative (fs; tmpfs; fat; devfs) {
+					[fnc.vfs_grab_phone] ;
+					!fs.write {
+						!fs.ipc_m_data_write /* forward payload */
+					} ;
+					[fnc.vfs_release_phone]
+				}
+			}
+		}
+	} +
+	
+	?truncate {
+		tentative {
+			alternative (fs; tmpfs; fat; devfs) {
+				[fnc.vfs_grab_phone] ;
+				!fs.truncate ;
+				[fnc.vfs_release_phone]
+			}
+		}
+	} +
+	
+	?fstat {
+		tentative {
+			?ipc_m_data_read /* struct stat */ {
+				alternative (fs; tmpfs; fat; devfs) {
+					[fnc.vfs_grab_phone] ;
+					!fs.stat {
+						!fs.ipc_m_data_read /* forward struct stat */
+					} ;
+					[fnc.vfs_release_phone]
+				}
+			}
+		}
+	} +
+	
+	?stat {
+		?ipc_m_data_write /* path */ ;
+		tentative {
+			?ipc_m_data_read /* struct stat */ {
+				alternative (fs; tmpfs; fat; devfs) {
+					[fnc.vfs_lookup_internal] ;
+					tentative {
+						!fs.stat {
+							!fs.ipc_m_data_read /* forward struct stat */
+						}
+					}
+				}
+			}
+		}
+	} +
+	
+	?mkdir {
+		?ipc_m_data_write /* path */ ;
+		tentative {
+			alternative (fs; tmpfs; fat; devfs) {
+				[fnc.vfs_lookup_internal]
+			}
+		}
+	} +
+	
+	?unlink {
+		?ipc_m_data_write /* path */ ;
+		tentative {
+			alternative (fs; tmpfs; fat; devfs) {
+				[fnc.vfs_lookup_internal]
+			}
+		}
+	} +
+	
+	?rename {
+		?ipc_m_data_write /* old path */ ;
+		tentative {
+			?ipc_m_data_write /* new path */ ;
+			tentative {
+				alternative (fs; tmpfs; fat; devfs) {
+					[fnc.vfs_lookup_internal] /* lookup old path */ ;
+					tentative {
+						[fnc.vfs_lookup_internal] /* lookup parent of new path */ ;
+						tentative {
+							[fnc.vfs_lookup_internal] /* destroy old link for the new path */ ;
+							tentative {
+								[fnc.vfs_lookup_internal] /* create new link for the new path */ ;
+								tentative {
+									[fnc.vfs_lookup_internal] /* destroy link for the old path */
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	} +
+	
+	?sync {
+		tentative {
+			alternative (fs; tmpfs; fat; devfs) {
+				!fs.sync
+			}
+		}
+	} +
+	
+	?seek
+	
+)* ;
+?ipc_m_phone_hungup
Index: contrib/bazaar/mbprotect/__init__.py
===================================================================
--- contrib/bazaar/mbprotect/__init__.py	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/bazaar/mbprotect/__init__.py	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2009 Jiri Svoboda
+# 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.
+#
+
+"""Main Branch Protection plugin for Bazaar."""
+
+#
+# This plugin employs the pre_change_branch_tip hook to protect the main
+# branch (a.k.a. linear history) of bzr repositories from unwanted change,
+# effectively making the main branch append-only.
+# 
+# Specifically we verify that the new main branch contains the old tip.
+# This prevents a branch from inadvertently aquiring the tip of another branch.
+#
+# Install this plugin in ~/.bazaar/plugins/mbprotect
+#
+# See also http://trac.helenos.org/trac.fcgi/wiki/BazaarWorkflow
+#
+
+import bzrlib.branch
+from bzrlib.errors import TipChangeRejected
+
+def pre_change_branch_tip(params):
+    repo = params.branch.repository
+
+    # Check if the old repository was empty.
+    if params.old_revid == 'null:':
+	return
+
+    # Look for old tip in new main branch.
+    for revision_id in repo.iter_reverse_revision_history(params.new_revid):
+	if revision_id == params.old_revid:
+	    return	# Found old tip
+
+    # Old tip was not found. Reject the change.
+    raise TipChangeRejected('Bad tip. Read http://trac.helenos.org/trac.fcgi/' +
+	'wiki/BazaarWorkflow')
+
+# Install hook.
+bzrlib.branch.Branch.hooks.install_named_hook('pre_change_branch_tip',
+    pre_change_branch_tip, 'MB-Protect tip check')
Index: contrib/conf/msim.conf
===================================================================
--- contrib/conf/msim.conf	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ contrib/conf/msim.conf	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -8,5 +8,5 @@
 add rwm mainmem 0x00000000
 mainmem generic 16M
-mainmem load "/dev/zero"
+mainmem fill 0
 
 add rom bootmem 0x1fc00000
Index: contrib/highlight/Syntax
===================================================================
--- contrib/highlight/Syntax	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/highlight/Syntax	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,5 @@
+file ..\*\\.(bp|BP)$ Behavior\sProtocol 
+include bp.syntax
+
+file ..\*\\.(adl|ADP)$ Architecture\sDescription\sLanguage
+include adl.syntax
Index: contrib/highlight/adl.syntax
===================================================================
--- contrib/highlight/adl.syntax	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/highlight/adl.syntax	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,59 @@
+# Architecture Description Language syntax highlighting rules
+#  by Martin Decky <martin@decky.cz>
+
+context default
+	keyword whole interface yellow
+	keyword whole frame yellow
+	keyword whole architecture yellow
+	
+	keyword whole system yellow
+	keyword whole extends yellow
+	keyword whole version yellow
+	
+	keyword whole inst yellow
+	keyword whole bind yellow
+	keyword whole to yellow
+	keyword whole subsume yellow
+	keyword whole delegate yellow
+	
+	keyword whole ipcarg_t yellow
+	keyword whole string yellow
+	keyword whole stream yellow
+	keyword whole void yellow
+	
+	keyword whole in yellow
+	keyword whole in_copy yellow
+	keyword whole out yellow
+	keyword whole out_copy yellow
+	
+	keyword whole protocol yellow
+	keyword whole initialization yellow
+	keyword whole finalization yellow
+	keyword whole provides yellow
+	keyword whole requires yellow
+	
+	keyword /\* brown
+	keyword \*/ brown
+	keyword // brown
+	
+	keyword { brightcyan
+	keyword } brightcyan
+	
+	keyword ( brightcyan
+	keyword ) brightcyan
+	
+	keyword , brightcyan
+	keyword : brightcyan
+	keyword ; brightmagenta
+	
+	keyword [ brightblue black
+	keyword ] brightblue black
+
+context exclusive [ ] brightblue black
+	keyword % brightcyan black
+
+context exclusive /\* \*/ brown
+	spellcheck
+
+context exclusive // \n brown
+	spellcheck
Index: contrib/highlight/bp.syntax
===================================================================
--- contrib/highlight/bp.syntax	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/highlight/bp.syntax	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+# Behavior Protocols syntax highlighting rules
+#  by Martin Decky <martin@decky.cz>
+
+context default
+	keyword whole NULL yellow
+	keyword whole tentative yellow
+	keyword whole alternative yellow
+	
+	keyword /\* brown
+	keyword \*/ brown
+	keyword # brown
+	
+	keyword ! brightred
+	keyword ? brightgreen
+	
+	keyword ( brightcyan
+	keyword ) brightcyan
+	
+	keyword { brightcyan
+	keyword } brightcyan
+	
+	keyword \+ brightmagenta
+	keyword ; brightmagenta
+	keyword \* brightmagenta
+	keyword | brightmagenta
+	
+	keyword \. brightcyan
+	
+	keyword [ brightblue black
+	keyword ] brightblue black
+
+context exclusive [ ] brightblue black
+	keyword % brightcyan black
+
+context exclusive /\* \*/ brown
+	spellcheck
+
+context exclusive # \n brown
+	spellcheck
Index: contrib/toolchain.sh
===================================================================
--- contrib/toolchain.sh	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ contrib/toolchain.sh	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,243 @@
+#!/bin/bash
+
+# Cross-compiler toolchain build script
+#  by Martin Decky <martin@decky.cz>
+#
+#  GPL'ed, copyleft
+#
+
+check_error() {
+	if [ "$1" -ne "0" ]; then
+		echo
+		echo "Script failed: $2"
+		exit 1
+	fi
+}
+
+check_md5() {
+	FILE="$1"
+	SUM="$2"
+	
+	COMPUTED="`md5sum "${FILE}" | cut -d' ' -f1`"
+	if [ "${SUM}" != "${COMPUTED}" ] ; then
+		echo
+		echo "Checksum of ${FILE} does not match."
+		exit 2
+	fi
+}
+
+show_usage() {
+	echo "Cross-compiler toolchain build script"
+	echo
+	echo "Syntax:"
+	echo " $0 <platform>"
+	echo
+	echo "Possible target platforms are:"
+	echo " amd64      AMD64 (x86-64, x64)"
+	echo " arm32      ARM"
+	echo " ia32       IA-32 (x86, i386)"
+	echo " ia64       IA-64 (Itanium)"
+	echo " mips32     MIPS little-endian"
+	echo " mips32eb   MIPS big-endian"
+	echo " ppc32      32-bit PowerPC"
+	echo " ppc64      64-bit PowerPC"
+	echo " sparc64    SPARC V9"
+	echo " all        build all targets"
+	echo
+	
+	exit 3
+}
+
+download_check() {
+	SOURCE="$1"
+	FILE="$2"
+	CHECKSUM="$3"
+	
+	if [ ! -f "${FILE}" ]; then
+		wget -c "${SOURCE}${FILE}"
+		check_error $? "Error downloading ${FILE}."
+	fi
+	
+	check_md5 "${FILE}" "${CHECKSUM}"
+}
+
+cleanup_dir() {
+	DIR="$1"
+	
+	if [ -d "${DIR}" ]; then
+		echo " >>> Removing ${DIR}"
+		rm -fr "${DIR}"
+	fi
+}
+
+create_dir() {
+	DIR="$1"
+	DESC="$2"
+	
+	echo ">>> Creating ${DESC}"
+	
+	mkdir -p "${DIR}"
+	test -d "${DIR}"
+	check_error $? "Unable to create ${DIR}."
+}
+
+unpack_tarball() {
+	FILE="$1"
+	DESC="$2"
+	
+	echo " >>> ${DESC}"
+	
+	tar -xjf "${FILE}"
+	check_error $? "Error unpacking ${DESC}."
+}
+
+patch_binutils() {
+	PLATFORM="$1"
+	
+	if [ "${PLATFORM}" == "arm32" ] ; then
+		patch -p1 <<EOF
+diff -Naur binutils-2.20.orig/gas/config/tc-arm.c binutils-2.20/gas/config/tc-arm.c
+--- binutils-2.20.orig/gas/config/tc-arm.c	2009-08-30 00:10:59.000000000 +0200
++++ binutils-2.20/gas/config/tc-arm.c	2009-11-02 14:25:11.000000000 +0100
+@@ -2485,8 +2485,9 @@
+       know (frag->tc_frag_data.first_map == NULL);
+       frag->tc_frag_data.first_map = symbolP;
+     }
+-  if (frag->tc_frag_data.last_map != NULL)
++  if (frag->tc_frag_data.last_map != NULL) {
+     know (S_GET_VALUE (frag->tc_frag_data.last_map) < S_GET_VALUE (symbolP));
++  }
+   frag->tc_frag_data.last_map = symbolP;
+ }
+EOF
+		check_error $? "Error patching binutils"
+	fi
+}
+
+build_target() {
+	PLATFORM="$1"
+	TARGET="$2"
+	
+	BINUTILS_VERSION="2.20"
+	GCC_VERSION="4.4.2"
+	
+	BINUTILS="binutils-${BINUTILS_VERSION}.tar.bz2"
+	GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
+	GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
+	GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
+	
+	BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
+	GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
+	
+	WORKDIR="`pwd`"
+	BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
+	GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
+	OBJDIR="${WORKDIR}/gcc-obj"
+	
+	if [ -z "${CROSS_PREFIX}" ] ; then
+		CROSS_PREFIX="/usr/local"
+	fi
+	
+	PREFIX="${CROSS_PREFIX}/${PLATFORM}"
+	
+	echo ">>> Downloading tarballs"
+	download_check "${BINUTILS_SOURCE}" "${BINUTILS}" "ee2d3e996e9a2d669808713360fa96f8"
+	download_check "${GCC_SOURCE}" "${GCC_CORE}" "d50ec5af20508974411d0c83c5f4e396"
+	download_check "${GCC_SOURCE}" "${GCC_OBJC}" "d8d26187d386a0591222a580b5a5b3d3"
+	download_check "${GCC_SOURCE}" "${GCC_CPP}" "43b1e4879eb282dc4b05e4c016d356d7"
+	
+	echo ">>> Removing previous content"
+	cleanup_dir "${PREFIX}"
+	cleanup_dir "${OBJDIR}"
+	cleanup_dir "${BINUTILSDIR}"
+	cleanup_dir "${GCCDIR}"
+	
+	create_dir "${PREFIX}" "destination directory"
+	create_dir "${OBJDIR}" "GCC object directory"
+	
+	echo ">>> Unpacking tarballs"
+	unpack_tarball "${BINUTILS}" "binutils"
+	unpack_tarball "${GCC_CORE}" "GCC Core"
+	unpack_tarball "${GCC_OBJC}" "Objective C"
+	unpack_tarball "${GCC_CPP}" "C++"
+	
+	echo ">>> Compiling and installing binutils"
+	cd "${BINUTILSDIR}"
+	check_error $? "Change directory failed."
+	patch_binutils "${PLATFORM}"
+	./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
+	check_error $? "Error configuring binutils."
+	make all install
+	check_error $? "Error compiling/installing binutils."
+	
+	echo ">>> Compiling and installing GCC"
+	cd "${OBJDIR}"
+	check_error $? "Change directory failed."
+	"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
+	check_error $? "Error configuring GCC."
+	PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
+	check_error $? "Error compiling/installing GCC."
+	
+	cd "${WORKDIR}"
+	check_error $? "Change directory failed."
+	
+	echo ">>> Cleaning up"
+	cleanup_dir "${OBJDIR}"
+	cleanup_dir "${BINUTILSDIR}"
+	cleanup_dir "${GCCDIR}"
+	
+	echo
+	echo ">>> Cross-compiler for ${TARGET} installed."
+}
+
+if [ "$#" -lt "1" ]; then
+	show_usage
+fi
+
+case "$1" in
+	"amd64")
+		build_target "amd64" "amd64-linux-gnu"
+		;;
+	"arm32")
+		build_target "arm32" "arm-linux-gnu"
+		;;
+	"ia32")
+		build_target "ia32" "i686-pc-linux-gnu"
+		;;
+	"ia64")
+		build_target "ia64" "ia64-pc-linux-gnu"
+		;;
+	"ia64")
+		build_target "ia64" "ia64-pc-linux-gnu"
+		;;
+	"mips32")
+		build_target "mips32" "mipsel-linux-gnu"
+		;;
+	"mips32eb")
+		build_target "mips32eb" "mips-linux-gnu"
+		;;
+	"ppc32")
+		build_target "ppc32" "ppc-linux-gnu"
+		;;
+	"ppc64")
+		build_target "ppc64" "ppc64-linux-gnu"
+		;;
+	"sparc64")
+		build_target "sparc64" "sparc64-linux-gnu"
+		;;
+	"all")
+		build_target "amd64" "amd64-linux-gnu"
+		build_target "arm32" "arm-linux-gnu"
+		build_target "ia32" "i686-pc-linux-gnu"
+		build_target "ia64" "ia64-pc-linux-gnu"
+		build_target "ia64" "ia64-pc-linux-gnu"
+		build_target "mips32" "mipsel-linux-gnu"
+		build_target "mips32eb" "mips-linux-gnu"
+		build_target "ppc32" "ppc-linux-gnu"
+		build_target "ppc64" "ppc64-linux-gnu"
+		build_target "sparc64" "sparc64-linux-gnu"
+		;;
+	*)
+		show_usage
+		;;
+esac
Index: ntrib/toolchain/toolchain.amd64.sh
===================================================================
--- contrib/toolchain/toolchain.amd64.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="amd64"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: ntrib/toolchain/toolchain.arm32.sh
===================================================================
--- contrib/toolchain/toolchain.arm32.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="arm"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: ntrib/toolchain/toolchain.ia32.sh
===================================================================
--- contrib/toolchain/toolchain.ia32.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="i686"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-pc-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: ntrib/toolchain/toolchain.ia64.sh
===================================================================
--- contrib/toolchain/toolchain.ia64.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="ia64"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-pc-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: ntrib/toolchain/toolchain.mipseb32.sh
===================================================================
--- contrib/toolchain/toolchain.mipseb32.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="mips"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: ntrib/toolchain/toolchain.mipsel32.sh
===================================================================
--- contrib/toolchain/toolchain.mipsel32.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="mipsel"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: ntrib/toolchain/toolchain.ppc32.sh
===================================================================
--- contrib/toolchain/toolchain.ppc32.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="ppc"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: ntrib/toolchain/toolchain.ppc64.sh
===================================================================
--- contrib/toolchain/toolchain.ppc64.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="ppc64"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: ntrib/toolchain/toolchain.sparc64.sh
===================================================================
--- contrib/toolchain/toolchain.sparc64.sh	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#!/bin/bash
-
-# Cross-Compiler Toolchain for ${PLATFORM}
-#  by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-
-check_error() {
-    if [ "$1" -ne "0" ]; then
-	echo
-	echo "Script failed: $2"
-	exit
-    fi
-}
-
-if [ -z "${CROSS_PREFIX}" ] ; then
-    CROSS_PREFIX="/usr/local"
-fi
-
-BINUTILS_VERSION="2.19.1"
-GCC_VERSION="4.3.3"
-
-BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
-GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
-GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
-GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
-
-BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
-GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
-
-PLATFORM="sparc64"
-WORKDIR=`pwd`
-TARGET="${PLATFORM}-linux-gnu"
-PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
-GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
-OBJDIR="${WORKDIR}/gcc-obj"
-
-echo ">>> Downloading tarballs"
-
-if [ ! -f "${BINUTILS}" ]; then
-    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
-    check_error $? "Error downloading binutils."
-fi
-if [ ! -f "${GCC_CORE}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CORE}"
-    check_error $? "Error downloading GCC Core."
-fi
-if [ ! -f "${GCC_OBJC}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_OBJC}"
-    check_error $? "Error downloading GCC Objective C."
-fi
-if [ ! -f "${GCC_CPP}" ]; then
-    wget -c "${GCC_SOURCE}${GCC_CPP}"
-    check_error $? "Error downloading GCC C++."
-fi
-
-echo ">>> Creating destionation directory"
-if [ ! -d "${PREFIX}" ]; then
-    mkdir -p "${PREFIX}" 
-    test -d "${PREFIX}"
-    check_error $? "Unable to create ${PREFIX}."
-fi
-
-echo ">>> Creating GCC work directory"
-if [ ! -d "${OBJDIR}" ]; then
-    mkdir -p "${OBJDIR}"
-    test -d "${OBJDIR}"
-    check_error $? "Unable to create ${OBJDIR}."
-fi
-
-echo ">>> Unpacking tarballs"
-tar -xvzf "${BINUTILS}"
-check_error $? "Error unpacking binutils."
-tar -xvjf "${GCC_CORE}"
-check_error $? "Error unpacking GCC Core."
-tar -xvjf "${GCC_OBJC}"
-check_error $? "Error unpacking GCC Objective C."
-tar -xvjf "${GCC_CPP}"
-check_error $? "Error unpacking GCC C++."
-
-echo ">>> Compiling and installing binutils"
-cd "${BINUTILSDIR}"
-check_error $? "Change directory failed."
-./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
-check_error $? "Error configuring binutils."
-make all install
-check_error $? "Error compiling/installing binutils."
-
-echo ">>> Compiling and installing GCC"
-cd "${OBJDIR}"
-check_error $? "Change directory failed."
-"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
-check_error $? "Error configuring GCC."
-PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
-check_error $? "Error compiling/installing GCC."
-
-echo
-echo ">>> Cross-compiler for ${TARGET} installed."
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,375 +27,13 @@
 #
 
+include Makefile.common
 
-## Include configuration
-#
+.PHONY: all clean
 
-include ../version
--include ../Makefile.config
--include ../config.defs
-
-INCLUDES = generic/include
-OPTIMIZATION = 3
-
-ifndef CROSS_PREFIX
-	CROSS_PREFIX = /usr/local
-endif
-
-## Common compiler flags
-#
-
-DEFS = -DKERNEL -DRELEASE=$(RELEASE) "-DNAME=$(NAME)" -D__$(BITS)_BITS__ -D__$(ENDIANESS)__
-
-GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -fno-builtin -Wall -Wextra -Wno-unused-parameter \
-	-Wmissing-prototypes -Werror -nostdlib -nostdinc -pipe
-
-ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
-	-fno-builtin -Wall -Wmissing-prototypes -Werror \
-	-nostdlib -nostdinc \
-	-wd170
-
-SUNCC_CFLAGS = -I$(INCLUDES) -xO$(OPTIMIZATION) \
-	-xnolib -xc99=all -features=extensions \
-	-erroff=E_ZERO_SIZED_STRUCT_UNION
-
-LFLAGS = -M
-AFLAGS =
-
--include arch/$(KARCH)/Makefile.inc
--include genarch/Makefile.inc
-
-## The at-sign
-#
-# The $(ATSIGN) variable holds the ASCII character representing the at-sign
-# ('@') used in various $(AS) constructs (e.g. @progbits). On architectures that
-# don't use '@' for starting a comment, $(ATSIGN) is merely '@'. However, on
-# those that do use it for starting a comment (e.g. arm32), $(ATSIGN) must be
-# defined as the percentile-sign ('%') in the architecture-dependent
-# Makefile.inc.
-#
-ATSIGN ?= @
-
-## Cross-platform assembly to start a symtab.data section
-#
-SYMTAB_SECTION=".section symtab.data, \"a\", $(ATSIGN)progbits;"
-
-## Simple detection for the type of the host system
-#
-HOST = $(shell uname)
-
-## On Solaris, some utilities have slightly different names
-#
-ifeq ($(HOST),SunOS)
-	BINUTILS_PREFIX = "g"
-else
-	BINUTILS_PREFIX = ""
-endif
-
-## Toolchain configuration
-#
-
-ifeq ($(COMPILER),gcc_native)
-	CC = gcc
-	GCC = gcc
-	AS = $(BINUTILS_PREFIX)as
-	LD = $(BINUTILS_PREFIX)ld
-	OBJCOPY = $(BINUTILS_PREFIX)objcopy
-	OBJDUMP = $(BINUTILS_PREFIX)objdump
-	LIBDIR = /usr/lib
-	CFLAGS = $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),icc_native)
-	CC = icc
-	GCC = gcc
-	AS = as
-	LD = ld
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-	LIBDIR = /usr/lib
-	CFLAGS = $(ICC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),suncc_native)
-	CC = suncc
-	GCC = gcc
-	AS = $(BINUTILS_PREFIX)as
-	LD = $(BINUTILS_PREFIX)ld
-	OBJCOPY = $(BINUTILS_PREFIX)objcopy
-	OBJDUMP = $(BINUTILS_PREFIX)objdump
-	LIBDIR = /usr/lib
-	CFLAGS = $(SUNCC_CFLAGS)
-	DEFS += $(CONFIG_DEFS)
-	DEPEND_DEFS = $(DEFS)
-endif
-
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/bin/$(TARGET)-gcc
-	GCC = $(CC)
-	AS = $(TOOLCHAIN_DIR)/bin/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/bin/$(TARGET)-ld
-	OBJCOPY = $(TOOLCHAIN_DIR)/bin/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/bin/$(TARGET)-objdump
-	LIBDIR = $(TOOLCHAIN_DIR)/lib
-	CFLAGS = $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-## Generic kernel sources
-#
-
-GENERIC_SOURCES = \
-	generic/src/adt/avl.c \
-	generic/src/adt/bitmap.c \
-	generic/src/adt/btree.c \
-	generic/src/adt/hash_table.c \
-	generic/src/adt/list.c \
-	generic/src/console/chardev.c \
-	generic/src/console/console.c \
-	generic/src/cpu/cpu.c \
-	generic/src/ddi/ddi.c \
-	generic/src/ddi/irq.c \
-	generic/src/ddi/device.c \
-	generic/src/debug/symtab.c \
-	generic/src/interrupt/interrupt.c \
-	generic/src/main/main.c \
-	generic/src/main/kinit.c \
-	generic/src/main/uinit.c \
-	generic/src/main/version.c \
-	generic/src/main/shutdown.c \
-	generic/src/proc/program.c \
-	generic/src/proc/scheduler.c \
-	generic/src/proc/thread.c \
-	generic/src/proc/task.c \
-	generic/src/proc/the.c \
-	generic/src/proc/tasklet.c \
-	generic/src/syscall/syscall.c \
-	generic/src/syscall/copy.c \
-	generic/src/mm/buddy.c \
-	generic/src/mm/frame.c \
-	generic/src/mm/page.c \
-	generic/src/mm/tlb.c \
-	generic/src/mm/as.c \
-	generic/src/mm/backend_anon.c \
-	generic/src/mm/backend_elf.c \
-	generic/src/mm/backend_phys.c \
-	generic/src/mm/slab.c \
-	generic/src/lib/func.c \
-	generic/src/lib/memstr.c \
-	generic/src/lib/sort.c \
-	generic/src/lib/string.c \
-	generic/src/lib/elf.c \
-	generic/src/lib/rd.c \
-	generic/src/printf/printf_core.c \
-	generic/src/printf/printf.c \
-	generic/src/printf/snprintf.c \
-	generic/src/printf/vprintf.c \
-	generic/src/printf/vsnprintf.c \
-	generic/src/time/clock.c \
-	generic/src/time/timeout.c \
-	generic/src/time/delay.c \
-	generic/src/preempt/preemption.c \
-	generic/src/synch/spinlock.c \
-	generic/src/synch/condvar.c \
-	generic/src/synch/rwlock.c \
-	generic/src/synch/mutex.c \
-	generic/src/synch/semaphore.c \
-	generic/src/synch/smc.c \
-	generic/src/synch/waitq.c \
-	generic/src/synch/futex.c \
-	generic/src/smp/ipi.c \
-	generic/src/smp/smp.c \
-	generic/src/ipc/ipc.c \
-	generic/src/ipc/sysipc.c \
-	generic/src/ipc/ipcrsc.c \
-	generic/src/ipc/irq.c \
-	generic/src/ipc/event.c \
-	generic/src/security/cap.c \
-	generic/src/sysinfo/sysinfo.c
-
-## Kernel console support
-#
-
-ifeq ($(CONFIG_KCONSOLE),y)
-GENERIC_SOURCES += \
-	generic/src/console/kconsole.c \
-	generic/src/console/cmd.c
-endif
-
-## Udebug interface sources
-#
-
-ifeq ($(CONFIG_UDEBUG),y)
-GENERIC_SOURCES += \
-	generic/src/ipc/kbox.c \
-	generic/src/udebug/udebug.c \
-	generic/src/udebug/udebug_ops.c \
-	generic/src/udebug/udebug_ipc.c
-endif
-
-## Test sources
-#
-
-ifeq ($(CONFIG_TEST),y)
-	CFLAGS += -Itest/
-	GENERIC_SOURCES += \
-		test/test.c \
-		test/atomic/atomic1.c \
-		test/btree/btree1.c \
-		test/avltree/avltree1.c \
-		test/fault/fault1.c \
-		test/mm/falloc1.c \
-		test/mm/falloc2.c \
-		test/mm/mapping1.c \
-		test/mm/slab1.c \
-		test/mm/slab2.c \
-		test/synch/rwlock1.c \
-		test/synch/rwlock2.c \
-		test/synch/rwlock3.c \
-		test/synch/rwlock4.c \
-		test/synch/rwlock5.c \
-		test/synch/semaphore1.c \
-		test/synch/semaphore2.c \
-		test/print/print1.c \
-		test/print/print2.c \
-		test/print/print3.c \
-		test/print/print4.c \
-		test/thread/thread1.c \
-		test/sysinfo/sysinfo1.c
-	
-	ifeq ($(KARCH),mips32)
-		GENERIC_SOURCES += test/debug/mips1.c
-	else
-		GENERIC_SOURCES += test/debug/mips1_skip.c
-	endif
-	
-	ifeq ($(KARCH),ia64)
-		GENERIC_SOURCES += test/mm/purge1.c
-	else
-		GENERIC_SOURCES += test/mm/purge1_skip.c
-	endif
-	
-	ifeq ($(CONFIG_FPU),y)
-		ifeq ($(KARCH),ia32)
-			TEST_FPU1 = y
-			TEST_SSE1 = y
-			GENERIC_SOURCES += test/fpu/fpu1_x86.c
-		endif
-		
-		ifeq ($(KARCH),amd64)
-			TEST_FPU1 = y
-			TEST_SSE1 = y
-			GENERIC_SOURCES += test/fpu/fpu1_x86.c
-		endif
-		
-		ifeq ($(KARCH),ia64)
-			TEST_FPU1 = y
-			GENERIC_SOURCES += test/fpu/fpu1_ia64.c
-		endif
-		
-		ifeq ($(KARCH),mips32)
-			TEST_MIPS2 = y
-		endif
-	endif
-	
-	ifneq ($(TEST_FPU1),y)
-		GENERIC_SOURCES += test/fpu/fpu1_skip.c
-	endif
-	
-	ifeq ($(TEST_SSE1),y)
-		GENERIC_SOURCES += test/fpu/sse1.c
-	else
-		GENERIC_SOURCES += test/fpu/sse1_skip.c
-	endif
-	
-	ifeq ($(TEST_MIPS2),y)
-		GENERIC_SOURCES += test/fpu/mips2.c
-	else
-		GENERIC_SOURCES += test/fpu/mips2_skip.c
-	endif
-	
-endif
-
-GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
-ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
-GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
-
-ifeq ($(CONFIG_SYMTAB),y)
-	SYMTAB_OBJECTS := generic/src/debug/real_map.o
-else
-	SYMTAB_OBJECTS :=
-endif
-
-.PHONY: all build clean archlinks depend disasm
-
-all: ../Makefile.config ../config.h ../config.defs
-	-rm Makefile.depend
-	$(MAKE) -C . build
-
-build: kernel.bin disasm
-
--include Makefile.depend
+all: ../version ../Makefile.config ../config.h ../config.defs
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(KARCH)/_link.ld
+	rm -f $(DEPEND) $(DEPEND_PREV) $(RAW) $(BIN) $(MAP) $(MAP_PREV) $(DISASM) $(DUMP) $(REAL_MAP).* $(ARCH_INCLUDE) $(GENARCH_INCLUDE) arch/*/_link.ld
 	find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
-	for arch in arch/* ; do \
-	    [ -e $$arch/_link.ld ] && rm $$arch/_link.ld 2>/dev/null ; \
-	done ; exit 0
-
-archlinks:
-	ln -sfn ../../arch/$(KARCH)/include/ generic/include/arch
-	ln -sfn ../../genarch/include/ generic/include/genarch
-
-depend: archlinks
-	-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-
-arch/$(KARCH)/_link.ld: arch/$(KARCH)/_link.ld.in
-	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $< | grep -v "^\#" > $@
-
-generic/src/debug/real_map.bin: depend arch/$(KARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
-	echo $(SYMTAB_SECTION) | $(AS) $(AFLAGS) -o generic/src/debug/empty_map.o
-	$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/empty_map.o  -o $@ -Map kernel.map.pre
-	$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
-	tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin 
-	# Do it once again, this time to get correct even the symbols
-	# on architectures, that have bss after symtab
-	echo $(SYMTAB_SECTION)" .incbin \"$@\"" | $(AS) $(AFLAGS) -o generic/src/debug/sizeok_map.o
-	$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/sizeok_map.o -o $@ -Map kernel.map.pre
-	$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
-	tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin 
-
-generic/src/debug/real_map.o: generic/src/debug/real_map.bin
-	echo $(SYMTAB_SECTION)" .incbin \"$<\"" | $(AS) $(AFLAGS) -o $@ 
-
-kernel.raw: depend arch/$(KARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(SYMTAB_OBJECTS)
-	$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS) -o $@ -Map kernel.map
-
-kernel.bin: kernel.raw
-	$(OBJCOPY) -O $(BFD) kernel.raw kernel.bin
-
-disasm: kernel.raw
-	$(OBJDUMP) -d kernel.raw > kernel.disasm
-
-%.o: %.S
-	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-#
-# The FPU tests are the only objects for which we allow the compiler to generate
-# FPU instructions.
-#
-test/fpu/%.o: test/fpu/%.c
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) -c $< -o $@
-
-#
-# Ordinary objects.
-#
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c $< -o $@ 
Index: kernel/Makefile.build
===================================================================
--- kernel/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,418 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Include configuration
+#
+
+include Makefile.common
+include ../version
+include ../Makefile.config
+include ../config.defs
+
+LINK = arch/$(KARCH)/_link.ld
+EMPTY_MAP = generic/src/debug/empty_map.o
+SIZEOK_MAP = generic/src/debug/sizeok_map.o
+
+INCLUDES = generic/include
+OPTIMIZATION = 3
+
+ifndef CROSS_PREFIX
+	CROSS_PREFIX = /usr/local
+endif
+
+## Common compiler flags
+#
+
+DEFS = -DKERNEL -DRELEASE=$(RELEASE) "-DNAME=$(NAME)" -D__$(BITS)_BITS__ -D__$(ENDIANESS)__
+
+GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
+	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
+	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
+	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \
+	-pipe
+
+ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
+	-ffreestanding -fno-builtin -nostdlib -nostdinc -Wall -Wmissing-prototypes \
+	-Werror -wd170
+
+SUNCC_CFLAGS = -I$(INCLUDES) -xO$(OPTIMIZATION) \
+	-xnolib -xc99=all -features=extensions \
+	-erroff=E_ZERO_SIZED_STRUCT_UNION
+
+CLANG_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
+	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
+	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
+	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -pipe \
+	-arch $(CLANG_ARCH)
+
+LFLAGS = -M
+AFLAGS =
+
+-include arch/$(KARCH)/Makefile.inc
+-include genarch/Makefile.inc
+
+## The at-sign
+#
+# The $(ATSIGN) variable holds the ASCII character representing the at-sign
+# ('@') used in various $(AS) constructs (e.g. @progbits). On architectures that
+# don't use '@' for starting a comment, $(ATSIGN) is merely '@'. However, on
+# those that do use it for starting a comment (e.g. arm32), $(ATSIGN) must be
+# defined as the percentile-sign ('%') in the architecture-dependent
+# Makefile.inc.
+#
+ATSIGN ?= @
+
+## Cross-platform assembly to start a symtab.data section
+#
+SYMTAB_SECTION=".section symtab.data, \"a\", $(ATSIGN)progbits;"
+
+## Simple detection for the type of the host system
+#
+HOST = $(shell uname)
+
+## On Solaris, some utilities have slightly different names
+#
+ifeq ($(HOST),SunOS)
+	BINUTILS_PREFIX = "g"
+else
+	BINUTILS_PREFIX = ""
+endif
+
+## Toolchain configuration
+#
+
+ifeq ($(COMPILER),gcc_native)
+	CC = gcc
+	GCC = $(CC)
+	AS = $(BINUTILS_PREFIX)as
+	LD = $(BINUTILS_PREFIX)ld
+	OBJCOPY = $(BINUTILS_PREFIX)objcopy
+	OBJDUMP = $(BINUTILS_PREFIX)objdump
+	LIBDIR = /usr/lib
+	CFLAGS = $(GCC_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
+
+ifeq ($(COMPILER),gcc_cross)
+	CC = $(TOOLCHAIN_DIR)/bin/$(TARGET)-gcc
+	GCC = $(CC)
+	AS = $(TOOLCHAIN_DIR)/bin/$(TARGET)-as
+	LD = $(TOOLCHAIN_DIR)/bin/$(TARGET)-ld
+	OBJCOPY = $(TOOLCHAIN_DIR)/bin/$(TARGET)-objcopy
+	OBJDUMP = $(TOOLCHAIN_DIR)/bin/$(TARGET)-objdump
+	LIBDIR = $(TOOLCHAIN_DIR)/lib
+	CFLAGS = $(GCC_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
+
+ifeq ($(COMPILER),icc)
+	CC = icc
+	GCC = gcc
+	AS = as
+	LD = ld
+	OBJCOPY = objcopy
+	OBJDUMP = objdump
+	LIBDIR = /usr/lib
+	CFLAGS = $(ICC_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
+
+ifeq ($(COMPILER),suncc)
+	CC = suncc
+	GCC = gcc
+	AS = $(BINUTILS_PREFIX)as
+	LD = $(BINUTILS_PREFIX)ld
+	OBJCOPY = $(BINUTILS_PREFIX)objcopy
+	OBJDUMP = $(BINUTILS_PREFIX)objdump
+	LIBDIR = /usr/lib
+	CFLAGS = $(SUNCC_CFLAGS)
+	DEFS += $(CONFIG_DEFS)
+	DEPEND_DEFS = $(DEFS)
+endif
+
+ifeq ($(COMPILER),clang)
+	CC = clang
+	GCC = gcc
+	AS = $(BINUTILS_PREFIX)as
+	LD = $(BINUTILS_PREFIX)ld
+	OBJCOPY = $(BINUTILS_PREFIX)objcopy
+	OBJDUMP = $(BINUTILS_PREFIX)objdump
+	LIBDIR = /usr/lib
+	CFLAGS = $(CLANG_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
+
+## Generic kernel sources
+#
+
+GENERIC_SOURCES = \
+	generic/src/adt/avl.c \
+	generic/src/adt/bitmap.c \
+	generic/src/adt/btree.c \
+	generic/src/adt/hash_table.c \
+	generic/src/adt/list.c \
+	generic/src/console/chardev.c \
+	generic/src/console/console.c \
+	generic/src/cpu/cpu.c \
+	generic/src/ddi/ddi.c \
+	generic/src/ddi/irq.c \
+	generic/src/ddi/device.c \
+	generic/src/debug/symtab.c \
+	generic/src/interrupt/interrupt.c \
+	generic/src/main/main.c \
+	generic/src/main/kinit.c \
+	generic/src/main/uinit.c \
+	generic/src/main/version.c \
+	generic/src/main/shutdown.c \
+	generic/src/proc/program.c \
+	generic/src/proc/scheduler.c \
+	generic/src/proc/thread.c \
+	generic/src/proc/task.c \
+	generic/src/proc/the.c \
+	generic/src/proc/tasklet.c \
+	generic/src/syscall/syscall.c \
+	generic/src/syscall/copy.c \
+	generic/src/mm/buddy.c \
+	generic/src/mm/frame.c \
+	generic/src/mm/page.c \
+	generic/src/mm/tlb.c \
+	generic/src/mm/as.c \
+	generic/src/mm/backend_anon.c \
+	generic/src/mm/backend_elf.c \
+	generic/src/mm/backend_phys.c \
+	generic/src/mm/slab.c \
+	generic/src/lib/func.c \
+	generic/src/lib/memstr.c \
+	generic/src/lib/sort.c \
+	generic/src/lib/string.c \
+	generic/src/lib/elf.c \
+	generic/src/lib/rd.c \
+	generic/src/printf/printf_core.c \
+	generic/src/printf/printf.c \
+	generic/src/printf/snprintf.c \
+	generic/src/printf/vprintf.c \
+	generic/src/printf/vsnprintf.c \
+	generic/src/time/clock.c \
+	generic/src/time/timeout.c \
+	generic/src/time/delay.c \
+	generic/src/preempt/preemption.c \
+	generic/src/synch/spinlock.c \
+	generic/src/synch/condvar.c \
+	generic/src/synch/rwlock.c \
+	generic/src/synch/mutex.c \
+	generic/src/synch/semaphore.c \
+	generic/src/synch/smc.c \
+	generic/src/synch/waitq.c \
+	generic/src/synch/futex.c \
+	generic/src/smp/ipi.c \
+	generic/src/smp/smp.c \
+	generic/src/ipc/ipc.c \
+	generic/src/ipc/sysipc.c \
+	generic/src/ipc/ipcrsc.c \
+	generic/src/ipc/irq.c \
+	generic/src/ipc/event.c \
+	generic/src/security/cap.c \
+	generic/src/sysinfo/sysinfo.c
+
+## Kernel console support
+#
+
+ifeq ($(CONFIG_KCONSOLE),y)
+GENERIC_SOURCES += \
+	generic/src/console/kconsole.c \
+	generic/src/console/cmd.c
+endif
+
+## Udebug interface sources
+#
+
+ifeq ($(CONFIG_UDEBUG),y)
+GENERIC_SOURCES += \
+	generic/src/ipc/kbox.c \
+	generic/src/udebug/udebug.c \
+	generic/src/udebug/udebug_ops.c \
+	generic/src/udebug/udebug_ipc.c
+endif
+
+## Test sources
+#
+
+ifeq ($(CONFIG_TEST),y)
+	CFLAGS += -Itest/
+	GENERIC_SOURCES += \
+		test/test.c \
+		test/atomic/atomic1.c \
+		test/btree/btree1.c \
+		test/avltree/avltree1.c \
+		test/fault/fault1.c \
+		test/mm/falloc1.c \
+		test/mm/falloc2.c \
+		test/mm/mapping1.c \
+		test/mm/slab1.c \
+		test/mm/slab2.c \
+		test/synch/rwlock1.c \
+		test/synch/rwlock2.c \
+		test/synch/rwlock3.c \
+		test/synch/rwlock4.c \
+		test/synch/rwlock5.c \
+		test/synch/semaphore1.c \
+		test/synch/semaphore2.c \
+		test/print/print1.c \
+		test/print/print2.c \
+		test/print/print3.c \
+		test/print/print4.c \
+		test/thread/thread1.c \
+		test/sysinfo/sysinfo1.c
+	
+	ifeq ($(KARCH),mips32)
+		GENERIC_SOURCES += test/debug/mips1.c
+	else
+		GENERIC_SOURCES += test/debug/mips1_skip.c
+	endif
+	
+	ifeq ($(KARCH),ia64)
+		GENERIC_SOURCES += test/mm/purge1.c
+	else
+		GENERIC_SOURCES += test/mm/purge1_skip.c
+	endif
+	
+	ifeq ($(CONFIG_FPU),y)
+		ifeq ($(KARCH),ia32)
+			TEST_FPU1 = y
+			TEST_SSE1 = y
+			GENERIC_SOURCES += test/fpu/fpu1_x86.c
+		endif
+		
+		ifeq ($(KARCH),amd64)
+			TEST_FPU1 = y
+			TEST_SSE1 = y
+			GENERIC_SOURCES += test/fpu/fpu1_x86.c
+		endif
+		
+		ifeq ($(KARCH),ia64)
+			TEST_FPU1 = y
+			GENERIC_SOURCES += test/fpu/fpu1_ia64.c
+		endif
+		
+		ifeq ($(KARCH),mips32)
+			TEST_MIPS2 = y
+		endif
+	endif
+	
+	ifneq ($(TEST_FPU1),y)
+		GENERIC_SOURCES += test/fpu/fpu1_skip.c
+	endif
+	
+	ifeq ($(TEST_SSE1),y)
+		GENERIC_SOURCES += test/fpu/sse1.c
+	else
+		GENERIC_SOURCES += test/fpu/sse1_skip.c
+	endif
+	
+	ifeq ($(TEST_MIPS2),y)
+		GENERIC_SOURCES += test/fpu/mips2.c
+	else
+		GENERIC_SOURCES += test/fpu/mips2_skip.c
+	endif
+	
+endif
+
+GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
+ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
+GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
+
+ifeq ($(CONFIG_SYMTAB),y)
+	SYMTAB_OBJECTS := generic/src/debug/real_map.o
+else
+	SYMTAB_OBJECTS :=
+endif
+
+.PHONY: all
+
+all: $(BIN) $(DISASM)
+
+-include $(DEPEND)
+
+$(BIN): $(RAW)
+	$(OBJCOPY) -O $(BFD) $< $@
+
+$(DISASM): $(RAW)
+	$(OBJDUMP) -d $< > $@
+
+$(RAW): $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(SYMTAB_OBJECTS)
+	$(LD) -T $(LINK) $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS) -o $@ -Map $(MAP)
+
+$(LINK): $(LINK).in $(DEPEND)
+	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $< | grep -v "^\#" > $@
+
+%.o: %.S $(DEPEND)
+	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.s $(DEPEND)
+	$(AS) $(AFLAGS) $< -o $@
+
+#
+# The FPU tests are the only objects for which we allow the compiler to generate
+# FPU instructions.
+#
+test/fpu/%.o: test/fpu/%.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) -c $< -o $@
+
+#
+# Ordinary objects.
+#
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c $< -o $@
+
+$(REAL_MAP).o: $(REAL_MAP).bin
+	echo $(SYMTAB_SECTION)" .incbin \"$<\"" | $(AS) $(AFLAGS) -o $@
+
+$(REAL_MAP).bin: $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
+	echo $(SYMTAB_SECTION) | $(AS) $(AFLAGS) -o $(EMPTY_MAP)
+	$(LD) -T $(LINK) $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(EMPTY_MAP) -o $@ -Map $(MAP_PREV)
+	$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > $(DUMP)
+	tools/genmap.py $(MAP_PREV) $(DUMP) $@
+	
+	# Do it once again, this time to get correct even the symbols
+	# on architectures that have bss after symtab
+	
+	echo $(SYMTAB_SECTION)" .incbin \"$@\"" | $(AS) $(AFLAGS) -o $(SIZEOK_MAP)
+	$(LD) -T $(LINK) $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SIZEOK_MAP) -o $@ -Map $(MAP_PREV)
+	$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > $(DUMP)
+	tools/genmap.py $(MAP_PREV) $(DUMP) $@
+
+$(DEPEND): $(ARCH_INCLUDE) $(GENARCH_INCLUDE)
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
+
+$(ARCH_INCLUDE): arch/$(KARCH)/include/
+	ln -sfn ../../$< $@
+
+$(GENARCH_INCLUDE): genarch/include/
+	ln -sfn ../../$< $@
Index: kernel/Makefile.common
===================================================================
--- kernel/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+RAW = kernel.raw
+BIN = kernel.bin
+MAP = kernel.map
+MAP_PREV = $(MAP).prev
+DISASM = kernel.disasm
+DUMP = kernel.dump
+REAL_MAP = generic/src/debug/real_map
+
+ARCH_INCLUDE = generic/include/arch
+GENARCH_INCLUDE = generic/include/genarch
Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/amd64/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -34,4 +34,5 @@
 BFD = binary
 TARGET = amd64-linux-gnu
+CLANG_ARCH = x86_64
 TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64
 
Index: rnel/arch/amd64/include/arg.h
===================================================================
--- kernel/arch/amd64/include/arg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2005 Ondrej Palkovsky
- * 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 amd64	
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_amd64_ARG_H_
-#define KERN_amd64_ARG_H_
-
-#include <stdarg.h>
-
-#endif
-
-/** @}
- */
-
Index: kernel/arch/amd64/include/mm/page.h
===================================================================
--- kernel/arch/amd64/include/mm/page.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/amd64/include/mm/page.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -177,5 +177,5 @@
 #define PFERR_CODE_ID		(1 << 4)
 
-static inline int get_pt_flags(pte_t *pt, size_t i)
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/amd64/src/amd64.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -151,13 +151,18 @@
 		i8254_init();
 		
+#if (defined(CONFIG_FB) || defined(CONFIG_EGA))
+		bool vesa = false;
+#endif
+		
 #ifdef CONFIG_FB
-		if (vesa_present()) 
-			vesa_init();
-		else
-#endif
+		vesa = vesa_init();
+#endif
+		
 #ifdef CONFIG_EGA
-			ega_init(EGA_BASE, EGA_VIDEORAM);  /* video */
-#else
-			{}
+		if (!vesa) {
+			outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
+			if (egadev)
+				stdout_wire(egadev);
+		}
 #endif
 		
@@ -249,28 +254,4 @@
 }
 
-/** Acquire console back for kernel
- *
- */
-void arch_grab_console(void)
-{
-#ifdef CONFIG_FB
-	if (vesa_present())
-		vesa_redraw();
-	else
-#endif
-#ifdef CONFIG_EGA
-		ega_redraw();
-#else
-		{}
-#endif
-}
-
-/** Return console to userspace
- *
- */
-void arch_release_console(void)
-{
-}
-
 /** Construct function pointer
  *
Index: kernel/arch/amd64/src/cpu/cpu.c
===================================================================
--- kernel/arch/amd64/src/cpu/cpu.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/amd64/src/cpu/cpu.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -130,5 +130,5 @@
 	CPU->arch.vendor = VendorUnknown;
 	if (has_cpuid()) {
-		cpuid(0, &info);
+		cpuid(INTEL_CPUID_LEVEL, &info);
 
 		/*
@@ -150,5 +150,5 @@
 		}
 				
-		cpuid(1, &info);
+		cpuid(INTEL_CPUID_STANDARD, &info);
 		CPU->arch.family = (info.cpuid_eax >> 8) & 0xf;
 		CPU->arch.model = (info.cpuid_eax >> 4) & 0xf;
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -34,5 +34,5 @@
 BFD = binary
 TARGET = arm-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm32
 
 ATSIGN = %
Index: rnel/arch/arm32/include/arg.h
===================================================================
--- kernel/arch/arm32/include/arg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup arm32	
- * @{
- */
-/** @file
- *  @brief Empty.
- */
-
-#ifndef KERN_arm32_ARG_H_
-#define KERN_arm32_ARG_H_
-
-#include <stdarg.h>
-
-#endif
-
-/** @}
- */
Index: kernel/arch/arm32/include/elf.h
===================================================================
--- kernel/arch/arm32/include/elf.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/include/elf.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup arm32	
+/** @addtogroup arm32
  * @{
  */
@@ -37,13 +37,13 @@
 #define KERN_arm32_ELF_H_
 
-#define	ELF_MACHINE		EM_ARM
+#define ELF_MACHINE  EM_ARM
 
-#ifdef BIG_ENDIAN
-#define ELF_DATA_ENCODING	ELFDATA2MSB
+#ifdef __BE__
+	#define ELF_DATA_ENCODING  ELFDATA2MSB
 #else
-#define ELF_DATA_ENCODING	ELFDATA2LSB
+	#define ELF_DATA_ENCODING  ELFDATA2LSB
 #endif
 
-#define ELF_CLASS		ELFCLASS32
+#define ELF_CLASS  ELFCLASS32
 
 #endif
Index: kernel/arch/arm32/include/mach/integratorcp/integratorcp.h
===================================================================
--- kernel/arch/arm32/include/mach/integratorcp/integratorcp.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/include/mach/integratorcp/integratorcp.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -98,15 +98,10 @@
 
 extern void icp_init(void);
-extern void icp_fb_init(void);
 extern void icp_output_init(void);
 extern void icp_input_init(void);
-extern void icp_release_console(void);
-extern void icp_grab_console(void);
 extern void icp_timer_irq_start(void);
 extern void icp_cpu_halt(void);
 extern void icp_irq_exception(int exc_no, istate_t *istate);
 extern uintptr_t icp_get_memory_size(void);
-extern uintptr_t icp_get_fb_address(void);
-extern void icp_fb_init(void);
 extern void icp_frame_init(void);
 
Index: kernel/arch/arm32/include/mach/testarm/testarm.h
===================================================================
--- kernel/arch/arm32/include/mach/testarm/testarm.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/include/mach/testarm/testarm.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -68,15 +68,10 @@
 
 extern void gxemul_init(void);
-extern void gxemul_fb_init(void);
 extern void gxemul_output_init(void);
 extern void gxemul_input_init(void);
-extern void gxemul_release_console(void);
-extern void gxemul_grab_console(void);
 extern void gxemul_timer_irq_start(void);
 extern void gxemul_cpu_halt(void);
 extern void gxemul_irq_exception(int exc_no, istate_t *istate);
 extern uintptr_t gxemul_get_memory_size(void);
-extern uintptr_t gxemul_get_fb_address(void);
-extern void gxemul_fb_init(void);
 extern void gxemul_frame_init(void);
 
Index: kernel/arch/arm32/include/machine_func.h
===================================================================
--- kernel/arch/arm32/include/machine_func.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/include/machine_func.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -49,13 +49,9 @@
 
 struct arm_machine_ops {
-	void		(*machine_grab_console)(void);
-	void		(*machine_release_console)(void);
 	void		(*machine_init)(void);
 	void		(*machine_timer_irq_start)(void);
 	void		(*machine_cpu_halt)(void);
 	uintptr_t	(*machine_get_memory_size)(void);
-	void		(*machine_fb_init)(void);
 	void		(*machine_irq_exception)(int, istate_t*);
-	uintptr_t	(*machine_get_fb_address)(void);
 	void		(*machine_frame_init)(void);
 	void		(*machine_output_init)(void);
@@ -64,11 +60,4 @@
 
 extern struct arm_machine_ops machine_ops;
-
-
-/** Acquire console back for kernel. */
-extern void machine_grab_console(void);
-
-/** Return console to userspace. */
-extern void machine_release_console(void);
 
 
@@ -91,9 +80,4 @@
 extern uintptr_t machine_get_memory_size(void);
 
-/** Initializes the Frame Buffer
- *
- */
-extern void machine_fb_init(void);
-
 
 /** Interrupt exception handler.
@@ -104,10 +88,4 @@
 extern void machine_irq_exception(int exc_no, istate_t *istate);
 
-
-/** Returns address of framebuffer device.
- *
- *  @return Address of framebuffer device.
- */
-extern uintptr_t machine_get_fb_address(void);
 
 /*
Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/src/arm32.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -89,11 +89,5 @@
 	interrupt_init();
 	
-#ifdef CONFIG_FB
-	machine_fb_init();
-#else
-#ifdef CONFIG_ARM_PRN
 	machine_output_init();
-#endif /* CONFIG_ARM_PRN */
-#endif /* CONFIG_FB */
 }
 
@@ -182,19 +176,4 @@
 }
 
-/** Acquire console back for kernel. */
-void arch_grab_console(void)
-{
-	machine_grab_console();
-#ifdef CONFIG_FB
-	fb_redraw();
-#endif
-}
-
-/** Return console to userspace. */
-void arch_release_console(void)
-{
-	machine_release_console();
-}
-
 /** @}
  */
Index: kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
===================================================================
--- kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -57,13 +57,9 @@
 static irq_t icp_timer_irq;
 struct arm_machine_ops machine_ops = {
-	MACHINE_GENFUNC,
-	MACHINE_GENFUNC,
 	icp_init,
 	icp_timer_irq_start,
 	icp_cpu_halt,
 	icp_get_memory_size,
-	icp_fb_init,
 	icp_irq_exception,
-	icp_get_fb_address,
 	icp_frame_init,
 	icp_output_init,
@@ -128,22 +124,4 @@
 }
 
-/** Initializes the icp frame buffer */
-void icp_fb_init(void)
-{
-	fb_properties_t prop = {
-		.addr = 0,
-		.offset = 0,
-		.x = 640,
-		.y = 480,
-		.scan = 2560,
-		.visual = VISUAL_BGR_0_8_8_8,
-	};
-	prop.addr = icp_get_fb_address();
-	fb_init(&prop);
-	fb_parea.pbase = ICP_FB;
-	fb_parea.frames = 300;
-	ddi_parea_register(&fb_parea);
-}
-
 /** Initializes icp_hw_map. */
 void icp_init(void)
@@ -172,17 +150,6 @@
 }
 
-
-/** Acquire console back for kernel. */
-void icp_grab_console(void)
-{
-}
-
-/** Return console to userspace. */
-void icp_release_console(void)
-{
-}
-
 /** Starts icp Real Time Clock device, which asserts regular interrupts.
- * 
+ *
  * @param frequency Interrupts frequency (0 disables RTC).
  */
@@ -296,29 +263,39 @@
 }
 
-/** Returns address of framebuffer device.
- *
- *  @return Address of framebuffer device.
- */
-uintptr_t icp_get_fb_address(void)
-{
+/*
+ * Integrator specific frame initialization
+ */
+void
+icp_frame_init(void)
+{
+	frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME);
+	frame_mark_unavailable(0, 256);
+}
+
+void icp_output_init(void)
+{
+#ifdef CONFIG_FB
 	if (!vga_init) {
 		icp_vga_init();
 		vga_init = true;
 	}
-	return (uintptr_t) ICP_FB;
-}
-
-/*
- * Integrator specific frame initialization
- */
-void
-icp_frame_init(void)
-{
-	frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME);
-	frame_mark_unavailable(0, 256);
-}
-
-void icp_output_init(void)
-{
+	
+	fb_properties_t prop = {
+		.addr = ICP_FB,
+		.offset = 0,
+		.x = 640,
+		.y = 480,
+		.scan = 2560,
+		.visual = VISUAL_BGR_0_8_8_8,
+	};
+	
+	outdev_t *fbdev = fb_init(&prop);
+	if (fbdev) {
+		stdout_wire(fbdev);
+		fb_parea.pbase = ICP_FB;
+		fb_parea.frames = 300;
+		ddi_parea_register(&fb_parea);
+	}
+#endif
 }
 
Index: kernel/arch/arm32/src/mach/testarm/testarm.c
===================================================================
--- kernel/arch/arm32/src/mach/testarm/testarm.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/src/mach/testarm/testarm.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -57,13 +57,9 @@
 
 struct arm_machine_ops machine_ops = {
-	MACHINE_GENFUNC,
-	MACHINE_GENFUNC,
 	gxemul_init,
 	gxemul_timer_irq_start,
 	gxemul_cpu_halt,
 	gxemul_get_memory_size,
-	gxemul_fb_init,
 	gxemul_irq_exception,
-	gxemul_get_fb_address,
 	gxemul_frame_init,
 	gxemul_output_init,
@@ -78,6 +74,7 @@
 }
 
-void gxemul_fb_init(void)
-{
+void gxemul_output_init(void)
+{
+#ifdef CONFIG_FB
 	fb_properties_t prop = {
 		.addr = GXEMUL_FB_ADDRESS,
@@ -88,10 +85,15 @@
 		.visual = VISUAL_RGB_8_8_8,
 	};
-	fb_init(&prop);
-}
-
-void gxemul_output_init(void)
-{
-	dsrlnout_init((ioport8_t *) gxemul_kbd);
+	
+	outdev_t *fbdev = fb_init(&prop);
+	if (fbdev)
+		stdout_wire(fbdev);
+#endif
+	
+#ifdef CONFIG_ARM_PRN
+	outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) gxemul_kbd);
+	if (dsrlndev)
+		stdout_wire(dsrlndev);
+#endif
 }
 
@@ -233,10 +235,4 @@
 }
 
-uintptr_t gxemul_get_fb_address()
-{
-	return ((uintptr_t)GXEMUL_FB_ADDRESS);
-}
-
-
 /** @}
  */
Index: kernel/arch/arm32/src/machine_func.c
===================================================================
--- kernel/arch/arm32/src/machine_func.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/arm32/src/machine_func.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -41,17 +41,4 @@
 
 
-/** Acquire console back for kernel. */
-void machine_grab_console(void)
-{
-	(machine_ops.machine_grab_console)();
-}
-
-/** Return console to userspace. */
-void machine_release_console(void)
-{
-	(machine_ops.machine_release_console)();
-}
-
-
 /** Maps HW devices to the kernel address space using #hw_map. */
 void machine_init(void)
@@ -84,13 +71,4 @@
 }
 
-/** Initializes the Frame Buffer
- *
- */
-void machine_fb_init(void)
-{
-	(machine_ops.machine_fb_init)();
-}
-
-
 /** Interrupt exception handler.
  *
@@ -103,13 +81,4 @@
 }
 
-
-/** Returns address of framebuffer device.
- *
- *  @return Address of framebuffer device.
- */
-uintptr_t machine_get_fb_address(void)
-{
-	return (machine_ops.machine_get_fb_address)();
-}
 
 /*
Index: kernel/arch/ia32/Makefile.inc
===================================================================
--- kernel/arch/ia32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -34,5 +34,6 @@
 BFD = binary
 TARGET = i686-pc-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686
+CLANG_ARCH = i386
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia32
 
 BITS = 32
@@ -43,4 +44,5 @@
 ICC_CFLAGS += $(CMN1)
 SUNCC_CFLAGS += $(CMN1)
+CLANG_CFLAGS += $(CMN1)
 
 ## Accepted CPUs
@@ -71,4 +73,5 @@
 GCC_CFLAGS += $(CMN2)
 ICC_CFLAGS += $(CMN2)
+CLANG_CFLAGS += $(CMN2)
 
 ARCH_SOURCES = \
Index: rnel/arch/ia32/include/arg.h
===================================================================
--- kernel/arch/ia32/include/arg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup ia32	
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_ia32_ARG_H_
-#define KERN_ia32_ARG_H_
-
-#include <stackarg.h>
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ia32/include/asm.h
===================================================================
--- kernel/arch/ia32/include/asm.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/include/asm.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -392,5 +392,5 @@
 	asm volatile (
 		"sgdtl %[gdtr_reg]\n"
-		:: [gdtr_reg] "m" (*gdtr_reg)
+		: [gdtr_reg] "=m" (*gdtr_reg)
 	);
 }
Index: kernel/arch/ia32/include/cpu.h
===================================================================
--- kernel/arch/ia32/include/cpu.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/include/cpu.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -50,4 +50,5 @@
 #include <arch/pm.h>
 #include <arch/asm.h>
+#include <arch/cpuid.h>
 
 typedef struct {
@@ -56,4 +57,6 @@
 	unsigned int model;
 	unsigned int stepping;
+	cpuid_feature_info fi;
+
 	tss_t *tss;
 	
Index: kernel/arch/ia32/include/cpuid.h
===================================================================
--- kernel/arch/ia32/include/cpuid.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/include/cpuid.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -63,5 +63,7 @@
 
 struct __cpuid_feature_info {
-	unsigned 			: 23;
+	unsigned      : 11;
+	unsigned sep  :  1;
+	unsigned      : 11;
 	unsigned mmx  :  1;
 	unsigned fxsr :  1;
Index: kernel/arch/ia32/include/drivers/vesa.h
===================================================================
--- kernel/arch/ia32/include/drivers/vesa.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/include/drivers/vesa.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -36,7 +36,7 @@
 #define KERN_ia32_VESA_H_
 
-extern int vesa_present(void);
-extern void vesa_redraw(void);
-extern void vesa_init(void);
+#include <arch/types.h>
+
+extern bool vesa_init(void);
 
 #endif
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/include/mm/page.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -146,5 +146,5 @@
 #define PFERR_CODE_RSVD		(1 << 3)	
 
-static inline int get_pt_flags(pte_t *pt, size_t i)
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/ia32/src/boot/boot.S
===================================================================
--- kernel/arch/ia32/src/boot/boot.S	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/src/boot/boot.S	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -85,12 +85,4 @@
 	pse_supported:
 	
-	bt $(INTEL_SEP), %edx
-	jc sep_supported
-	
-		movl $sep_msg, %esi
-		jmp error_halt
-	
-	sep_supported:
-
 #include "vesa_prot.inc"
 
@@ -225,4 +217,2 @@
 	.asciz "Page Size Extension not supported. System halted."
 
-sep_msg:
-	.asciz "SYSENTER/SYSEXIT not supported. System halted."
Index: kernel/arch/ia32/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia32/src/cpu/cpu.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/src/cpu/cpu.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -92,5 +92,4 @@
 void cpu_arch_init(void)
 {
-	cpuid_feature_info fi;
 	cpuid_extended_feature_info efi;
 	cpu_info_t info;
@@ -102,15 +101,15 @@
 	CPU->fpu_owner = NULL;
 	
-	cpuid(1, &info);
+	cpuid(INTEL_CPUID_STANDARD, &info);
 	
-	fi.word = info.cpuid_edx;
+	CPU->arch.fi.word = info.cpuid_edx;
 	efi.word = info.cpuid_ecx;
 	
-	if (fi.bits.fxsr)
+	if (CPU->arch.fi.bits.fxsr)
 		fpu_fxsr();
 	else
 		fpu_fsr();
 	
-	if (fi.bits.sse) {
+	if (CPU->arch.fi.bits.sse) {
 		asm volatile (
 			"mov %%cr4, %[help]\n"
@@ -122,6 +121,8 @@
 	}
 	
-	/* Setup fast SYSENTER/SYSEXIT syscalls */
-	syscall_setup_cpu();
+	if (CPU->arch.fi.bits.sep) {
+		/* Setup fast SYSENTER/SYSEXIT syscalls */
+		syscall_setup_cpu();
+	}
 }
 
@@ -132,5 +133,5 @@
 	CPU->arch.vendor = VendorUnknown;
 	if (has_cpuid()) {
-		cpuid(0, &info);
+		cpuid(INTEL_CPUID_LEVEL, &info);
 
 		/*
@@ -150,5 +151,5 @@
 			CPU->arch.vendor = VendorIntel;
 		
-		cpuid(1, &info);
+		cpuid(INTEL_CPUID_STANDARD, &info);
 		CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f;
 		CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f;
Index: kernel/arch/ia32/src/drivers/vesa.c
===================================================================
--- kernel/arch/ia32/src/drivers/vesa.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/src/drivers/vesa.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -40,4 +40,6 @@
 #include <genarch/fb/visuals.h>
 #include <arch/drivers/vesa.h>
+#include <console/chardev.h>
+#include <console/console.h>
 #include <putchar.h>
 #include <mm/page.h>
@@ -66,15 +68,10 @@
 uint8_t vesa_blue_pos;
 
-int vesa_present(void)
+bool vesa_init(void)
 {
-	if ((vesa_width != 0xffff) && (vesa_height != 0xffff))
-		return true;
+	if ((vesa_width == 0xffff) || (vesa_height == 0xffff))
+		return false;
 	
-	return false;
-}
-
-void vesa_init(void)
-{
-	unsigned int visual;
+	visual_t visual;
 	
 	switch (vesa_bpp) {
@@ -97,5 +94,6 @@
 		break;
 	default:
-		panic("Unsupported bits per pixel.");
+		LOG("Unsupported bits per pixel.");
+		return false;
 	}
 	
@@ -108,10 +106,11 @@
 		.visual = visual,
 	};
-	fb_init(&vesa_props);
-}
-
-void vesa_redraw(void)
-{
-	fb_redraw();
+	
+	outdev_t *fbdev = fb_init(&vesa_props);
+	if (!fbdev)
+		return false;
+	
+	stdout_wire(fbdev);
+	return true;
 }
 
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/src/ia32.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -112,13 +112,18 @@
 		i8254_init();
 		
+#if (defined(CONFIG_FB) || defined(CONFIG_EGA))
+		bool vesa = false;
+#endif
+		
 #ifdef CONFIG_FB
-		if (vesa_present())
-			vesa_init();
-		else
-#endif
+		vesa = vesa_init();
+#endif
+		
 #ifdef CONFIG_EGA
-			ega_init(EGA_BASE, EGA_VIDEORAM);  /* video */
-#else
-			{}
+		if (!vesa) {
+			outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
+			if (egadev)
+				stdout_wire(egadev);
+		}
 #endif
 		
@@ -201,30 +206,6 @@
 	THREAD->arch.tls = addr;
 	set_tls_desc(addr);
-
+	
 	return 0;
-}
-
-/** Acquire console back for kernel
- *
- */
-void arch_grab_console(void)
-{
-#ifdef CONFIG_FB
-	if (vesa_present())
-		vesa_redraw();
-	else
-#endif
-#ifdef CONFIG_EGA
-		ega_redraw();
-#else
-		{}
-#endif
-}
-
-/** Return console to userspace
- *
- */
-void arch_release_console(void)
-{
 }
 
Index: kernel/arch/ia32/src/proc/scheduler.c
===================================================================
--- kernel/arch/ia32/src/proc/scheduler.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/src/proc/scheduler.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -61,6 +61,8 @@
 	    SP_DELTA];
 	
-	/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
-	write_msr(IA32_MSR_SYSENTER_ESP, kstk);
+	if (CPU->arch.fi.bits.sep) {
+		/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
+		write_msr(IA32_MSR_SYSENTER_ESP, kstk);
+	}
 	
 	/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */
Index: kernel/arch/ia32/src/userspace.c
===================================================================
--- kernel/arch/ia32/src/userspace.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia32/src/userspace.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -70,6 +70,6 @@
 		"movl %[uarg], %%eax\n"
 		
-		/* %ebx is defined to hold pcb_ptr - set it to 0 */
-		"xorl %%ebx, %%ebx\n"
+		/* %edi is defined to hold pcb_ptr - set it to 0 */
+		"xorl %%edi, %%edi\n"
 		
 		"iret\n"
Index: kernel/arch/ia64/_link.ld.in
===================================================================
--- kernel/arch/ia64/_link.ld.in	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/_link.ld.in	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -7,8 +7,11 @@
  */
 
+#define LOAD_ADDRESS_V	0xe000000004404000
+#define LOAD_ADDRESS_P	0x0000000004404000
+
 ENTRY(kernel_image_start)
 
 SECTIONS {
-	.image 0xe000000004404000: AT (0x0000000004404000) { 
+	.image LOAD_ADDRESS_V: AT (LOAD_ADDRESS_P) {
 		ktext_start = .;
 		*(K_TEXT_START);
@@ -21,4 +24,10 @@
 		*(.opd)
 		*(.data .data.*)
+		hardcoded_load_address = .;
+		QUAD(LOAD_ADDRESS_V);
+		hardcoded_ktext_size = .;
+		QUAD(ktext_end - ktext_start);
+		hardcoded_kdata_size = .;
+		QUAD(kdata_end - kdata_start);
 		*(.got .got.*)
 		*(.sdata)
@@ -38,7 +47,3 @@
 	}
 
-	_hardcoded_ktext_size = ktext_end - ktext_start;
-	_hardcoded_kdata_size = kdata_end - kdata_start;
-	_hardcoded_load_address = 0xe000000004404000;
-
 }
Index: rnel/arch/ia64/include/arg.h
===================================================================
--- kernel/arch/ia64/include/arg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup ia64	
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_ia64_ARG_H_
-#define KERN_ia64_ARG_H_
-
-#include <stdarg.h>
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ia64/include/asm.h
===================================================================
--- kernel/arch/ia64/include/asm.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/asm.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64	
+/** @addtogroup ia64
  * @{
  */
@@ -41,14 +41,17 @@
 #include <arch/register.h>
 
-#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL
+#define IA64_IOSPACE_ADDRESS  0xE001000000000000ULL
 
 static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	uintptr_t prt = (uintptr_t) port;
-
-	*((ioport8_t *)(IA64_IOSPACE_ADDRESS +
+	
+	*((ioport8_t *) (IA64_IOSPACE_ADDRESS +
 	    ((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
-
-	asm volatile ("mf\n" ::: "memory");
+	
+	asm volatile (
+		"mf\n"
+		::: "memory"
+	);
 }
 
@@ -56,9 +59,12 @@
 {
 	uintptr_t prt = (uintptr_t) port;
-
-	*((ioport16_t *)(IA64_IOSPACE_ADDRESS +
+	
+	*((ioport16_t *) (IA64_IOSPACE_ADDRESS +
 	    ((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
-
-	asm volatile ("mf\n" ::: "memory");
+	
+	asm volatile (
+		"mf\n"
+		::: "memory"
+	);
 }
 
@@ -66,9 +72,12 @@
 {
 	uintptr_t prt = (uintptr_t) port;
-
-	*((ioport32_t *)(IA64_IOSPACE_ADDRESS +
+	
+	*((ioport32_t *) (IA64_IOSPACE_ADDRESS +
 	    ((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
-
-	asm volatile ("mf\n" ::: "memory");
+	
+	asm volatile (
+		"mf\n"
+		::: "memory"
+	);
 }
 
@@ -76,8 +85,11 @@
 {
 	uintptr_t prt = (uintptr_t) port;
-
-	asm volatile ("mf\n" ::: "memory");
-
-	return *((ioport8_t *)(IA64_IOSPACE_ADDRESS +
+	
+	asm volatile (
+		"mf\n"
+		::: "memory"
+	);
+	
+	return *((ioport8_t *) (IA64_IOSPACE_ADDRESS +
 	    ((prt & 0xfff) | ((prt >> 2) << 12))));
 }
@@ -86,8 +98,11 @@
 {
 	uintptr_t prt = (uintptr_t) port;
-
-	asm volatile ("mf\n" ::: "memory");
-
-	return *((ioport16_t *)(IA64_IOSPACE_ADDRESS +
+	
+	asm volatile (
+		"mf\n"
+		::: "memory"
+	);
+	
+	return *((ioport16_t *) (IA64_IOSPACE_ADDRESS +
 	    ((prt & 0xfff) | ((prt >> 2) << 12))));
 }
@@ -96,8 +111,11 @@
 {
 	uintptr_t prt = (uintptr_t) port;
-
-	asm volatile ("mf\n" ::: "memory");
-
-	return *((ioport32_t *)(IA64_IOSPACE_ADDRESS +
+	
+	asm volatile (
+		"mf\n"
+		::: "memory"
+	);
+	
+	return *((ioport32_t *) (IA64_IOSPACE_ADDRESS +
 	    ((prt & 0xfff) | ((prt >> 2) << 12))));
 }
@@ -112,13 +130,24 @@
 {
 	uint64_t v;
-
-	//I'm not sure why but this code bad inlines in scheduler, 
-	//so THE shifts about 16B and causes kernel panic
-	//asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
-	//return v;
-	
-	//this code have the same meaning but inlines well
-	asm volatile ("mov %0 = r12" : "=r" (v)  );
-	return v & (~(STACK_SIZE-1));
+	
+	/* I'm not sure why but this code bad inlines in scheduler,
+	   so THE shifts about 16B and causes kernel panic
+	   
+	   asm volatile (
+	       "and %[value] = %[mask], r12"
+	       : [value] "=r" (v)
+	       : [mask] "r" (~(STACK_SIZE - 1))
+	   );
+	   return v;
+	   
+	   This code have the same meaning but inlines well.
+	*/
+	
+	asm volatile (
+		"mov %[value] = r12"
+		: [value] "=r" (v)
+	);
+	
+	return (v & (~(STACK_SIZE - 1)));
 }
 
@@ -131,5 +160,8 @@
 	uint64_t v;
 	
-	asm volatile ("mov %0 = psr\n" : "=r" (v));
+	asm volatile (
+		"mov %[value] = psr\n"
+		: [value] "=r" (v)
+	);
 	
 	return v;
@@ -144,5 +176,8 @@
 	uint64_t v;
 	
-	asm volatile ("mov %0 = cr.iva\n" : "=r" (v));
+	asm volatile (
+		"mov %[value] = cr.iva\n"
+		: [value] "=r" (v)
+	);
 	
 	return v;
@@ -155,5 +190,8 @@
 static inline void iva_write(uint64_t v)
 {
-	asm volatile ("mov cr.iva = %0\n" : : "r" (v));
+	asm volatile (
+		"mov cr.iva = %[value]\n"
+		:: [value] "r" (v)
+	);
 }
 
@@ -167,5 +205,8 @@
 	uint64_t v;
 	
-	asm volatile ("mov %0 = cr.ivr\n" : "=r" (v));
+	asm volatile (
+		"mov %[value] = cr.ivr\n"
+		: [value] "=r" (v)
+	);
 	
 	return v;
@@ -176,5 +217,8 @@
 	uint64_t v;
 	
-	asm volatile ("mov %0 = cr64\n" : "=r" (v));
+	asm volatile (
+		"mov %[value] = cr64\n"
+		: [value] "=r" (v)
+	);
 	
 	return v;
@@ -188,5 +232,8 @@
 static inline void itc_write(uint64_t v)
 {
-	asm volatile ("mov ar.itc = %0\n" : : "r" (v));
+	asm volatile (
+		"mov ar.itc = %[value]\n"
+		:: [value] "r" (v)
+	);
 }
 
@@ -199,5 +246,8 @@
 	uint64_t v;
 	
-	asm volatile ("mov %0 = ar.itc\n" : "=r" (v));
+	asm volatile (
+		"mov %[value] = ar.itc\n"
+		: [value] "=r" (v)
+	);
 	
 	return v;
@@ -210,5 +260,8 @@
 static inline void itm_write(uint64_t v)
 {
-	asm volatile ("mov cr.itm = %0\n" : : "r" (v));
+	asm volatile (
+		"mov cr.itm = %[value]\n"
+		:: [value] "r" (v)
+	);
 }
 
@@ -221,5 +274,8 @@
 	uint64_t v;
 	
-	asm volatile ("mov %0 = cr.itm\n" : "=r" (v));
+	asm volatile (
+		"mov %[value] = cr.itm\n"
+		: [value] "=r" (v)
+	);
 	
 	return v;
@@ -234,5 +290,8 @@
 	uint64_t v;
 	
-	asm volatile ("mov %0 = cr.itv\n" : "=r" (v));
+	asm volatile (
+		"mov %[value] = cr.itv\n"
+		: [value] "=r" (v)
+	);
 	
 	return v;
@@ -245,5 +304,8 @@
 static inline void itv_write(uint64_t v)
 {
-	asm volatile ("mov cr.itv = %0\n" : : "r" (v));
+	asm volatile (
+		"mov cr.itv = %[value]\n"
+		:: [value] "r" (v)
+	);
 }
 
@@ -254,5 +316,8 @@
 static inline void eoi_write(uint64_t v)
 {
-	asm volatile ("mov cr.eoi = %0\n" : : "r" (v));
+	asm volatile (
+		"mov cr.eoi = %[value]\n"
+		:: [value] "r" (v)
+	);
 }
 
@@ -264,6 +329,9 @@
 {
 	uint64_t v;
-
-	asm volatile ("mov %0 = cr.tpr\n"  : "=r" (v));
+	
+	asm volatile (
+		"mov %[value] = cr.tpr\n"
+		: [value] "=r" (v)
+	);
 	
 	return v;
@@ -276,5 +344,8 @@
 static inline void tpr_write(uint64_t v)
 {
-	asm volatile ("mov cr.tpr = %0\n" : : "r" (v));
+	asm volatile (
+		"mov cr.tpr = %[value]\n"
+		:: [value] "r" (v)
+	);
 }
 
@@ -291,8 +362,8 @@
 	
 	asm volatile (
-		"mov %0 = psr\n"
-		"rsm %1\n"
-		: "=r" (v)
-		: "i" (PSR_I_MASK)
+		"mov %[value] = psr\n"
+		"rsm %[mask]\n"
+		: [value] "=r" (v)
+		: [mask] "i" (PSR_I_MASK)
 	);
 	
@@ -312,10 +383,10 @@
 	
 	asm volatile (
-		"mov %0 = psr\n"
-		"ssm %1\n"
+		"mov %[value] = psr\n"
+		"ssm %[mask]\n"
 		";;\n"
 		"srlz.d\n"
-		: "=r" (v)
-		: "i" (PSR_I_MASK)
+		: [value] "=r" (v)
+		: [mask] "i" (PSR_I_MASK)
 	);
 	
@@ -349,5 +420,10 @@
 static inline void pk_disable(void)
 {
-	asm volatile ("rsm %0\n" : : "i" (PSR_PK_MASK));
+	asm volatile (
+		"rsm %[mask]\n"
+		";;\n"
+		"srlz.d\n"
+		:: [mask] "i" (PSR_PK_MASK)
+	);
 }
 
Index: kernel/arch/ia64/include/atomic.h
===================================================================
--- kernel/arch/ia64/include/atomic.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/atomic.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64	
+/** @addtogroup ia64
  * @{
  */
@@ -36,21 +36,4 @@
 #define KERN_ia64_ATOMIC_H_
 
-/** Atomic addition.
- *
- * @param val		Atomic value.
- * @param imm		Value to add.
- *
- * @return		Value before addition.
- */
-static inline long atomic_add(atomic_t *val, int imm)
-{
-	long v;
-
- 	asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v),
-	    "+m" (val->count) : "i" (imm));
- 
-	return v;
-}
-
 static inline uint64_t test_and_set(atomic_t *val)
 {
@@ -58,7 +41,8 @@
 		
 	asm volatile (
-		"movl %0 = 0x1;;\n"
-		"xchg8 %0 = %1, %0;;\n"
-		: "=r" (v), "+m" (val->count)
+		"movl %[v] = 0x1;;\n"
+		"xchg8 %[v] = %[count], %[v];;\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
 	);
 	
@@ -76,30 +60,74 @@
 static inline void atomic_inc(atomic_t *val)
 {
-	atomic_add(val, 1);
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], 1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
 }
 
 static inline void atomic_dec(atomic_t *val)
 {
-	atomic_add(val, -1);
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], -1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
 }
 
 static inline long atomic_preinc(atomic_t *val)
 {
-	return atomic_add(val, 1) + 1;
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], 1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+	
+	return (v + 1);
 }
 
 static inline long atomic_predec(atomic_t *val)
 {
-	return atomic_add(val, -1) - 1;
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], -1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+	
+	return (v - 1);
 }
 
 static inline long atomic_postinc(atomic_t *val)
 {
-	return atomic_add(val, 1);
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], 1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+	
+	return v;
 }
 
 static inline long atomic_postdec(atomic_t *val)
 {
-	return atomic_add(val, -1);
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], -1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+	
+	return v;
 }
 
Index: kernel/arch/ia64/include/drivers/ski.h
===================================================================
--- kernel/arch/ia64/include/drivers/ski.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/drivers/ski.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -44,10 +44,8 @@
 } ski_instance_t;
 
-extern void skiout_init(void);
+extern outdev_t *skiout_init(void);
 
 extern ski_instance_t *skiin_init(void);
 extern void skiin_wire(ski_instance_t *, indev_t *);
-extern void ski_kbd_grab(void);
-extern void ski_kbd_release(void);
 
 #endif
Index: kernel/arch/ia64/include/faddr.h
===================================================================
--- kernel/arch/ia64/include/faddr.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/faddr.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64	
+/** @addtogroup ia64
  * @{
  */
@@ -38,13 +38,13 @@
 #include <arch/types.h>
 
-/** 
+/**
  *
  * Calculate absolute address of function
  * referenced by fptr pointer.
  *
- * @param f Function pointer.
+ * @param fptr Function pointer.
  *
  */
-#define FADDR(f)	 (*((uintptr_t *)(f)));
+#define FADDR(fptr)  (((fncptr_t *) (fptr))->fnc)
 
 #endif
Index: kernel/arch/ia64/include/interrupt.h
===================================================================
--- kernel/arch/ia64/include/interrupt.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/interrupt.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -40,5 +40,5 @@
 
 /** ia64 has 256 INRs. */
-#define INR_COUNT	256
+#define INR_COUNT  256
 
 /*
@@ -47,25 +47,28 @@
  * to genarch.
  */
-#define IVT_ITEMS       0
-#define IVT_FIRST       0
+#define IVT_ITEMS  0
+#define IVT_FIRST  0
 
 /** External Interrupt vectors. */
 
-#define VECTOR_TLB_SHOOTDOWN_IPI 0xf0
-#define INTERRUPT_TIMER		255
-#define IRQ_KBD			(0x01 + LEGACY_INTERRUPT_BASE)
-#define IRQ_MOUSE		(0x0c + LEGACY_INTERRUPT_BASE)
-#define INTERRUPT_SPURIOUS	15
-#define LEGACY_INTERRUPT_BASE	0x20
+#define VECTOR_TLB_SHOOTDOWN_IPI  0xf0
+
+#define INTERRUPT_SPURIOUS  15
+#define INTERRUPT_TIMER     255
+
+#define LEGACY_INTERRUPT_BASE  0x20
+
+#define IRQ_KBD    (0x01 + LEGACY_INTERRUPT_BASE)
+#define IRQ_MOUSE  (0x0c + LEGACY_INTERRUPT_BASE)
 
 /** General Exception codes. */
-#define GE_ILLEGALOP		0
-#define GE_PRIVOP		1
-#define GE_PRIVREG		2
-#define GE_RESREGFLD		3
-#define GE_DISBLDISTRAN		4
-#define GE_ILLEGALDEP		8
+#define GE_ILLEGALOP     0
+#define GE_PRIVOP        1
+#define GE_PRIVREG       2
+#define GE_RESREGFLD     3
+#define GE_DISBLDISTRAN  4
+#define GE_ILLEGALDEP    8
 
-#define EOI	0		/**< The actual value doesn't matter. */
+#define EOI  0  /**< The actual value doesn't matter. */
 
 typedef struct {
@@ -100,5 +103,5 @@
 	uint128_t f30;
 	uint128_t f31;
-		
+	
 	uintptr_t ar_bsp;
 	uintptr_t ar_bspstore;
@@ -132,5 +135,5 @@
 {
 	istate->cr_iip = retaddr;
-	istate->cr_ipsr.ri = 0;		/* return to instruction slot #0 */
+	istate->cr_ipsr.ri = 0;    /* return to instruction slot #0 */
 }
 
Index: kernel/arch/ia64/include/mm/as.h
===================================================================
--- kernel/arch/ia64/include/mm/as.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/mm/as.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64mm	
+/** @addtogroup ia64mm
  * @{
  */
@@ -36,12 +36,12 @@
 #define KERN_ia64_AS_H_
 
-#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	0
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
 
-#define KERNEL_ADDRESS_SPACE_START_ARCH		(unsigned long) 0xe000000000000000ULL
-#define KERNEL_ADDRESS_SPACE_END_ARCH		(unsigned long) 0xffffffffffffffffULL
-#define USER_ADDRESS_SPACE_START_ARCH		(unsigned long) 0x0000000000000000ULL
-#define USER_ADDRESS_SPACE_END_ARCH		(unsigned long) 0xdfffffffffffffffULL
+#define KERNEL_ADDRESS_SPACE_START_ARCH  ((unsigned long) 0xe000000000000000ULL)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    ((unsigned long) 0xffffffffffffffffULL)
+#define USER_ADDRESS_SPACE_START_ARCH    ((unsigned long) 0x0000000000000000ULL)
+#define USER_ADDRESS_SPACE_END_ARCH      ((unsigned long) 0xdfffffffffffffffULL)
 
-#define USTACK_ADDRESS_ARCH	0x0000000ff0000000ULL
+#define USTACK_ADDRESS_ARCH  0x0000000ff0000000ULL
 
 typedef struct {
@@ -50,7 +50,7 @@
 #include <genarch/mm/as_ht.h>
 
-#define as_constructor_arch(as, flags)		(as != as)
-#define as_destructor_arch(as)			(as != as)
-#define as_create_arch(as, flags)		(as != as)
+#define as_constructor_arch(as, flags)  (as != as)
+#define as_destructor_arch(as)          (as != as)
+#define as_create_arch(as, flags)       (as != as)
 #define as_deinstall_arch(as)
 #define as_invalidate_translation_cache(as, page, cnt)
Index: kernel/arch/ia64/include/mm/page.h
===================================================================
--- kernel/arch/ia64/include/mm/page.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/mm/page.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -28,5 +28,5 @@
  */
 
-/** @addtogroup ia64mm	
+/** @addtogroup ia64mm
  * @{
  */
@@ -39,15 +39,15 @@
 #include <arch/mm/frame.h>
 
-#define PAGE_SIZE	FRAME_SIZE
-#define PAGE_WIDTH	FRAME_WIDTH
+#define PAGE_SIZE   FRAME_SIZE
+#define PAGE_WIDTH  FRAME_WIDTH
 
 #ifdef KERNEL
 
 /** Bit width of the TLB-locked portion of kernel address space. */
-#define KERNEL_PAGE_WIDTH		28	/* 256M */
-#define IO_PAGE_WIDTH			26	/* 64M */
-#define FW_PAGE_WIDTH			28	/* 256M */
-
-#define USPACE_IO_PAGE_WIDTH		12	/* 4K */
+#define KERNEL_PAGE_WIDTH  28  /* 256M */
+#define IO_PAGE_WIDTH      26  /* 64M */
+#define FW_PAGE_WIDTH      28  /* 256M */
+
+#define USPACE_IO_PAGE_WIDTH  12  /* 4K */
 
 
@@ -59,45 +59,45 @@
 
 /* Firmware area (bellow 4GB in phys mem) */
-#define FW_OFFSET             0x00000000F0000000
+#define FW_OFFSET   0x00000000F0000000
 /* Legacy IO space */
-#define IO_OFFSET             0x0001000000000000
+#define IO_OFFSET   0x0001000000000000
 /* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000 */
-#define VIO_OFFSET            0x0002000000000000
-
-
-#define PPN_SHIFT			12
-
-#define VRN_SHIFT			61
-#define VRN_MASK			(7LL << VRN_SHIFT)
-#define VA2VRN(va)			((va)>>VRN_SHIFT)
+#define VIO_OFFSET  0x0002000000000000
+
+
+#define PPN_SHIFT  12
+
+#define VRN_SHIFT   61
+#define VRN_MASK    (7ULL << VRN_SHIFT)
+#define VA2VRN(va)  ((va) >> VRN_SHIFT)
 
 #ifdef __ASM__
-#define VRN_KERNEL	 		7
+	#define VRN_KERNEL  7
 #else
-#define VRN_KERNEL	 		7LL
+	#define VRN_KERNEL  7ULL
 #endif
 
-#define REGION_REGISTERS 		8
-
-#define KA2PA(x)	((uintptr_t) (x - (VRN_KERNEL << VRN_SHIFT)))
-#define PA2KA(x)	((uintptr_t) (x + (VRN_KERNEL << VRN_SHIFT)))
-
-#define VHPT_WIDTH 			20	/* 1M */
-#define VHPT_SIZE 			(1 << VHPT_WIDTH)
-
-#define PTA_BASE_SHIFT			15
+#define REGION_REGISTERS  8
+
+#define KA2PA(x)  ((uintptr_t) ((x) - (VRN_KERNEL << VRN_SHIFT)))
+#define PA2KA(x)  ((uintptr_t) ((x) + (VRN_KERNEL << VRN_SHIFT)))
+
+#define VHPT_WIDTH  20  /* 1M */
+#define VHPT_SIZE   (1 << VHPT_WIDTH)
+
+#define PTA_BASE_SHIFT  15
 
 /** Memory Attributes. */
-#define MA_WRITEBACK	0x0
-#define MA_UNCACHEABLE	0x4
+#define MA_WRITEBACK    0x00
+#define MA_UNCACHEABLE  0x04
 
 /** Privilege Levels. Only the most and the least privileged ones are ever used. */
-#define PL_KERNEL	0x0
-#define PL_USER		0x3
+#define PL_KERNEL  0x00
+#define PL_USER    0x03
 
 /* Access Rigths. Only certain combinations are used by the kernel. */
-#define AR_READ		0x0
-#define AR_EXECUTE	0x1
-#define AR_WRITE	0x2
+#define AR_READ     0x00
+#define AR_EXECUTE  0x01
+#define AR_WRITE    0x02
 
 #ifndef __ASM__
@@ -113,5 +113,5 @@
 struct vhpt_tag_info {
 	unsigned long long tag : 63;
-	unsigned ti : 1;
+	unsigned int ti : 1;
 } __attribute__ ((packed));
 
@@ -123,26 +123,26 @@
 struct vhpt_entry_present {
 	/* Word 0 */
-	unsigned p : 1;
-	unsigned : 1;
-	unsigned ma : 3;
-	unsigned a : 1;
-	unsigned d : 1;
-	unsigned pl : 2;
-	unsigned ar : 3;
+	unsigned int p : 1;
+	unsigned int : 1;
+	unsigned int ma : 3;
+	unsigned int a : 1;
+	unsigned int d : 1;
+	unsigned int pl : 2;
+	unsigned int ar : 3;
 	unsigned long long ppn : 38;
-	unsigned : 2;
-	unsigned ed : 1;
-	unsigned ig1 : 11;
+	unsigned int : 2;
+	unsigned int ed : 1;
+	unsigned int ig1 : 11;
 	
 	/* Word 1 */
-	unsigned : 2;
-	unsigned ps : 6;
-	unsigned key : 24;
-	unsigned : 32;
+	unsigned int : 2;
+	unsigned int ps : 6;
+	unsigned int key : 24;
+	unsigned int : 32;
 	
 	/* Word 2 */
 	union vhpt_tag tag;
 	
-	/* Word 3 */													
+	/* Word 3 */
 	uint64_t ig3 : 64;
 } __attribute__ ((packed));
@@ -150,21 +150,21 @@
 struct vhpt_entry_not_present {
 	/* Word 0 */
-	unsigned p : 1;
+	unsigned int p : 1;
 	unsigned long long ig0 : 52;
-	unsigned ig1 : 11;
+	unsigned int ig1 : 11;
 	
 	/* Word 1 */
-	unsigned : 2;
-	unsigned ps : 6;
+	unsigned int : 2;
+	unsigned int ps : 6;
 	unsigned long long ig2 : 56;
-
+	
 	/* Word 2 */
 	union vhpt_tag tag;
 	
-	/* Word 3 */													
+	/* Word 3 */
 	uint64_t ig3 : 64;
 } __attribute__ ((packed));
 
-typedef union vhpt_entry {
+typedef union {
 	struct vhpt_entry_present present;
 	struct vhpt_entry_not_present not_present;
@@ -173,22 +173,22 @@
 
 struct region_register_map {
-	unsigned ve : 1;
-	unsigned : 1;
-	unsigned ps : 6;
-	unsigned rid : 24;
-	unsigned : 32;
-} __attribute__ ((packed));
-
-typedef union region_register {
+	unsigned int ve : 1;
+	unsigned int : 1;
+	unsigned int ps : 6;
+	unsigned int rid : 24;
+	unsigned int : 32;
+} __attribute__ ((packed));
+
+typedef union {
 	struct region_register_map map;
 	unsigned long long word;
-} region_register;
+} region_register_t;
 
 struct pta_register_map {
-	unsigned ve : 1;
-	unsigned : 1;
-	unsigned size : 6;
-	unsigned vf : 1;
-	unsigned : 6;
+	unsigned int ve : 1;
+	unsigned int : 1;
+	unsigned int size : 6;
+	unsigned int vf : 1;
+	unsigned int : 6;
 	unsigned long long base : 49;
 } __attribute__ ((packed));
@@ -197,5 +197,5 @@
 	struct pta_register_map map;
 	uint64_t word;
-} pta_register;
+} pta_register_t;
 
 /** Return Translation Hashed Entry Address.
@@ -211,7 +211,11 @@
 {
 	uint64_t ret;
-
-	asm volatile ("thash %0 = %1\n" : "=r" (ret) : "r" (va));
-
+	
+	asm volatile (
+		"thash %[ret] = %[va]\n"
+		: [ret] "=r" (ret)
+		: [va] "r" (va)
+	);
+	
 	return ret;
 }
@@ -229,7 +233,11 @@
 {
 	uint64_t ret;
-
-	asm volatile ("ttag %0 = %1\n" : "=r" (ret) : "r" (va));
-
+	
+	asm volatile (
+		"ttag %[ret] = %[va]\n"
+		: [ret] "=r" (ret)
+		: [va] "r" (va)
+	);
+	
 	return ret;
 }
@@ -244,6 +252,13 @@
 {
 	uint64_t ret;
+	
 	ASSERT(i < REGION_REGISTERS);
-	asm volatile ("mov %0 = rr[%1]\n" : "=r" (ret) : "r" (i << VRN_SHIFT));
+	
+	asm volatile (
+		"mov %[ret] = rr[%[index]]\n"
+		: [ret] "=r" (ret)
+		: [index] "r" (i << VRN_SHIFT)
+	);
+	
 	return ret;
 }
@@ -257,11 +272,12 @@
 {
 	ASSERT(i < REGION_REGISTERS);
-	asm volatile (
-		"mov rr[%0] = %1\n" 
-		: 
-		: "r" (i << VRN_SHIFT), "r" (v)
-	);
-}
- 
+	
+	asm volatile (
+		"mov rr[%[index]] = %[value]\n"
+		:: [index] "r" (i << VRN_SHIFT),
+		   [value] "r" (v)
+	);
+}
+
 /** Read Page Table Register.
  *
@@ -272,5 +288,8 @@
 	uint64_t ret;
 	
-	asm volatile ("mov %0 = cr.pta\n" : "=r" (ret));
+	asm volatile (
+		"mov %[ret] = cr.pta\n"
+		: [ret] "=r" (ret)
+	);
 	
 	return ret;
@@ -283,5 +302,8 @@
 static inline void pta_write(uint64_t v)
 {
-	asm volatile ("mov cr.pta = %0\n" : : "r" (v));
+	asm volatile (
+		"mov cr.pta = %[value]\n"
+		:: [value] "r" (v)
+	);
 }
 
Index: kernel/arch/ia64/include/mm/tlb.h
===================================================================
--- kernel/arch/ia64/include/mm/tlb.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/mm/tlb.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64mm	
+/** @addtogroup ia64mm
  * @{
  */
@@ -42,34 +42,33 @@
 
 /** Data and instruction Translation Register indices. */
-#define DTR_KERNEL	0
-#define ITR_KERNEL	0
-#define DTR_KSTACK1	4
-#define DTR_KSTACK2	5
+#define DTR_KERNEL   0
+#define ITR_KERNEL   0
+#define DTR_KSTACK1  4
+#define DTR_KSTACK2  5
 
 /** Portion of TLB insertion format data structure. */
-union tlb_entry {
+typedef union {
 	uint64_t word[2];
 	struct {
 		/* Word 0 */
-		unsigned p : 1;			/**< Present. */
-		unsigned : 1;
-		unsigned ma : 3;		/**< Memory attribute. */
-		unsigned a : 1;			/**< Accessed. */
-		unsigned d : 1;			/**< Dirty. */
-		unsigned pl : 2;		/**< Privilege level. */
-		unsigned ar : 3;		/**< Access rights. */
-		unsigned long long ppn : 38;	/**< Physical Page Number, a.k.a. PFN. */
-		unsigned : 2;
-		unsigned ed : 1;
-		unsigned ig1 : 11;
-
+		unsigned int p : 1;           /**< Present. */
+		unsigned int : 1;
+		unsigned int ma : 3;          /**< Memory attribute. */
+		unsigned int a : 1;           /**< Accessed. */
+		unsigned int d : 1;           /**< Dirty. */
+		unsigned int pl : 2;          /**< Privilege level. */
+		unsigned int ar : 3;          /**< Access rights. */
+		unsigned long long ppn : 38;  /**< Physical Page Number, a.k.a. PFN. */
+		unsigned int : 2;
+		unsigned int ed : 1;
+		unsigned int ig1 : 11;
+		
 		/* Word 1 */
-		unsigned : 2;
-		unsigned ps : 6;		/**< Page size will be 2^ps. */
-		unsigned key : 24;		/**< Protection key, unused. */
-		unsigned : 32;
+		unsigned int : 2;
+		unsigned int ps : 6;    /**< Page size will be 2^ps. */
+		unsigned int key : 24;  /**< Protection key, unused. */
+		unsigned int : 32;
 	} __attribute__ ((packed));
-} __attribute__ ((packed));
-typedef union tlb_entry tlb_entry_t;
+} __attribute__ ((packed)) tlb_entry_t;
 
 extern void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc);
Index: kernel/arch/ia64/include/register.h
===================================================================
--- kernel/arch/ia64/include/register.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/register.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64	
+/** @addtogroup ia64
  * @{
  */
@@ -36,98 +36,107 @@
 #define KERN_ia64_REGISTER_H_
 
-#define CR_IVR_MASK	0xf
-#define PSR_IC_MASK	0x2000
-#define PSR_I_MASK	0x4000
-#define PSR_PK_MASK	0x8000
-
-#define PSR_DT_MASK	(1 << 17)
-#define PSR_RT_MASK	(1 << 27)
-
-#define PSR_DFL_MASK	(1 << 18)
-#define PSR_DFH_MASK	(1 << 19)
-
-#define PSR_IT_MASK	0x0000001000000000
-
-#define PSR_CPL_SHIFT		32
-#define PSR_CPL_MASK_SHIFTED	3
-
-#define PFM_MASK        (~0x3fffffffff)
-
-#define RSC_MODE_MASK	3
-#define RSC_PL_MASK	12
+#define DCR_PP_MASK  (1 << 0)
+#define DCR_BE_MASK  (1 << 1)
+#define DCR_LC_MASK  (1 << 2)
+#define DCR_DM_MASK  (1 << 8)
+#define DCR_DP_MASK  (1 << 9)
+#define DCR_DK_MASK  (1 << 10)
+#define DCR_DX_MASK  (1 << 11)
+#define DCR_DR_MASK  (1 << 12)
+#define DCR_DA_MASK  (1 << 13)
+#define DCR_DD_MASK  (1 << 14)
+
+#define CR_IVR_MASK  0x0f
+
+#define PSR_IC_MASK   (1 << 13)
+#define PSR_I_MASK    (1 << 14)
+#define PSR_PK_MASK   (1 << 15)
+#define PSR_DT_MASK   (1 << 17)
+#define PSR_DFL_MASK  (1 << 18)
+#define PSR_DFH_MASK  (1 << 19)
+#define PSR_RT_MASK   (1 << 27)
+#define PSR_IT_MASK   (1 << 36)
+
+#define PSR_CPL_SHIFT         32
+#define PSR_CPL_MASK_SHIFTED  3
+
+#define PFM_MASK  (~0x3fffffffff)
+
+#define RSC_MODE_MASK   3
+#define RSC_PL_MASK     12
 
 /** Application registers. */
-#define AR_KR0		0
-#define AR_KR1		1
-#define AR_KR2		2
-#define AR_KR3		3
-#define AR_KR4		4
-#define AR_KR5		5
-#define AR_KR6		6
-#define AR_KR7		7
-/* AR 8-15 reserved */
-#define AR_RSC		16
-#define AR_BSP		17
-#define AR_BSPSTORE	18
-#define AR_RNAT		19
-/* AR 20 reserved */
-#define AR_FCR		21
-/* AR 22-23 reserved */
-#define AR_EFLAG	24
-#define AR_CSD		25
-#define AR_SSD		26
-#define AR_CFLG		27
-#define AR_FSR		28
-#define AR_FIR		29
-#define AR_FDR		30
-/* AR 31 reserved */
-#define AR_CCV		32
-/* AR 33-35 reserved */
-#define AR_UNAT		36
-/* AR 37-39 reserved */
-#define AR_FPSR		40
-/* AR 41-43 reserved */
-#define AR_ITC		44
-/* AR 45-47 reserved */
-/* AR 48-63 ignored */
-#define AR_PFS		64
-#define AR_LC		65
-#define AR_EC		66
-/* AR 67-111 reserved */
-/* AR 112-127 ignored */
+#define AR_KR0       0
+#define AR_KR1       1
+#define AR_KR2       2
+#define AR_KR3       3
+#define AR_KR4       4
+#define AR_KR5       5
+#define AR_KR6       6
+#define AR_KR7       7
+/* ARs 8-15 are reserved */
+#define AR_RSC       16
+#define AR_BSP       17
+#define AR_BSPSTORE  18
+#define AR_RNAT      19
+/* AR 20 is reserved */
+#define AR_FCR       21
+/* ARs 22-23 are reserved */
+#define AR_EFLAG     24
+#define AR_CSD       25
+#define AR_SSD       26
+#define AR_CFLG      27
+#define AR_FSR       28
+#define AR_FIR       29
+#define AR_FDR       30
+/* AR 31 is reserved */
+#define AR_CCV       32
+/* ARs 33-35 are reserved */
+#define AR_UNAT      36
+/* ARs 37-39 are reserved */
+#define AR_FPSR      40
+/* ARs 41-43 are reserved */
+#define AR_ITC       44
+/* ARs 45-47 are reserved */
+/* ARs 48-63 are ignored */
+#define AR_PFS       64
+#define AR_LC        65
+#define AR_EC        66
+/* ARs 67-111 are reserved */
+/* ARs 112-127 are ignored */
 
 /** Control registers. */
-#define CR_DCR		0
-#define CR_ITM		1
-#define CR_IVA		2
-/* CR3-CR7 reserved */
-#define CR_PTA		8
-/* CR9-CR15 reserved */
-#define CR_IPSR		16
-#define CR_ISR		17
-/* CR18 reserved */
-#define CR_IIP		19
-#define CR_IFA		20
-#define CR_ITIR		21
-#define CR_IIPA		22
-#define CR_IFS		23
-#define CR_IIM		24
-#define CR_IHA		25
-/* CR26-CR63 reserved */
-#define CR_LID		64
-#define CR_IVR		65
-#define CR_TPR		66
-#define CR_EOI		67
-#define CR_IRR0		68
-#define CR_IRR1		69
-#define CR_IRR2		70
-#define CR_IRR3		71
-#define CR_ITV		72
-#define CR_PMV		73
-#define CR_CMCV		74
-/* CR75-CR79 reserved */
-#define CR_LRR0		80
-#define CR_LRR1		81
-/* CR82-CR127 reserved */
+#define CR_DCR   0
+#define CR_ITM   1
+#define CR_IVA   2
+/* CR3-CR7 are reserved */
+#define CR_PTA   8
+/* CR9-CR15 are reserved */
+#define CR_IPSR  16
+#define CR_ISR   17
+/* CR18 is reserved */
+#define CR_IIP   19
+#define CR_IFA   20
+#define CR_ITIR  21
+#define CR_IIPA  22
+#define CR_IFS   23
+#define CR_IIM   24
+#define CR_IHA   25
+/* CR26-CR63 are reserved */
+#define CR_LID   64
+#define CR_IVR   65
+#define CR_TPR   66
+#define CR_EOI   67
+#define CR_IRR0  68
+#define CR_IRR1  69
+#define CR_IRR2  70
+#define CR_IRR3  71
+#define CR_ITV   72
+#define CR_PMV   73
+#define CR_CMCV  74
+/* CR75-CR79 are reserved */
+#define CR_LRR0  80
+#define CR_LRR1  81
+/* CR82-CR127 are reserved */
 
 #ifndef __ASM__
@@ -136,127 +145,118 @@
 
 /** Processor Status Register. */
-union psr {
-	uint64_t value;
-	struct {
-		unsigned : 1;
-		unsigned be : 1;	/**< Big-Endian data accesses. */
-		unsigned up : 1;	/**< User Performance monitor enable. */
-		unsigned ac : 1;	/**< Alignment Check. */
-		unsigned mfl : 1;	/**< Lower floating-point register written. */
-		unsigned mfh : 1;	/**< Upper floating-point register written. */
-		unsigned : 7;
-		unsigned ic : 1;	/**< Interruption Collection. */
-		unsigned i : 1;		/**< Interrupt Bit. */
-		unsigned pk : 1;	/**< Protection Key enable. */
-		unsigned : 1;
-		unsigned dt : 1;	/**< Data address Translation. */
-		unsigned dfl : 1;	/**< Disabled Floating-point Low register set. */
-		unsigned dfh : 1;	/**< Disabled Floating-point High register set. */
-		unsigned sp : 1;	/**< Secure Performance monitors. */
-		unsigned pp : 1;	/**< Privileged Performance monitor enable. */
-		unsigned di : 1;	/**< Disable Instruction set transition. */
-		unsigned si : 1;	/**< Secure Interval timer. */
-		unsigned db : 1;	/**< Debug Breakpoint fault. */
-		unsigned lp : 1;	/**< Lower Privilege transfer trap. */
-		unsigned tb : 1;	/**< Taken Branch trap. */
-		unsigned rt : 1;	/**< Register Stack Translation. */
-		unsigned : 4;
-		unsigned cpl : 2;	/**< Current Privilege Level. */
-		unsigned is : 1;	/**< Instruction Set. */
-		unsigned mc : 1;	/**< Machine Check abort mask. */
-		unsigned it : 1;	/**< Instruction address Translation. */
-		unsigned id : 1;	/**< Instruction Debug fault disable. */
-		unsigned da : 1;	/**< Disable Data Access and Dirty-bit faults. */
-		unsigned dd : 1;	/**< Data Debug fault disable. */
-		unsigned ss : 1;	/**< Single Step enable. */
-		unsigned ri : 2;	/**< Restart Instruction. */
-		unsigned ed : 1;	/**< Exception Deferral. */
-		unsigned bn : 1;	/**< Register Bank. */
-		unsigned ia : 1;	/**< Disable Instruction Access-bit faults. */
-	} __attribute__ ((packed));
-};
-typedef union psr psr_t;
+typedef union {
+	uint64_t value;
+	struct {
+		unsigned int : 1;
+		unsigned int be : 1;   /**< Big-Endian data accesses. */
+		unsigned int up : 1;   /**< User Performance monitor enable. */
+		unsigned int ac : 1;   /**< Alignment Check. */
+		unsigned int mfl : 1;  /**< Lower floating-point register written. */
+		unsigned int mfh : 1;  /**< Upper floating-point register written. */
+		unsigned int : 7;
+		unsigned int ic : 1;   /**< Interruption Collection. */
+		unsigned int i : 1;    /**< Interrupt Bit. */
+		unsigned int pk : 1;   /**< Protection Key enable. */
+		unsigned int : 1;
+		unsigned int dt : 1;   /**< Data address Translation. */
+		unsigned int dfl : 1;  /**< Disabled Floating-point Low register set. */
+		unsigned int dfh : 1;  /**< Disabled Floating-point High register set. */
+		unsigned int sp : 1;   /**< Secure Performance monitors. */
+		unsigned int pp : 1;   /**< Privileged Performance monitor enable. */
+		unsigned int di : 1;   /**< Disable Instruction set transition. */
+		unsigned int si : 1;   /**< Secure Interval timer. */
+		unsigned int db : 1;   /**< Debug Breakpoint fault. */
+		unsigned int lp : 1;   /**< Lower Privilege transfer trap. */
+		unsigned int tb : 1;   /**< Taken Branch trap. */
+		unsigned int rt : 1;   /**< Register Stack Translation. */
+		unsigned int : 4;
+		unsigned int cpl : 2;  /**< Current Privilege Level. */
+		unsigned int is : 1;   /**< Instruction Set. */
+		unsigned int mc : 1;   /**< Machine Check abort mask. */
+		unsigned int it : 1;   /**< Instruction address Translation. */
+		unsigned int id : 1;   /**< Instruction Debug fault disable. */
+		unsigned int da : 1;   /**< Disable Data Access and Dirty-bit faults. */
+		unsigned int dd : 1;   /**< Data Debug fault disable. */
+		unsigned int ss : 1;   /**< Single Step enable. */
+		unsigned int ri : 2;   /**< Restart Instruction. */
+		unsigned int ed : 1;   /**< Exception Deferral. */
+		unsigned int bn : 1;   /**< Register Bank. */
+		unsigned int ia : 1;   /**< Disable Instruction Access-bit faults. */
+	} __attribute__ ((packed));
+} psr_t;
 
 /** Register Stack Configuration Register */
-union rsc {
-	uint64_t value;
-	struct {
-		unsigned mode : 2;
-		unsigned pl : 2;	/**< Privilege Level. */
-		unsigned be : 1;	/**< Big-endian. */
-		unsigned : 11;
-		unsigned loadrs : 14;
-	} __attribute__ ((packed));
-};
-typedef union rsc rsc_t;
+typedef union {
+	uint64_t value;
+	struct {
+		unsigned int mode : 2;
+		unsigned int pl : 2;    /**< Privilege Level. */
+		unsigned int be : 1;    /**< Big-endian. */
+		unsigned int : 11;
+		unsigned int loadrs : 14;
+	} __attribute__ ((packed));
+} rsc_t;
 
 /** External Interrupt Vector Register */
-union cr_ivr {
-	uint8_t  vector;
-	uint64_t value;
-};
-
-typedef union cr_ivr cr_ivr_t;
+typedef union {
+	uint8_t vector;
+	uint64_t value;
+} cr_ivr_t;
 
 /** Task Priority Register */
-union cr_tpr {
-	struct {
-		unsigned : 4;
-		unsigned mic: 4;		/**< Mask Interrupt Class. */
-		unsigned : 8;
-		unsigned mmi: 1;		/**< Mask Maskable Interrupts. */
-	} __attribute__ ((packed));
-	uint64_t value;
-};
-
-typedef union cr_tpr cr_tpr_t;
+typedef union {
+	uint64_t value;
+	struct {
+		unsigned int : 4;
+		unsigned int mic: 4;  /**< Mask Interrupt Class. */
+		unsigned int : 8;
+		unsigned int mmi: 1;  /**< Mask Maskable Interrupts. */
+	} __attribute__ ((packed));
+} cr_tpr_t;
 
 /** Interval Timer Vector */
-union cr_itv {
-	struct {
-		unsigned vector : 8;
-		unsigned : 4;
-		unsigned : 1;
-		unsigned : 3;
-		unsigned m : 1;			/**< Mask. */
-	} __attribute__ ((packed));
-	uint64_t value;
-};
-
-typedef union cr_itv cr_itv_t;
+typedef union {
+	uint64_t value;
+	struct {
+		unsigned int vector : 8;
+		unsigned int : 4;
+		unsigned int : 1;
+		unsigned int : 3;
+		unsigned int m : 1;       /**< Mask. */
+	} __attribute__ ((packed));
+} cr_itv_t;
 
 /** Interruption Status Register */
-union cr_isr {
+typedef union {
+	uint64_t value;
 	struct {
 		union {
 			/** General Exception code field structuring. */
+			uint16_t code;
 			struct {
-				unsigned ge_na : 4;
-				unsigned ge_code : 4;
+				unsigned int ge_na : 4;
+				unsigned int ge_code : 4;
 			} __attribute__ ((packed));
-			uint16_t code;
 		};
 		uint8_t vector;
-		unsigned : 8;
-		unsigned x : 1;			/**< Execute exception. */
-		unsigned w : 1;			/**< Write exception. */
-		unsigned r : 1;			/**< Read exception. */
-		unsigned na : 1;		/**< Non-access exception. */
-		unsigned sp : 1;		/**< Speculative load exception. */
-		unsigned rs : 1;		/**< Register stack. */
-		unsigned ir : 1;		/**< Incomplete Register frame. */
-		unsigned ni : 1;		/**< Nested Interruption. */
-		unsigned so : 1;		/**< IA-32 Supervisor Override. */
-		unsigned ei : 2;		/**< Excepting Instruction. */
-		unsigned ed : 1;		/**< Exception Deferral. */
-		unsigned : 20;
-	} __attribute__ ((packed));
-	uint64_t value;
-};
-
-typedef union cr_isr cr_isr_t;
+		unsigned int : 8;
+		unsigned int x : 1;   /**< Execute exception. */
+		unsigned int w : 1;   /**< Write exception. */
+		unsigned int r : 1;   /**< Read exception. */
+		unsigned int na : 1;  /**< Non-access exception. */
+		unsigned int sp : 1;  /**< Speculative load exception. */
+		unsigned int rs : 1;  /**< Register stack. */
+		unsigned int ir : 1;  /**< Incomplete Register frame. */
+		unsigned int ni : 1;  /**< Nested Interruption. */
+		unsigned int so : 1;  /**< IA-32 Supervisor Override. */
+		unsigned int ei : 2;  /**< Excepting Instruction. */
+		unsigned int ed : 1;  /**< Exception Deferral. */
+		unsigned int : 20;
+	} __attribute__ ((packed));
+} cr_isr_t;
 
 /** CPUID Register 3 */
-union cpuid3 {
+typedef union {
+	uint64_t value;
 	struct {
 		uint8_t number;
@@ -266,8 +266,5 @@
 		uint8_t archrev;
 	} __attribute__ ((packed));
-	uint64_t value;
-};
-
-typedef union cpuid3 cpuid3_t;
+} cpuid3_t;
 
 #endif /* !__ASM__ */
Index: kernel/arch/ia64/include/types.h
===================================================================
--- kernel/arch/ia64/include/types.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/include/types.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -67,5 +67,5 @@
 	unative_t fnc;
 	unative_t gp;
-} fncptr_t;
+} __attribute__((may_alias)) fncptr_t;
 
 #define PRIp "lx"	/**< Format for uintptr_t. */
Index: kernel/arch/ia64/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia64/src/cpu/cpu.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/cpu/cpu.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -54,9 +54,9 @@
 	char vendor[2 * sizeof(uint64_t) + 1];
 	
-	*((uint64_t *) &vendor[0 * sizeof(uint64_t)]) = CPU->arch.cpuid0;
-	*((uint64_t *) &vendor[1 * sizeof(uint64_t)]) = CPU->arch.cpuid1;
+	memcpy(vendor, &CPU->arch.cpuid0, 8);
+	memcpy(vendor + 8, &CPU->arch.cpuid1, 8);
 	vendor[sizeof(vendor) - 1] = 0;
 	
-	switch(m->arch.cpuid3.family) {
+	switch (m->arch.cpuid3.family) {
 	case FAMILY_ITANIUM:
 		family_str = "Itanium";
Index: kernel/arch/ia64/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -47,23 +47,84 @@
 enum {
 	/** Interval between polling in microseconds */
-	POLL_INTERVAL =  10000,  /* 0.01 s */
-
+	POLL_INTERVAL = 10000,  /* 0.01 s */
+	
 	/** Max. number of characters to pull out at a time */
-	POLL_LIMIT    =     30,
-
-	SKI_INIT_CONSOLE  = 20,
-	SKI_GETCHAR       = 21,
-	SKI_PUTCHAR       = 31
+	POLL_LIMIT = 30,
+	
+	SKI_INIT_CONSOLE = 20,
+	SKI_GETCHAR      = 21,
+	SKI_PUTCHAR      = 31
 };
 
 static void ski_putchar(outdev_t *, const wchar_t, bool);
 
-static outdev_operations_t skiout_ops = {
-	.write = ski_putchar
+static outdev_operations_t skidev_ops = {
+	.write = ski_putchar,
+	.redraw = NULL
 };
 
-static outdev_t skiout;            /**< Ski output device. */
-static bool initialized = false;
-static bool kbd_disabled = false;
+static ski_instance_t *instance = NULL;
+
+/** Ask debug console if a key was pressed.
+ *
+ * Use SSC (Simulator System Call) to
+ * get character from debug console.
+ *
+ * This call is non-blocking.
+ *
+ * @return ASCII code of pressed key or 0 if no key pressed.
+ *
+ */
+static wchar_t ski_getchar(void)
+{
+	uint64_t ch;
+	
+	asm volatile (
+		"mov r15 = %1\n"
+		"break 0x80000;;\n"  /* modifies r8 */
+		"mov %0 = r8;;\n"
+		
+		: "=r" (ch)
+		: "i" (SKI_GETCHAR)
+		: "r15", "r8"
+	);
+	
+	return (wchar_t) ch;
+}
+
+/** Ask keyboard if a key was pressed.
+ *
+ * If so, it will repeat and pull up to POLL_LIMIT characters.
+ */
+static void poll_keyboard(ski_instance_t *instance)
+{
+	if (silent)
+		return;
+	
+	int count = POLL_LIMIT;
+	
+	while (count > 0) {
+		wchar_t ch = ski_getchar();
+		
+		if (ch == '\0')
+			break;
+		
+		indev_push_character(instance->srlnin, ch);
+		--count;
+	}
+}
+
+/** Kernel thread for polling keyboard. */
+static void kskipoll(void *arg)
+{
+	ski_instance_t *instance = (ski_instance_t *) arg;
+	
+	while (true) {
+		if (!silent)
+			poll_keyboard(instance);
+		
+		thread_usleep(POLL_INTERVAL);
+	}
+}
 
 /** Initialize debug console
@@ -75,5 +136,5 @@
 static void ski_init(void)
 {
-	if (initialized)
+	if (instance)
 		return;
 	
@@ -86,5 +147,18 @@
 	);
 	
-	initialized = true;
+	instance = malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
+	
+	if (instance) {
+		instance->thread = thread_create(kskipoll, instance, TASK, 0,
+		    "kskipoll", true);
+		
+		if (!instance->thread) {
+			free(instance);
+			instance = NULL;
+			return;
+		}
+		
+		instance->srlnin = NULL;
+	}
 }
 
@@ -124,77 +198,28 @@
 }
 
-void skiout_init(void)
+outdev_t *skiout_init(void)
 {
 	ski_init();
-	
-	outdev_initialize("skiout", &skiout, &skiout_ops);
-	stdout = &skiout;
-	
-	sysinfo_set_item_val("fb", NULL, false);
-}
-
-/** Ask debug console if a key was pressed.
- *
- * Use SSC (Simulator System Call) to
- * get character from debug console.
- *
- * This call is non-blocking.
- *
- * @return ASCII code of pressed key or 0 if no key pressed.
- *
- */
-static wchar_t ski_getchar(void)
-{
-	uint64_t ch;
-	
-	asm volatile (
-		"mov r15 = %1\n"
-		"break 0x80000;;\n"  /* modifies r8 */
-		"mov %0 = r8;;\n"
-		
-		: "=r" (ch)
-		: "i" (SKI_GETCHAR)
-		: "r15", "r8"
-	);
-	
-	return (wchar_t) ch;
-}
-
-/** Ask keyboard if a key was pressed.
- *
- * If so, it will repeat and pull up to POLL_LIMIT characters.
- */
-static void poll_keyboard(ski_instance_t *instance)
-{
-	wchar_t ch;
-	int count;
-
-	if (kbd_disabled)
-		return;
-
-	count = POLL_LIMIT;
-
-	while (count > 0) {
-		ch = ski_getchar();
-
-		if (ch == '\0')
-			break;
-
-		indev_push_character(instance->srlnin, ch);
-		--count;
-	}
-}
-
-/** Kernel thread for polling keyboard. */
-static void kskipoll(void *arg)
-{
-	ski_instance_t *instance = (ski_instance_t *) arg;
-	
-	while (true) {
-		if (!silent)
-			poll_keyboard(instance);
-		
-		thread_usleep(POLL_INTERVAL);
-	}
+	if (!instance)
+		return NULL;
+	
+	outdev_t *skidev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!skidev)
+		return NULL;
+	
+	outdev_initialize("skidev", skidev, &skidev_ops);
+	skidev->data = instance;
+	
+	if (!fb_exported) {
+		/*
+		 * This is the necessary evil until the userspace driver is entirely
+		 * self-sufficient.
+		 */
+		sysinfo_set_item_val("fb", NULL, false);
+		
+		fb_exported = true;
+	}
+	
+	return skidev;
 }
 
@@ -202,20 +227,4 @@
 {
 	ski_init();
-	
-	ski_instance_t *instance =
-	    malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
-	
-	if (instance) {
-		instance->thread = thread_create(kskipoll, instance, TASK, 0,
-		    "kskipoll", true);
-		
-		if (!instance->thread) {
-			free(instance);
-			return NULL;
-		}
-		
-		instance->srlnin = NULL;
-	}
-	
 	return instance;
 }
@@ -233,14 +242,4 @@
 }
 
-void ski_kbd_grab(void)
-{
-	kbd_disabled = false;
-}
-
-void ski_kbd_release(void)
-{
-	kbd_disabled = true;
-}
-
 /** @}
  */
Index: kernel/arch/ia64/src/ia64.c
===================================================================
--- kernel/arch/ia64/src/ia64.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/ia64.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -160,9 +160,13 @@
 	}
 	
-	skiout_init();
+	outdev_t *skidev = skiout_init();
+	if (skidev)
+		stdout_wire(skidev);
 #endif
 	
 #ifdef CONFIG_EGA
-	ega_init(EGA_BASE, EGA_VIDEORAM);
+	outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
+	if (egadev)
+		stdout_wire(egadev);
 #endif
 	
@@ -249,25 +253,5 @@
 unative_t sys_tls_set(unative_t addr)
 {
-        return 0;
-}
-
-/** Acquire console back for kernel
- *
- */
-void arch_grab_console(void)
-{
-#ifdef MACHINE_ski
-	ski_kbd_grab();
-#endif
-}
-
-/** Return console to userspace
- *
- */
-void arch_release_console(void)
-{
-#ifdef MACHINE_ski
-	ski_kbd_release();
-#endif
+	return 0;
 }
 
Index: kernel/arch/ia64/src/ivt.S
===================================================================
--- kernel/arch/ia64/src/ivt.S	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/ivt.S	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -391,5 +391,5 @@
 
     /* 10. call handler */
-    	movl r1 = _hardcoded_load_address
+    	movl r1 = kernel_image_start
     
     	mov b1 = loc2
Index: kernel/arch/ia64/src/mm/as.c
===================================================================
--- kernel/arch/ia64/src/mm/as.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/mm/as.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -55,5 +55,5 @@
 void as_install_arch(as_t *as)
 {
-	region_register rr;
+	region_register_t rr;
 	int i;
 	
@@ -73,7 +73,7 @@
 		rr.map.ps = PAGE_WIDTH;
 		rr_write(i, rr.word);
+		srlz_d();
+		srlz_i();
 	}
-	srlz_d();
-	srlz_i();
 }
 
Index: kernel/arch/ia64/src/mm/page.c
===================================================================
--- kernel/arch/ia64/src/mm/page.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/mm/page.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -63,6 +63,6 @@
 void set_environment(void)
 {
-	region_register rr;
-	pta_register pta;
+	region_register_t rr;
+	pta_register_t pta;
 	int i;
 #ifdef CONFIG_VHPT
@@ -131,5 +131,5 @@
 vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid)
 {
-	region_register rr_save, rr;
+	region_register_t rr_save, rr;
 	size_t vrn;
 	rid_t rid;
@@ -176,5 +176,5 @@
 bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v)
 {
-	region_register rr_save, rr;	
+	region_register_t rr_save, rr;
 	size_t vrn;
 	rid_t rid;
@@ -223,5 +223,5 @@
     int flags)
 {
-	region_register rr_save, rr;	
+	region_register_t rr_save, rr;
 	size_t vrn;
 	rid_t rid;
@@ -257,11 +257,11 @@
 	v->present.ma = (flags & PAGE_CACHEABLE) ?
 	    MA_WRITEBACK : MA_UNCACHEABLE;
-	v->present.a = false;	/* not accessed */
-	v->present.d = false;	/* not dirty */
+	v->present.a = false;  /* not accessed */
+	v->present.d = false;  /* not dirty */
 	v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
 	v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ;
 	v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0; 
 	v->present.ppn = frame >> PPN_SHIFT;
-	v->present.ed = false;	/* exception not deffered */
+	v->present.ed = false;  /* exception not deffered */
 	v->present.ps = PAGE_WIDTH;
 	v->present.key = 0;
Index: kernel/arch/ia64/src/mm/tlb.c
===================================================================
--- kernel/arch/ia64/src/mm/tlb.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/mm/tlb.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64mm	
+/** @addtogroup ia64mm
  * @{
  */
@@ -53,4 +53,6 @@
 #include <interrupt.h>
 
+#define IO_FRAME_BASE 0xFFFFC000000
+
 /** Invalidate all TLB entries. */
 void tlb_invalidate_all(void)
@@ -59,7 +61,7 @@
 	uintptr_t adr;
 	uint32_t count1, count2, stride1, stride2;
-		
+	
 	unsigned int i, j;
-		
+	
 	adr = PAL_PTCE_INFO_BASE();
 	count1 = PAL_PTCE_INFO_COUNT1();
@@ -67,13 +69,12 @@
 	stride1 = PAL_PTCE_INFO_STRIDE1();
 	stride2 = PAL_PTCE_INFO_STRIDE2();
-		
+	
 	ipl = interrupts_disable();
-
+	
 	for (i = 0; i < count1; i++) {
 		for (j = 0; j < count2; j++) {
 			asm volatile (
-				"ptc.e %0 ;;"
-				:
-				: "r" (adr)
+				"ptc.e %[adr] ;;"
+				:: [adr] "r" (adr)
 			);
 			adr += stride2;
@@ -81,17 +82,19 @@
 		adr += stride1;
 	}
-
+	
 	interrupts_restore(ipl);
-
+	
 	srlz_d();
 	srlz_i();
+	
 #ifdef CONFIG_VHPT
 	vhpt_invalidate_all();
-#endif	
+#endif
 }
 
 /** Invalidate entries belonging to an address space.
  *
- * @param asid		Address space identifier.
+ * @param asid Address space identifier.
+ *
  */
 void tlb_invalidate_asid(asid_t asid)
@@ -103,12 +106,12 @@
 void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
 {
-	region_register rr;
+	region_register_t rr;
 	bool restore_rr = false;
 	int b = 0;
 	int c = cnt;
-
+	
 	uintptr_t va;
 	va = page;
-
+	
 	rr.word = rr_read(VA2VRN(va));
 	if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
@@ -117,6 +120,6 @@
 		 * Save the old content of the register and replace the RID.
 		 */
-		region_register rr0;
-
+		region_register_t rr0;
+		
 		rr0 = rr;
 		rr0.map.rid = ASID2RID(asid, VA2VRN(va));
@@ -126,5 +129,5 @@
 	}
 	
-	while(c >>= 1)
+	while (c >>= 1)
 		b++;
 	b >>= 1;
@@ -169,6 +172,12 @@
 		break;
 	}
-	for(; va < (page + cnt * PAGE_SIZE); va += (1 << ps))
-		asm volatile ("ptc.l %0, %1;;" :: "r" (va), "r" (ps << 2));
+	
+	for (; va < (page + cnt * PAGE_SIZE); va += (1 << ps))
+		asm volatile (
+			"ptc.l %[va], %[ps] ;;"
+			:: [va]"r" (va),
+			   [ps] "r" (ps << 2)
+		);
+	
 	srlz_d();
 	srlz_i();
@@ -183,8 +192,9 @@
 /** Insert data into data translation cache.
  *
- * @param va		Virtual page address.
- * @param asid		Address space identifier.
- * @param entry		The rest of TLB entry as required by TLB insertion
- * 			format.
+ * @param va    Virtual page address.
+ * @param asid  Address space identifier.
+ * @param entry The rest of TLB entry as required by TLB insertion
+ *              format.
+ *
  */
 void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
@@ -195,8 +205,8 @@
 /** Insert data into instruction translation cache.
  *
- * @param va		Virtual page address.
- * @param asid		Address space identifier.
- * @param entry		The rest of TLB entry as required by TLB insertion
- * 			format.
+ * @param va    Virtual page address.
+ * @param asid  Address space identifier.
+ * @param entry The rest of TLB entry as required by TLB insertion
+ *              format.
  */
 void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
@@ -207,16 +217,17 @@
 /** Insert data into instruction or data translation cache.
  *
- * @param va		Virtual page address.
- * @param asid		Address space identifier.
- * @param entry		The rest of TLB entry as required by TLB insertion
- * 			format.
- * @param dtc		If true, insert into data translation cache, use
- * 			instruction translation cache otherwise.
+ * @param va    Virtual page address.
+ * @param asid  Address space identifier.
+ * @param entry The rest of TLB entry as required by TLB insertion
+ *              format.
+ * @param dtc   If true, insert into data translation cache, use
+ *              instruction translation cache otherwise.
+ *
  */
 void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc)
 {
-	region_register rr;
+	region_register_t rr;
 	bool restore_rr = false;
-
+	
 	rr.word = rr_read(VA2VRN(va));
 	if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
@@ -225,6 +236,6 @@
 		 * Save the old content of the register and replace the RID.
 		 */
-		region_register rr0;
-
+		region_register_t rr0;
+		
 		rr0 = rr;
 		rr0.map.rid = ASID2RID(asid, VA2VRN(va));
@@ -235,18 +246,20 @@
 	
 	asm volatile (
-		"mov r8 = psr;;\n"
-		"rsm %0;;\n"   			/* PSR_IC_MASK */
-		"srlz.d;;\n"
-		"srlz.i;;\n"
-		"mov cr.ifa = %1\n"		/* va */
-		"mov cr.itir = %2;;\n"		/* entry.word[1] */
-		"cmp.eq p6,p7 = %4,r0;;\n"	/* decide between itc and dtc */
-		"(p6) itc.i %3;;\n"
-		"(p7) itc.d %3;;\n"
-		"mov psr.l = r8;;\n"
-		"srlz.d;;\n"
-		:
-		: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]),
-		    "r" (entry.word[0]), "r" (dtc)
+		"mov r8 = psr ;;\n"
+		"rsm %[mask] ;;\n"                 /* PSR_IC_MASK */
+		"srlz.d ;;\n"
+		"srlz.i ;;\n"
+		"mov cr.ifa = %[va]\n"             /* va */
+		"mov cr.itir = %[word1] ;;\n"      /* entry.word[1] */
+		"cmp.eq p6, p7 = %[dtc], r0 ;;\n"  /* decide between itc and dtc */
+		"(p6) itc.i %[word0] ;;\n"
+		"(p7) itc.d %[word0] ;;\n"
+		"mov psr.l = r8 ;;\n"
+		"srlz.d ;;\n"
+		:: [mask] "i" (PSR_IC_MASK),
+		   [va] "r" (va),
+		   [word0] "r" (entry.word[0]),
+		   [word1] "r" (entry.word[1]),
+		   [dtc] "r" (dtc)
 		: "p6", "p7", "r8"
 	);
@@ -261,12 +274,12 @@
 /** Insert data into instruction translation register.
  *
- * @param va		Virtual page address.
- * @param asid		Address space identifier.
- * @param entry		The rest of TLB entry as required by TLB insertion
- * 			format.
- * @param tr		Translation register.
- */
-void
-itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)
+ * @param va    Virtual page address.
+ * @param asid  Address space identifier.
+ * @param entry The rest of TLB entry as required by TLB insertion
+ *              format.
+ * @param tr    Translation register.
+ *
+ */
+void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)
 {
 	tr_mapping_insert(va, asid, entry, false, tr);
@@ -275,12 +288,12 @@
 /** Insert data into data translation register.
  *
- * @param va		Virtual page address.
- * @param asid		Address space identifier.
- * @param entry		The rest of TLB entry as required by TLB insertion
- * 			format.
- * @param tr		Translation register.
- */
-void
-dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)
+ * @param va    Virtual page address.
+ * @param asid  Address space identifier.
+ * @param entry The rest of TLB entry as required by TLB insertion
+ *              format.
+ * @param tr    Translation register.
+ *
+ */
+void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)
 {
 	tr_mapping_insert(va, asid, entry, true, tr);
@@ -289,19 +302,19 @@
 /** Insert data into instruction or data translation register.
  *
- * @param va		Virtual page address.
- * @param asid		Address space identifier.
- * @param entry		The rest of TLB entry as required by TLB insertion
- * 			format.
- * @param dtr		If true, insert into data translation register, use
- * 			instruction translation register otherwise.
- * @param tr		Translation register.
- */
-void
-tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr,
+ * @param va    Virtual page address.
+ * @param asid  Address space identifier.
+ * @param entry The rest of TLB entry as required by TLB insertion
+ *              format.
+ * @param dtr   If true, insert into data translation register, use
+ *              instruction translation register otherwise.
+ * @param tr    Translation register.
+ *
+ */
+void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr,
     size_t tr)
 {
-	region_register rr;
+	region_register_t rr;
 	bool restore_rr = false;
-
+	
 	rr.word = rr_read(VA2VRN(va));
 	if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
@@ -310,6 +323,6 @@
 		 * Save the old content of the register and replace the RID.
 		 */
-		region_register rr0;
-
+		region_register_t rr0;
+		
 		rr0 = rr;
 		rr0.map.rid = ASID2RID(asid, VA2VRN(va));
@@ -318,20 +331,23 @@
 		srlz_i();
 	}
-
+	
 	asm volatile (
-		"mov r8 = psr;;\n"
-		"rsm %0;;\n"			/* PSR_IC_MASK */
-		"srlz.d;;\n"
-		"srlz.i;;\n"
-		"mov cr.ifa = %1\n"        	/* va */		 
-		"mov cr.itir = %2;;\n"		/* entry.word[1] */ 
-		"cmp.eq p6,p7 = %5,r0;;\n"	/* decide between itr and dtr */
-		"(p6) itr.i itr[%4] = %3;;\n"
-		"(p7) itr.d dtr[%4] = %3;;\n"
-		"mov psr.l = r8;;\n"
-		"srlz.d;;\n"
-		:
-		: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]),
-		    "r" (entry.word[0]), "r" (tr), "r" (dtr)
+		"mov r8 = psr ;;\n"
+		"rsm %[mask] ;;\n"                       /* PSR_IC_MASK */
+		"srlz.d ;;\n"
+		"srlz.i ;;\n"
+		"mov cr.ifa = %[va]\n"                   /* va */
+		"mov cr.itir = %[word1] ;;\n"            /* entry.word[1] */
+		"cmp.eq p6, p7 = %[dtr], r0 ;;\n"        /* decide between itr and dtr */
+		"(p6) itr.i itr[%[tr]] = %[word0] ;;\n"
+		"(p7) itr.d dtr[%[tr]] = %[word0] ;;\n"
+		"mov psr.l = r8 ;;\n"
+		"srlz.d ;;\n"
+		:: [mask] "i" (PSR_IC_MASK),
+		   [va] "r" (va),
+		   [word1] "r" (entry.word[1]),
+		   [word0] "r" (entry.word[0]),
+		   [tr] "r" (tr),
+		   [dtr] "r" (dtr)
 		: "p6", "p7", "r8"
 	);
@@ -346,12 +362,12 @@
 /** Insert data into DTLB.
  *
- * @param page		Virtual page address including VRN bits.
- * @param frame		Physical frame address.
- * @param dtr		If true, insert into data translation register, use data
- * 			translation cache otherwise.
- * @param tr		Translation register if dtr is true, ignored otherwise.
- */
-void
-dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr,
+ * @param page  Virtual page address including VRN bits.
+ * @param frame Physical frame address.
+ * @param dtr   If true, insert into data translation register, use data
+ *              translation cache otherwise.
+ * @param tr    Translation register if dtr is true, ignored otherwise.
+ *
+ */
+void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr,
     size_t tr)
 {
@@ -361,8 +377,8 @@
 	entry.word[1] = 0;
 	
-	entry.p = true;			/* present */
+	entry.p = true;           /* present */
 	entry.ma = MA_WRITEBACK;
-	entry.a = true;			/* already accessed */
-	entry.d = true;			/* already dirty */
+	entry.a = true;           /* already accessed */
+	entry.d = true;           /* already dirty */
 	entry.pl = PL_KERNEL;
 	entry.ar = AR_READ | AR_WRITE;
@@ -380,10 +396,15 @@
  * Purge DTR entries used by the kernel.
  *
- * @param page		Virtual page address including VRN bits.
- * @param width		Width of the purge in bits.
+ * @param page  Virtual page address including VRN bits.
+ * @param width Width of the purge in bits.
+ *
  */
 void dtr_purge(uintptr_t page, size_t width)
 {
-	asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width << 2));
+	asm volatile (
+		"ptr.d %[page], %[width]\n"
+		:: [page] "r" (page),
+		   [width] "r" (width << 2)
+	);
 }
 
@@ -391,10 +412,11 @@
 /** Copy content of PTE into data translation cache.
  *
- * @param t		PTE.
+ * @param t PTE.
+ *
  */
 void dtc_pte_copy(pte_t *t)
 {
 	tlb_entry_t entry;
-
+	
 	entry.word[0] = 0;
 	entry.word[1] = 0;
@@ -410,17 +432,19 @@
 	
 	dtc_mapping_insert(t->page, t->as->asid, entry);
+	
 #ifdef CONFIG_VHPT
 	vhpt_mapping_insert(t->page, t->as->asid, entry);
-#endif	
+#endif
 }
 
 /** Copy content of PTE into instruction translation cache.
  *
- * @param t		PTE.
+ * @param t PTE.
+ *
  */
 void itc_pte_copy(pte_t *t)
 {
 	tlb_entry_t entry;
-
+	
 	entry.word[0] = 0;
 	entry.word[1] = 0;
@@ -437,25 +461,27 @@
 	
 	itc_mapping_insert(t->page, t->as->asid, entry);
+	
 #ifdef CONFIG_VHPT
 	vhpt_mapping_insert(t->page, t->as->asid, entry);
-#endif	
+#endif
 }
 
 /** Instruction TLB fault handler for faults with VHPT turned off.
  *
- * @param vector		Interruption vector.
- * @param istate		Structure with saved interruption state.
+ * @param vector Interruption vector.
+ * @param istate Structure with saved interruption state.
+ *
  */
 void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate)
 {
-	region_register rr;
+	region_register_t rr;
 	rid_t rid;
 	uintptr_t va;
 	pte_t *t;
 	
-	va = istate->cr_ifa;	/* faulting address */
+	va = istate->cr_ifa; /* faulting address */
 	rr.word = rr_read(VA2VRN(va));
 	rid = rr.map.rid;
-
+	
 	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va);
@@ -473,5 +499,5 @@
 		page_table_unlock(AS, true);
 		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate,"Page fault at %p.",va);
+			fault_if_from_uspace(istate, "Page fault at %p.", va);
 			panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
 			    istate->cr_iip);
@@ -488,14 +514,13 @@
 }
 
-#define IO_FRAME_BASE 0xFFFFC000000
-
 /**
  * There is special handling of memory mapped legacy io, because of 4KB sized
  * access for userspace.
  *
- * @param va		Virtual address of page fault.
- * @param istate	Structure with saved interruption state.
- *
- * @return		One on success, zero on failure.
+ * @param va     Virtual address of page fault.
+ * @param istate Structure with saved interruption state.
+ *
+ * @return One on success, zero on failure.
+ *
  */
 static int try_memmap_io_insertion(uintptr_t va, istate_t *istate)
@@ -505,27 +530,27 @@
 			uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >>
 			    USPACE_IO_PAGE_WIDTH;
-
+			
 			if (is_io_page_accessible(io_page)) {
 				uint64_t page, frame;
-
+				
 				page = IO_OFFSET +
 				    (1 << USPACE_IO_PAGE_WIDTH) * io_page;
 				frame = IO_FRAME_BASE +
 				    (1 << USPACE_IO_PAGE_WIDTH) * io_page;
-
+				
 				tlb_entry_t entry;
-	
+				
 				entry.word[0] = 0;
 				entry.word[1] = 0;
-	
-				entry.p = true;		/* present */
-				entry.ma = MA_UNCACHEABLE;		
-				entry.a = true;		/* already accessed */
-				entry.d = true;		/* already dirty */
+				
+				entry.p = true;             /* present */
+				entry.ma = MA_UNCACHEABLE;
+				entry.a = true;             /* already accessed */
+				entry.d = true;             /* already dirty */
 				entry.pl = PL_USER;
 				entry.ar = AR_READ | AR_WRITE;
 				entry.ppn = frame >> PPN_SHIFT;
 				entry.ps = USPACE_IO_PAGE_WIDTH;
-	
+				
 				dtc_mapping_insert(page, TASK->as->asid, entry);
 				return 1;
@@ -536,5 +561,5 @@
 		}
 	}
-		
+	
 	return 0;
 }
@@ -542,17 +567,27 @@
 /** Data TLB fault handler for faults with VHPT turned off.
  *
- * @param vector	Interruption vector.
- * @param istate	Structure with saved interruption state.
+ * @param vector Interruption vector.
+ * @param istate Structure with saved interruption state.
+ *
  */
 void alternate_data_tlb_fault(uint64_t vector, istate_t *istate)
 {
-	region_register rr;
-	rid_t rid;
-	uintptr_t va;
-	pte_t *t;
-	
-	va = istate->cr_ifa;	/* faulting address */
-	rr.word = rr_read(VA2VRN(va));
-	rid = rr.map.rid;
+	if (istate->cr_isr.sp) {
+		/* Speculative load. Deffer the exception
+		   until a more clever approach can be used.
+		   
+		   Currently if we try to find the mapping
+		   for the speculative load while in the kernel,
+		   we might introduce a livelock because of
+		   the possibly invalid values of the address. */
+		istate->cr_ipsr.ed = true;
+		return;
+	}
+	
+	uintptr_t va = istate->cr_ifa;  /* faulting address */
+	
+	region_register_t rr;
+	rr.word = rr_read(VA2VRN(va));
+	rid_t rid = rr.map.rid;
 	if (RID2ASID(rid) == ASID_KERNEL) {
 		if (VA2VRN(va) == VRN_KERNEL) {
@@ -565,13 +600,14 @@
 		}
 	}
-
+	
+	
 	page_table_lock(AS, true);
-	t = page_mapping_find(AS, va);
-	if (t) {
+	pte_t *entry = page_mapping_find(AS, va);
+	if (entry) {
 		/*
 		 * The mapping was found in the software page hash table.
 		 * Insert it into data translation cache.
 		 */
-		dtc_pte_copy(t);
+		dtc_pte_copy(entry);
 		page_table_unlock(AS, true);
 	} else {
@@ -579,10 +615,11 @@
 		if (try_memmap_io_insertion(va, istate))
 			return;
-		/*
-		 * Forward the page fault to the address space page fault 
+		
+		/*
+		 * Forward the page fault to the address space page fault
 		 * handler.
 		 */
 		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate,"Page fault at %p.",va);
+			fault_if_from_uspace(istate, "Page fault at %p.", va);
 			panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
 			    istate->cr_iip);
@@ -595,32 +632,34 @@
  * This fault should not occur.
  *
- * @param vector	Interruption vector.
- * @param istate	Structure with saved interruption state.
+ * @param vector Interruption vector.
+ * @param istate Structure with saved interruption state.
+ *
  */
 void data_nested_tlb_fault(uint64_t vector, istate_t *istate)
 {
-	panic("%s.", __func__);
+	ASSERT(false);
 }
 
 /** Data Dirty bit fault handler.
  *
- * @param vector	Interruption vector.
- * @param istate	Structure with saved interruption state.
+ * @param vector Interruption vector.
+ * @param istate Structure with saved interruption state.
+ *
  */
 void data_dirty_bit_fault(uint64_t vector, istate_t *istate)
 {
-	region_register rr;
+	region_register_t rr;
 	rid_t rid;
 	uintptr_t va;
 	pte_t *t;
 	
-	va = istate->cr_ifa;	/* faulting address */
+	va = istate->cr_ifa;  /* faulting address */
 	rr.word = rr_read(VA2VRN(va));
 	rid = rr.map.rid;
-
+	
 	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va);
-	ASSERT(t && t->p);
-	if (t && t->p && t->w) {
+	ASSERT((t) && (t->p));
+	if ((t) && (t->p) && (t->w)) {
 		/*
 		 * Update the Dirty bit in page tables and reinsert
@@ -631,5 +670,5 @@
 	} else {
 		if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
-			fault_if_from_uspace(istate,"Page fault at %p.",va);
+			fault_if_from_uspace(istate, "Page fault at %p.", va);
 			panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
 			    istate->cr_iip);
@@ -641,22 +680,23 @@
 /** Instruction access bit fault handler.
  *
- * @param vector	Interruption vector.
- * @param istate	Structure with saved interruption state.
+ * @param vector Interruption vector.
+ * @param istate Structure with saved interruption state.
+ *
  */
 void instruction_access_bit_fault(uint64_t vector, istate_t *istate)
 {
-	region_register rr;
+	region_register_t rr;
 	rid_t rid;
 	uintptr_t va;
-	pte_t *t;	
-
-	va = istate->cr_ifa;	/* faulting address */
+	pte_t *t;
+	
+	va = istate->cr_ifa;  /* faulting address */
 	rr.word = rr_read(VA2VRN(va));
 	rid = rr.map.rid;
-
+	
 	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va);
-	ASSERT(t && t->p);
-	if (t && t->p && t->x) {
+	ASSERT((t) && (t->p));
+	if ((t) && (t->p) && (t->x)) {
 		/*
 		 * Update the Accessed bit in page tables and reinsert
@@ -679,20 +719,21 @@
  * @param vector Interruption vector.
  * @param istate Structure with saved interruption state.
+ *
  */
 void data_access_bit_fault(uint64_t vector, istate_t *istate)
 {
-	region_register rr;
+	region_register_t rr;
 	rid_t rid;
 	uintptr_t va;
 	pte_t *t;
-
-	va = istate->cr_ifa;	/* faulting address */
+	
+	va = istate->cr_ifa;  /* faulting address */
 	rr.word = rr_read(VA2VRN(va));
 	rid = rr.map.rid;
-
+	
 	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va);
-	ASSERT(t && t->p);
-	if (t && t->p) {
+	ASSERT((t) && (t->p));
+	if ((t) && (t->p)) {
 		/*
 		 * Update the Accessed bit in page tables and reinsert
@@ -715,16 +756,17 @@
  * @param vector Interruption vector.
  * @param istate Structure with saved interruption state.
+ *
  */
 void data_access_rights_fault(uint64_t vector, istate_t *istate)
 {
-	region_register rr;
+	region_register_t rr;
 	rid_t rid;
 	uintptr_t va;
 	pte_t *t;
-
-	va = istate->cr_ifa;	/* faulting address */
+	
+	va = istate->cr_ifa;  /* faulting address */
 	rr.word = rr_read(VA2VRN(va));
 	rid = rr.map.rid;
-
+	
 	/*
 	 * Assume a write to a read-only page.
@@ -732,5 +774,5 @@
 	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va);
-	ASSERT(t && t->p);
+	ASSERT((t) && (t->p));
 	ASSERT(!t->w);
 	if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
@@ -746,16 +788,17 @@
  * @param vector Interruption vector.
  * @param istate Structure with saved interruption state.
+ *
  */
 void page_not_present(uint64_t vector, istate_t *istate)
 {
-	region_register rr;
+	region_register_t rr;
 	rid_t rid;
 	uintptr_t va;
 	pte_t *t;
 	
-	va = istate->cr_ifa;	/* faulting address */
+	va = istate->cr_ifa;  /* faulting address */
 	rr.word = rr_read(VA2VRN(va));
 	rid = rr.map.rid;
-
+	
 	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va);
Index: kernel/arch/ia64/src/mm/vhpt.c
===================================================================
--- kernel/arch/ia64/src/mm/vhpt.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/mm/vhpt.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64mm	
+/** @addtogroup ia64mm
  * @{
  */
@@ -44,5 +44,5 @@
 	vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH,
 	    FRAME_KA | FRAME_ATOMIC);
-	if (!vhpt_base) 
+	if (!vhpt_base)
 		panic("Kernel configured with VHPT but no memory for table.");
 	vhpt_invalidate_all();
@@ -53,15 +53,14 @@
 void vhpt_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
 {
-	region_register rr_save, rr;
+	region_register_t rr_save, rr;
 	size_t vrn;
 	rid_t rid;
 	uint64_t tag;
-
+	
 	vhpt_entry_t *ventry;
-
-
+	
 	vrn = va >> VRN_SHIFT;
 	rid = ASID2RID(asid, vrn);
-																												
+	
 	rr_save.word = rr_read(vrn);
 	rr.word = rr_save.word;
@@ -75,5 +74,5 @@
 	srlz_i();
 	srlz_d();
-
+	
 	ventry->word[0] = entry.word[0];
 	ventry->word[1] = entry.word[1];
Index: kernel/arch/ia64/src/start.S
===================================================================
--- kernel/arch/ia64/src/start.S	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ia64/src/start.S	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -32,13 +32,13 @@
 #include <mm/asid.h>
 
-#define RR_MASK (0xFFFFFFFF00000002)
-#define RID_SHIFT	8
-#define PS_SHIFT	2
-
-#define KERNEL_TRANSLATION_I	0x0010000000000661
-#define KERNEL_TRANSLATION_D	0x0010000000000661
-#define KERNEL_TRANSLATION_VIO	0x0010000000000671
-#define KERNEL_TRANSLATION_IO	0x00100FFFFC000671 
-#define KERNEL_TRANSLATION_FW	0x00100000F0000671 
+#define RR_MASK    (0xFFFFFFFF00000002)
+#define RID_SHIFT  8
+#define PS_SHIFT   2
+
+#define KERNEL_TRANSLATION_I    0x0010000000000661
+#define KERNEL_TRANSLATION_D    0x0010000000000661
+#define KERNEL_TRANSLATION_VIO  0x0010000000000671
+#define KERNEL_TRANSLATION_IO   0x00100FFFFC000671
+#define KERNEL_TRANSLATION_FW   0x00100000F0000671
 
 .section K_TEXT_START, "ax"
@@ -49,8 +49,8 @@
 kernel_image_start:
 	.auto
-
+	
 #ifdef CONFIG_SMP
 	# Identify self(CPU) in OS structures by ID / EID
-
+	
 	mov r9 = cr64
 	mov r10 = 1
@@ -62,34 +62,34 @@
 	st1 [r8] = r10
 #endif
-
+	
 	mov psr.l = r0
 	srlz.i
 	srlz.d
-
+	
 	# Fill TR.i and TR.d using Region Register #VRN_KERNEL
-
+	
 	movl r8 = (VRN_KERNEL << VRN_SHIFT)
 	mov r9 = rr[r8]
-
+	
 	movl r10 = (RR_MASK)
 	and r9 = r10, r9
 	movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT))
-	or  r9 = r10, r9
-
+	or r9 = r10, r9
+	
 	mov rr[r8] = r9
-
+	
 	movl r8 = (VRN_KERNEL << VRN_SHIFT)
 	mov cr.ifa = r8
-
+	
 	mov r11 = cr.itir
 	movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT)
 	or r10 = r10, r11
 	mov cr.itir = r10
-
+	
 	movl r10 = (KERNEL_TRANSLATION_I)
 	itr.i itr[r0] = r10
 	movl r10 = (KERNEL_TRANSLATION_D)
 	itr.d dtr[r0] = r10
-
+	
 	movl r7 = 1
 	movl r8 = (VRN_KERNEL << VRN_SHIFT) | VIO_OFFSET
@@ -97,5 +97,5 @@
 	movl r10 = (KERNEL_TRANSLATION_VIO)
 	itr.d dtr[r7] = r10
-
+	
 	mov r11 = cr.itir
 	movl r10 = ~0xfc
@@ -104,5 +104,5 @@
 	or r10 = r10, r11
 	mov cr.itir = r10
-
+	
 	movl r7 = 2
 	movl r8 = (VRN_KERNEL << VRN_SHIFT) | IO_OFFSET
@@ -110,7 +110,7 @@
 	movl r10 = (KERNEL_TRANSLATION_IO)
 	itr.d dtr[r7] = r10
-
-	# Setup mapping for fimware arrea (also SAPIC)
-
+	
+	# Setup mapping for firmware area (also SAPIC)
+	
 	mov r11 = cr.itir
 	movl r10 = ~0xfc
@@ -119,5 +119,5 @@
 	or r10 = r10, r11
 	mov cr.itir = r10
-
+	
 	movl r7 = 3
 	movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET
@@ -125,10 +125,17 @@
 	movl r10 = (KERNEL_TRANSLATION_FW)
 	itr.d dtr[r7] = r10
-
+	
+	# Initialize DSR
+	
+	movl r10 = (DCR_DP_MASK | DCR_DK_MASK | DCR_DX_MASK | DCR_DR_MASK | DCR_DA_MASK | DCR_DD_MASK | DCR_LC_MASK)
+	mov r9 = cr.dcr
+	or r10 = r10, r9
+	mov cr.dcr = r10
+	
 	# Initialize PSR
-
+	
 	movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK)  /* Enable paging */
 	mov r9 = psr
-
+	
 	or r10 = r10, r9
 	mov cr.ipsr = r10
@@ -138,7 +145,7 @@
 	srlz.d
 	srlz.i
-
+	
 	.explicit
-
+	
 	/*
 	 * Return From Interrupt is the only way to
@@ -147,15 +154,14 @@
 	rfi ;;
 
-
 .global paging_start
 paging_start:
-
+	
 	/*
 	 * Now we are paging.
 	 */
-
+	
 	# Switch to register bank 1
 	bsw.1
-
+	
 #ifdef CONFIG_SMP
 	# Am I BSP or AP?
@@ -164,6 +170,6 @@
 	cmp.eq p3, p2 = r20, r0 ;;
 #else
-	cmp.eq p3, p2 = r0, r0 ;;	/* you are BSP */
-#endif	/* CONFIG_SMP */
+	cmp.eq p3, p2 = r0, r0 ;;  /* you are BSP */
+#endif  /* CONFIG_SMP */
 	
 	# Initialize register stack
@@ -172,47 +178,38 @@
 	mov ar.bspstore = r8
 	loadrs
-
+	
 	# Initialize memory stack to some sane value
 	movl r12 = stack0 ;;
-	add r12 = -16, r12	/* allocate a scratch area on the stack */
-
+	add r12 = -16, r12  /* allocate a scratch area on the stack */
+	
 	# Initialize gp (Global Pointer) register
-	movl r20 = (VRN_KERNEL << VRN_SHIFT);;
-	or r20 = r20,r1;;
-	movl r1 = _hardcoded_load_address
+	movl r20 = (VRN_KERNEL << VRN_SHIFT) ;;
+	or r20 = r20, r1 ;;
+	movl r1 = kernel_image_start
 	
 	/*
-	 * Initialize hardcoded_* variables. Do only BSP
+	 * Initialize bootinfo on BSP.
 	 */
-(p3)	movl r14 = _hardcoded_ktext_size
-(p3)	movl r15 = _hardcoded_kdata_size
-(p3)	movl r16 = _hardcoded_load_address ;;
-(p3)	addl r17 = @gprel(hardcoded_ktext_size), gp
-(p3)	addl r18 = @gprel(hardcoded_kdata_size), gp
-(p3)	addl r19 = @gprel(hardcoded_load_address), gp
-(p3)	addl r21 = @gprel(bootinfo), gp
-	;;
-(p3)	st8 [r17] = r14
-(p3)	st8 [r18] = r15
-(p3)	st8 [r19] = r16
+(p3)	addl r21 = @gprel(bootinfo), gp ;;
 (p3)	st8 [r21] = r20
-
+	
 	ssm (1 << 19) ;; /* Disable f32 - f127 */
 	srlz.i
 	srlz.d ;;
-
+	
 #ifdef CONFIG_SMP
 (p2)	movl r18 = main_ap ;;
-(p2)   	mov b1 = r18 ;;
+(p2)	mov b1 = r18 ;;
 (p2)	br.call.sptk.many b0 = b1
-
+	
 	# Mark that BSP is on
+	
 	mov r20 = 1 ;;
 	movl r21 = bsp_started ;;
 	st8 [r21] = r20 ;;
 #endif
-
+	
 	br.call.sptk.many b0 = arch_pre_main
-
+	
 	movl r18 = main_bsp ;;
 	mov b1 = r18 ;;
@@ -227,7 +224,7 @@
 kernel_image_ap_start:
 	.auto
-
+	
 	# Identify self(CPU) in OS structures by ID / EID
-
+	
 	mov r9 = cr64
 	mov r10 = 1
@@ -240,18 +237,18 @@
 	
 	# Wait for wakeup synchro signal (#3 in cpu_by_id_eid_list)
-	
+
 kernel_image_ap_start_loop:
 	movl r11 = kernel_image_ap_start_loop
 	and r11 = r11, r12
-   	mov b1 = r11 
-
-	ld1 r20 = [r8] ;;
-	movl r21 = 3 ;;
-	cmp.eq p2, p3 = r20, r21 ;;
+	mov b1 = r11
+	
+	ld1 r20 = [r8]
+	movl r21 = 3
+	cmp.eq p2, p3 = r20, r21
 (p3)	br.call.sptk.many b0 = b1
-
+	
 	movl r11 = kernel_image_start
 	and r11 = r11, r12
-	mov b1 = r11 
+	mov b1 = r11
 	br.call.sptk.many b0 = b1
 
@@ -259,10 +256,10 @@
 .global bsp_started
 bsp_started:
-.space 8
+	.space 8
 
 .align 4096
 .global cpu_by_id_eid_list
 cpu_by_id_eid_list:
-.space 65536
-
-#endif	/* CONFIG_SMP */
+	.space 65536
+
+#endif  /* CONFIG_SMP */
Index: kernel/arch/mips32/Makefile.inc
===================================================================
--- kernel/arch/mips32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/mips32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -33,5 +33,5 @@
 BFD = binary
 TARGET = mipsel-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32
 
 GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3
@@ -48,5 +48,5 @@
 ifeq ($(MACHINE),bgxemul)
 	BFD_NAME = elf32-tradbigmips
-	TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips
+	TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32eb
 	TARGET = mips-linux-gnu
 	ENDIANESS = BE
Index: rnel/arch/mips32/include/arg.h
===================================================================
--- kernel/arch/mips32/include/arg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,60 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup mips32	
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_mips32_ARG_H_
-#define KERN_mips32_ARG_H_
-
-#include <arch/types.h>
-
-/**
- * va_arg macro for MIPS32 - problem is that 64 bit values must be aligned on an 8-byte boundary (32bit values not)
- * To satisfy this, paddings must be sometimes inserted. 
- */
-
-typedef uintptr_t va_list;
-
-#define va_start(ap, lst) \
-	((ap) = (va_list)&(lst) + sizeof(lst))
-
-#define va_arg(ap, type)	\
-	(((type *)((ap) = (va_list)( (sizeof(type) <= 4) ? ((uintptr_t)((ap) + 2*4 - 1) & (~3)) : ((uintptr_t)((ap) + 2*8 -1) & (~7)) )))[-1])
-
-#define va_copy(dst,src) ((dst)=(src))
-
-#define va_end(ap)
-
-#endif
-
-/** @}
- */
Index: kernel/arch/mips32/include/mm/page.h
===================================================================
--- kernel/arch/mips32/include/mm/page.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/mips32/include/mm/page.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -141,5 +141,5 @@
 #include <arch/exception.h>
 
-static inline int get_pt_flags(pte_t *pt, size_t i)
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/mips32/include/mm/tlb.h
===================================================================
--- kernel/arch/mips32/include/mm/tlb.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/mips32/include/mm/tlb.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -59,5 +59,5 @@
 typedef union {
 	struct {
-#ifdef BIG_ENDIAN
+#ifdef __BE__
 		unsigned : 2;       /* zero */
 		unsigned pfn : 24;  /* frame number */
@@ -80,5 +80,5 @@
 typedef union {
 	struct {
-#ifdef BIG_ENDIAN
+#ifdef __BE__
 		unsigned vpn2 : 19;
 		unsigned : 5;
@@ -95,5 +95,5 @@
 typedef union {
 	struct {
-#ifdef BIG_ENDIAN
+#ifdef __BE__
 		unsigned : 7;
 		unsigned mask : 12;
@@ -110,5 +110,5 @@
 typedef union {
 	struct {
-#ifdef BIG_ENDIAN
+#ifdef __BE__
 		unsigned p : 1;
 		unsigned : 27;
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/mips32/src/mips32.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -144,10 +144,15 @@
 		.visual = VISUAL_RGB_8_8_8,
 	};
-	fb_init(&gxemul_prop);
-#else
+	
+	outdev_t *fbdev = fb_init(&gxemul_prop);
+	if (fbdev)
+		stdout_wire(fbdev);
+#endif
+
 #ifdef CONFIG_MIPS_PRN
-	dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
-#endif /* CONFIG_MIPS_PRN */
-#endif /* CONFIG_FB */
+	outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
+	if (dsrlndev)
+		stdout_wire(dsrlndev);
+#endif
 }
 
@@ -252,18 +257,4 @@
 }
 
-void arch_grab_console(void)
-{
-#ifdef CONFIG_FB
-	fb_redraw();
-#endif
-}
-
-/** Return console to userspace
- *
- */
-void arch_release_console(void)
-{
-}
-
 /** @}
  */
Index: kernel/arch/ppc32/Makefile.inc
===================================================================
--- kernel/arch/ppc32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ppc32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -34,5 +34,5 @@
 BFD = binary
 TARGET = ppc-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc32
 
 GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
Index: rnel/arch/ppc32/include/arg.h
===================================================================
--- kernel/arch/ppc32/include/arg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright (c) 2005 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 ppc32	
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_ppc32_ARG_H_
-#define KERN_ppc32_ARG_H_
-
-#include <stdarg.h>
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ppc32/include/asm/regname.h
===================================================================
--- kernel/arch/ppc32/include/asm/regname.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ppc32/include/asm/regname.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ppc32/include/boot/boot.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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/include/mm/page.h
===================================================================
--- kernel/arch/ppc32/include/mm/page.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ppc32/include/mm/page.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -131,5 +131,5 @@
 #include <arch/interrupt.h>
 
-static inline int get_pt_flags(pte_t *pt, size_t i)
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/ppc32/src/mm/tlb.c
===================================================================
--- kernel/arch/ppc32/src/mm/tlb.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ppc32/src/mm/tlb.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/ppc32/src/ppc32.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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,78 @@
 	/* 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,
+		};
+		
+		outdev_t *fbdev = fb_init(&fb_prop);
+		if (fbdev)
+			stdout_wire(fbdev);
+	}
+	
+	return true;
+}
+
 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 +175,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 +212,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);
 }
 
@@ -180,21 +237,4 @@
 }
 
-/** Acquire console back for kernel
- *
- */
-void arch_grab_console(void)
-{
-#ifdef CONFIG_FB
-	fb_redraw();
-#endif
-}
-
-/** Return console to userspace
- *
- */
-void arch_release_console(void)
-{
-}
-
 /** Construct function pointer
  *
Index: rnel/arch/sparc64/include/arg.h
===================================================================
--- kernel/arch/sparc64/include/arg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup sparc64	
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_sparc64_ARG_H_
-#define KERN_sparc64_ARG_H_
-
-#include <stdarg.h>
-
-#endif
-
-/** @}
- */
Index: kernel/arch/sparc64/include/drivers/fhc.h
===================================================================
--- kernel/arch/sparc64/include/drivers/fhc.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/include/drivers/fhc.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
Index: kernel/arch/sparc64/include/drivers/scr.h
===================================================================
--- kernel/arch/sparc64/include/drivers/scr.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/include/drivers/scr.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -50,5 +50,4 @@
 
 extern void scr_init(ofw_tree_node_t *node);
-extern void scr_redraw(void);
 
 #endif
Index: kernel/arch/sparc64/include/drivers/sgcn.h
===================================================================
--- kernel/arch/sparc64/include/drivers/sgcn.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/include/drivers/sgcn.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -39,21 +39,22 @@
 #include <console/chardev.h>
 #include <proc/thread.h>
+#include <synch/spinlock.h>
 
 /* number of bytes in the TOC magic, including the NULL-terminator */
-#define TOC_MAGIC_BYTES		8
+#define TOC_MAGIC_BYTES  8
 
 /* number of bytes in the TOC key, including the NULL-terminator */
-#define TOC_KEY_SIZE		8
+#define TOC_KEY_SIZE  8
 
 /* maximum number of entries in the SRAM table of contents */
-#define MAX_TOC_ENTRIES		32
+#define MAX_TOC_ENTRIES  32
 
 /* number of bytes in the SGCN buffer magic, including the NULL-terminator */
-#define SGCN_MAGIC_BYTES	4
+#define SGCN_MAGIC_BYTES  4
 
 /**
  * Entry in the SRAM table of contents. Describes one segment of the SRAM
  * which serves a particular purpose (e.g. OBP serial console, Solaris serial
- * console, Solaris mailbox,...). 
+ * console, Solaris mailbox,...).
  */
 typedef struct {
@@ -84,5 +85,5 @@
 /**
  * SGCN buffer header. It is placed at the very beginning of the SGCN
- * buffer. 
+ * buffer.
  */
 typedef struct {
@@ -104,5 +105,5 @@
 	/** offset within the SGCN buffer of the input buffer write pointer */
 	uint32_t in_wrptr;
-
+	
 	/** offset within the SGCN buffer of the output buffer start */
 	uint32_t out_begin;
@@ -119,13 +120,29 @@
 
 typedef struct {
+	/** Starting address of SRAM */
+	uintptr_t sram_begin;
+	
+	/** Starting address of the SGCN buffer */
+	uintptr_t buffer_begin;
+	
+	/**
+	 * Ensure that writing to the buffer and consequent
+	 * update of the write pointer are one atomic operation.
+	 */
+	SPINLOCK_DECLARE(output_lock);
+	
+	/**
+	 * Prevent the input buffer read/write pointers from
+	 * getting to inconsistent state.
+	 */
+	SPINLOCK_DECLARE(input_lock);
+	
 	thread_t *thread;
 	indev_t *srlnin;
 } sgcn_instance_t;
 
-extern void sgcn_grab(void);
-extern void sgcn_release(void);
 extern sgcn_instance_t *sgcnin_init(void);
 extern void sgcnin_wire(sgcn_instance_t *, indev_t *);
-extern void sgcnout_init(void);
+extern outdev_t *sgcnout_init(void);
 
 #endif
Index: kernel/arch/sparc64/src/console.c
===================================================================
--- kernel/arch/sparc64/src/console.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/src/console.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -103,6 +103,9 @@
 	}
 #endif
+	
 #ifdef CONFIG_SGCN_PRN
-	sgcnout_init();
+	outdev_t *sgcndev = sgcnout_init();
+	if (sgcndev)
+		stdout_wire(sgcndev);
 #endif
 }
@@ -131,29 +134,4 @@
 }
 
-
-/** Acquire console back for kernel
- *
- */
-void arch_grab_console(void)
-{
-#ifdef CONFIG_FB
-	scr_redraw();
-#endif
-	
-#ifdef CONFIG_SGCN_KBD
-	sgcn_grab();
-#endif
-}
-
-/** Return console to userspace
- *
- */
-void arch_release_console(void)
-{
-#ifdef CONFIG_SGCN_KBD
-	sgcn_release();
-#endif
-}
-
 /** @}
  */
Index: kernel/arch/sparc64/src/drivers/fhc.c
===================================================================
--- kernel/arch/sparc64/src/drivers/fhc.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/src/drivers/fhc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/src/drivers/kbd.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/src/drivers/pci.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/src/drivers/scr.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -35,6 +35,11 @@
 #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>
+#include <console/chardev.h>
+#include <console/console.h>
 #include <arch/types.h>
 #include <string.h>
@@ -235,12 +240,10 @@
 		.visual = visual,
 	};
-	fb_init(&props);
+	
+	outdev_t *fbdev = fb_init(&props);
+	if (fbdev)
+		stdout_wire(fbdev);
 }
 
-void scr_redraw(void)
-{
-	fb_redraw();
-}
-
 /** @}
  */
Index: kernel/arch/sparc64/src/drivers/sgcn.c
===================================================================
--- kernel/arch/sparc64/src/drivers/sgcn.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/arch/sparc64/src/drivers/sgcn.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -49,5 +49,5 @@
 #include <synch/spinlock.h>
 
-#define POLL_INTERVAL		10000
+#define POLL_INTERVAL  10000
 
 /*
@@ -57,14 +57,14 @@
  * not sure whether this value is valid generally. 
  */
-#define SBBC_START		0x63000000000
+#define SBBC_START  0x63000000000
 
 /* offset of SRAM within the SBBC memory */
-#define SBBC_SRAM_OFFSET	0x900000
+#define SBBC_SRAM_OFFSET  0x900000
 
 /* size (in bytes) of the physical memory area which will be mapped */
-#define MAPPED_AREA_SIZE	(128 * 1024)
+#define MAPPED_AREA_SIZE  (128 * 1024)
 
 /* magic string contained at the beginning of SRAM */
-#define SRAM_TOC_MAGIC		"TOCSRAM"
+#define SRAM_TOC_MAGIC  "TOCSRAM"
 
 /*
@@ -78,8 +78,8 @@
  * Therefore HelenOS needs to make no such arrangements any more.
  */
-#define CONSOLE_KEY		"OBPCONS"
+#define CONSOLE_KEY  "OBPCONS"
 
 /* magic string contained at the beginning of the console buffer */
-#define SGCN_BUFFER_MAGIC	"CON"
+#define SGCN_BUFFER_MAGIC  "CON"
 
 /*
@@ -87,8 +87,8 @@
  * offset from the SRAM beginning.
  */
-#define SRAM(type, offset)	((type *) (sram_begin + (offset)))
+#define SRAM(type, offset)  ((type *) (instance->sram_begin + (offset)))
 
 /* Returns a pointer to the SRAM table of contents. */
-#define SRAM_TOC		(SRAM(iosram_toc_t, 0))
+#define SRAM_TOC  (SRAM(iosram_toc_t, 0))
 
 /*
@@ -97,43 +97,17 @@
  */
 #define SGCN_BUFFER(type, offset) \
-	((type *) (sgcn_buffer_begin + (offset)))
+	((type *) (instance->buffer_begin + (offset)))
 
 /** Returns a pointer to the console buffer header. */
-#define SGCN_BUFFER_HEADER	(SGCN_BUFFER(sgcn_buffer_header_t, 0))
-
-/** starting address of SRAM, will be set by the init_sram_begin function */
-static uintptr_t sram_begin;
-
-/**
- * starting address of the SGCN buffer, will be set by the
- * init_sgcn_buffer_begin function
- */
-static uintptr_t sgcn_buffer_begin;
-
-/* true iff the kernel driver should ignore pressed keys */
-static bool kbd_disabled;
-
-/* 
- * Ensures that writing to the buffer and consequent update of the write pointer
- * are together one atomic operation.
- */
-SPINLOCK_INITIALIZE(sgcn_output_lock);
-
-/* 
- * Prevents the input buffer read/write pointers from getting to inconsistent
- * state. 
- */
-SPINLOCK_INITIALIZE(sgcn_input_lock);
-
-
-/* functions referenced from definitions of I/O operations structures */
+#define SGCN_BUFFER_HEADER  (SGCN_BUFFER(sgcn_buffer_header_t, 0))
+
 static void sgcn_putchar(outdev_t *, const wchar_t, bool);
 
-/** SGCN output device operations */
-static outdev_operations_t sgcnout_ops = {
-	.write = sgcn_putchar
+static outdev_operations_t sgcndev_ops = {
+	.write = sgcn_putchar,
+	.redraw = NULL
 };
 
-static outdev_t sgcnout;	/**< SGCN output device. */
+static sgcn_instance_t *instance = NULL;
 
 /**
@@ -158,23 +132,68 @@
 static void init_sram_begin(void)
 {
-	ofw_tree_node_t *chosen;
-	ofw_tree_property_t *iosram_toc;
-	uintptr_t sram_begin_physical;
-
-	chosen = ofw_tree_lookup("/chosen");
+	ASSERT(instance)
+	
+	ofw_tree_node_t *chosen = ofw_tree_lookup("/chosen");
 	if (!chosen)
 		panic("Cannot find '/chosen'.");
-
-	iosram_toc = ofw_tree_getprop(chosen, "iosram-toc");
+	
+	ofw_tree_property_t *iosram_toc =
+	    ofw_tree_getprop(chosen, "iosram-toc");
 	if (!iosram_toc)
 		panic("Cannot find property 'iosram-toc'.");
 	if (!iosram_toc->value)
 		panic("Cannot find SRAM TOC.");
-
-	sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
+	
+	uintptr_t sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
 	    + *((uint32_t *) iosram_toc->value);
-	sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
+	instance->sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
 	
 	register_sram(sram_begin_physical);
+}
+
+/**
+ * Function regularly called by the keyboard polling thread. Finds out whether
+ * there are some unread characters in the input queue. If so, it picks them up
+ * and sends them to the upper layers of HelenOS.
+ */
+static void sgcn_poll(sgcn_instance_t *instance)
+{
+	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
+	uint32_t end = SGCN_BUFFER_HEADER->in_end;
+	uint32_t size = end - begin;
+	
+	if (silent)
+		return;
+	
+	spinlock_lock(&instance->input_lock);
+	
+	/* we need pointers to volatile variables */
+	volatile char *buf_ptr = (volatile char *)
+	    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
+	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
+	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
+	
+	while (*in_rdptr_ptr != *in_wrptr_ptr) {
+		buf_ptr = (volatile char *)
+		    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
+		char c = *buf_ptr;
+		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
+		
+		indev_push_character(instance->srlnin, c);
+	}
+	
+	spinlock_unlock(&instance->input_lock);
+}
+
+/**
+ * Polling thread function.
+ */
+static void ksgcnpoll(void *instance) {
+	while (true) {
+		if (!silent)
+			sgcn_poll(instance);
+		
+		thread_usleep(POLL_INTERVAL);
+	}
 }
 
@@ -190,29 +209,41 @@
  * under the sram.buffer.offset sysinfo key.
  */
-static void sgcn_buffer_begin_init(void)
-{
-	static bool initialized;
-	
-	if (initialized)
+static void sgcn_init(void)
+{
+	if (instance)
 		return;
-
-	init_sram_begin();
-		
-	ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
-	
-	/* lookup TOC entry with the correct key */
-	uint32_t i;
-	for (i = 0; i < MAX_TOC_ENTRIES; i++) {
-		if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
-			break;
-	}
-	ASSERT(i < MAX_TOC_ENTRIES);
-	
-	sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset;
-	
-	sysinfo_set_item_val("sram.buffer.offset", NULL,
-	    SRAM_TOC->keys[i].offset);
-	
-	initialized = true;
+	
+	instance = malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC);
+	
+	if (instance) {
+		instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
+		    "ksgcnpoll", true);
+		
+		if (!instance->thread) {
+			free(instance);
+			instance = NULL;
+			return;
+		}
+		
+		init_sram_begin();
+		
+		ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
+		
+		/* Lookup TOC entry with the correct key */
+		uint32_t i;
+		for (i = 0; i < MAX_TOC_ENTRIES; i++) {
+			if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
+				break;
+		}
+		ASSERT(i < MAX_TOC_ENTRIES);
+		
+		instance->buffer_begin =
+		    instance->sram_begin + SRAM_TOC->keys[i].offset;
+		
+		sysinfo_set_item_val("sram.buffer.offset", NULL,
+		    SRAM_TOC->keys[i].offset);
+		
+		instance->srlnin = NULL;
+	}
 }
 
@@ -228,10 +259,10 @@
 	uint32_t size = end - begin;
 	
-	/* we need pointers to volatile variables */
+	/* We need pointers to volatile variables */
 	volatile char *buf_ptr = (volatile char *)
 	    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
 	volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
 	volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
-
+	
 	/*
 	 * Write the character and increment the write pointer modulo the
@@ -249,6 +280,6 @@
 	 */
 	uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
-	while (*out_rdptr_ptr == new_wrptr)
-		;
+	while (*out_rdptr_ptr == new_wrptr);
+	
 	*buf_ptr = c;
 	*out_wrptr_ptr = new_wrptr;
@@ -259,8 +290,8 @@
  * character is converted to CRLF.
  */
-static void sgcn_putchar(outdev_t *od, const wchar_t ch, bool silent)
+static void sgcn_putchar(outdev_t *dev, const wchar_t ch, bool silent)
 {
 	if (!silent) {
-		spinlock_lock(&sgcn_output_lock);
+		spinlock_lock(&instance->output_lock);
 		
 		if (ascii_check(ch)) {
@@ -271,66 +302,5 @@
 			sgcn_do_putchar(U_SPECIAL);
 		
-		spinlock_unlock(&sgcn_output_lock);
-	}
-}
-
-/**
- * Grabs the input for kernel.
- */
-void sgcn_grab(void)
-{
-	kbd_disabled = false;
-}
-
-/**
- * Releases the input so that userspace can use it.
- */
-void sgcn_release(void)
-{
-	kbd_disabled = true;
-}
-
-/**
- * Function regularly called by the keyboard polling thread. Finds out whether
- * there are some unread characters in the input queue. If so, it picks them up
- * and sends them to the upper layers of HelenOS.
- */
-static void sgcn_poll(sgcn_instance_t *instance)
-{
-	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->in_end;
-	uint32_t size = end - begin;
-
-	if (kbd_disabled)
-		return;
-
-	spinlock_lock(&sgcn_input_lock);
-	
-	/* we need pointers to volatile variables */
-	volatile char *buf_ptr = (volatile char *)
-	    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
-	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
-	
-	while (*in_rdptr_ptr != *in_wrptr_ptr) {
-		buf_ptr = (volatile char *)
-		    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-		char c = *buf_ptr;
-		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
-			
-		indev_push_character(instance->srlnin, c);	
-	}	
-
-	spinlock_unlock(&sgcn_input_lock);
-}
-
-/**
- * Polling thread function.
- */
-static void ksgcnpoll(void *instance) {
-	while (1) {
-		if (!silent) 
-			sgcn_poll(instance);
-		thread_usleep(POLL_INTERVAL);
+		spinlock_unlock(&instance->output_lock);
 	}
 }
@@ -341,20 +311,5 @@
 sgcn_instance_t *sgcnin_init(void)
 {
-	sgcn_buffer_begin_init();
-	
-	sgcn_instance_t *instance =
-	    malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC);
-	
-	if (instance) {
-		instance->srlnin = NULL;
-		instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
-		    "ksgcnpoll", true);
-		
-		if (!instance->thread) {
-			free(instance);
-			return NULL;
-		}
-	}
-	
+	sgcn_init();
 	return instance;
 }
@@ -364,8 +319,8 @@
 	ASSERT(instance);
 	ASSERT(srlnin);
-
+	
 	instance->srlnin = srlnin;
 	thread_ready(instance->thread);
-
+	
 	sysinfo_set_item_val("kbd", NULL, true);
 }
@@ -374,12 +329,28 @@
  * A public function which initializes output to the Serengeti console.
  */
-void sgcnout_init(void)
-{
-	sgcn_buffer_begin_init();
-
-	sysinfo_set_item_val("fb.kind", NULL, 4);
-
-	outdev_initialize("sgcnout", &sgcnout, &sgcnout_ops);	
-	stdout = &sgcnout;
+outdev_t *sgcnout_init(void)
+{
+	sgcn_init();
+	if (!instance)
+		return NULL;
+	
+	outdev_t *sgcndev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!sgcndev)
+		return NULL;
+	
+	outdev_initialize("sgcndev", sgcndev, &sgcndev_ops);
+	sgcndev->data = instance;
+	
+	if (!fb_exported) {
+		/*
+		 * This is the necessary evil until the userspace driver is entirely
+		 * self-sufficient.
+		 */
+		sysinfo_set_item_val("fb.kind", NULL, 4);
+		
+		fb_exported = true;
+	}
+	
+	return sgcndev;
 }
 
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -59,5 +59,6 @@
 ifeq ($(CONFIG_SOFTINT),y)
 	GENARCH_SOURCES += \
-		genarch/src/softint/division.c
+		genarch/src/softint/division.c \
+		genarch/src/softint/multiplication.c
 endif
 
@@ -130,10 +131,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/drivers/dsrln/dsrlnout.h
===================================================================
--- kernel/genarch/include/drivers/dsrln/dsrlnout.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/include/drivers/dsrln/dsrlnout.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -40,6 +40,7 @@
 #include <arch/types.h>
 #include <typedefs.h>
+#include <console/chardev.h>
 
-extern void dsrlnout_init(ioport8_t *);
+extern outdev_t *dsrlnout_init(ioport8_t *);
 
 #endif
Index: kernel/genarch/include/drivers/ega/ega.h
===================================================================
--- kernel/genarch/include/drivers/ega/ega.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/include/drivers/ega/ega.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -38,4 +38,5 @@
 #include <arch/types.h>
 #include <typedefs.h>
+#include <console/chardev.h>
 
 #define EGA_COLS       80
@@ -48,6 +49,5 @@
 #define EGA_DATA_REG   1
 
-extern void ega_redraw(void);
-extern void ega_init(ioport8_t *, uintptr_t);
+extern outdev_t *ega_init(ioport8_t *, uintptr_t);
 
 #endif
Index: kernel/genarch/include/fb/fb.h
===================================================================
--- kernel/genarch/include/fb/fb.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/include/fb/fb.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -37,5 +37,6 @@
 
 #include <arch/types.h>
-#include <synch/spinlock.h>
+#include <console/chardev.h>
+#include <genarch/fb/visuals.h>
 
 /**
@@ -45,5 +46,5 @@
 	/** Physical address of the framebuffer device. */
 	uintptr_t addr;
-
+	
 	/**
 	 * Address where the first (top left) pixel is mapped,
@@ -51,22 +52,19 @@
 	 */
 	unsigned int offset;
-
+	
 	/** Screen width in pixels. */
 	unsigned int x;
-
+	
 	/** Screen height in pixels. */
 	unsigned int y;
-
+	
 	/** Bytes per one scanline. */
 	unsigned int scan;
-
+	
 	/** Color model. */
-	unsigned int visual;
+	visual_t visual;
 } fb_properties_t;
 
-SPINLOCK_EXTERN(fb_lock);
-
-void fb_redraw(void);
-void fb_init(fb_properties_t *props);
+outdev_t *fb_init(fb_properties_t *props);
 
 #endif
Index: kernel/genarch/include/fb/visuals.h
===================================================================
--- kernel/genarch/include/fb/visuals.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/include/fb/visuals.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/genarch/include/ofw/ebus.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/genarch/include/ofw/fhc.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/include/ofw/ofw_tree.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/genarch/include/ofw/pci.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/genarch/include/ofw/sbus.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/genarch/include/ofw/upa.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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/include/softint/multiplication.h
===================================================================
--- kernel/genarch/include/softint/multiplication.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/genarch/include/softint/multiplication.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009 Josef Cejka
+ * 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 genarch
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#ifndef __SOFTINT_MULTIPLICATION_H__
+#define __SOFTINT_MULTIPLICATION_H__
+
+/* 64 bit multiplication */
+long long __muldi3(long long a, long long b);
+
+#endif
+
+/** @}
+ */
+
+
Index: kernel/genarch/src/acpi/acpi.c
===================================================================
--- kernel/genarch/src/acpi/acpi.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/acpi/acpi.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -46,4 +46,10 @@
 #define RSDP_REVISION_OFFS	15
 
+#define CMP_SIGNATURE(left, right) \
+	(((left)[0] == (right)[0]) && \
+	((left)[1] == (right)[1]) && \
+	((left)[2] == (right)[2]) && \
+	((left)[3] == (right)[3]))
+
 struct acpi_rsdp *acpi_rsdp = NULL;
 struct acpi_rsdt *acpi_rsdt = NULL;
@@ -105,6 +111,6 @@
 			struct acpi_sdt_header *h = (struct acpi_sdt_header *) (unative_t) acpi_rsdt->entry[i];
 		
-			map_sdt(h);	
-			if (*((uint32_t *) &h->signature[0]) == *((uint32_t *) &signature_map[j].signature[0])) {
+			map_sdt(h);
+			if (CMP_SIGNATURE(h->signature, signature_map[j].signature)) {
 				if (!acpi_sdt_check((uint8_t *) h))
 					goto next;
@@ -127,5 +133,5 @@
 
 			map_sdt(h);
-			if (*((uint32_t *) &h->signature[0]) == *((uint32_t *) &signature_map[j].signature[0])) {
+			if (CMP_SIGNATURE(h->signature, signature_map[j].signature)) {
 				if (!acpi_sdt_check((uint8_t *) h))
 					goto next;
Index: kernel/genarch/src/drivers/dsrln/dsrlnout.c
===================================================================
--- kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -35,40 +35,63 @@
  */
 
-
 #include <genarch/drivers/dsrln/dsrlnout.h>
 #include <console/chardev.h>
 #include <arch/asm.h>
+#include <mm/slab.h>
 #include <console/console.h>
 #include <sysinfo/sysinfo.h>
 #include <string.h>
 
-static ioport8_t *dsrlnout_base;
+typedef struct {
+	ioport8_t *base;
+} dsrlnout_instance_t;
 
-static void dsrlnout_putchar(outdev_t *dev __attribute__((unused)), const wchar_t ch, bool silent)
+static void dsrlnout_putchar(outdev_t *dev, const wchar_t ch, bool silent)
 {
+	dsrlnout_instance_t *instance = (dsrlnout_instance_t *) dev->data;
+	
 	if (!silent) {
 		if (ascii_check(ch))
-			pio_write_8(dsrlnout_base, ch);
+			pio_write_8(instance->base, ch);
 		else
-			pio_write_8(dsrlnout_base, U_SPECIAL);
+			pio_write_8(instance->base, U_SPECIAL);
 	}
 }
 
-static outdev_t dsrlnout_console;
-static outdev_operations_t dsrlnout_ops = {
-	.write = dsrlnout_putchar
+static outdev_operations_t dsrlndev_ops = {
+	.write = dsrlnout_putchar,
+	.redraw = NULL
 };
 
-void dsrlnout_init(ioport8_t *base)
+outdev_t *dsrlnout_init(ioport8_t *base)
 {
-	/* Initialize the software structure. */
-	dsrlnout_base = base;
+	outdev_t *dsrlndev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!dsrlndev)
+		return NULL;
 	
-	outdev_initialize("dsrlnout", &dsrlnout_console, &dsrlnout_ops);
-	stdout = &dsrlnout_console;
+	dsrlnout_instance_t *instance = malloc(sizeof(dsrlnout_instance_t), FRAME_ATOMIC);
+	if (!instance) {
+		free(dsrlndev);
+		return NULL;
+	}
 	
-	sysinfo_set_item_val("fb", NULL, true);
-	sysinfo_set_item_val("fb.kind", NULL, 3);
-	sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(base));
+	outdev_initialize("dsrlndev", dsrlndev, &dsrlndev_ops);
+	dsrlndev->data = instance;
+	
+	instance->base = base;
+	
+	if (!fb_exported) {
+		/*
+		 * This is the necessary evil until the userspace driver is entirely
+		 * self-sufficient.
+		 */
+		sysinfo_set_item_val("fb", NULL, true);
+		sysinfo_set_item_val("fb.kind", NULL, 3);
+		sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(base));
+		
+		fb_exported = true;
+	}
+	
+	return dsrlndev;
 }
 
Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -56,10 +56,4 @@
  */
 
-SPINLOCK_INITIALIZE(egalock);
-static uint32_t ega_cursor;
-static uint8_t *videoram;
-static uint8_t *backbuf;
-static ioport8_t *ega_base;
-
 #define SPACE  0x20
 #define STYLE  0x1e
@@ -68,4 +62,21 @@
 #define EMPTY_CHAR  ((STYLE << 8) | SPACE)
 
+typedef struct {
+	SPINLOCK_DECLARE(lock);
+	
+	uint32_t cursor;
+	uint8_t *addr;
+	uint8_t *backbuf;
+	ioport8_t *base;
+} ega_instance_t;
+
+static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent);
+static void ega_redraw(outdev_t *dev);
+
+static outdev_operations_t egadev_ops = {
+	.write = ega_putchar,
+	.redraw = ega_redraw
+};
+
 static uint16_t ega_oem_glyph(const wchar_t ch)
 {
@@ -427,71 +438,80 @@
  * This function takes care of scrolling.
  */
-static void ega_check_cursor(bool silent)
-{
-	if (ega_cursor < EGA_SCREEN)
+static void ega_check_cursor(ega_instance_t *instance, bool silent)
+{
+	if (instance->cursor < EGA_SCREEN)
 		return;
 	
-	memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2),
+	memmove((void *) instance->backbuf,
+	    (void *) (instance->backbuf + EGA_COLS * 2),
 	    (EGA_SCREEN - EGA_COLS) * 2);
-	memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
+	memsetw(instance->backbuf + (EGA_SCREEN - EGA_COLS) * 2,
+	    EGA_COLS, EMPTY_CHAR);
 	
 	if (!silent) {
-		memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2),
+		memmove((void *) instance->addr,
+		    (void *) (instance->addr + EGA_COLS * 2),
 		    (EGA_SCREEN - EGA_COLS) * 2);
-		memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
-	}
-	
-	ega_cursor = ega_cursor - EGA_COLS;
-}
-
-static void ega_show_cursor(bool silent)
+		memsetw(instance->addr + (EGA_SCREEN - EGA_COLS) * 2,
+		    EGA_COLS, EMPTY_CHAR);
+	}
+	
+	instance->cursor = instance->cursor - EGA_COLS;
+}
+
+static void ega_show_cursor(ega_instance_t *instance, bool silent)
 {
 	if (!silent) {
-		pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
-		uint8_t stat = pio_read_8(ega_base + EGA_DATA_REG);
-		pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
-		pio_write_8(ega_base + EGA_DATA_REG, stat & (~(1 << 5)));
-	}
-}
-
-static void ega_move_cursor(bool silent)
+		pio_write_8(instance->base + EGA_INDEX_REG, 0x0a);
+		uint8_t stat = pio_read_8(instance->base + EGA_DATA_REG);
+		pio_write_8(instance->base + EGA_INDEX_REG, 0x0a);
+		pio_write_8(instance->base + EGA_DATA_REG, stat & (~(1 << 5)));
+	}
+}
+
+static void ega_move_cursor(ega_instance_t *instance, bool silent)
 {
 	if (!silent) {
-		pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
-		pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff));
-		pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
-		pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff));
-	}
-}
-
-static void ega_sync_cursor(bool silent)
+		pio_write_8(instance->base + EGA_INDEX_REG, 0x0e);
+		pio_write_8(instance->base + EGA_DATA_REG,
+		    (uint8_t) ((instance->cursor >> 8) & 0xff));
+		pio_write_8(instance->base + EGA_INDEX_REG, 0x0f);
+		pio_write_8(instance->base + EGA_DATA_REG,
+		    (uint8_t) (instance->cursor & 0xff));
+	}
+}
+
+static void ega_sync_cursor(ega_instance_t *instance, bool silent)
 {
 	if (!silent) {
-		pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
-		uint8_t hi = pio_read_8(ega_base + EGA_DATA_REG);
-		pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
-		uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG);
+		pio_write_8(instance->base + EGA_INDEX_REG, 0x0e);
+		uint8_t hi = pio_read_8(instance->base + EGA_DATA_REG);
+		pio_write_8(instance->base + EGA_INDEX_REG, 0x0f);
+		uint8_t lo = pio_read_8(instance->base + EGA_DATA_REG);
 		
-		ega_cursor = (hi << 8) | lo;
+		instance->cursor = (hi << 8) | lo;
 	} else
-		ega_cursor = 0;
-	
-	if (ega_cursor >= EGA_SCREEN)
-		ega_cursor = 0;
-	
-	if ((ega_cursor % EGA_COLS) != 0)
-		ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
-	
-	memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
+		instance->cursor = 0;
+	
+	if (instance->cursor >= EGA_SCREEN)
+		instance->cursor = 0;
+	
+	if ((instance->cursor % EGA_COLS) != 0)
+		instance->cursor =
+		    (instance->cursor + EGA_COLS) - instance->cursor % EGA_COLS;
+	
+	memsetw(instance->backbuf + instance->cursor * 2,
+	    EGA_SCREEN - instance->cursor, EMPTY_CHAR);
 	
 	if (!silent)
-		memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
-	
-	ega_check_cursor(silent);
-	ega_move_cursor(silent);
-	ega_show_cursor(silent);
-}
-
-static void ega_display_char(wchar_t ch, bool silent)
+		memsetw(instance->addr + instance->cursor * 2,
+		    EGA_SCREEN - instance->cursor, EMPTY_CHAR);
+	
+	ega_check_cursor(instance, silent);
+	ega_move_cursor(instance, silent);
+	ega_show_cursor(instance, silent);
+}
+
+static void ega_display_char(ega_instance_t *instance, wchar_t ch, bool silent)
 {
 	uint16_t index = ega_oem_glyph(ch);
@@ -507,79 +527,114 @@
 	}
 	
-	backbuf[ega_cursor * 2] = glyph;
-	backbuf[ega_cursor * 2 + 1] = style;
+	instance->backbuf[instance->cursor * 2] = glyph;
+	instance->backbuf[instance->cursor * 2 + 1] = style;
 	
 	if (!silent) {
-		videoram[ega_cursor * 2] = glyph;
-		videoram[ega_cursor * 2 + 1] = style;
-	}
-}
-
-static void ega_putchar(outdev_t *dev __attribute__((unused)), wchar_t ch, bool silent)
-{
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&egalock);
+		instance->addr[instance->cursor * 2] = glyph;
+		instance->addr[instance->cursor * 2 + 1] = style;
+	}
+}
+
+static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent)
+{
+	ega_instance_t *instance = (ega_instance_t *) dev->data;
+	
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&instance->lock);
 	
 	switch (ch) {
 	case '\n':
-		ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
+		instance->cursor = (instance->cursor + EGA_COLS)
+		    - instance->cursor % EGA_COLS;
 		break;
 	case '\t':
-		ega_cursor = (ega_cursor + 8) - ega_cursor % 8;
+		instance->cursor = (instance->cursor + 8)
+		    - instance->cursor % 8;
 		break;
 	case '\b':
-		if (ega_cursor % EGA_COLS)
-			ega_cursor--;
+		if (instance->cursor % EGA_COLS)
+			instance->cursor--;
 		break;
 	default:
-		ega_display_char(ch, silent);
-		ega_cursor++;
+		ega_display_char(instance, ch, silent);
+		instance->cursor++;
 		break;
 	}
-	ega_check_cursor(silent);
-	ega_move_cursor(silent);
-	
-	spinlock_unlock(&egalock);
+	ega_check_cursor(instance, silent);
+	ega_move_cursor(instance, silent);
+	
+	spinlock_unlock(&instance->lock);
 	interrupts_restore(ipl);
 }
 
-static outdev_t ega_console;
-static outdev_operations_t ega_ops = {
-	.write = ega_putchar
-};
-
-void ega_init(ioport8_t *base, uintptr_t videoram_phys)
-{
-	/* Initialize the software structure. */
-	ega_base = base;
-	
-	backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0);
-	if (!backbuf)
-		panic("Unable to allocate backbuffer.");
-	
-	videoram = (uint8_t *) hw_map(videoram_phys, EGA_VRAM_SIZE);
+static void ega_redraw(outdev_t *dev)
+{
+	ega_instance_t *instance = (ega_instance_t *) dev->data;
+	
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&instance->lock);
+	
+	memcpy(instance->addr, instance->backbuf, EGA_VRAM_SIZE);
+	ega_move_cursor(instance, silent);
+	ega_show_cursor(instance, silent);
+	
+	spinlock_unlock(&instance->lock);
+	interrupts_restore(ipl);
+}
+
+outdev_t *ega_init(ioport8_t *base, uintptr_t addr)
+{
+	outdev_t *egadev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!egadev)
+		return NULL;
+	
+	ega_instance_t *instance = malloc(sizeof(ega_instance_t), FRAME_ATOMIC);
+	if (!instance) {
+		free(egadev);
+		return NULL;
+	}
+	
+	outdev_initialize("egadev", egadev, &egadev_ops);
+	egadev->data = instance;
+	
+	spinlock_initialize(&instance->lock, "*ega_lock");
+	
+	instance->base = base;
+	instance->addr = (uint8_t *) hw_map(addr, EGA_VRAM_SIZE);
+	if (!instance->addr) {
+		LOG("Unable to EGA video memory.");
+		free(instance);
+		free(egadev);
+		return NULL;
+	}
+	
+	instance->backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0);
+	if (!instance->backbuf) {
+		LOG("Unable to allocate backbuffer.");
+		free(instance);
+		free(egadev);
+		return NULL;
+	}
 	
 	/* Synchronize the back buffer and cursor position. */
-	memcpy(backbuf, videoram, EGA_VRAM_SIZE);
-	ega_sync_cursor(silent);
-	
-	outdev_initialize("ega", &ega_console, &ega_ops);
-	stdout = &ega_console;
-	
-	sysinfo_set_item_val("fb", NULL, true);
-	sysinfo_set_item_val("fb.kind", NULL, 2);
-	sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
-	sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
-	sysinfo_set_item_val("fb.blinking", NULL, true);
-	sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys);
-}
-
-void ega_redraw(void)
-{
-	memcpy(videoram, backbuf, EGA_VRAM_SIZE);
-	ega_move_cursor(silent);
-	ega_show_cursor(silent);
+	memcpy(instance->backbuf, instance->addr, EGA_VRAM_SIZE);
+	ega_sync_cursor(instance, silent);
+	
+	if (!fb_exported) {
+		/*
+		 * This is the necessary evil until the userspace driver is entirely
+		 * self-sufficient.
+		 */
+		sysinfo_set_item_val("fb", NULL, true);
+		sysinfo_set_item_val("fb.kind", NULL, 2);
+		sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
+		sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
+		sysinfo_set_item_val("fb.blinking", NULL, true);
+		sysinfo_set_item_val("fb.address.physical", NULL, addr);
+		
+		fb_exported = true;
+	}
+	
+	return egadev;
 }
 
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/fb/fb.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -53,49 +53,67 @@
 #include <byteorder.h>
 
-SPINLOCK_INITIALIZE(fb_lock);
-
-static uint8_t *fb_addr;
-static uint16_t *backbuf;
-static uint8_t *glyphs;
-static uint8_t *bgscan;
-
-static unsigned int xres;
-static unsigned int yres;
-
-static unsigned int ylogo;
-static unsigned int ytrim;
-static unsigned int rowtrim;
-
-static unsigned int scanline;
-static unsigned int glyphscanline;
-
-static unsigned int pixelbytes;
-static unsigned int glyphbytes;
-static unsigned int bgscanbytes;
-
-static unsigned int cols;
-static unsigned int rows;
-static unsigned int position = 0;
-
 #define BG_COLOR     0x000080
 #define FG_COLOR     0xffff00
 #define INV_COLOR    0xaaaaaa
 
-#define RED(x, bits)         (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
-#define GREEN(x, bits)       (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
-#define BLUE(x, bits)        (((x) >> (8 - (bits))) & ((1 << (bits)) - 1))
-
-#define COL2X(col)           ((col) * FONT_WIDTH)
-#define ROW2Y(row)           ((row) * FONT_SCANLINES)
-
-#define X2COL(x)             ((x) / FONT_WIDTH)
-#define Y2ROW(y)             ((y) / FONT_SCANLINES)
-
-#define FB_POS(x, y)         ((y) * scanline + (x) * pixelbytes)
-#define BB_POS(col, row)     ((row) * cols + (col))
-#define GLYPH_POS(glyph, y)  ((glyph) * glyphbytes + (y) * glyphscanline)
-
-
-static void (*rgb_conv)(void *, uint32_t);
+#define RED(x, bits)    (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
+#define GREEN(x, bits)  (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
+#define BLUE(x, bits)   (((x) >> (8 - (bits))) & ((1 << (bits)) - 1))
+
+#define COL2X(col)  ((col) * FONT_WIDTH)
+#define ROW2Y(row)  ((row) * FONT_SCANLINES)
+
+#define X2COL(x)  ((x) / FONT_WIDTH)
+#define Y2ROW(y)  ((y) / FONT_SCANLINES)
+
+#define FB_POS(instance, x, y) \
+	((y) * (instance)->scanline + (x) * (instance)->pixelbytes)
+
+#define BB_POS(instance, col, row) \
+	((row) * (instance)->cols + (col))
+
+#define GLYPH_POS(instance, glyph, y) \
+	((glyph) * (instance)->glyphbytes + (y) * (instance)->glyphscanline)
+
+typedef void (* rgb_conv_t)(void *, uint32_t);
+
+typedef struct {
+	SPINLOCK_DECLARE(lock);
+	
+	uint8_t *addr;
+	uint16_t *backbuf;
+	uint8_t *glyphs;
+	uint8_t *bgscan;
+	
+	rgb_conv_t rgb_conv;
+	
+	unsigned int xres;
+	unsigned int yres;
+	
+	unsigned int ylogo;
+	unsigned int ytrim;
+	unsigned int rowtrim;
+	
+	unsigned int scanline;
+	unsigned int glyphscanline;
+	
+	unsigned int pixelbytes;
+	unsigned int glyphbytes;
+	unsigned int bgscanbytes;
+	
+	unsigned int cols;
+	unsigned int rows;
+	
+	unsigned int position;
+} fb_instance_t;
+
+static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent);
+static void fb_redraw_internal(fb_instance_t *instance);
+static void fb_redraw(outdev_t *dev);
+
+static outdev_operations_t fbdev_ops = {
+	.write = fb_putchar,
+	.redraw = fb_redraw
+};
 
 /*
@@ -169,5 +187,4 @@
 	    GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
 }
-
 
 /** BGR 3:2:3
@@ -179,5 +196,5 @@
  * and setting it to simulate the 8-bit truecolor.
  *
- * Currently we set the palette on the ia32, amd64 and sparc64 port.
+ * Currently we set the palette on the ia32, amd64, ppc32 and sparc64 port.
  *
  * Note that the byte is being inverted by this function. The reason is
@@ -194,22 +211,22 @@
 }
 
-
 /** Hide logo and refresh screen
  *
  */
-static void logo_hide(bool silent)
-{
-	ylogo = 0;
-	ytrim = yres;
-	rowtrim = rows;
+static void logo_hide(fb_instance_t *instance, bool silent)
+{
+	instance->ylogo = 0;
+	instance->ytrim = instance->yres;
+	instance->rowtrim = instance->rows;
+	
 	if (!silent)
-		fb_redraw();
-}
-
+		fb_redraw_internal(instance);
+}
 
 /** Draw character at given position
  *
  */
-static void glyph_draw(uint16_t glyph, unsigned int col, unsigned int row, bool silent, bool overlay)
+static void glyph_draw(fb_instance_t *instance, uint16_t glyph,
+    unsigned int col, unsigned int row, bool silent, bool overlay)
 {
 	unsigned int x = COL2X(col);
@@ -217,17 +234,17 @@
 	unsigned int yd;
 	
-	if (y >= ytrim)
-		logo_hide(silent);
+	if (y >= instance->ytrim)
+		logo_hide(instance, silent);
 	
 	if (!overlay)
-		backbuf[BB_POS(col, row)] = glyph;
+		instance->backbuf[BB_POS(instance, col, row)] = glyph;
 	
 	if (!silent) {
 		for (yd = 0; yd < FONT_SCANLINES; yd++)
-			memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)],
-			    &glyphs[GLYPH_POS(glyph, yd)], glyphscanline);
-	}
-}
-
+			memcpy(&instance->addr[FB_POS(instance, x, y + yd + instance->ylogo)],
+			    &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
+			    instance->glyphscanline);
+	}
+}
 
 /** Scroll screen down by one row
@@ -235,8 +252,8 @@
  *
  */
-static void screen_scroll(bool silent)
-{
-	if (ylogo > 0) {
-		logo_hide(silent);
+static void screen_scroll(fb_instance_t *instance, bool silent)
+{
+	if (instance->ylogo > 0) {
+		logo_hide(instance, silent);
 		return;
 	}
@@ -245,5 +262,5 @@
 		unsigned int row;
 		
-		for (row = 0; row < rows; row++) {
+		for (row = 0; row < instance->rows; row++) {
 			unsigned int y = ROW2Y(row);
 			unsigned int yd;
@@ -253,20 +270,20 @@
 				unsigned int col;
 				
-				for (col = 0, x = 0; col < cols; col++,
-				    x += FONT_WIDTH) {
+				for (col = 0, x = 0; col < instance->cols;
+				    col++, x += FONT_WIDTH) {
 					uint16_t glyph;
 					
-					if (row < rows - 1) {
-						if (backbuf[BB_POS(col, row)] ==
-						    backbuf[BB_POS(col, row + 1)])
+					if (row < instance->rows - 1) {
+						if (instance->backbuf[BB_POS(instance, col, row)] ==
+						    instance->backbuf[BB_POS(instance, col, row + 1)])
 							continue;
 						
-						glyph = backbuf[BB_POS(col, row + 1)];
+						glyph = instance->backbuf[BB_POS(instance, col, row + 1)];
 					} else
 						glyph = 0;
 					
-					memcpy(&fb_addr[FB_POS(x, y + yd)],
-					    &glyphs[GLYPH_POS(glyph, yd)],
-					    glyphscanline);
+					memcpy(&instance->addr[FB_POS(instance, x, y + yd)],
+					    &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
+					    instance->glyphscanline);
 				}
 			}
@@ -274,80 +291,26 @@
 	}
 	
-	memmove(backbuf, &backbuf[BB_POS(0, 1)], cols * (rows - 1) * sizeof(uint16_t));
-	memsetw(&backbuf[BB_POS(0, rows - 1)], cols, 0);
-}
-
-
-static void cursor_put(bool silent)
-{
-	unsigned int col = position % cols;
-	unsigned int row = position / cols;
-	
-	glyph_draw(fb_font_glyph(U_CURSOR), col, row, silent, true);
-}
-
-
-static void cursor_remove(bool silent)
-{
-	unsigned int col = position % cols;
-	unsigned int row = position / cols;
-	
-	glyph_draw(backbuf[BB_POS(col, row)], col, row, silent, true);
-}
-
-
-/** Print character to screen
- *
- * Emulate basic terminal commands.
- *
- */
-static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent)
-{
-	spinlock_lock(&fb_lock);
-	
-	switch (ch) {
-	case '\n':
-		cursor_remove(silent);
-		position += cols;
-		position -= position % cols;
-		break;
-	case '\r':
-		cursor_remove(silent);
-		position -= position % cols;
-		break;
-	case '\b':
-		cursor_remove(silent);
-		if (position % cols)
-			position--;
-		break;
-	case '\t':
-		cursor_remove(silent);
-		do {
-			glyph_draw(fb_font_glyph(' '), position % cols,
-			    position / cols, silent, false);
-			position++;
-		} while ((position % 8) && (position < cols * rows));
-		break;
-	default:
-		glyph_draw(fb_font_glyph(ch), position % cols,
-		    position / cols, silent, false);
-		position++;
-	}
-	
-	if (position >= cols * rows) {
-		position -= cols;
-		screen_scroll(silent);
-	}
-	
-	cursor_put(silent);
-	
-	spinlock_unlock(&fb_lock);
-}
-
-static outdev_t fb_console;
-static outdev_operations_t fb_ops = {
-	.write = fb_putchar
-};
-
+	memmove(instance->backbuf, &instance->backbuf[BB_POS(instance, 0, 1)],
+	    instance->cols * (instance->rows - 1) * sizeof(uint16_t));
+	memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)],
+	    instance->cols, 0);
+}
+
+static void cursor_put(fb_instance_t *instance, bool silent)
+{
+	unsigned int col = instance->position % instance->cols;
+	unsigned int row = instance->position / instance->cols;
+	
+	glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, silent, true);
+}
+
+static void cursor_remove(fb_instance_t *instance, bool silent)
+{
+	unsigned int col = instance->position % instance->cols;
+	unsigned int row = instance->position / instance->cols;
+	
+	glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)],
+	    col, row, silent, true);
+}
 
 /** Render glyphs
@@ -357,5 +320,5 @@
  *
  */
-static void glyphs_render(void)
+static void glyphs_render(fb_instance_t *instance)
 {
 	/* Prerender glyphs */
@@ -376,9 +339,10 @@
 			
 			for (x = 0; x < FONT_WIDTH; x++) {
-				void *dst = &glyphs[GLYPH_POS(glyph, y) +
-				    x * pixelbytes];
+				void *dst =
+				    &instance->glyphs[GLYPH_POS(instance, glyph, y) +
+				    x * instance->pixelbytes];
 				uint32_t rgb = (fb_font[glyph][y] &
 				    (1 << (7 - x))) ? fg_color : BG_COLOR;
-				rgb_conv(dst, rgb);
+				instance->rgb_conv(dst, rgb);
 			}
 		}
@@ -388,15 +352,63 @@
 	unsigned int x;
 	
-	for (x = 0; x < xres; x++)
-		rgb_conv(&bgscan[x * pixelbytes], BG_COLOR);
-}
-
-
-/** Refresh the screen
- *
- */
-void fb_redraw(void)
-{
-	if (ylogo > 0) {
+	for (x = 0; x < instance->xres; x++)
+		instance->rgb_conv(&instance->bgscan[x * instance->pixelbytes], BG_COLOR);
+}
+
+/** Print character to screen
+ *
+ * Emulate basic terminal commands.
+ *
+ */
+static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent)
+{
+	fb_instance_t *instance = (fb_instance_t *) dev->data;
+	spinlock_lock(&instance->lock);
+	
+	switch (ch) {
+	case '\n':
+		cursor_remove(instance, silent);
+		instance->position += instance->cols;
+		instance->position -= instance->position % instance->cols;
+		break;
+	case '\r':
+		cursor_remove(instance, silent);
+		instance->position -= instance->position % instance->cols;
+		break;
+	case '\b':
+		cursor_remove(instance, silent);
+		if (instance->position % instance->cols)
+			instance->position--;
+		break;
+	case '\t':
+		cursor_remove(instance, silent);
+		do {
+			glyph_draw(instance, fb_font_glyph(' '),
+			    instance->position % instance->cols,
+			    instance->position / instance->cols, silent, false);
+			instance->position++;
+		} while ((instance->position % 8)
+		    && (instance->position < instance->cols * instance->rows));
+		break;
+	default:
+		glyph_draw(instance, fb_font_glyph(ch),
+		    instance->position % instance->cols,
+		    instance->position / instance->cols, silent, false);
+		instance->position++;
+	}
+	
+	if (instance->position >= instance->cols * instance->rows) {
+		instance->position -= instance->cols;
+		screen_scroll(instance, silent);
+	}
+	
+	cursor_put(instance, silent);
+	
+	spinlock_unlock(&instance->lock);
+}
+
+static void fb_redraw_internal(fb_instance_t *instance)
+{
+	if (instance->ylogo > 0) {
 		unsigned int y;
 		
@@ -404,6 +416,6 @@
 			unsigned int x;
 			
-			for (x = 0; x < xres; x++)
-				rgb_conv(&fb_addr[FB_POS(x, y)],
+			for (x = 0; x < instance->xres; x++)
+				instance->rgb_conv(&instance->addr[FB_POS(instance, x, y)],
 				    (x < LOGO_WIDTH) ?
 				    fb_logo[y * LOGO_WIDTH + x] :
@@ -414,6 +426,6 @@
 	unsigned int row;
 	
-	for (row = 0; row < rowtrim; row++) {
-		unsigned int y = ylogo + ROW2Y(row);
+	for (row = 0; row < instance->rowtrim; row++) {
+		unsigned int y = instance->ylogo + ROW2Y(row);
 		unsigned int yd;
 		
@@ -422,42 +434,60 @@
 			unsigned int col;
 			
-			for (col = 0, x = 0; col < cols;
+			for (col = 0, x = 0; col < instance->cols;
 			    col++, x += FONT_WIDTH) {
-				uint16_t glyph = backbuf[BB_POS(col, row)];
-				void *dst = &fb_addr[FB_POS(x, y + yd)];
-				void *src = &glyphs[GLYPH_POS(glyph, yd)];
-				memcpy(dst, src, glyphscanline);
+				uint16_t glyph =
+				    instance->backbuf[BB_POS(instance, col, row)];
+				void *dst = &instance->addr[FB_POS(instance, x, y + yd)];
+				void *src = &instance->glyphs[GLYPH_POS(instance, glyph, yd)];
+				memcpy(dst, src, instance->glyphscanline);
 			}
 		}
 	}
 	
-	if (COL2X(cols) < xres) {
+	if (COL2X(instance->cols) < instance->xres) {
 		unsigned int y;
-		unsigned int size = (xres - COL2X(cols)) * pixelbytes;
-		
-		for (y = ylogo; y < yres; y++)
-			memcpy(&fb_addr[FB_POS(COL2X(cols), y)], bgscan, size);
-	}
-	
-	if (ROW2Y(rowtrim) + ylogo < yres) {
+		unsigned int size =
+		    (instance->xres - COL2X(instance->cols)) * instance->pixelbytes;
+		
+		for (y = instance->ylogo; y < instance->yres; y++)
+			memcpy(&instance->addr[FB_POS(instance, COL2X(instance->cols), y)],
+			    instance->bgscan, size);
+	}
+	
+	if (ROW2Y(instance->rowtrim) + instance->ylogo < instance->yres) {
 		unsigned int y;
 		
-		for (y = ROW2Y(rowtrim) + ylogo; y < yres; y++)
-			memcpy(&fb_addr[FB_POS(0, y)], bgscan, bgscanbytes);
-	}
-}
-
+		for (y = ROW2Y(instance->rowtrim) + instance->ylogo;
+		    y < instance->yres; y++)
+			memcpy(&instance->addr[FB_POS(instance, 0, y)],
+			    instance->bgscan, instance->bgscanbytes);
+	}
+}
+
+/** Refresh the screen
+ *
+ */
+static void fb_redraw(outdev_t *dev)
+{
+	fb_instance_t *instance = (fb_instance_t *) dev->data;
+	
+	spinlock_lock(&instance->lock);
+	fb_redraw_internal(instance);
+	spinlock_unlock(&instance->lock);
+}
 
 /** Initialize framebuffer as a output character device
  *
- * @param addr   Physical address of the framebuffer
- * @param x      Screen width in pixels
- * @param y      Screen height in pixels
- * @param scan   Bytes per one scanline
- * @param visual Color model
- *
- */
-void fb_init(fb_properties_t *props)
-{
+ */
+outdev_t *fb_init(fb_properties_t *props)
+{
+	ASSERT(props);
+	ASSERT(props->x > 0);
+	ASSERT(props->y > 0);
+	ASSERT(props->scan > 0);
+	
+	rgb_conv_t rgb_conv;
+	unsigned int pixelbytes;
+	
 	switch (props->visual) {
 	case VISUAL_INDIRECT_8:
@@ -506,64 +536,108 @@
 		break;
 	default:
-		panic("Unsupported visual.");
-	}
-	
-	xres = props->x;
-	yres = props->y;
-	scanline = props->scan;
-	
-	cols = X2COL(xres);
-	rows = Y2ROW(yres);
-	
-	if (yres > ylogo) {
-		ylogo = LOGO_HEIGHT;
-		rowtrim = rows - Y2ROW(ylogo);
-		if (ylogo % FONT_SCANLINES > 0)
-			rowtrim--;
-		ytrim = ROW2Y(rowtrim);
+		LOG("Unsupported visual.");
+		return NULL;
+	}
+	
+	outdev_t *fbdev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!fbdev)
+		return NULL;
+	
+	fb_instance_t *instance = malloc(sizeof(fb_instance_t), FRAME_ATOMIC);
+	if (!instance) {
+		free(fbdev);
+		return NULL;
+	}
+	
+	outdev_initialize("fbdev", fbdev, &fbdev_ops);
+	fbdev->data = instance;
+	
+	spinlock_initialize(&instance->lock, "*fb_lock");
+	instance->rgb_conv = rgb_conv;
+	instance->pixelbytes = pixelbytes;
+	instance->xres = props->x;
+	instance->yres = props->y;
+	instance->scanline = props->scan;
+	instance->position = 0;
+	
+	instance->cols = X2COL(instance->xres);
+	instance->rows = Y2ROW(instance->yres);
+	
+	if (instance->yres > LOGO_HEIGHT) {
+		instance->ylogo = LOGO_HEIGHT;
+		instance->rowtrim = instance->rows - Y2ROW(instance->ylogo);
+		if (instance->ylogo % FONT_SCANLINES > 0)
+			instance->rowtrim--;
+		instance->ytrim = ROW2Y(instance->rowtrim);
 	} else {
-		ylogo = 0;
-		ytrim = yres;
-		rowtrim = rows;
-	}
-	
-	glyphscanline = FONT_WIDTH * pixelbytes;
-	glyphbytes = ROW2Y(glyphscanline);
-	bgscanbytes = xres * pixelbytes;
-	
-	size_t fbsize = scanline * yres;
-	size_t bbsize = cols * rows * sizeof(uint16_t);
-	size_t glyphsize = FONT_GLYPHS * glyphbytes;
-	
-	backbuf = (uint16_t *) malloc(bbsize, 0);
-	if (!backbuf)
-		panic("Unable to allocate backbuffer.");
-	
-	glyphs = (uint8_t *) malloc(glyphsize, 0);
-	if (!glyphs)
-		panic("Unable to allocate glyphs.");
-	
-	bgscan = malloc(bgscanbytes, 0);
-	if (!bgscan)
-		panic("Unable to allocate background pixel.");
-	
-	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);
-	sysinfo_set_item_val("fb.kind", NULL, 1);
-	sysinfo_set_item_val("fb.width", NULL, xres);
-	sysinfo_set_item_val("fb.height", NULL, yres);
-	sysinfo_set_item_val("fb.scanline", NULL, scanline);
-	sysinfo_set_item_val("fb.visual", NULL, props->visual);
-	sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
-	
-	fb_redraw();
-	
-	outdev_initialize("fb", &fb_console, &fb_ops);
-	stdout = &fb_console;
+		instance->ylogo = 0;
+		instance->ytrim = instance->yres;
+		instance->rowtrim = instance->rows;
+	}
+	
+	instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
+	instance->glyphbytes = ROW2Y(instance->glyphscanline);
+	instance->bgscanbytes = instance->xres * instance->pixelbytes;
+	
+	size_t fbsize = instance->scanline * instance->yres;
+	size_t bbsize = instance->cols * instance->rows * sizeof(uint16_t);
+	size_t glyphsize = FONT_GLYPHS * instance->glyphbytes;
+	
+	instance->addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
+	if (!instance->addr) {
+		LOG("Unable to map framebuffer.");
+		free(instance);
+		free(fbdev);
+		return NULL;
+	}
+	
+	instance->backbuf = (uint16_t *) malloc(bbsize, 0);
+	if (!instance->backbuf) {
+		LOG("Unable to allocate backbuffer.");
+		free(instance);
+		free(fbdev);
+		return NULL;
+	}
+	
+	instance->glyphs = (uint8_t *) malloc(glyphsize, 0);
+	if (!instance->glyphs) {
+		LOG("Unable to allocate glyphs.");
+		free(instance->backbuf);
+		free(instance);
+		free(fbdev);
+		return NULL;
+	}
+	
+	instance->bgscan = malloc(instance->bgscanbytes, 0);
+	if (!instance->bgscan) {
+		LOG("Unable to allocate background pixel.");
+		free(instance->glyphs);
+		free(instance->backbuf);
+		free(instance);
+		free(fbdev);
+		return NULL;
+	}
+	
+	memsetw(instance->backbuf, instance->cols * instance->rows, 0);
+	glyphs_render(instance);
+	
+	if (!fb_exported) {
+		/*
+		 * This is the necessary evil until the userspace driver is entirely
+		 * self-sufficient.
+		 */
+		sysinfo_set_item_val("fb", NULL, true);
+		sysinfo_set_item_val("fb.kind", NULL, 1);
+		sysinfo_set_item_val("fb.width", NULL, instance->xres);
+		sysinfo_set_item_val("fb.height", NULL, instance->yres);
+		sysinfo_set_item_val("fb.scanline", NULL, instance->scanline);
+		sysinfo_set_item_val("fb.visual", NULL, props->visual);
+		sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
+		
+		fb_exported = true;
+	}
+	
+	fb_redraw(fbdev);
+	return fbdev;
 }
 
Index: kernel/genarch/src/ofw/ebus.c
===================================================================
--- kernel/genarch/src/ofw/ebus.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/ofw/ebus.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/ofw/fhc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/ofw/pci.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/ofw/sbus.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/genarch/src/ofw/upa.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -37,4 +37,5 @@
 
 #include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/upa.h>
 #include <arch/memstr.h>
 #include <func.h>
Index: kernel/genarch/src/softint/multiplication.c
===================================================================
--- kernel/genarch/src/softint/multiplication.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ kernel/genarch/src/softint/multiplication.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2009 Josef Cejka
+ * 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 genarch
+ * @{
+ */ 
+/**
+ * @file
+ * SW implementation of 32 and 64 bit multiplication.
+ */
+
+#include <genarch/softint/multiplication.h>
+
+/** Set 1 to return MAX_INT64 or MIN_INT64 on overflow */
+#ifndef SOFTINT_CHECK_OF
+# define SOFTINT_CHECK_OF 0
+#endif
+
+#define MAX_UINT16 (0xFFFFu)
+#define MAX_UINT32 (0xFFFFFFFFu)
+#define MAX_INT64 (0x7FFFFFFFFFFFFFFFll)
+#define MIN_INT64 (0x8000000000000000ll)
+
+/**
+ * Multiply two integers and return long long as result. 
+ * This function is overflow safe.
+ * @param a
+ * @param b
+ * @result
+ */
+static unsigned long long mul(unsigned int a, unsigned int b) {
+	unsigned int a1, a2, b1, b2;
+	unsigned long long t1, t2, t3;	
+
+	a1 = a >> 16;
+	a2 = a & MAX_UINT16;
+	b1 = b >> 16;
+	b2 = b & MAX_UINT16;
+
+	t1 = a1 * b1;
+	t2 = a1*b2;
+	t2 += a2*b1;
+	t3 = a2*b2;
+
+	t3 = (((t1 << 16) + t2) << 16) + t3; 
+
+	return t3;
+}
+
+/** Emulate multiplication of two 64-bit long long integers.
+ *
+ */
+long long __muldi3 (long long a, long long b)
+{
+	long long result;
+	unsigned long long t1,t2;
+	unsigned long long a1, a2, b1, b2;
+	char neg = 0;
+
+	if (a < 0) {
+		neg = !neg;
+		a = -a;
+	}
+
+	if (b < 0) {
+		neg = !neg;
+		b = -b;
+	}
+
+	a1 = a >> 32;
+	b1 = b >> 32;
+
+	a2 = a & (MAX_UINT32);
+	b2 = b & (MAX_UINT32);
+
+	if (SOFTINT_CHECK_OF && (a1 != 0) && (b1 != 0)) {
+		// error, overflow
+		return (neg?MIN_INT64:MAX_INT64);
+	}
+
+	// (if OF checked) a1 or b1 is zero => result fits in 64 bits, no need to another overflow check
+	t1 = mul(a1,b2) + mul(b1,a2);	
+
+	if (SOFTINT_CHECK_OF && t1 > MAX_UINT32) {
+		// error, overflow
+		return (neg?MIN_INT64:MAX_INT64);
+	}
+
+	t1 = t1 << 32;
+	t2 = mul(a2,b2);
+	t2 += t1;
+
+	/* t2 & (1ull << 63) - if this bit is set in unsigned long long,
+	 * result does not fit in signed one */
+	if (SOFTINT_CHECK_OF && ((t2 < t1) || (t2 & (1ull << 63)))) {
+		// error, overflow
+		return (neg?MIN_INT64:MAX_INT64);
+	}
+
+	result = t2;
+
+	if (neg) {
+		result = -result;
+	}
+
+	return result;
+}	
+
+/** @}
+ */
Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/console/chardev.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -36,4 +36,5 @@
 #define KERN_CHARDEV_H_
 
+#include <adt/list.h>
 #include <arch/types.h>
 #include <synch/waitq.h>
@@ -73,7 +74,10 @@
 	/** Write character to output. */
 	void (* write)(struct outdev *, wchar_t, bool);
+	
+	/** Redraw any previously cached characters. */
+	void (* redraw)(struct outdev *);
 } outdev_operations_t;
 
-/** Character input device. */
+/** Character output device. */
 typedef struct outdev {
 	char *name;
@@ -81,4 +85,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 fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/console/console.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -44,4 +44,5 @@
 
 extern indev_t *stdin_wire(void);
+extern void stdout_wire(outdev_t *outdev);
 extern void console_init(void);
 
@@ -59,7 +60,4 @@
 extern unative_t sys_debug_disable_console(void);
 
-extern void arch_grab_console(void);
-extern void arch_release_console(void);
-
 #endif /* KERN_CONSOLE_H_ */
 
Index: kernel/generic/include/context.h
===================================================================
--- kernel/generic/include/context.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/context.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -51,17 +51,29 @@
 /** Save register context.
  *
- * Save current register context (including stack pointers)
- * to context structure.
- *
- * Note that call to context_restore() will return at the same
+ * Save the current register context (including stack pointer) to a context
+ * structure. A subsequent call to context_restore() will return to the same
  * address as the corresponding call to context_save().
  *
- * This MUST be a macro, gcc -O0 does not inline functions even
- * if they are marked inline and context_save_arch must be called
- * from level <= that when context_restore is called.
+ * Note that context_save_arch() must reuse the stack frame of the function
+ * which called context_save(). We guarantee this by:
  *
- * @param c Context structure.
+ *   a) implementing context_save_arch() in assembly so that it does not create
+ *      its own stack frame, and by
+ *   b) defining context_save() as a macro because the inline keyword is just a
+ *      hint for the compiler, not a real constraint; the application of a macro
+ *      will definitely not create a stack frame either.
  *
- * @return context_save() returns 1, context_restore() returns 0.
+ * To imagine what could happen if there were some extra stack frames created
+ * either by context_save() or context_save_arch(), we need to realize that the
+ * sp saved in the contex_t structure points to the current stack frame as it
+ * existed when context_save_arch() was executing. After the return from
+ * context_save_arch() and context_save(), any extra stack frames created by
+ * these functions will be destroyed and their contents sooner or later
+ * overwritten by functions called next. Any attempt to restore to a context
+ * saved like that would therefore lead to a disaster.
+ *
+ * @param c		Context structure.
+ *
+ * @return		context_save() returns 1, context_restore() returns 0.
  */
 #define context_save(c)   context_save_arch(c)
@@ -69,13 +81,12 @@
 /** Restore register context.
  *
- * Restore previously saved register context (including stack pointers)
- * from context structure.
+ * Restore a previously saved register context (including stack pointer) from
+ * a context structure.
  *
- * Note that this function does not normally return.
- * Instead, it returns at the same address as the
- * corresponding call to context_save(), the only
- * difference being return value.
+ * Note that this function does not normally return.  Instead, it returns to the
+ * same address as the corresponding call to context_save(), the only difference
+ * being return value.
  *
- * @param c Context structure.
+ * @param c		Context structure.
  */
 static inline void context_restore(context_t *c)
Index: kernel/generic/include/ddi/irq.h
===================================================================
--- kernel/generic/include/ddi/irq.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/ddi/irq.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -37,13 +37,29 @@
 
 typedef enum {
+	/** Read 1 byte from the I/O space. */
 	CMD_PIO_READ_8 = 1,
+	/** Read 2 bytes from the I/O space. */
 	CMD_PIO_READ_16,
+	/** Read 4 bytes from the I/O space. */
 	CMD_PIO_READ_32,
+	/** Write 1 byte to the I/O space. */
 	CMD_PIO_WRITE_8,
+	/** Write 2 bytes to the I/O space. */
 	CMD_PIO_WRITE_16,
+	/** Write 4 bytes to the I/O space. */
 	CMD_PIO_WRITE_32,
+	/**
+	 * Perform a bit test on the source argument and store the result into
+	 * the destination argument.
+	 */
 	CMD_BTEST,
+	/**
+	 * Predicate the execution of the following N commands by the boolean
+	 * value of the source argument.
+	 */
 	CMD_PREDICATE,
+	/** Accept the interrupt. */
 	CMD_ACCEPT,
+	/** Decline the interrupt. */
 	CMD_DECLINE,
 	CMD_LAST
Index: kernel/generic/include/ipc/sysipc.h
===================================================================
--- kernel/generic/include/ipc/sysipc.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/ipc/sysipc.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -52,4 +52,5 @@
 unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec,
     int nonblocking);
+unative_t sys_ipc_poke(void);
 unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
     unative_t method, unative_t arg1, unative_t arg2, int mode);
Index: kernel/generic/include/main/main.h
===================================================================
--- kernel/generic/include/main/main.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/main/main.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -38,4 +38,7 @@
 #include <arch/types.h>
 
+extern size_t hardcoded_kdata_size;
+extern size_t hardcoded_ktext_size;
+extern uintptr_t hardcoded_load_address;
 extern uintptr_t stack_safe;
 
Index: kernel/generic/include/print.h
===================================================================
--- kernel/generic/include/print.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/print.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -37,9 +37,5 @@
 
 #include <arch/types.h>
-#include <synch/spinlock.h>
-#include <arch/arg.h>
-
-/* We need this address in spinlock to avoid deadlock in deadlock detection */
-SPINLOCK_EXTERN(printf_lock);
+#include <stdarg.h>
 
 #define EOF (-1)
Index: kernel/generic/include/printf/printf_core.h
===================================================================
--- kernel/generic/include/printf/printf_core.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/printf/printf_core.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -37,5 +37,5 @@
 
 #include <typedefs.h>
-#include <arch/arg.h>
+#include <stdarg.h>
 
 /** Structure for specifying output methods for different printf clones. */
Index: rnel/generic/include/stackarg.h
===================================================================
--- kernel/generic/include/stackarg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup generic	
- * @{
- */
-/** @file
- */
-
-/*
- * Variable argument list manipulation macros
- * for architectures using stack to pass arguments.
- */
- 
-#ifndef KERN_STACKARG_H_
-#define KERN_STACKARG_H_
-
-#include <arch/types.h>
-
-typedef struct va_list {
-	int pos;
-	uint8_t *last;
-} va_list;
-
-#define va_start(ap, lst) 		\
-	(ap).pos = sizeof(lst); 			\
-	(ap).last = (uint8_t *) &(lst)
-
-#define va_arg(ap, type) 		\
-	(*((type *)((ap).last + ((ap).pos += sizeof(type)) - sizeof(type))))
-
-#define va_copy(dst, src) dst = src
-#define va_end(ap)
-
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/stdarg.h
===================================================================
--- kernel/generic/include/stdarg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/stdarg.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -37,5 +37,5 @@
  * for all architectures with compiler support for __builtin_va_*.
  */
- 
+
 #ifndef KERN_STDARG_H_
 #define KERN_STDARG_H_
@@ -43,8 +43,8 @@
 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_copy(dst, src)		__builtin_va_copy(dst, src)
+#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_copy(dst, src)   __builtin_va_copy(dst, src)
 
 #endif
Index: kernel/generic/include/synch/spinlock.h
===================================================================
--- kernel/generic/include/synch/spinlock.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/synch/spinlock.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -43,9 +43,11 @@
 
 #ifdef CONFIG_SMP
+
 typedef struct {
+	atomic_t val;
+	
 #ifdef CONFIG_DEBUG_SPINLOCK
 	char *name;
 #endif
-	atomic_t val;
 } spinlock_t;
 
@@ -54,6 +56,6 @@
  * where the lock gets initialized in run time.
  */
-#define SPINLOCK_DECLARE(slname) 	spinlock_t slname
-#define SPINLOCK_EXTERN(slname)		extern spinlock_t slname
+#define SPINLOCK_DECLARE(lock_name)  spinlock_t lock_name
+#define SPINLOCK_EXTERN(lock_name)   extern spinlock_t lock_name
 
 /*
@@ -62,25 +64,44 @@
  */
 #ifdef CONFIG_DEBUG_SPINLOCK
-#define SPINLOCK_INITIALIZE(slname) 	\
-	spinlock_t slname = { 		\
-		.name = #slname,	\
-		.val = { 0 }		\
+
+#define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
+	spinlock_t lock_name = { \
+		.name = desc_name, \
+		.val = { 0 } \
 	}
+
+#define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
+	static spinlock_t lock_name = { \
+		.name = desc_name, \
+		.val = { 0 } \
+	}
+
+#define spinlock_lock(lock)  spinlock_lock_debug(lock)
+
 #else
-#define SPINLOCK_INITIALIZE(slname) 	\
-	spinlock_t slname = { 		\
-		.val = { 0 }		\
+
+#define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
+	spinlock_t lock_name = { \
+		.val = { 0 } \
 	}
+
+#define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
+	static spinlock_t lock_name = { \
+		.val = { 0 } \
+	}
+
+#define spinlock_lock(lock)  atomic_lock_arch(&(lock)->val)
+
 #endif
 
-extern void spinlock_initialize(spinlock_t *sl, char *name);
-extern int spinlock_trylock(spinlock_t *sl);
-extern void spinlock_lock_debug(spinlock_t *sl);
+#define SPINLOCK_INITIALIZE(lock_name) \
+	SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name)
 
-#ifdef CONFIG_DEBUG_SPINLOCK
-#  define spinlock_lock(x) spinlock_lock_debug(x)
-#else
-#  define spinlock_lock(x) atomic_lock_arch(&(x)->val)
-#endif
+#define SPINLOCK_STATIC_INITIALIZE(lock_name) \
+	SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
+
+extern void spinlock_initialize(spinlock_t *lock, char *name);
+extern int spinlock_trylock(spinlock_t *lock);
+extern void spinlock_lock_debug(spinlock_t *lock);
 
 /** Unlock spinlock
@@ -90,8 +111,8 @@
  * @param sl Pointer to spinlock_t structure.
  */
-static inline void spinlock_unlock(spinlock_t *sl)
+static inline void spinlock_unlock(spinlock_t *lock)
 {
-	ASSERT(atomic_get(&sl->val) != 0);
-
+	ASSERT(atomic_get(&lock->val) != 0);
+	
 	/*
 	 * Prevent critical section code from bleeding out this way down.
@@ -99,5 +120,5 @@
 	CS_LEAVE_BARRIER();
 	
-	atomic_set(&sl->val, 0);
+	atomic_set(&lock->val, 0);
 	preemption_enable();
 }
@@ -105,31 +126,43 @@
 #ifdef CONFIG_DEBUG_SPINLOCK
 
-extern int printf(const char *, ...);
+#include <print.h>
 
-#define DEADLOCK_THRESHOLD		100000000
-#define DEADLOCK_PROBE_INIT(pname)	size_t pname = 0
-#define DEADLOCK_PROBE(pname, value)					\
-	if ((pname)++ > (value)) {					\
-		(pname) = 0;						\
-		printf("Deadlock probe %s: exceeded threshold %u\n",	\
-		    "cpu%u: function=%s, line=%u\n",			\
-		    #pname, (value), CPU->id, __func__, __LINE__);	\
+#define DEADLOCK_THRESHOLD  100000000
+
+#define DEADLOCK_PROBE_INIT(pname)  size_t pname = 0
+
+#define DEADLOCK_PROBE(pname, value) \
+	if ((pname)++ > (value)) { \
+		(pname) = 0; \
+		printf("Deadlock probe %s: exceeded threshold %u\n", \
+		    "cpu%u: function=%s, line=%u\n", \
+		    #pname, (value), CPU->id, __func__, __LINE__); \
 	}
-#else
-#define DEADLOCK_PROBE_INIT(pname)
-#define DEADLOCK_PROBE(pname, value)
-#endif
 
 #else
 
+#define DEADLOCK_PROBE_INIT(pname)
+#define DEADLOCK_PROBE(pname, value)
+
+#endif
+
+#else /* CONFIG_SMP */
+
 /* On UP systems, spinlocks are effectively left out. */
+
 #define SPINLOCK_DECLARE(name)
 #define SPINLOCK_EXTERN(name)
+
 #define SPINLOCK_INITIALIZE(name)
+#define SPINLOCK_STATIC_INITIALIZE(name)
 
-#define spinlock_initialize(x, name)
-#define spinlock_lock(x)		preemption_disable()
-#define spinlock_trylock(x) 		(preemption_disable(), 1)
-#define spinlock_unlock(x)		preemption_enable()
+#define SPINLOCK_INITIALIZE_NAME(name, desc_name)
+#define SPINLOCK_STATIC_INITIALIZE_NAME(name, desc_name)
+
+#define spinlock_initialize(lock, name)
+
+#define spinlock_lock(lock)     preemption_disable()
+#define spinlock_trylock(lock)  (preemption_disable(), 1)
+#define spinlock_unlock(lock)   preemption_enable()
 
 #define DEADLOCK_PROBE_INIT(pname)
Index: kernel/generic/include/synch/waitq.h
===================================================================
--- kernel/generic/include/synch/waitq.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/synch/waitq.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -68,12 +68,13 @@
 struct thread;
 
-extern void waitq_initialize(waitq_t *wq);
-extern int waitq_sleep_timeout(waitq_t *wq, uint32_t usec, int flags);
-extern ipl_t waitq_sleep_prepare(waitq_t *wq);
-extern int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, int flags);
-extern void waitq_sleep_finish(waitq_t *wq, int rc, ipl_t ipl);
-extern void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode);
-extern void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode);
-extern void waitq_interrupt_sleep(struct thread *t);
+extern void waitq_initialize(waitq_t *);
+extern int waitq_sleep_timeout(waitq_t *, uint32_t, int);
+extern ipl_t waitq_sleep_prepare(waitq_t *);
+extern int waitq_sleep_timeout_unsafe(waitq_t *, uint32_t, int);
+extern void waitq_sleep_finish(waitq_t *, int, ipl_t);
+extern void waitq_wakeup(waitq_t *, wakeup_mode_t);
+extern void _waitq_wakeup_unsafe(waitq_t *, wakeup_mode_t);
+extern void waitq_interrupt_sleep(struct thread *);
+extern void waitq_unsleep(waitq_t *);
 
 #endif
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/syscall/syscall.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -66,4 +66,5 @@
 	SYS_IPC_FORWARD_SLOW,
 	SYS_IPC_WAIT,
+	SYS_IPC_POKE,
 	SYS_IPC_HANGUP,
 	SYS_IPC_REGISTER_IRQ,
Index: kernel/generic/include/sysinfo/sysinfo.h
===================================================================
--- kernel/generic/include/sysinfo/sysinfo.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/include/sysinfo/sysinfo.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -38,4 +38,6 @@
 #include <arch/types.h>
 #include <string.h>
+
+extern bool fb_exported;
 
 typedef union sysinfo_item_val {
Index: kernel/generic/src/console/chardev.c
===================================================================
--- kernel/generic/src/console/chardev.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/console/chardev.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -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/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/console/cmd.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -409,4 +409,17 @@
 };
 
+/* Data and methods for 'kill' command */
+static int cmd_kill(cmd_arg_t *argv);
+static cmd_arg_t kill_argv = {
+	.type = ARG_TYPE_INT,
+};
+static cmd_info_t kill_info = {
+	.name = "kill",
+	.description = "kill <taskid> Kill a task.",
+	.func = cmd_kill,
+	.argc = 1,
+	.argv = &kill_argv
+};
+
 /* Data and methods for 'zone' command */
 static int cmd_zone(cmd_arg_t *argv);
@@ -459,4 +472,5 @@
 	&help_info,
 	&ipc_info,
+	&kill_info,
 	&set4_info,
 	&slabs_info,
@@ -848,5 +862,6 @@
  * @return Always 1
  */
-int cmd_slabs(cmd_arg_t * argv) {
+int cmd_slabs(cmd_arg_t * argv)
+{
 	slab_print_list();
 	return 1;
@@ -860,5 +875,6 @@
  * @return Always 1
  */
-int cmd_threads(cmd_arg_t * argv) {
+int cmd_threads(cmd_arg_t * argv)
+{
 	thread_print_list();
 	return 1;
@@ -871,5 +887,6 @@
  * @return Always 1
  */
-int cmd_tasks(cmd_arg_t * argv) {
+int cmd_tasks(cmd_arg_t * argv)
+{
 	task_print_list();
 	return 1;
@@ -882,5 +899,6 @@
  * @return Always 1
  */
-int cmd_sched(cmd_arg_t * argv) {
+int cmd_sched(cmd_arg_t * argv)
+{
 	sched_print_list();
 	return 1;
@@ -893,5 +911,6 @@
  * return Always 1
  */
-int cmd_zones(cmd_arg_t * argv) {
+int cmd_zones(cmd_arg_t * argv)
+{
 	zone_print_list();
 	return 1;
@@ -904,5 +923,6 @@
  * return Always 1
  */
-int cmd_zone(cmd_arg_t * argv) {
+int cmd_zone(cmd_arg_t * argv)
+{
 	zone_print_one(argv[0].intval);
 	return 1;
@@ -915,9 +935,23 @@
  * return Always 1
  */
-int cmd_ipc(cmd_arg_t * argv) {
+int cmd_ipc(cmd_arg_t * argv)
+{
 	ipc_print_task(argv[0].intval);
 	return 1;
 }
 
+/** Command for killing a task
+ *
+ * @param argv Integer argument from cmdline expected
+ *
+ * return 0 on failure, 1 on success.
+ */
+int cmd_kill(cmd_arg_t * argv)
+{
+	if (task_kill(argv[0].intval) != EOK)
+		return 0;
+
+	return 1;
+}
 
 /** Command for listing processors.
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/console/console.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -71,8 +71,11 @@
 
 /** Kernel log spinlock */
-SPINLOCK_INITIALIZE(klog_lock);
+SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "*klog_lock");
 
 /** Physical memory area used for klog buffer */
 static parea_t klog_parea;
+
+static indev_t stdin_sink;
+static outdev_t stdout_source;
 
 static indev_operations_t stdin_ops = {
@@ -80,4 +83,12 @@
 };
 
+static void stdout_write(outdev_t *dev, wchar_t ch, bool silent);
+static void stdout_redraw(outdev_t *dev);
+
+static outdev_operations_t stdout_ops = {
+	.write = stdout_write,
+	.redraw = stdout_redraw
+};
+
 /** Silence output */
 bool silent = false;
@@ -90,10 +101,41 @@
 {
 	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);
+		if ((sink) && (sink->op->write))
+			sink->op->write(sink, ch, silent);
+	}
+}
+
+static void stdout_redraw(outdev_t *dev)
+{
+	link_t *cur;
+	
+	for (cur = dev->list.next; cur != &dev->list; cur = cur->next) {
+		outdev_t *sink = list_get_instance(cur, outdev_t, link);
+		if ((sink) && (sink->op->redraw))
+			sink->op->redraw(sink);
+	}
 }
 
@@ -128,5 +170,6 @@
 	
 	silent = false;
-	arch_grab_console();
+	if ((stdout) && (stdout->op->redraw))
+		stdout->op->redraw(stdout);
 	
 	/* Force the console to print the prompt */
@@ -137,6 +180,6 @@
 void release_console(void)
 {
+	// FIXME arch_release_console
 	silent = true;
-	arch_release_console();
 }
 
@@ -276,15 +319,15 @@
 	
 	if (size > PAGE_SIZE)
-		return ELIMIT;
+		return (unative_t) ELIMIT;
 	
 	if (size > 0) {
 		data = (char *) malloc(size + 1, 0);
 		if (!data)
-			return ENOMEM;
+			return (unative_t) ENOMEM;
 		
 		rc = copy_from_uspace(data, buf, size);
 		if (rc) {
 			free(data);
-			return rc;
+			return (unative_t) rc;
 		}
 		data[size] = 0;
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/ddi/ddi.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -276,5 +276,5 @@
 unative_t sys_preempt_control(int enable)
 {
-	if (!cap_get(TASK) & CAP_PREEMPT_CONTROL)
+	if (!(cap_get(TASK) & CAP_PREEMPT_CONTROL))
 		return EPERM;
 	
Index: kernel/generic/src/ipc/kbox.c
===================================================================
--- kernel/generic/src/ipc/kbox.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/ipc/kbox.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -137,5 +137,5 @@
 		/* Only detach kbox thread unless already terminating. */
 		mutex_lock(&TASK->kb.cleanup_lock);
-		if (&TASK->kb.finished == false) {
+		if (TASK->kb.finished == false) {
 			/* Detach kbox thread so it gets freed from memory. */
 			thread_detach(TASK->kb.thread);
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/ipc/sysipc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -44,4 +44,5 @@
 #include <ipc/ipcrsc.h>
 #include <ipc/kbox.h>
+#include <synch/waitq.h>
 #include <udebug/udebug_ipc.h>
 #include <arch/interrupt.h>
@@ -1051,4 +1052,11 @@
 }
 
+/** Interrupt one thread from sys_ipc_wait_for_call(). */
+unative_t sys_ipc_poke(void)
+{
+	waitq_unsleep(&TASK->answerbox.wq);	
+	return EOK;
+}
+
 /** Connect an IRQ handler to a task.
  *
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/main/main.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -101,16 +101,4 @@
 context_t ctx;
 
-/*
- * These 'hardcoded' variables will be intialized by
- * the linker or the low level assembler code with
- * appropriate sizes and addresses.
- */
-
-/** Virtual address of where the kernel is loaded. */
-uintptr_t hardcoded_load_address = 0;
-/** Size of the kernel code in bytes. */
-size_t hardcoded_ktext_size = 0;
-/** Size of the kernel data in bytes. */
-size_t hardcoded_kdata_size = 0;
 /** Lowest safe stack virtual address. */
 uintptr_t stack_safe = 0;		
Index: kernel/generic/src/printf/printf_core.c
===================================================================
--- kernel/generic/src/printf/printf_core.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/printf/printf_core.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -39,5 +39,5 @@
 #include <printf/printf_core.h>
 #include <print.h>
-#include <arch/arg.h>
+#include <stdarg.h>
 #include <macros.h>
 #include <string.h>
Index: kernel/generic/src/printf/vprintf.c
===================================================================
--- kernel/generic/src/printf/vprintf.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/printf/vprintf.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -42,5 +42,5 @@
 #include <string.h>
 
-SPINLOCK_INITIALIZE(printf_lock);  /**< vprintf spinlock */
+SPINLOCK_STATIC_INITIALIZE_NAME(printf_lock, "*printf_lock");
 
 static int vprintf_str_write(const char *str, size_t size, void *data)
Index: kernel/generic/src/synch/spinlock.c
===================================================================
--- kernel/generic/src/synch/spinlock.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/synch/spinlock.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -45,23 +45,20 @@
 #include <symtab.h>
 
-#ifdef CONFIG_FB
-#include <genarch/fb/fb.h>
-#endif
-
 #ifdef CONFIG_SMP
 
 /** Initialize spinlock
  *
- * Initialize spinlock.
+ * @param sl Pointer to spinlock_t structure.
  *
- * @param sl Pointer to spinlock_t structure.
  */
-void spinlock_initialize(spinlock_t *sl, char *name)
+void spinlock_initialize(spinlock_t *lock, char *name)
 {
-	atomic_set(&sl->val, 0);
+	atomic_set(&lock->val, 0);
 #ifdef CONFIG_DEBUG_SPINLOCK
-	sl->name = name;
-#endif	
+	lock->name = name;
+#endif
 }
+
+#ifdef CONFIG_DEBUG_SPINLOCK
 
 /** Lock spinlock
@@ -71,41 +68,40 @@
  * possible occurence of deadlock.
  *
- * @param sl Pointer to spinlock_t structure.
+ * @param lock Pointer to spinlock_t structure.
+ *
  */
-#ifdef CONFIG_DEBUG_SPINLOCK
-void spinlock_lock_debug(spinlock_t *sl)
+void spinlock_lock_debug(spinlock_t *lock)
 {
 	size_t i = 0;
 	bool deadlock_reported = false;
-
+	
 	preemption_disable();
-	while (test_and_set(&sl->val)) {
-
+	while (test_and_set(&lock->val)) {
 		/*
-		 * We need to be careful about printf_lock and fb_lock.
-		 * Both of them are used to report deadlocks via
-		 * printf() and fb_putchar().
+		 * We need to be careful about particular locks
+		 * which are directly used to report deadlocks
+		 * via printf() (and recursively other functions).
+		 * This conserns especially printf_lock and the
+		 * framebuffer lock.
 		 *
+		 * Any lock whose name is prefixed by "*" will be
+		 * ignored by this deadlock detection routine
+		 * as this might cause an infinite recursion.
 		 * We trust our code that there is no possible deadlock
-		 * caused by these two locks (except when an exception
-		 * is triggered for instance by printf() or fb_putchar()).
-		 * However, we encountered false positives caused by very
-		 * slow VESA framebuffer interaction (especially when
+		 * caused by these locks (except when an exception
+		 * is triggered for instance by printf()).
+		 *
+		 * We encountered false positives caused by very
+		 * slow framebuffer interaction (especially when
 		 * run in a simulator) that caused problems with both
-		 * printf_lock and fb_lock.
+		 * printf_lock and the framebuffer lock.
 		 *
-		 * Possible deadlocks on both printf_lock and fb_lock
-		 * are therefore not reported as they would cause an
-		 * infinite recursion.
 		 */
-		if (sl == &printf_lock)
+		if (lock->name[0] == '*')
 			continue;
-#ifdef CONFIG_FB
-		if (sl == &fb_lock)
-			continue;
-#endif
+		
 		if (i++ > DEADLOCK_THRESHOLD) {
 			printf("cpu%u: looping on spinlock %" PRIp ":%s, "
-			    "caller=%" PRIp "(%s)\n", CPU->id, sl, sl->name,
+			    "caller=%" PRIp "(%s)\n", CPU->id, lock, lock->name,
 			    CALLER, symtab_fmt_name_lookup(CALLER));
 			
@@ -114,8 +110,8 @@
 		}
 	}
-
+	
 	if (deadlock_reported)
 		printf("cpu%u: not deadlocked\n", CPU->id);
-
+	
 	/*
 	 * Prevent critical section code from bleeding out this way up.
@@ -123,4 +119,5 @@
 	CS_ENTER_BARRIER();
 }
+
 #endif
 
@@ -131,20 +128,19 @@
  * signal failure.
  *
- * @param sl Pointer to spinlock_t structure.
+ * @param lock Pointer to spinlock_t structure.
  *
  * @return Zero on failure, non-zero otherwise.
+ *
  */
-int spinlock_trylock(spinlock_t *sl)
+int spinlock_trylock(spinlock_t *lock)
 {
-	int rc;
+	preemption_disable();
+	int rc = !test_and_set(&lock->val);
 	
-	preemption_disable();
-	rc = !test_and_set(&sl->val);
-
 	/*
 	 * Prevent critical section code from bleeding out this way up.
 	 */
 	CS_ENTER_BARRIER();
-
+	
 	if (!rc)
 		preemption_enable();
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/synch/waitq.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -171,4 +171,37 @@
 out:
 	spinlock_unlock(&threads_lock);
+	interrupts_restore(ipl);
+}
+
+/** Interrupt the first thread sleeping in the wait queue.
+ *
+ * Note that the caller somehow needs to know that the thread to be interrupted
+ * is sleeping interruptibly.
+ *
+ * @param wq		Pointer to wait queue.
+ */
+void waitq_unsleep(waitq_t *wq)
+{
+	ipl_t ipl;
+
+	ipl = interrupts_disable();
+	spinlock_lock(&wq->lock);
+
+	if (!list_empty(&wq->head)) {
+		thread_t *t;
+		
+		t = list_get_instance(wq->head.next, thread_t, wq_link);
+		spinlock_lock(&t->lock);
+		ASSERT(t->sleep_interruptible);
+		if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
+			t->timeout_pending = false;
+		list_remove(&t->wq_link);
+		t->saved_context = t->sleep_interruption_context;
+		t->sleep_queue = NULL;
+		spinlock_unlock(&t->lock);
+		thread_ready(t);
+	}
+
+	spinlock_unlock(&wq->lock);
 	interrupts_restore(ipl);
 }
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/syscall/syscall.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -137,4 +137,5 @@
 	(syshandler_t) sys_ipc_forward_slow,
 	(syshandler_t) sys_ipc_wait_for_call,
+	(syshandler_t) sys_ipc_poke,
 	(syshandler_t) sys_ipc_hangup,
 	(syshandler_t) sys_ipc_register_irq,
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -38,6 +38,6 @@
 #include <syscall/copy.h>
 
+bool fb_exported = false;
 sysinfo_item_t *_root = NULL;
-
 
 static sysinfo_item_t *sysinfo_find_item(const char *name, sysinfo_item_t *subtree)
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -33,9 +33,4 @@
 
 DIRS = \
-	lib/libc \
-	lib/libfs \
-	lib/libblock \
-	lib/softint \
-	lib/softfloat \
 	srv/bd/ata_bd \
 	srv/bd/file_bd \
@@ -52,4 +47,6 @@
 	srv/vfs \
 	srv/devmap \
+	srv/part/mbr_part \
+	app/edit \
 	app/tetris \
 	app/shutters \
@@ -60,4 +57,5 @@
 	app/init \
 	app/getvc \
+	app/redir \
 	app/bdsh
 
@@ -82,10 +80,20 @@
 endif
 
+LIBC = lib/libc
+LIBS = \
+	lib/libfs \
+	lib/libblock \
+	lib/softint \
+	lib/softfloat
+
+LIBC_BUILD = $(addsuffix .build,$(LIBC))
+LIBS_BUILD = $(addsuffix .build,$(LIBS))
+
 BUILDS := $(addsuffix .build,$(DIRS))
-CLEANS := $(addsuffix .clean,$(DIRS))
+CLEANS := $(addsuffix .clean,$(DIRS)) $(addsuffix .clean,$(LIBS)) $(addsuffix .clean,$(LIBC))
 
-.PHONY: all $(BUILDS) $(CLEANS) clean
+.PHONY: all $(LIBC_BUILD) $(LIBS_BUILD) $(BUILDS) $(CLEANS) clean
 
-all: ../Makefile.config ../config.h ../config.defs $(BUILDS)
+all: $(BUILDS)
 
 clean: $(CLEANS)
@@ -94,4 +102,10 @@
 	-$(MAKE) -C $(basename $@) clean
 
-$(BUILDS):
+$(BUILDS): $(LIBC_BUILD) $(LIBS_BUILD)
 	$(MAKE) -C $(basename $@) all
+
+$(LIBS_BUILD): $(LIBC_BUILD)
+	$(MAKE) -C $(basename $@) all
+
+$(LIBC_BUILD):
+	$(MAKE) -C $(basename $@) all
Index: uspace/app/bdsh/Makefile
===================================================================
--- uspace/app/bdsh/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/bdsh/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,139 +1,40 @@
-# Copyright (c) 2005,  Martin Decky
-# All rights reserved.
-# Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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:
+# 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 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.
 #
-# 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.
+# 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.
 #
-# Neither the name of the original program's authors nor the names of its
-# contributors may be used to endorse or promote products derived from this
-# software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
 
-include ../../../version
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
-LIBBLOCK_PREFIX = ../../lib/libblock
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I../../srv/kbd/include -I$(LIBBLOCK_PREFIX)
-
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
-DEFS += -DRELEASE=$(RELEASE)
-
-PROGRAM = bdsh
-
-# Any directory that cleaning targets should know about
-SUBDIRS = \
-	./ \
-	cmds/ \
-	cmds/modules/ \
-	cmds/modules/help/ \
-	cmds/modules/mkdir/ \
-	cmds/modules/rm/ \
-	cmds/modules/bdd/ \
-	cmds/modules/cat/ \
-	cmds/modules/touch/ \
-	cmds/modules/ls/ \
-	cmds/modules/pwd/ \
-	cmds/modules/sleep/ \
-	cmds/modules/cp/ \
-	cmds/modules/mv/ \
-	cmds/modules/mount/ \
-	cmds/modules/kcon/ \
-	cmds/builtins/ \
-	cmds/builtins/exit/\
-	cmds/builtins/cd/
-
-SOURCES = \
-	cmds/modules/help/help.c \
-	cmds/modules/mkdir/mkdir.c \
-	cmds/modules/rm/rm.c \
-	cmds/modules/bdd/bdd.c \
-	cmds/modules/cat/cat.c \
-	cmds/modules/touch/touch.c \
-	cmds/modules/ls/ls.c \
-	cmds/modules/pwd/pwd.c \
-	cmds/modules/sleep/sleep.c \
-	cmds/modules/cp/cp.c \
-	cmds/modules/mv/mv.c \
-	cmds/modules/mount/mount.c \
-	cmds/modules/kcon/kcon.c \
-	cmds/builtins/exit/exit.c \
-	cmds/builtins/cd/cd.c \
-	cmds/mod_cmds.c \
-	cmds/builtin_cmds.c \
-	errors.c \
-	input.c \
-	util.c \
-	exec.c \
-	scli.c
-
-CFLAGS += -I. -Icmds/ -Icmds/builtins -Icmds/modules
-
-OBJECTS = $(SOURCES:.c=.o)
-
-# For easy cleaning, *.o is already handled
-CLEANDIRS := $(addsuffix *~,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.bak,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.tmp,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.out,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.d,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.gch,$(SUBDIRS) )
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(CFLAGS) $(INC) -c $< -o $@
-	@$(CC) -M $(CFLAGS) $(INC) $*.c > $*.d
-
-$(PROGRAM): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(PROGRAM).map
-
-# Everything else is a phony target
-.PHONY: all clean distclean depend disasm
-
-all: $(PROGRAM) disasm
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	@-rm -f $(OBJECTS)
-	@-rm -f $(PROGRAM)
-	@-rm -f $(PROGRAM).map
-	@-rm -f $(PROGRAM).disasm
-	@-rm -f $(CLEANDIRS)
-
-depend:
-	@echo ''
-
-disasm:
-	$(OBJDUMP) -d $(PROGRAM) >$(PROGRAM).disasm
-
-distclean: clean
-
-# Do not delete - dependencies
--include $(OBJECTS:.o=.d)
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/bdsh/Makefile.build
===================================================================
--- uspace/app/bdsh/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/bdsh/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I$(LIBBLOCK_PREFIX) -I. -Icmds/ -Icmds/builtins -Icmds/modules
+
+## Sources
+#
+
+SOURCES = \
+	cmds/modules/help/help.c \
+	cmds/modules/mkdir/mkdir.c \
+	cmds/modules/rm/rm.c \
+	cmds/modules/bdd/bdd.c \
+	cmds/modules/cat/cat.c \
+	cmds/modules/touch/touch.c \
+	cmds/modules/ls/ls.c \
+	cmds/modules/pwd/pwd.c \
+	cmds/modules/sleep/sleep.c \
+	cmds/modules/cp/cp.c \
+	cmds/modules/mv/mv.c \
+	cmds/modules/mount/mount.c \
+	cmds/modules/kcon/kcon.c \
+	cmds/builtins/exit/exit.c \
+	cmds/builtins/cd/cd.c \
+	cmds/mod_cmds.c \
+	cmds/builtin_cmds.c \
+	errors.c \
+	input.c \
+	util.c \
+	exec.c \
+	scli.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/bdsh/Makefile.common
===================================================================
--- uspace/app/bdsh/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/bdsh/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBBLOCK_PREFIX = ../../lib/libblock
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = bdsh
Index: uspace/app/bdsh/cmds/modules/bdd/bdd.c
===================================================================
--- uspace/app/bdsh/cmds/modules/bdd/bdd.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/bdsh/cmds/modules/bdd/bdd.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -40,7 +40,10 @@
 #include <devmap.h>
 #include <errno.h>
+#include <assert.h>
 
-#define BLOCK_SIZE	512
-#define BPR		 16
+enum {
+	/* Number of bytes per row */
+	BPR = 16
+};
 
 static const char *cmdname = "bdd";
@@ -66,9 +69,9 @@
 	unsigned int i, j;
 	dev_handle_t handle;
-	block_t *block;
 	uint8_t *blk;
 	size_t size, bytes, rows;
+	size_t block_size;
 	int rc;
-	bn_t boff;
+	bn_t ba;
 	uint8_t b;
 
@@ -82,7 +85,7 @@
 
 	if (argc >= 3)
-		boff = strtol(argv[2], NULL, 0);
+		ba = strtol(argv[2], NULL, 0);
 	else
-		boff = 0;
+		ba = 0;
 
 	if (argc >= 4)
@@ -93,25 +96,37 @@
 	rc = devmap_device_get_handle(argv[1], &handle, 0);
 	if (rc != EOK) {
-		printf("Error: could not resolve device `%s'.\n", argv[1]);
+		printf("%s: Error resolving device `%s'.\n", cmdname, argv[1]);
 		return CMD_FAILURE;
 	}
 
-	rc = block_init(handle, BLOCK_SIZE);
+	rc = block_init(handle, 2048);
 	if (rc != EOK)  {
-		printf("Error: could not init libblock.\n");
+		printf("%s: Error initializing libblock.\n", cmdname);
 		return CMD_FAILURE;
 	}
 
-	rc = block_cache_init(handle, BLOCK_SIZE, 2, CACHE_MODE_WB);
+	rc = block_get_bsize(handle, &block_size);
 	if (rc != EOK) {
-		printf("Error: could not init block cache.\n");
+		printf("%s: Error determining device block size.\n", cmdname);
+		return CMD_FAILURE;
+	}
+
+	blk = malloc(block_size);
+	if (blk == NULL) {
+		printf("%s: Error allocating memory.\n", cmdname);
+		block_fini(handle);
 		return CMD_FAILURE;
 	}
 
 	while (size > 0) {
-		block = block_get(handle, boff, 0);
-		blk = (uint8_t *) block->data;
+		rc = block_read_direct(handle, ba, 1, blk);
+		if (rc != EOK) {
+			printf("%s: Error reading block %llu\n", cmdname, ba);
+			free(blk);
+			block_fini(handle);
+			return CMD_FAILURE;
+		}
 
-		bytes = (size < BLOCK_SIZE) ? size : BLOCK_SIZE;
+		bytes = (size < block_size) ? size : block_size;
 		rows = (bytes + BPR - 1) / BPR;
 
@@ -139,6 +154,4 @@
 		}
 
-		block_put(block);
-
 		if (size > rows * BPR)
 			size -= rows * BPR;
@@ -146,7 +159,9 @@
 			size = 0;
 
-		boff += rows * BPR;
+		/* Next block */
+		ba += 1;
 	}
 
+	free(blk);
 	block_fini(handle);
 
Index: uspace/app/bdsh/scli.c
===================================================================
--- uspace/app/bdsh/scli.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/bdsh/scli.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -61,8 +61,6 @@
 	usr->line = (char *) NULL;
 	usr->name = "root";
-	usr->home = "/";
 	usr->cwd = (char *) NULL;
 	usr->prompt = (char *) NULL;
-	chdir(usr->home);
 	usr->lasterr = 0;
 	return (int) cli_set_prompt(usr);
Index: uspace/app/bdsh/scli.h
===================================================================
--- uspace/app/bdsh/scli.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/bdsh/scli.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -7,5 +7,4 @@
 typedef struct {
 	char *name;
-	char *home;
 	char *line;
 	char *cwd;
Index: uspace/app/edit/Makefile
===================================================================
--- uspace/app/edit/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+include Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
+
+clean:
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/edit/Makefile.build
===================================================================
--- uspace/app/edit/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	edit.c \
+	sheet.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/edit/Makefile.common
===================================================================
--- uspace/app/edit/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = edit
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/edit.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,686 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 edit
+ * @brief Text editor.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <vfs/vfs.h>
+#include <io/console.h>
+#include <io/color.h>
+#include <io/keycode.h>
+#include <errno.h>
+#include <align.h>
+#include <macros.h>
+#include <bool.h>
+
+#include "sheet.h"
+
+enum redraw_flags {
+	REDRAW_TEXT	= (1 << 0),
+	REDRAW_ROW	= (1 << 1),
+	REDRAW_STATUS	= (1 << 2),
+	REDRAW_CARET	= (1 << 3)
+};
+
+/** Pane
+ *
+ * A rectangular area of the screen used to edit a document. Different
+ * panes can be possibly used to edit the same document.
+ */
+typedef struct {
+	/* Pane dimensions */
+	int rows, columns;
+
+	/* Position of the visible area */
+	int sh_row, sh_column;
+
+	/** Bitmask of components that need redrawing */
+	enum redraw_flags rflags;
+
+	/** Current position of the caret */
+	tag_t caret_pos;
+
+	/** 
+	 * Ideal column where the caret should try to get. This is used
+	 * for maintaining the same column during vertical movement.
+	 */
+	int ideal_column;
+} pane_t;
+
+/** Document
+ *
+ * Associates a sheet with a file where it can be saved to.
+ */
+typedef struct {
+	char *file_name;
+	sheet_t sh;
+} doc_t;
+
+static int con;
+static doc_t doc;
+static bool done;
+static pane_t pane;
+
+static int scr_rows, scr_columns;
+
+#define ROW_BUF_SIZE 4096
+#define BUF_SIZE 64
+#define TAB_WIDTH 8
+#define ED_INFTY 65536
+
+static void key_handle_unmod(console_event_t const *ev);
+static void key_handle_ctrl(console_event_t const *ev);
+static int file_save(char const *fname);
+static int file_insert(char *fname);
+static int file_save_range(char const *fname, spt_t const *spos,
+    spt_t const *epos);
+static void pane_text_display(void);
+static void pane_row_display(void);
+static void pane_row_range_display(int r0, int r1);
+static void pane_status_display(void);
+static void pane_caret_display(void);
+static void insert_char(wchar_t c);
+static void delete_char_before(void);
+static void delete_char_after(void);
+static void caret_update(void);
+static void caret_move(int drow, int dcolumn, enum dir_spec align_dir);
+static void pt_get_sof(spt_t *pt);
+static void pt_get_eof(spt_t *pt);
+static void status_display(char const *str);
+
+
+int main(int argc, char *argv[])
+{
+	console_event_t ev;
+	coord_t coord;
+	bool new_file;
+
+	spt_t pt;
+
+	con = fphone(stdout);
+	console_clear(con);
+
+	console_get_size(con, &scr_columns, &scr_rows);
+
+	pane.rows = scr_rows - 1;
+	pane.columns = scr_columns;
+	pane.sh_row = 1;
+	pane.sh_column = 1;
+
+	/* Start with an empty sheet. */
+	sheet_init(&doc.sh);
+
+	/* Place caret at the beginning of file. */
+	coord.row = coord.column = 1;
+	sheet_get_cell_pt(&doc.sh, &coord, dir_before, &pt);
+	sheet_place_tag(&doc.sh, &pt, &pane.caret_pos);
+	pane.ideal_column = coord.column;
+
+	if (argc == 2) {
+		doc.file_name = argv[1];
+	} else if (argc > 1) {
+		printf("Invalid arguments.\n");
+		return -2;
+	} else {
+		doc.file_name = "/edit.txt";
+	}
+
+	new_file = false;
+
+	if (file_insert(doc.file_name) != EOK)
+		new_file = true;
+
+	/* Move to beginning of file. */
+	caret_move(-ED_INFTY, -ED_INFTY, dir_before);
+
+	/* Initial display */
+	console_clear(con);
+	pane_text_display();
+	pane_status_display();
+	if (new_file)
+		status_display("File not found. Created empty file.");
+	pane_caret_display();
+
+
+	done = false;
+
+	while (!done) {
+		console_get_event(con, &ev);
+		pane.rflags = 0;
+
+		if (ev.type == KEY_PRESS) {
+			/* Handle key press. */
+			if (((ev.mods & KM_ALT) == 0) &&
+			     (ev.mods & KM_CTRL) != 0) {
+				key_handle_ctrl(&ev);
+			} else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {
+				key_handle_unmod(&ev);
+			}
+		}
+
+		/* Redraw as necessary. */
+
+		if (pane.rflags & REDRAW_TEXT)
+			pane_text_display();
+		if (pane.rflags & REDRAW_ROW)
+			pane_row_display();
+		if (pane.rflags & REDRAW_STATUS)
+			pane_status_display();
+		if (pane.rflags & REDRAW_CARET)
+			pane_caret_display();
+			
+	}
+
+	console_clear(con);
+
+	return 0;
+}
+
+/** Handle key without modifier. */
+static void key_handle_unmod(console_event_t const *ev)
+{
+	switch (ev->key) {
+	case KC_ENTER:
+		insert_char('\n');
+		caret_update();
+		break;
+	case KC_LEFT:
+		caret_move(0, -1, dir_before);
+		break;
+	case KC_RIGHT:
+		caret_move(0, 0, dir_after);
+		break;
+	case KC_UP:
+		caret_move(-1, 0, dir_before);
+		break;
+	case KC_DOWN:
+		caret_move(+1, 0, dir_before);
+		break;
+	case KC_HOME:
+		caret_move(0, -ED_INFTY, dir_before);
+		break;
+	case KC_END:
+		caret_move(0, +ED_INFTY, dir_before);
+		break;
+	case KC_PAGE_UP:
+		caret_move(-pane.rows, 0, dir_before);
+		break;
+	case KC_PAGE_DOWN:
+		caret_move(+pane.rows, 0, dir_before);
+		break;
+	case KC_BACKSPACE:
+		delete_char_before();
+		caret_update();
+		break;
+	case KC_DELETE:
+		delete_char_after();
+		caret_update();
+		break;
+	default:
+		if (ev->c >= 32 || ev->c == '\t') {
+			insert_char(ev->c);
+			caret_update();
+		}
+		break;
+	}
+}
+
+/** Handle Ctrl-key combination. */
+static void key_handle_ctrl(console_event_t const *ev)
+{
+	switch (ev->key) {
+	case KC_Q:
+		done = true;
+		break;
+	case KC_S:
+		(void) file_save(doc.file_name);
+		break;
+	default:
+		break;
+	}
+}
+
+
+/** Save the document. */
+static int file_save(char const *fname)
+{
+	spt_t sp, ep;
+	int rc;
+
+	status_display("Saving...");
+	pt_get_sof(&sp);
+	pt_get_eof(&ep);
+
+	rc = file_save_range(fname, &sp, &ep);
+	status_display("File saved.");
+
+	return rc;
+}
+
+/** Insert file at caret position.
+ *
+ * Reads in the contents of a file and inserts them at the current position
+ * of the caret.
+ */
+static int file_insert(char *fname)
+{
+	FILE *f;
+	wchar_t c;
+	char buf[BUF_SIZE];
+	int bcnt;
+	int n_read;
+	size_t off;
+
+	f = fopen(fname, "rt");
+	if (f == NULL)
+		return EINVAL;
+
+	bcnt = 0;
+
+	while (true) {
+		if (bcnt < STR_BOUNDS(1)) {
+			n_read = fread(buf + bcnt, 1, BUF_SIZE - bcnt, f);
+			bcnt += n_read;
+		}
+
+		off = 0;
+		c = str_decode(buf, &off, bcnt);
+		if (c == '\0')
+			break;
+
+		bcnt -= off;
+		memcpy(buf, buf + off, bcnt);
+
+		insert_char(c);
+	}
+
+	fclose(f);
+
+	return EOK;
+}
+
+/** Save a range of text into a file. */
+static int file_save_range(char const *fname, spt_t const *spos,
+    spt_t const *epos)
+{
+	FILE *f;
+	char buf[BUF_SIZE];
+	spt_t sp, bep;
+	size_t bytes, n_written;
+
+	f = fopen(fname, "wt");
+	if (f == NULL)
+		return EINVAL;
+
+	sp = *spos;
+
+	do {
+		sheet_copy_out(&doc.sh, &sp, epos, buf, BUF_SIZE, &bep);
+		bytes = str_size(buf);
+
+		n_written = fwrite(buf, 1, bytes, f);
+		if (n_written != bytes) {
+			return EIO;
+		}
+
+		sp = bep;
+	} while (!spt_equal(&bep, epos));
+
+	fclose(f);
+
+	return EOK;
+}
+
+static void pane_text_display(void)
+{
+	int sh_rows, rows;
+	int i, j;
+
+	sheet_get_num_rows(&doc.sh, &sh_rows);
+	rows = min(sh_rows - pane.sh_row + 1, pane.rows);
+
+	/* Draw rows from the sheet. */
+
+	console_goto(con, 0, 0);
+	pane_row_range_display(0, rows);
+
+	/* Clear the remaining rows if file is short. */
+
+	for (i = rows; i < pane.rows; ++i) {
+		console_goto(con, 0, i);
+		for (j = 0; j < scr_columns; ++j)
+			putchar(' ');
+		fflush(stdout);
+	}
+
+	pane.rflags |= (REDRAW_STATUS | REDRAW_CARET);
+	pane.rflags &= ~REDRAW_ROW;
+}
+
+/** Display just the row where the caret is. */
+static void pane_row_display(void)
+{
+	spt_t caret_pt;
+	coord_t coord;
+	int ridx;
+
+	tag_get_pt(&pane.caret_pos, &caret_pt);
+	spt_get_coord(&caret_pt, &coord);
+
+	ridx = coord.row - pane.sh_row;
+	pane_row_range_display(ridx, ridx + 1);
+	pane.rflags |= (REDRAW_STATUS | REDRAW_CARET);
+}
+
+static void pane_row_range_display(int r0, int r1)
+{
+	int i, j, fill;
+	spt_t rb, re, dep;
+	coord_t rbc, rec;
+	char row_buf[ROW_BUF_SIZE];
+	wchar_t c;
+	size_t pos, size;
+	unsigned s_column;
+
+	/* Draw rows from the sheet. */
+
+	console_goto(con, 0, 0);
+	for (i = r0; i < r1; ++i) {
+		/* Starting point for row display */
+		rbc.row = pane.sh_row + i;
+		rbc.column = pane.sh_column;
+		sheet_get_cell_pt(&doc.sh, &rbc, dir_before, &rb);
+
+		/* Ending point for row display */
+		rec.row = pane.sh_row + i;
+		rec.column = pane.sh_column + pane.columns;
+		sheet_get_cell_pt(&doc.sh, &rec, dir_before, &re);
+
+		/* Copy the text of the row to the buffer. */
+		sheet_copy_out(&doc.sh, &rb, &re, row_buf, ROW_BUF_SIZE, &dep);
+
+		/* Display text from the buffer. */
+
+		console_goto(con, 0, i);
+		size = str_size(row_buf);
+		pos = 0;
+		s_column = 1;
+		while (pos < size) {
+			c = str_decode(row_buf, &pos, size);
+			if (c != '\t') {
+				printf("%lc", c);
+				s_column += 1;
+			} else {
+				fill = 1 + ALIGN_UP(s_column, TAB_WIDTH)
+				    - s_column;
+
+				for (j = 0; j < fill; ++j)
+					putchar(' ');
+				s_column += fill;
+			}
+		}
+
+		/* Fill until the end of display area. */
+
+		if (str_length(row_buf) < (unsigned) scr_columns)
+			fill = scr_columns - str_length(row_buf);
+		else
+			fill = 0;
+
+		for (j = 0; j < fill; ++j)
+			putchar(' ');
+		fflush(stdout);
+	}
+
+	pane.rflags |= REDRAW_CARET;
+}
+
+/** Display pane status in the status line. */
+static void pane_status_display(void)
+{
+	spt_t caret_pt;
+	coord_t coord;
+	int n;
+
+	tag_get_pt(&pane.caret_pos, &caret_pt);
+	spt_get_coord(&caret_pt, &coord);
+
+	console_goto(con, 0, scr_rows - 1);
+	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
+	n = printf(" %d, %d: File '%s'. Ctrl-S Save  Ctrl-Q Quit",
+	    coord.row, coord.column, doc.file_name);
+	printf("%*s", scr_columns - 1 - n, "");
+	fflush(stdout);
+	console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+
+	pane.rflags |= REDRAW_CARET;
+}
+
+/** Set cursor to reflect position of the caret. */
+static void pane_caret_display(void)
+{
+	spt_t caret_pt;
+	coord_t coord;
+
+	tag_get_pt(&pane.caret_pos, &caret_pt);
+
+	spt_get_coord(&caret_pt, &coord);
+	console_goto(con, coord.column - pane.sh_column,
+	    coord.row - pane.sh_row);
+}
+
+/** Insert a character at caret position. */
+static void insert_char(wchar_t c)
+{
+	spt_t pt;
+	char cbuf[STR_BOUNDS(1) + 1];
+	size_t offs;
+
+	tag_get_pt(&pane.caret_pos, &pt);
+
+	offs = 0;
+	chr_encode(c, cbuf, &offs, STR_BOUNDS(1) + 1);
+	cbuf[offs] = '\0';
+
+	(void) sheet_insert(&doc.sh, &pt, dir_before, cbuf);
+
+	pane.rflags |= REDRAW_ROW;
+	if (c == '\n')
+		pane.rflags |= REDRAW_TEXT;
+}
+
+/** Delete the character before the caret. */
+static void delete_char_before(void)
+{
+	spt_t sp, ep;
+	coord_t coord;
+
+	tag_get_pt(&pane.caret_pos, &ep);
+	spt_get_coord(&ep, &coord);
+
+	coord.column -= 1;
+	sheet_get_cell_pt(&doc.sh, &coord, dir_before, &sp);
+
+	(void) sheet_delete(&doc.sh, &sp, &ep);
+
+	pane.rflags |= REDRAW_ROW;
+	if (coord.column < 1)
+		pane.rflags |= REDRAW_TEXT;
+}
+
+/** Delete the character after the caret. */
+static void delete_char_after(void)
+{
+	spt_t sp, ep;
+	coord_t sc, ec;
+
+	tag_get_pt(&pane.caret_pos, &sp);
+	spt_get_coord(&sp, &sc);
+
+	sheet_get_cell_pt(&doc.sh, &sc, dir_after, &ep);
+	spt_get_coord(&ep, &ec);
+
+	(void) sheet_delete(&doc.sh, &sp, &ep);
+
+	pane.rflags |= REDRAW_ROW;
+	if (ec.row != sc.row)
+		pane.rflags |= REDRAW_TEXT;
+}
+
+/** Scroll pane after caret has moved.
+ *
+ * After modifying the position of the caret, this is called to scroll
+ * the pane to ensure that the caret is in the visible area.
+ */
+static void caret_update(void)
+{
+	spt_t pt;
+	coord_t coord;
+
+	tag_get_pt(&pane.caret_pos, &pt);
+	spt_get_coord(&pt, &coord);
+
+	/* Scroll pane vertically. */
+
+	if (coord.row < pane.sh_row) {
+		pane.sh_row = coord.row;
+		pane.rflags |= REDRAW_TEXT;
+	}
+
+	if (coord.row > pane.sh_row + pane.rows - 1) {
+		pane.sh_row = coord.row - pane.rows + 1;
+		pane.rflags |= REDRAW_TEXT;
+	}
+
+	/* Scroll pane horizontally. */
+
+	if (coord.column < pane.sh_column) {
+		pane.sh_column = coord.column;
+		pane.rflags |= REDRAW_TEXT;
+	}
+
+	if (coord.column > pane.sh_column + pane.columns - 1) {
+		pane.sh_column = coord.column - pane.columns + 1;
+		pane.rflags |= REDRAW_TEXT;
+	}
+
+	pane.rflags |= (REDRAW_CARET | REDRAW_STATUS);
+}
+
+/** Change the caret position.
+ *
+ * Moves caret relatively to the current position. Looking at the first
+ * character cell after the caret and moving by @a drow and @a dcolumn, we get
+ * to a new character cell, and thus a new character. Then we either go to the
+ * point before the the character or after it, depending on @a align_dir.
+ */
+static void caret_move(int drow, int dcolumn, enum dir_spec align_dir)
+{
+	spt_t pt;
+	coord_t coord;
+	int num_rows;
+	bool pure_vertical;
+
+	tag_get_pt(&pane.caret_pos, &pt);
+	spt_get_coord(&pt, &coord);
+	coord.row += drow; coord.column += dcolumn;
+
+	/* Clamp coordinates. */
+	if (drow < 0 && coord.row < 1) coord.row = 1;
+	if (dcolumn < 0 && coord.column < 1) coord.column = 1;
+	if (drow > 0) {
+		sheet_get_num_rows(&doc.sh, &num_rows);
+		if (coord.row > num_rows) coord.row = num_rows;
+	}
+
+	/* For purely vertical movement try attaining @c ideal_column. */
+	pure_vertical = (dcolumn == 0 && align_dir == dir_before);
+	if (pure_vertical)
+		coord.column = pane.ideal_column;
+
+	/*
+	 * Select the point before or after the character at the designated
+	 * coordinates. The character can be wider than one cell (e.g. tab).
+	 */
+	sheet_get_cell_pt(&doc.sh, &coord, align_dir, &pt);
+	sheet_remove_tag(&doc.sh, &pane.caret_pos);
+	sheet_place_tag(&doc.sh, &pt, &pane.caret_pos);
+
+	/* For non-vertical movement set the new value for @c ideal_column. */
+	if (!pure_vertical) {
+		spt_get_coord(&pt, &coord);
+		pane.ideal_column = coord.column;
+	}
+
+	caret_update();
+}
+
+
+/** Get start-of-file s-point. */
+static void pt_get_sof(spt_t *pt)
+{
+	coord_t coord;
+
+	coord.row = coord.column = 1;
+	sheet_get_cell_pt(&doc.sh, &coord, dir_before, pt);
+}
+
+/** Get end-of-file s-point. */
+static void pt_get_eof(spt_t *pt)
+{
+	coord_t coord;
+	int num_rows;
+
+	sheet_get_num_rows(&doc.sh, &num_rows);
+	coord.row = num_rows + 1;
+	coord.column = 1;
+
+	sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt);
+}
+
+/** Display text in the status line. */
+static void status_display(char const *str)
+{
+	console_goto(con, 0, scr_rows - 1);
+	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
+	printf(" %*s ", -(scr_columns - 3), str);
+	fflush(stdout);
+	console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+
+	pane.rflags |= REDRAW_CARET;
+}
+
+/** @}
+ */
Index: uspace/app/edit/sheet.c
===================================================================
--- uspace/app/edit/sheet.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/sheet.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 edit
+ * @{
+ */
+/**
+ * @file
+ * @brief Prototype implementation of Sheet data structure.
+ *
+ * The sheet is an abstract data structure representing a piece of text.
+ * On top of this data structure we can implement a text editor. It is
+ * possible to implement the sheet such that the editor can make small
+ * changes to large files or files containing long lines efficiently.
+ *
+ * The sheet structure allows basic operations of text insertion, deletion,
+ * retrieval and mapping of coordinates to position in the file and vice
+ * versa. The text that is inserted or deleted can contain tabs and newlines
+ * which are interpreted and properly acted upon.
+ *
+ * This is a trivial implementation with poor efficiency with O(N+n)
+ * insertion and deletion and O(N) mapping (in both directions), where
+ * N is the size of the file and n is the size of the inserted/deleted text.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <adt/list.h>
+#include <align.h>
+#include <macros.h>
+
+#include "sheet.h"
+
+enum {
+	TAB_WIDTH	= 8,
+
+	/** Initial  of dat buffer in bytes */
+	INITIAL_SIZE	= 32
+};
+
+/** Initialize an empty sheet. */
+int sheet_init(sheet_t *sh)
+{
+	sh->dbuf_size = INITIAL_SIZE;
+	sh->text_size = 0;
+
+	sh->data = malloc(sh->dbuf_size);
+	if (sh->data == NULL)
+		return ENOMEM;
+
+	list_initialize(&sh->tags_head);
+
+	return EOK;
+}
+
+/** Insert text into sheet.
+ *
+ * @param sh	Sheet to insert to.
+ * @param pos	Point where to insert.
+ * @param dir	Whether to insert before or after the point (affects tags).
+ * @param str	The text to insert (printable characters, tabs, newlines).
+ *
+ * @return	EOK on success or negative error code.
+ *
+ * @note	@a dir affects which way tags that were placed on @a pos will
+ * 		move. If @a dir is @c dir_before, the tags will move forward
+ *		and vice versa.
+ */
+int sheet_insert(sheet_t *sh, spt_t *pos, enum dir_spec dir, char *str)
+{
+	char *ipp;
+	size_t sz;
+	link_t *link;
+	tag_t *tag;
+	char *newp;
+
+	sz = str_size(str);
+	if (sh->text_size + sz > sh->dbuf_size) {
+		/* Enlarge data buffer. */
+		newp = realloc(sh->data, sh->dbuf_size * 2);
+		if (newp == NULL)
+			return ELIMIT;
+
+		sh->data = newp;
+		sh->dbuf_size = sh->dbuf_size * 2;
+	}
+
+	ipp = sh->data + pos->b_off;
+
+	/* Copy data. */
+	memmove(ipp + sz, ipp, sh->text_size - pos->b_off);
+	memcpy(ipp, str, sz);
+	sh->text_size += sz;
+
+	/* Adjust tags. */
+
+	link = sh->tags_head.next;
+	while (link != &sh->tags_head) {
+		tag = list_get_instance(link, tag_t, link);
+
+		if (tag->b_off > pos->b_off)
+			tag->b_off += sz;
+		else if (tag->b_off == pos->b_off && dir == dir_before)
+			tag->b_off += sz;
+
+		link = link->next;
+	}
+
+	return EOK;
+}
+
+/** Delete text from sheet.
+ *
+ * Deletes the range of text between two points from the sheet.
+ *
+ * @param sh	Sheet to delete from.
+ * @param spos	Starting point.
+ * @param epos	Ending point.
+ *
+ * @return	EOK on success or negative error code.
+ **/
+int sheet_delete(sheet_t *sh, spt_t *spos, spt_t *epos)
+{
+	char *spp;
+	size_t sz;
+	link_t *link;
+	tag_t *tag;
+	char *newp;
+	size_t shrink_size;
+
+	spp = sh->data + spos->b_off;
+	sz = epos->b_off - spos->b_off;
+
+	memmove(spp, spp + sz, sh->text_size - (spos->b_off + sz));
+	sh->text_size -= sz;
+
+	/* Adjust tags. */
+	link = sh->tags_head.next;
+	while (link != &sh->tags_head) {
+		tag = list_get_instance(link, tag_t, link);
+
+		if (tag->b_off >= epos->b_off)
+			tag->b_off -= sz;
+		else if (tag->b_off >= spos->b_off)
+			tag->b_off = spos->b_off;
+
+		link = link->next;
+	}
+
+	/* See if we should free up some memory. */
+	shrink_size = max(sh->dbuf_size / 4, INITIAL_SIZE);
+	if (sh->text_size <= shrink_size && sh->dbuf_size > INITIAL_SIZE) {
+		/* Shrink data buffer. */
+		newp = realloc(sh->data, shrink_size);
+		if (newp == NULL) {
+			/* Failed to shrink buffer... no matter. */
+			return EOK;
+		}
+
+		sh->data = newp;
+		sh->dbuf_size = shrink_size;
+	}
+
+	return EOK;
+}
+
+/** Read text from sheet. */
+void sheet_copy_out(sheet_t *sh, spt_t const *spos, spt_t const *epos,
+    char *buf, size_t bufsize, spt_t *fpos)
+{
+	char *spp;
+	size_t range_sz;
+	size_t copy_sz;
+	size_t off, prev;
+	wchar_t c;
+
+	spp = sh->data + spos->b_off;
+	range_sz = epos->b_off - spos->b_off;
+	copy_sz = (range_sz < bufsize - 1) ? range_sz : bufsize - 1;
+
+	prev = off = 0;
+	do {
+		prev = off;
+		c = str_decode(spp, &off, copy_sz);
+	} while (c != '\0');
+
+	/* Crop copy_sz down to the last full character. */
+	copy_sz = prev;
+
+	memcpy(buf, spp, copy_sz);
+	buf[copy_sz] = '\0';
+
+	fpos->b_off = spos->b_off + copy_sz;
+	fpos->sh = sh;
+}
+
+/** Get point preceding or following character cell. */
+void sheet_get_cell_pt(sheet_t *sh, coord_t const *coord, enum dir_spec dir,
+    spt_t *pt)
+{
+	size_t cur_pos, prev_pos;
+	wchar_t c;
+	coord_t cc;
+
+	cc.row = cc.column = 1;
+	cur_pos = prev_pos = 0;
+	while (true) {
+		if (prev_pos >= sh->text_size) {
+			/* Cannot advance any further. */
+			break;
+		}
+
+		if ((cc.row >= coord->row && cc.column > coord->column) ||
+		    cc.row > coord->row) {
+			/* We are past the requested coordinates. */
+			break;
+		}
+
+		prev_pos = cur_pos;
+
+		c = str_decode(sh->data, &cur_pos, sh->text_size);
+		if (c == '\n') {
+			++cc.row;
+			cc.column = 1;
+		} else if (c == '\t') {
+			cc.column = 1 + ALIGN_UP(cc.column, TAB_WIDTH);
+		} else {
+			++cc.column;
+		}
+	}
+
+	pt->sh = sh;
+	pt->b_off = (dir == dir_before) ? prev_pos : cur_pos;
+}
+
+/** Get the number of character cells a row occupies. */
+void sheet_get_row_width(sheet_t *sh, int row, int *length)
+{
+	coord_t coord;
+	spt_t pt;
+
+	/* Especially nasty hack */
+	coord.row = row;
+	coord.column = 65536;
+	
+	sheet_get_cell_pt(sh, &coord, dir_before, &pt);
+	spt_get_coord(&pt, &coord);
+	*length = coord.column - 1;
+}
+
+/** Get the number of rows in a sheet. */
+void sheet_get_num_rows(sheet_t *sh, int *rows)
+{
+	int cnt;
+	size_t bo;
+
+	cnt = 1;
+	for (bo = 0; bo < sh->dbuf_size; ++bo) {
+		if (sh->data[bo] == '\n')
+			cnt += 1;
+	}
+
+	*rows = cnt;
+}
+
+/** Get the coordinates of an s-point. */
+void spt_get_coord(spt_t const *pos, coord_t *coord)
+{
+	size_t off;
+	coord_t cc;
+	wchar_t c;
+	sheet_t *sh;
+
+	sh = pos->sh;
+	cc.row = cc.column = 1;
+
+	off = 0;
+	while (off < pos->b_off && off < sh->text_size) {
+		c = str_decode(sh->data, &off, sh->text_size);
+		if (c == '\n') {
+			++cc.row;
+			cc.column = 1;
+		} else if (c == '\t') {
+			cc.column = 1 + ALIGN_UP(cc.column, TAB_WIDTH);
+		} else {
+			++cc.column;
+		}
+	}
+
+	*coord = cc;
+}
+
+/** Test if two s-points are equal. */
+bool spt_equal(spt_t const *a, spt_t const *b)
+{
+	return a->b_off == b->b_off;
+}
+
+/** Place a tag on the specified s-point. */
+void sheet_place_tag(sheet_t *sh, spt_t const *pt, tag_t *tag)
+{
+	tag->b_off = pt->b_off;
+	tag->sh = sh;
+	list_append(&tag->link, &sh->tags_head);
+}
+
+/** Remove a tag from the sheet. */
+void sheet_remove_tag(sheet_t *sh, tag_t *tag)
+{
+	list_remove(&tag->link);
+}
+
+/** Get s-point on which the tag is located right now. */
+void tag_get_pt(tag_t const *tag, spt_t *pt)
+{
+	pt->b_off = tag->b_off;
+	pt->sh = tag->sh;
+}
+
+/** @}
+ */
Index: uspace/app/edit/sheet.h
===================================================================
--- uspace/app/edit/sheet.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/sheet.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 edit
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef SHEET_H__
+#define SHEET_H__
+
+#include <adt/list.h>
+#include <sys/types.h>
+#include <bool.h>
+
+/** Direction (in linear space) */
+enum dir_spec {
+	/** Before specified point */
+	dir_before,
+	/** After specified point */
+	dir_after
+};
+
+/** Sheet */
+typedef struct {
+	/* Note: This structure is opaque for the user. */
+
+	size_t text_size;
+	size_t dbuf_size;
+	char *data;
+
+	link_t tags_head;
+} sheet_t;
+
+/** Character cell coordinates
+ *
+ * These specify a character cell. The first cell is (1,1).
+ */
+typedef struct {
+	int row;
+	int column;
+} coord_t;
+
+/** S-point
+ *
+ * An s-point specifies the boundary between two successive characters
+ * in the linear file space (including the beginning of file or the end
+ * of file. An s-point only remains valid as long as no modifications
+ * (insertions/deletions) are performed on the sheet.
+ */
+typedef struct {
+	/* Note: This structure is opaque for the user. */
+	sheet_t *sh;
+	size_t b_off;
+} spt_t;
+
+/** Tag
+ *
+ * A tag is similar to an s-point, but remains valid over modifications
+ * to the sheet. A tag tends to 'stay put'. Any tag must be properly
+ * removed from the sheet before it is deallocated by the user.
+ */
+typedef struct {
+	/* Note: This structure is opaque for the user. */
+
+	/** Link to list of all tags in the sheet (see sheet_t.tags_head) */
+	link_t link;
+	sheet_t *sh;
+	size_t b_off;
+} tag_t;
+
+extern int sheet_init(sheet_t *);
+extern int sheet_insert(sheet_t *, spt_t *, enum dir_spec, char *);
+extern int sheet_delete(sheet_t *, spt_t *, spt_t *);
+extern void sheet_copy_out(sheet_t *, spt_t const *, spt_t const *, char *,
+    size_t, spt_t *);
+extern void sheet_get_cell_pt(sheet_t *, coord_t const *, enum dir_spec,
+    spt_t *);
+extern void sheet_get_row_width(sheet_t *, int, int *);
+extern void sheet_get_num_rows(sheet_t *, int *);
+extern void spt_get_coord(spt_t const *, coord_t *);
+extern bool spt_equal(spt_t const *, spt_t const *);
+
+extern void sheet_place_tag(sheet_t *, spt_t const *, tag_t *);
+extern void sheet_remove_tag(sheet_t *, tag_t *);
+extern void tag_get_pt(tag_t const *, spt_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/getvc/Makefile
===================================================================
--- uspace/app/getvc/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/getvc/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2009 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,53 +28,13 @@
 #
 
-include ../../../version
+include Makefile.common
 
-## Setup toolchain
-#
+.PHONY: all clean
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-DEFS += -DRELEASE=$(RELEASE) "-DNAME=$(NAME)"
-
-## Sources
-#
-
-OUTPUT = getvc
-SOURCES = \
-	getvc.c \
-	version.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../version $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/getvc/Makefile.build
===================================================================
--- uspace/app/getvc/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/getvc/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+include ../../../version
+
+DEFS += -DRELEASE=$(RELEASE) "-DNAME=$(NAME)"
+
+## Sources
+#
+
+SOURCES = \
+	getvc.c \
+	version.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/getvc/Makefile.common
===================================================================
--- uspace/app/getvc/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/getvc/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = getvc
Index: uspace/app/getvc/getvc.c
===================================================================
--- uspace/app/getvc/getvc.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/getvc/getvc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -36,4 +36,5 @@
 
 #include <sys/types.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -46,23 +47,34 @@
 }
 
-static void closeall(void)
+static void reopen(FILE **stream, int fd, const char *path, int flags, const char *mode)
 {
-	fclose(stdin);
-	fclose(stdout);
-	fclose(stderr);
+	if (fclose(*stream))
+		return;
 	
-	close(0);
-	close(1);
-	close(2);
+	*stream = NULL;
+	
+	int oldfd = open(path, flags);
+	if (oldfd < 0)
+		return;
+	
+	if (oldfd != fd) {
+		if (dup2(oldfd, fd) != fd)
+			return;
+		
+		if (close(oldfd))
+			return;
+	}
+	
+	*stream = fdopen(fd, mode);
 }
 
 static task_id_t spawn(char *fname)
 {
-	char *argv[2];
+	char *args[2];
 	
-	argv[0] = fname;
-	argv[1] = NULL;
+	args[0] = fname;
+	args[1] = NULL;
 	
-	task_id_t id = task_spawn(fname, argv);
+	task_id_t id = task_spawn(fname, args);
 	
 	if (id == 0)
@@ -74,7 +86,4 @@
 int main(int argc, char *argv[])
 {
-	task_exit_t texit;
-	int retval;
-
 	if (argc < 3) {
 		usage();
@@ -82,26 +91,35 @@
 	}
 	
-	closeall();
+	reopen(&stdin, 0, argv[1], O_RDONLY, "r");
+	reopen(&stdout, 1, argv[1], O_WRONLY, "w");
+	reopen(&stderr, 2, argv[1], O_WRONLY, "w");
 	
-	stdin = fopen(argv[1], "r");
-	stdout = fopen(argv[1], "w");
-	stderr = fopen(argv[1], "w");
-
 	/*
-	 * FIXME: fopen() should actually detect that we are opening a console
+	 * FIXME: fdopen() should actually detect that we are opening a console
 	 * and it should set line-buffering mode automatically.
 	 */
 	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
 	
-	if ((stdin == NULL)
-	    || (stdout == NULL)
-	    || (stderr == NULL))
+	if (stdin == NULL)
 		return -2;
+	
+	if (stdout == NULL)
+		return -3;
+	
+	if (stderr == NULL)
+		return -4;
 	
 	version_print(argv[1]);
 	task_id_t id = spawn(argv[2]);
-	task_wait(id, &texit, &retval);
 	
-	return 0;
+	if (id != 0) {
+		task_exit_t texit;
+		int retval;
+		task_wait(id, &texit, &retval);
+		
+		return 0;
+	}
+	
+	return -5;
 }
 
Index: uspace/app/init/Makefile
===================================================================
--- uspace/app/init/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/init/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I../../..
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = init
-SOURCES = \
-	init.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/init/Makefile.build
===================================================================
--- uspace/app/init/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/init/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	init.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/init/Makefile.common
===================================================================
--- uspace/app/init/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/init/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = init
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/init/init.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -48,5 +48,4 @@
 #include <string.h>
 #include <devmap.h>
-#include <config.h>
 #include "init.h"
 
Index: uspace/app/klog/Makefile
===================================================================
--- uspace/app/klog/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/klog/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = klog
-SOURCES = \
-	klog.c
-
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/klog/Makefile.build
===================================================================
--- uspace/app/klog/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/klog/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	klog.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/klog/Makefile.common
===================================================================
--- uspace/app/klog/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/klog/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = klog
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/klog/klog.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -74,5 +74,5 @@
 	}
 	
-	int res = ipc_share_in_start_1_0(PHONE_NS, (void *) klog,
+	int res = async_share_in_start_1_0(PHONE_NS, (void *) klog,
 	    klog_size, SERVICE_MEM_KLOG);
 	if (res != EOK) {
Index: uspace/app/redir/Makefile
===================================================================
--- uspace/app/redir/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/redir/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+include Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../version $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
+
+clean:
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/redir/Makefile.build
===================================================================
--- uspace/app/redir/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/redir/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	redir.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/redir/Makefile.common
===================================================================
--- uspace/app/redir/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/redir/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = redir
Index: uspace/app/redir/redir.c
===================================================================
--- uspace/app/redir/redir.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/redir/redir.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,157 @@
+/*
+ * 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 redir Redirector
+ * @brief Redirect stdin/stdout/stderr.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <task.h>
+
+static void usage(void)
+{
+	printf("Usage: redir [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n");
+}
+
+static void reopen(FILE **stream, int fd, const char *path, int flags, const char *mode)
+{
+	if (fclose(*stream))
+		return;
+	
+	*stream = NULL;
+	
+	int oldfd = open(path, flags);
+	if (oldfd < 0)
+		return;
+	
+	if (oldfd != fd) {
+		if (dup2(oldfd, fd) != fd)
+			return;
+		
+		if (close(oldfd))
+			return;
+	}
+	
+	*stream = fdopen(fd, mode);
+}
+
+static task_id_t spawn(int argc, char *argv[])
+{
+	char **args = (char *) calloc(argc + 1, sizeof(char *));
+	if (!args) {
+		printf("No memory available\n");
+		return 0;
+	}
+	
+	int i;
+	for (i = 0; i < argc; i++)
+		args[i] = argv[i];
+	
+	args[argc] = NULL;
+	
+	task_id_t id = task_spawn(argv[0], args);
+	
+	free(args);
+	
+	if (id == 0)
+		printf("Error spawning %s\n", argv[0]);
+	
+	return id;
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc < 3) {
+		usage();
+		return -1;
+	}
+	
+	int i;
+	for (i = 1; i < argc; i++) {
+		if (str_cmp(argv[i], "-i") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -2;
+			}
+			reopen(&stdin, 0, argv[i], O_RDONLY, "r");
+		} else if (str_cmp(argv[i], "-o") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -3;
+			}
+			reopen(&stdout, 1, argv[i], O_WRONLY | O_CREAT, "w");
+		} else if (str_cmp(argv[i], "-e") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -4;
+			}
+			reopen(&stderr, 2, argv[i], O_WRONLY | O_CREAT, "w");
+		} else if (str_cmp(argv[i], "--") == 0) {
+			i++;
+			break;
+		}
+	}
+	
+	if (i >= argc) {
+		usage();
+		return -5;
+	}
+	
+	/*
+	 * FIXME: fdopen() should actually detect that we are opening a console
+	 * and it should set line-buffering mode automatically.
+	 */
+	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
+	
+	task_id_t id = spawn(argc - i, argv + i);
+	
+	if (id != 0) {
+		task_exit_t texit;
+		int retval;
+		task_wait(id, &texit, &retval);
+		
+		return retval;
+	}
+	
+	return -6;
+}
+
+/** @}
+ */
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/tester/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,66 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I../../srv/kbd/include
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = tester
-SOURCES = tester.c \
-	thread/thread1.c \
-	print/print1.c \
-	print/print2.c \
-	print/print3.c \
-	print/print4.c \
-	console/console1.c \
-	stdio/stdio1.c \
-	stdio/stdio2.c \
-	fault/fault1.c \
-	fault/fault2.c \
-	vfs/vfs1.c \
-	ipc/ping_pong.c \
-	ipc/register.c \
-	ipc/connect.c \
-	loop/loop1.c \
-	mm/malloc1.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/tester/Makefile.build
===================================================================
--- uspace/app/tester/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/tester/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,77 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	tester.c \
+	thread/thread1.c \
+	print/print1.c \
+	print/print2.c \
+	print/print3.c \
+	print/print4.c \
+	console/console1.c \
+	stdio/stdio1.c \
+	stdio/stdio2.c \
+	fault/fault1.c \
+	fault/fault2.c \
+	vfs/vfs1.c \
+	ipc/ping_pong.c \
+	ipc/register.c \
+	ipc/connect.c \
+	loop/loop1.c \
+	mm/malloc1.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/tester/Makefile.common
===================================================================
--- uspace/app/tester/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/tester/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = tester
Index: uspace/app/tetris/Makefile
===================================================================
--- uspace/app/tetris/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/tetris/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,39 +1,40 @@
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
 
-include $(LIBC_PREFIX)/Makefile.toolchain
+include Makefile.common
 
-LIBS = $(LIBC_PREFIX)/libc.a
+.PHONY: all clean
 
-OUTPUT = tetris
-SOURCES = shapes.c scores.c input.c tetris.c screen.c
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend *.o
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/tetris/Makefile.build
===================================================================
--- uspace/app/tetris/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/tetris/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	shapes.c \
+	scores.c \
+	input.c \
+	tetris.c \
+	screen.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/tetris/Makefile.common
===================================================================
--- uspace/app/tetris/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/tetris/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = tetris
Index: uspace/app/tetris/screen.h
===================================================================
--- uspace/app/tetris/screen.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/tetris/screen.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -51,6 +51,6 @@
 
 typedef struct {
-	ipcarg_t ws_row;
-	ipcarg_t ws_col;
+	int ws_row;
+	int ws_col;
 } winsize_t;
 
Index: uspace/app/trace/Makefile
===================================================================
--- uspace/app/trace/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/trace/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,53 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I../../srv/kbd/include
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = trace
-SOURCES = trace.c \
-	syscalls.c \
-	ipcp.c \
-	ipc_desc.c \
-	proto.c \
-	errors.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm:
-	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/trace/Makefile.build
===================================================================
--- uspace/app/trace/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/trace/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	trace.c \
+	syscalls.c \
+	ipcp.c \
+	ipc_desc.c \
+	proto.c \
+	errors.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/trace/Makefile.common
===================================================================
--- uspace/app/trace/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/trace/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = trace
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/app/trace/syscalls.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -62,4 +62,5 @@
     [SYS_IPC_FORWARD_SLOW] = { "ipc_forward_slow",	3,	V_ERRNO },
     [SYS_IPC_WAIT] = { "ipc_wait_for_call",		3,	V_HASH },
+    [SYS_IPC_POKE] = { "ipc_poke",			0,	V_ERRNO },
     [SYS_IPC_HANGUP] = { "ipc_hangup",			1,	V_ERRNO },
     [SYS_IPC_REGISTER_IRQ] = { "ipc_register_irq",	4,	V_ERRNO },
Index: uspace/lib/libblock/Makefile
===================================================================
--- uspace/lib/libblock/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libblock/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -28,40 +28,13 @@
 #
 
-## Common compiler flags
-#
+include Makefile.common
 
-LIBC_PREFIX = ../libc
+.PHONY: all clean
 
-## Setup toolchain
-#
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -Iinclude
-
-## Sources
-#
-
-SOURCES = \
-	libblock.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend
-
-all: libblock.a
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f libblock.a Makefile.depend
+	rm -f $(DEPEND) $(DEPEND_PREV) $(LIBBLOCK)
 	find . -name '*.o' -follow -exec rm \{\} \;
-
-depend:
-	-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
-
-libblock.a: depend $(OBJECTS)
-	$(AR) rc libblock.a $(OBJECTS)
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
Index: uspace/lib/libblock/Makefile.build
===================================================================
--- uspace/lib/libblock/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/libblock/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	libblock.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(LIBBLOCK)
+
+-include $(DEPEND)
+
+$(LIBBLOCK): $(OBJECTS)
+	$(AR) rc $@ $(OBJECTS)
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/lib/libblock/Makefile.common
===================================================================
--- uspace/lib/libblock/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/libblock/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../libc
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+LIBBLOCK = libblock.a
Index: uspace/lib/libblock/libblock.c
===================================================================
--- uspace/lib/libblock/libblock.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libblock/libblock.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -50,4 +50,5 @@
 #include <adt/list.h>
 #include <adt/hash_table.h>
+#include <macros.h>
 #include <mem.h>
 
@@ -62,5 +63,5 @@
 typedef struct {
 	fibril_mutex_t lock;
-	size_t block_size;		/**< Block size. */
+	size_t lblock_size;		/**< Logical block size. */
 	unsigned block_count;		/**< Total number of blocks. */
 	unsigned blocks_cached;		/**< Number of cached blocks. */
@@ -74,15 +75,16 @@
 	dev_handle_t dev_handle;
 	int dev_phone;
-	fibril_mutex_t com_area_lock;
-	void *com_area;
-	size_t com_size;
+	fibril_mutex_t comm_area_lock;
+	void *comm_area;
+	size_t comm_size;
 	void *bb_buf;
-	off_t bb_off;
-	size_t bb_size;
+	bn_t bb_addr;
+	size_t pblock_size;		/**< Physical block size. */
 	cache_t *cache;
 } devcon_t;
 
-static int read_block(devcon_t *devcon, bn_t boff, size_t block_size);
-static int write_block(devcon_t *devcon, bn_t boff, size_t block_size);
+static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
+static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
+static int get_block_size(int dev_phone, size_t *bsize);
 
 static devcon_t *devcon_search(dev_handle_t dev_handle)
@@ -102,9 +104,12 @@
 }
 
-static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area,
-   size_t com_size)
+static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize,
+    void *comm_area, size_t comm_size)
 {
 	link_t *cur;
 	devcon_t *devcon;
+
+	if (comm_size < bsize)
+		return EINVAL;
 
 	devcon = malloc(sizeof(devcon_t));
@@ -115,10 +120,10 @@
 	devcon->dev_handle = dev_handle;
 	devcon->dev_phone = dev_phone;
-	fibril_mutex_initialize(&devcon->com_area_lock);
-	devcon->com_area = com_area;
-	devcon->com_size = com_size;
+	fibril_mutex_initialize(&devcon->comm_area_lock);
+	devcon->comm_area = comm_area;
+	devcon->comm_size = comm_size;
 	devcon->bb_buf = NULL;
-	devcon->bb_off = 0;
-	devcon->bb_size = 0;
+	devcon->bb_addr = 0;
+	devcon->pblock_size = bsize;
 	devcon->cache = NULL;
 
@@ -144,13 +149,14 @@
 }
 
-int block_init(dev_handle_t dev_handle, size_t com_size)
+int block_init(dev_handle_t dev_handle, size_t comm_size)
 {
 	int rc;
 	int dev_phone;
-	void *com_area;
-	
-	com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,
+	void *comm_area;
+	size_t bsize;
+
+	comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
 	    MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
-	if (!com_area) {
+	if (!comm_area) {
 		return ENOMEM;
 	}
@@ -158,19 +164,25 @@
 	dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING);
 	if (dev_phone < 0) {
-		munmap(com_area, com_size);
+		munmap(comm_area, comm_size);
 		return dev_phone;
 	}
 
-	rc = ipc_share_out_start(dev_phone, com_area,
+	rc = async_share_out_start(dev_phone, comm_area,
 	    AS_AREA_READ | AS_AREA_WRITE);
 	if (rc != EOK) {
-	    	munmap(com_area, com_size);
+	    	munmap(comm_area, comm_size);
 		ipc_hangup(dev_phone);
 		return rc;
 	}
-	
-	rc = devcon_add(dev_handle, dev_phone, com_area, com_size);
+
+	if (get_block_size(dev_phone, &bsize) != EOK) {
+		munmap(comm_area, comm_size);
+		ipc_hangup(dev_phone);
+		return rc;
+	}
+	
+	rc = devcon_add(dev_handle, dev_phone, bsize, comm_area, comm_size);
 	if (rc != EOK) {
-		munmap(com_area, com_size);
+		munmap(comm_area, comm_size);
 		ipc_hangup(dev_phone);
 		return rc;
@@ -195,5 +207,5 @@
 	}
 
-	munmap(devcon->com_area, devcon->com_size);
+	munmap(devcon->comm_area, devcon->comm_size);
 	ipc_hangup(devcon->dev_phone);
 
@@ -201,5 +213,5 @@
 }
 
-int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size)
+int block_bb_read(dev_handle_t dev_handle, bn_t ba)
 {
 	void *bb_buf;
@@ -211,21 +223,20 @@
 	if (devcon->bb_buf)
 		return EEXIST;
-	bb_buf = malloc(size);
+	bb_buf = malloc(devcon->pblock_size);
 	if (!bb_buf)
 		return ENOMEM;
-	
-	fibril_mutex_lock(&devcon->com_area_lock);
-	rc = read_block(devcon, 0, size);
+
+	fibril_mutex_lock(&devcon->comm_area_lock);
+	rc = read_blocks(devcon, 0, 1);
 	if (rc != EOK) {
-		fibril_mutex_unlock(&devcon->com_area_lock);
+		fibril_mutex_unlock(&devcon->comm_area_lock);
 	    	free(bb_buf);
 		return rc;
 	}
-	memcpy(bb_buf, devcon->com_area, size);
-	fibril_mutex_unlock(&devcon->com_area_lock);
+	memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
+	fibril_mutex_unlock(&devcon->comm_area_lock);
 
 	devcon->bb_buf = bb_buf;
-	devcon->bb_off = off;
-	devcon->bb_size = size;
+	devcon->bb_addr = ba;
 
 	return EOK;
@@ -275,8 +286,11 @@
 	fibril_mutex_initialize(&cache->lock);
 	list_initialize(&cache->free_head);
-	cache->block_size = size;
+	cache->lblock_size = size;
 	cache->block_count = blocks;
 	cache->blocks_cached = 0;
 	cache->mode = mode;
+
+	/* No block size translation a.t.m. */
+	assert(cache->lblock_size == devcon->pblock_size);
 
 	if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
@@ -306,4 +320,5 @@
 	b->refcnt = 1;
 	b->dirty = false;
+	b->toxic = false;
 	fibril_rwlock_initialize(&b->contents_lock);
 	link_initialize(&b->free_link);
@@ -313,4 +328,6 @@
 /** Instantiate a block in memory and get a reference to it.
  *
+ * @param block			Pointer to where the function will store the
+ * 				block pointer on success.
  * @param dev_handle		Device handle of the block device.
  * @param boff			Block offset.
@@ -319,7 +336,7 @@
  *				device.
  *
- * @return			Block structure.
- */
-block_t *block_get(dev_handle_t dev_handle, bn_t boff, int flags)
+ * @return			EOK on success or a negative error code.
+ */
+int block_get(block_t **block, dev_handle_t dev_handle, bn_t boff, int flags)
 {
 	devcon_t *devcon;
@@ -328,5 +345,5 @@
 	link_t *l;
 	unsigned long key = boff;
-	bn_t oboff;
+	int rc;
 	
 	devcon = devcon_search(dev_handle);
@@ -336,4 +353,9 @@
 	
 	cache = devcon->cache;
+
+retry:
+	rc = EOK;
+	b = NULL;
+
 	fibril_mutex_lock(&cache->lock);
 	l = hash_table_find(&cache->block_hash, &key);
@@ -346,4 +368,6 @@
 		if (b->refcnt++ == 0)
 			list_remove(&b->free_link);
+		if (b->toxic)
+			rc = EIO;
 		fibril_mutex_unlock(&b->lock);
 		fibril_mutex_unlock(&cache->lock);
@@ -352,7 +376,4 @@
 		 * The block was not found in the cache.
 		 */
-		int rc;
-		bool sync = false;
-
 		if (cache_can_grow(cache)) {
 			/*
@@ -364,5 +385,5 @@
 			if (!b)
 				goto recycle;
-			b->data = malloc(cache->block_size);
+			b->data = malloc(cache->lblock_size);
 			if (!b->data) {
 				free(b);
@@ -376,10 +397,58 @@
 			unsigned long temp_key;
 recycle:
-			assert(!list_empty(&cache->free_head));
+			if (list_empty(&cache->free_head)) {
+				fibril_mutex_unlock(&cache->lock);
+				rc = ENOMEM;
+				goto out;
+			}
 			l = cache->free_head.next;
-			list_remove(l);
 			b = list_get_instance(l, block_t, free_link);
-			sync = b->dirty;
-			oboff = b->boff;
+
+			fibril_mutex_lock(&b->lock);
+			if (b->dirty) {
+				/*
+				 * The block needs to be written back to the
+				 * device before it changes identity. Do this
+				 * while not holding the cache lock so that
+				 * concurrency is not impeded. Also move the
+				 * block to the end of the free list so that we
+				 * do not slow down other instances of
+				 * block_get() draining the free list.
+				 */
+				list_remove(&b->free_link);
+				list_append(&b->free_link, &cache->free_head);
+				fibril_mutex_unlock(&cache->lock);
+				fibril_mutex_lock(&devcon->comm_area_lock);
+				memcpy(devcon->comm_area, b->data, b->size);
+				rc = write_blocks(devcon, b->boff, 1);
+				fibril_mutex_unlock(&devcon->comm_area_lock);
+				if (rc != EOK) {
+					/*
+					 * We did not manage to write the block
+					 * to the device. Keep it around for
+					 * another try. Hopefully, we will grab
+					 * another block next time.
+					 */
+					fibril_mutex_unlock(&b->lock);
+					goto retry;
+				}
+				b->dirty = false;
+				if (!fibril_mutex_trylock(&cache->lock)) {
+					/*
+					 * Somebody is probably racing with us.
+					 * Unlock the block and retry.
+					 */
+					fibril_mutex_unlock(&b->lock);
+					goto retry;
+				}
+
+			}
+			fibril_mutex_unlock(&b->lock);
+
+			/*
+			 * Unlink the block from the free list and the hash
+			 * table.
+			 */
+			list_remove(&b->free_link);
 			temp_key = b->boff;
 			hash_table_remove(&cache->block_hash, &temp_key, 1);
@@ -388,5 +457,5 @@
 		block_initialize(b);
 		b->dev_handle = dev_handle;
-		b->size = cache->block_size;
+		b->size = cache->lblock_size;
 		b->boff = boff;
 		hash_table_insert(&cache->block_hash, &key, &b->hash_link);
@@ -394,21 +463,10 @@
 		/*
 		 * Lock the block before releasing the cache lock. Thus we don't
-		 * kill concurent operations on the cache while doing I/O on the
-		 * block.
+		 * kill concurrent operations on the cache while doing I/O on
+		 * the block.
 		 */
 		fibril_mutex_lock(&b->lock);
 		fibril_mutex_unlock(&cache->lock);
 
-		if (sync) {
-			/*
-			 * The block is dirty and needs to be written back to
-			 * the device before we can read in the new contents.
-			 */
-			fibril_mutex_lock(&devcon->com_area_lock);
-			memcpy(devcon->com_area, b->data, b->size);
-			rc = write_block(devcon, oboff, cache->block_size);
-			assert(rc == EOK);
-			fibril_mutex_unlock(&devcon->com_area_lock);
-		}
 		if (!(flags & BLOCK_FLAGS_NOREAD)) {
 			/*
@@ -416,14 +474,23 @@
 			 * the new contents from the device.
 			 */
-			fibril_mutex_lock(&devcon->com_area_lock);
-			rc = read_block(devcon, b->boff, cache->block_size);
-			assert(rc == EOK);
-			memcpy(b->data, devcon->com_area, cache->block_size);
-			fibril_mutex_unlock(&devcon->com_area_lock);
-		}
+			fibril_mutex_lock(&devcon->comm_area_lock);
+			rc = read_blocks(devcon, b->boff, 1);
+			memcpy(b->data, devcon->comm_area, cache->lblock_size);
+			fibril_mutex_unlock(&devcon->comm_area_lock);
+			if (rc != EOK) 
+				b->toxic = true;
+		} else
+			rc = EOK;
 
 		fibril_mutex_unlock(&b->lock);
 	}
-	return b;
+out:
+	if ((rc != EOK) && b) {
+		assert(b->toxic);
+		(void) block_put(b);
+		b = NULL;
+	}
+	*block = b;
+	return rc;
 }
 
@@ -433,10 +500,14 @@
  *
  * @param block		Block of which a reference is to be released.
- */
-void block_put(block_t *block)
+ *
+ * @return		EOK on success or a negative error code.
+ */
+int block_put(block_t *block)
 {
 	devcon_t *devcon = devcon_search(block->dev_handle);
 	cache_t *cache;
-	int rc;
+	unsigned blocks_cached;
+	enum cache_mode mode;
+	int rc = EOK;
 
 	assert(devcon);
@@ -444,4 +515,31 @@
 
 	cache = devcon->cache;
+
+retry:
+	fibril_mutex_lock(&cache->lock);
+	blocks_cached = cache->blocks_cached;
+	mode = cache->mode;
+	fibril_mutex_unlock(&cache->lock);
+
+	/*
+	 * Determine whether to sync the block. Syncing the block is best done
+	 * when not holding the cache lock as it does not impede concurrency.
+	 * Since the situation may have changed when we unlocked the cache, the
+	 * blocks_cached and mode variables are mere hints. We will recheck the
+	 * conditions later when the cache lock is held again.
+	 */
+	fibril_mutex_lock(&block->lock);
+	if (block->toxic)
+		block->dirty = false;	/* will not write back toxic block */
+	if (block->dirty && (block->refcnt == 1) &&
+	    (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
+		fibril_mutex_lock(&devcon->comm_area_lock);
+		memcpy(devcon->comm_area, block->data, block->size);
+		rc = write_blocks(devcon, block->boff, 1);
+		fibril_mutex_unlock(&devcon->comm_area_lock);
+		block->dirty = false;
+	}
+	fibril_mutex_unlock(&block->lock);
+
 	fibril_mutex_lock(&cache->lock);
 	fibril_mutex_lock(&block->lock);
@@ -449,18 +547,23 @@
 		/*
 		 * Last reference to the block was dropped. Either free the
-		 * block or put it on the free list.
+		 * block or put it on the free list. In case of an I/O error,
+		 * free the block.
 		 */
-		if (cache->blocks_cached > CACHE_HI_WATERMARK) {
+		if ((cache->blocks_cached > CACHE_HI_WATERMARK) ||
+		    (rc != EOK)) {
 			/*
-			 * Currently there are too many cached blocks.
+			 * Currently there are too many cached blocks or there
+			 * was an I/O error when writing the block back to the
+			 * device.
 			 */
 			if (block->dirty) {
-				fibril_mutex_lock(&devcon->com_area_lock);
-				memcpy(devcon->com_area, block->data,
-				    block->size);
-				rc = write_block(devcon, block->boff,
-				    block->size);
-				assert(rc == EOK);
-				fibril_mutex_unlock(&devcon->com_area_lock);
+				/*
+				 * We cannot sync the block while holding the
+				 * cache lock. Release everything and retry.
+				 */
+				block->refcnt++;
+				fibril_mutex_unlock(&block->lock);
+				fibril_mutex_unlock(&cache->lock);
+				goto retry;
 			}
 			/*
@@ -473,22 +576,25 @@
 			cache->blocks_cached--;
 			fibril_mutex_unlock(&cache->lock);
-			return;
+			return rc;
 		}
 		/*
 		 * Put the block on the free list.
 		 */
+		if (cache->mode != CACHE_MODE_WB && block->dirty) {
+			/*
+			 * We cannot sync the block while holding the cache
+			 * lock. Release everything and retry.
+			 */
+			block->refcnt++;
+			fibril_mutex_unlock(&block->lock);
+			fibril_mutex_unlock(&cache->lock);
+			goto retry;
+		}
 		list_append(&block->free_link, &cache->free_head);
-		if (cache->mode != CACHE_MODE_WB && block->dirty) {
-			fibril_mutex_lock(&devcon->com_area_lock);
-			memcpy(devcon->com_area, block->data, block->size);
-			rc = write_block(devcon, block->boff, block->size);
-			assert(rc == EOK);
-			fibril_mutex_unlock(&devcon->com_area_lock);
-
-			block->dirty = false;
-		}
 	}
 	fibril_mutex_unlock(&block->lock);
 	fibril_mutex_unlock(&cache->lock);
+
+	return rc;
 }
 
@@ -508,12 +614,16 @@
  */
 int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
-    off_t *pos, void *dst, size_t size, size_t block_size)
+    off_t *pos, void *dst, size_t size)
 {
 	off_t offset = 0;
 	size_t left = size;
-	devcon_t *devcon = devcon_search(dev_handle);
-	assert(devcon);
-	
-	fibril_mutex_lock(&devcon->com_area_lock);
+	size_t block_size;
+	devcon_t *devcon;
+
+	devcon = devcon_search(dev_handle);
+	assert(devcon);
+	block_size = devcon->pblock_size;
+	
+	fibril_mutex_lock(&devcon->comm_area_lock);
 	while (left > 0) {
 		size_t rd;
@@ -529,5 +639,5 @@
 			 * destination buffer.
 			 */
-			memcpy(dst + offset, devcon->com_area + *bufpos, rd);
+			memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
 			offset += rd;
 			*bufpos += rd;
@@ -540,7 +650,7 @@
 			int rc;
 
-			rc = read_block(devcon, *pos / block_size, block_size);
+			rc = read_blocks(devcon, *pos / block_size, 1);
 			if (rc != EOK) {
-				fibril_mutex_unlock(&devcon->com_area_lock);
+				fibril_mutex_unlock(&devcon->comm_area_lock);
 				return rc;
 			}
@@ -550,30 +660,99 @@
 		}
 	}
-	fibril_mutex_unlock(&devcon->com_area_lock);
+	fibril_mutex_unlock(&devcon->comm_area_lock);
 	
 	return EOK;
 }
 
-/** Read block from block device.
+/** Read blocks directly from device (bypass cache).
+ *
+ * @param dev_handle	Device handle of the block device.
+ * @param ba		Address of first block.
+ * @param cnt		Number of blocks.
+ * @param src		Buffer for storing the data.
+ *
+ * @return		EOK on success or negative error code on failure.
+ */
+int block_read_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, void *buf)
+{
+	devcon_t *devcon;
+	int rc;
+
+	devcon = devcon_search(dev_handle);
+	assert(devcon);
+	
+	fibril_mutex_lock(&devcon->comm_area_lock);
+
+	rc = read_blocks(devcon, ba, cnt);
+	if (rc == EOK)
+		memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
+
+	fibril_mutex_unlock(&devcon->comm_area_lock);
+
+	return rc;
+}
+
+/** Write blocks directly to device (bypass cache).
+ *
+ * @param dev_handle	Device handle of the block device.
+ * @param ba		Address of first block.
+ * @param cnt		Number of blocks.
+ * @param src		The data to be written.
+ *
+ * @return		EOK on success or negative error code on failure.
+ */
+int block_write_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt,
+    const void *data)
+{
+	devcon_t *devcon;
+	int rc;
+
+	devcon = devcon_search(dev_handle);
+	assert(devcon);
+	
+	fibril_mutex_lock(&devcon->comm_area_lock);
+
+	memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
+	rc = read_blocks(devcon, ba, cnt);
+
+	fibril_mutex_unlock(&devcon->comm_area_lock);
+
+	return rc;
+}
+
+/** Get device block size.
+ *
+ * @param dev_handle	Device handle of the block device.
+ * @param bsize		Output block size.
+ *
+ * @return		EOK on success or negative error code on failure.
+ */
+int block_get_bsize(dev_handle_t dev_handle, size_t *bsize)
+{
+	devcon_t *devcon;
+
+	devcon = devcon_search(dev_handle);
+	assert(devcon);
+	
+	return get_block_size(devcon->dev_phone, bsize);
+}
+
+/** Read blocks from block device.
  *
  * @param devcon	Device connection.
- * @param boff		Block index.
- * @param block_size	Block size.
+ * @param ba		Address of first block.
+ * @param cnt		Number of blocks.
  * @param src		Buffer for storing the data.
  *
  * @return		EOK on success or negative error code on failure.
  */
-static int read_block(devcon_t *devcon, bn_t boff, size_t block_size)
-{
-	ipcarg_t retval;
+static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
+{
 	int rc;
 
 	assert(devcon);
-	rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size,
-	    &retval);
-	if ((rc != EOK) || (retval != EOK))
-		return (rc != EOK ? rc : (int) retval);
-
-	return EOK;
+	rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
+	    UPPER32(ba), cnt);
+	return rc;
 }
 
@@ -581,22 +760,31 @@
  *
  * @param devcon	Device connection.
- * @param boff		Block index.
- * @param block_size	Block size.
+ * @param ba		Address of first block.
+ * @param cnt		Number of blocks.
  * @param src		Buffer containing the data to write.
  *
  * @return		EOK on success or negative error code on failure.
  */
-static int write_block(devcon_t *devcon, bn_t boff, size_t block_size)
-{
-	ipcarg_t retval;
+static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
+{
 	int rc;
 
 	assert(devcon);
-	rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size,
-	    &retval);
-	if ((rc != EOK) || (retval != EOK))
-		return (rc != EOK ? rc : (int) retval);
-
-	return EOK;
+	rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
+	    UPPER32(ba), cnt);
+	return rc;
+}
+
+/** Get block size used by the device. */
+static int get_block_size(int dev_phone, size_t *bsize)
+{
+	ipcarg_t bs;
+	int rc;
+
+	rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
+	if (rc == EOK)
+		*bsize = (size_t) bs;
+
+	return rc;
 }
 
Index: uspace/lib/libblock/libblock.h
===================================================================
--- uspace/lib/libblock/libblock.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libblock/libblock.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -60,5 +60,5 @@
 #define BLOCK_FLAGS_NOREAD	1
 
-typedef unsigned bn_t;	/**< Block number type. */
+typedef uint64_t bn_t;	/**< Block number type. */
 
 typedef struct block {
@@ -69,4 +69,6 @@
 	/** If true, the block needs to be written back to the block device. */
 	bool dirty;
+	/** If true, the blcok does not contain valid data. */
+	bool toxic;
 	/** Readers / Writer lock protecting the contents of the block. */
 	fibril_rwlock_t contents_lock;
@@ -96,14 +98,18 @@
 extern void block_fini(dev_handle_t);
 
-extern int block_bb_read(dev_handle_t, off_t, size_t);
+extern int block_bb_read(dev_handle_t, bn_t);
 extern void *block_bb_get(dev_handle_t);
 
 extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode);
 
-extern block_t *block_get(dev_handle_t, bn_t, int);
-extern void block_put(block_t *);
+extern int block_get(block_t **, dev_handle_t, bn_t, int);
+extern int block_put(block_t *);
 
 extern int block_seqread(dev_handle_t, off_t *, size_t *, off_t *, void *,
-    size_t, size_t);
+    size_t);
+
+extern int block_get_bsize(dev_handle_t, size_t *);
+extern int block_read_direct(dev_handle_t, bn_t, size_t, void *);
+extern int block_write_direct(dev_handle_t, bn_t, size_t, const void *);
 
 #endif
Index: uspace/lib/libc/Makefile
===================================================================
--- uspace/lib/libc/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,101 +27,13 @@
 #
 
-## Common compiler flags
-#
+include Makefile.common
 
-LIBC_PREFIX = $(shell pwd)
-SOFTINT_PREFIX = ../softint
+.PHONY: all clean
 
-
-## Setup toolchain
-#
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-
-## Sources
-#
-
-GENERIC_SOURCES = \
-	generic/libc.c \
-	generic/ddi.c \
-	generic/as.c \
-	generic/cap.c \
-	generic/devmap.c \
-	generic/event.c \
-	generic/errno.c \
-	generic/mem.c \
-	generic/string.c \
-	generic/fibril.c \
-	generic/fibril_sync.c \
-	generic/pcb.c \
-	generic/smc.c \
-	generic/thread.c \
-	generic/tls.c \
-	generic/task.c \
-	generic/futex.c \
-	generic/io/asprintf.c \
-	generic/io/io.c \
-	generic/io/printf.c \
-	generic/io/klog.c \
-	generic/io/snprintf.c \
-	generic/io/vprintf.c \
-	generic/io/vsnprintf.c \
-	generic/io/printf_core.c \
-	generic/io/console.c \
-	generic/malloc.c \
-	generic/sysinfo.c \
-	generic/ipc.c \
-	generic/async.c \
-	generic/loader.c \
-	generic/getopt.c \
-	generic/adt/list.o \
-	generic/adt/hash_table.o \
-	generic/time.c \
-	generic/err.c \
-	generic/stdlib.c \
-	generic/mman.c \
-	generic/udebug.c \
-	generic/vfs/vfs.c \
-	generic/vfs/canonify.c
-
-ARCH_SOURCES += \
-	arch/$(UARCH)/src/entry.s \
-	arch/$(UARCH)/src/thread_entry.s
-
-GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
-ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
-OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS)
-
-.PHONY: all clean depend kerninc
-
-all: kerninc libc.a arch/$(UARCH)/_link.ld
-
-kerninc:
-	ln -sfn ../../../../kernel/generic/include include/kernel
-	ln -sfn kernel/arch include/arch
-	ln -sfn ../arch/$(UARCH)/include include/libarch
-
--include Makefile.depend
+all: ../../../Makefile.config ../../../config.h ../../../config.defs
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f include/kernel include/arch include/libarch libc.a arch/$(UARCH)/_link.ld Makefile.depend
-	find generic/ arch/$(UARCH)/ -name '*.o' -follow -exec rm \{\} \;
-
-depend: kerninc
-	-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-
-libc.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
-	$(AR) rc libc.a $(LIBS) $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
-
-arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in
-	$(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) $(LIBC) arch/*/_link.ld
+	find generic/ arch/*/ -name '*.o' -follow -exec rm \{\} \;
Index: uspace/lib/libc/Makefile.build
===================================================================
--- uspace/lib/libc/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/libc/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,132 @@
+#
+# Copyright (c) 2005 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.
+#
+
+## Common compiler flags
+#
+
+LIBC_PREFIX = $(shell pwd)
+SOFTINT_PREFIX = ../softint
+LINK = arch/$(UARCH)/_link.ld
+
+
+## Setup toolchain
+#
+
+include Makefile.common
+include Makefile.toolchain
+
+
+## Sources
+#
+
+GENERIC_SOURCES = \
+	generic/libc.c \
+	generic/ddi.c \
+	generic/as.c \
+	generic/cap.c \
+	generic/devmap.c \
+	generic/event.c \
+	generic/errno.c \
+	generic/mem.c \
+	generic/string.c \
+	generic/fibril.c \
+	generic/fibril_sync.c \
+	generic/pcb.c \
+	generic/smc.c \
+	generic/thread.c \
+	generic/tls.c \
+	generic/task.c \
+	generic/futex.c \
+	generic/io/asprintf.c \
+	generic/io/io.c \
+	generic/io/printf.c \
+	generic/io/klog.c \
+	generic/io/snprintf.c \
+	generic/io/vprintf.c \
+	generic/io/vsnprintf.c \
+	generic/io/printf_core.c \
+	generic/io/console.c \
+	generic/malloc.c \
+	generic/sysinfo.c \
+	generic/ipc.c \
+	generic/async.c \
+	generic/loader.c \
+	generic/getopt.c \
+	generic/adt/list.o \
+	generic/adt/hash_table.o \
+	generic/time.c \
+	generic/err.c \
+	generic/stdlib.c \
+	generic/mman.c \
+	generic/udebug.c \
+	generic/vfs/vfs.c \
+	generic/vfs/canonify.c
+
+ARCH_SOURCES += \
+	arch/$(UARCH)/src/entry.s \
+	arch/$(UARCH)/src/thread_entry.s
+
+GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
+ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
+OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS)
+
+.PHONY: all
+
+all: $(LIBC) $(LINK)
+
+-include $(DEPEND)
+
+$(LIBC): $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
+	$(AR) rc $@ $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
+
+$(LINK): $(LINK).in
+	$(GCC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
+
+%.o: %.S $(DEPEND)
+	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.s $(DEPEND)
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND): $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH)
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
+
+$(INCLUDE_ARCH): $(INCLUDE_KERNEL) $(INCLUDE_KERNEL)/arch
+	ln -sfn kernel/arch $@
+
+$(INCLUDE_LIBARCH): arch/$(UARCH)/include
+	ln -sfn ../$< $@
+
+$(INCLUDE_KERNEL)/arch: ../../../kernel/generic/include/arch $(INCLUDE_KERNEL)
+
+$(INCLUDE_KERNEL): ../../../kernel/generic/include/
+	ln -sfn ../$< $@
Index: uspace/lib/libc/Makefile.common
===================================================================
--- uspace/lib/libc/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/libc/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+LIBC = libc.a
+INCLUDE_KERNEL = include/kernel
+INCLUDE_ARCH = include/arch
+INCLUDE_LIBARCH = include/libarch
Index: uspace/lib/libc/Makefile.toolchain
===================================================================
--- uspace/lib/libc/Makefile.toolchain	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/Makefile.toolchain	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,9 +27,23 @@
 #
 
-CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
+GCC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
 	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -fno-builtin -Wall -Wextra -Wno-unused-parameter \
-	-Wmissing-prototypes -Werror-implicit-function-declaration -nostdlib \
-	-nostdinc -pipe -g -D__$(ENDIANESS)__
+	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
+	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
+	-Werror-implicit-function-declaration -pipe -g -D__$(ENDIANESS)__
+
+ICC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
+	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
+	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
+	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
+	-Werror-implicit-function-declaration -pipe -g -D__$(ENDIANESS)__
+
+CLANG_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
+	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
+	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
+	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
+	-Werror-implicit-function-declaration -pipe -g -arch $(CLANG_ARCH) \
+	-D__$(ENDIANESS)__
+
 LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a
 AFLAGS =
@@ -45,7 +59,7 @@
 #
 
--include $(LIBC_PREFIX)/../../../Makefile.config
--include $(LIBC_PREFIX)/../../../config.defs
--include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc
+include $(LIBC_PREFIX)/../../../Makefile.config
+include $(LIBC_PREFIX)/../../../config.defs
+include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc
 
 ## Simple detection of the host system
@@ -64,6 +78,19 @@
 #
 
+ifeq ($(COMPILER),gcc_cross)
+	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
+	GCC = $(CC)
+	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
+	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
+	AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar
+	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
+	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
+	CFLAGS = $(GCC_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
+
 ifeq ($(COMPILER),gcc_native)
 	CC = gcc
+	GCC = $(CC)
 	AS = $(BINUTILS_PREFIX)as
 	LD = $(BINUTILS_PREFIX)ld
@@ -71,9 +98,11 @@
 	OBJCOPY = $(BINUTILS_PREFIX)objcopy
 	OBJDUMP = $(BINUTILS_PREFIX)objdump
+	CFLAGS = $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
-ifeq ($(COMPILER),icc_native)
+ifeq ($(COMPILER),icc)
 	CC = icc
+	GCC = gcc
 	AS = as
 	LD = ld
@@ -81,14 +110,17 @@
 	OBJCOPY = objcopy
 	OBJDUMP = objdump
+	CFLAGS = $(ICC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
-	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
-	AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar
-	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
+ifeq ($(COMPILER),clang)
+	CC = clang
+	GCC = gcc
+	AS = $(BINUTILS_PREFIX)as
+	LD = $(BINUTILS_PREFIX)ld
+	AR = $(BINUTILS_PREFIX)ar
+	OBJCOPY = $(BINUTILS_PREFIX)objcopy
+	OBJDUMP = $(BINUTILS_PREFIX)objdump
+	CFLAGS = $(CLANG_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
Index: uspace/lib/libc/arch/amd64/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/amd64/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/amd64/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -31,4 +31,5 @@
 
 TARGET = amd64-linux-gnu
+CLANG_ARCH = x86_64
 TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin
 
Index: uspace/lib/libc/arch/arm32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/arm32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/arm32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -32,5 +32,5 @@
 
 TARGET = arm-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm32/bin
 
 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
@@ -39,5 +39,5 @@
 	arch/$(UARCH)/src/eabi.S
 
-CFLAGS += -ffixed-r9 -mtp=soft
+GCC_CFLAGS += -ffixed-r9 -mtp=soft
 LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
 
Index: uspace/lib/libc/arch/ia32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/ia32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/ia32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -31,5 +31,6 @@
 
 TARGET = i686-pc-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686/bin
+CLANG_ARCH = i386
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia32/bin
 
 ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \
Index: uspace/lib/libc/arch/ia32/_link.ld.in
===================================================================
--- uspace/lib/libc/arch/ia32/_link.ld.in	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/ia32/_link.ld.in	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -3,5 +3,5 @@
 
 PHDRS {
-        text PT_LOAD FLAGS(5);
+	text PT_LOAD FLAGS(5);
 	data PT_LOAD FLAGS(6);
 }
@@ -9,21 +9,24 @@
 SECTIONS {
 	. = 0x1000 + SIZEOF_HEADERS;
-
+	
 	.init : {
 		*(.init);
 	} :text
+	
 	.text : {
 		*(.text);
-                *(.rodata*);
+		*(.rodata*);
 	} :text
-
+	
 	. = . + 0x1000;
-
+	
 	.data : {
 		*(.data);
 	} :data
+	
 	.tdata : {
 		_tdata_start = .;
 		*(.tdata);
+		*(.gnu.linkonce.tb.*);
 		_tdata_end = .;
 		_tbss_start = .;
@@ -31,11 +34,14 @@
 		_tbss_end = .;
 	} :data
+	
 	_tls_alignment = ALIGNOF(.tdata);
+	
 	.bss : {
-                *(COMMON);
-                *(.bss);
+		*(COMMON);
+		*(.bss);
 	} :data
 	
 	. = ALIGN(0x1000);
+	
 	_heap = .;
 	
@@ -43,4 +49,3 @@
 		*(*);
 	}
-
 }
Index: pace/lib/libc/arch/ia32/include/stackarg.h
===================================================================
--- uspace/lib/libc/arch/ia32/include/stackarg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,66 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libcia32
- * @{
- */
-/** @file
- */
-
-/*
- * Variable argument list manipulation macros
- * for architectures using stack to pass arguments.
- */
- 
-#ifndef LIBC_ia32_STACKARG_H_
-#define LIBC_ia32_STACKARG_H_
-
-#include <sys/types.h>
-
-/* dont allow to define it second time in stdarg.h */
-#define __VARARGS_DEFINED
-
-typedef struct va_list {
-	int pos;
-	uint8_t *last;
-} va_list;
-
-#define va_start(ap, lst) \
-	(ap).pos = sizeof(lst); 			\
-	(ap).last = (uint8_t *) &(lst)
-
-#define va_arg(ap, type) 		\
-	(*((type *)((ap).last + ((ap).pos  += sizeof(type) ) - sizeof(type))))
-
-#define va_end(ap)
-
-
-#endif
-
-/** @}
- */
Index: uspace/lib/libc/arch/ia32/include/syscall.h
===================================================================
--- uspace/lib/libc/arch/ia32/include/syscall.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/ia32/include/syscall.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -40,19 +40,19 @@
 #include <kernel/syscall/syscall.h>
 
-#define __syscall0	__syscall_sysenter
-#define __syscall1	__syscall_sysenter
-#define __syscall2	__syscall_sysenter
-#define __syscall3	__syscall_sysenter
-#define __syscall4	__syscall_sysenter
-#define __syscall5	__syscall_int
-#define __syscall6	__syscall_int
+#define __syscall0	__syscall_fast_func
+#define __syscall1	__syscall_fast_func
+#define __syscall2	__syscall_fast_func
+#define __syscall3	__syscall_fast_func
+#define __syscall4	__syscall_fast_func
+#define __syscall5	__syscall_slow
+#define __syscall6	__syscall_slow
 
 extern sysarg_t
-__syscall_sysenter(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,
-     const sysarg_t, const sysarg_t, const syscall_t);
+(* __syscall_fast_func)(const sysarg_t, const sysarg_t, const sysarg_t,
+    const sysarg_t, const sysarg_t, const sysarg_t, const syscall_t);
 
 extern sysarg_t
-__syscall_int(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,
-     const sysarg_t, const sysarg_t, const syscall_t);
+__syscall_slow(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,
+    const sysarg_t, const sysarg_t, const syscall_t);
 
 #endif
Index: uspace/lib/libc/arch/ia32/src/entry.s
===================================================================
--- uspace/lib/libc/arch/ia32/src/entry.s	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/ia32/src/entry.s	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,4 +27,7 @@
 #
 
+INTEL_CPUID_STANDARD = 1
+INTEL_SEP = 11
+
 .section .init, "ax"
 
@@ -35,5 +38,5 @@
 ## User-space task entry point
 #
-# %ebx contains the PCB pointer
+# %edi contains the PCB pointer
 #
 __entry:
@@ -44,6 +47,15 @@
 	# Do not set %gs, it contains descriptor that can see TLS
 
+	# Detect the mechanism used for making syscalls
+	movl $(INTEL_CPUID_STANDARD), %eax
+	cpuid
+	bt $(INTEL_SEP), %edx
+	jnc 0f
+	leal __syscall_fast_func, %eax
+	movl $__syscall_fast, (%eax)
+0:
+
 	# Pass the PCB pointer to __main as the first argument
-	pushl %ebx
+	pushl %edi
 	call __main
 
Index: uspace/lib/libc/arch/ia32/src/syscall.S
===================================================================
--- uspace/lib/libc/arch/ia32/src/syscall.S	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/ia32/src/syscall.S	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,4 +27,10 @@
 #
 
+.data
+
+.global __syscall_fast_func
+__syscall_fast_func:
+	.long __syscall_slow
+
 .text
 
@@ -35,6 +41,6 @@
  * could benefit from this and not save unused registers on the stack.
  */
-.global __syscall_int
-__syscall_int:
+.global __syscall_slow
+__syscall_slow:
 	pushl %ebx
 	pushl %esi
@@ -64,6 +70,6 @@
  * segment, otherwise the SYSENTER wouldn't work in the first place).
  */
-.global __syscall_sysenter
-__syscall_sysenter:
+.global __syscall_fast
+__syscall_fast:
 	pushl %ebx
 	pushl %esi
Index: uspace/lib/libc/arch/ia64/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/ia64/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/ia64/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -38,5 +38,5 @@
 	arch/$(UARCH)/src/ddi.c
 
-CFLAGS += -fno-unwind-tables
+GCC_CFLAGS += -fno-unwind-tables
 LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
 
Index: uspace/lib/libc/arch/ia64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/atomic.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/ia64/include/atomic.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libcia64	
+/** @addtogroup libcia64
  * @{
  */
@@ -36,28 +36,77 @@
 #define LIBC_ia64_ATOMIC_H_
 
-/** Atomic addition.
- *
- * @param val Atomic value.
- * @param imm Value to add.
- *
- * @return Value before addition.
- */
-static inline long atomic_add(atomic_t *val, int imm)
+static inline void atomic_inc(atomic_t *val)
 {
 	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], 1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+}
 
- 	asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm));
- 
+static inline void atomic_dec(atomic_t *val)
+{
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], -1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+}
+
+static inline long atomic_preinc(atomic_t *val)
+{
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], 1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+	
+	return (v + 1);
+}
+
+static inline long atomic_predec(atomic_t *val)
+{
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], -1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+	
+	return (v - 1);
+}
+
+static inline long atomic_postinc(atomic_t *val)
+{
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], 1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+	
 	return v;
 }
 
-static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); }
-static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); }
-
-static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; }
-static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; }
-
-static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); }
-static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); }
+static inline long atomic_postdec(atomic_t *val)
+{
+	long v;
+	
+	asm volatile (
+		"fetchadd8.rel %[v] = %[count], -1\n"
+		: [v] "=r" (v),
+		  [count] "+m" (val->count)
+	);
+	
+	return v;
+}
 
 #endif
Index: uspace/lib/libc/arch/mips32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/mips32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/mips32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -31,5 +31,5 @@
 
 TARGET = mipsel-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32/bin
 
 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
@@ -37,5 +37,5 @@
 	arch/$(UARCH)/src/tls.c
 
-CFLAGS += -mips3
+GCC_CFLAGS += -mips3
 
 ENDIANESS = LE
Index: pace/lib/libc/arch/mips32/include/stackarg.h
===================================================================
--- uspace/lib/libc/arch/mips32/include/stackarg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * 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 libcmips32	
- * @{
- */
-/** @file
- * @ingroup libcmips32eb	
- */
-
-#ifndef LIBC_mips32_STACKARG_H_
-#define LIBC_mips32_STACKARG_H_
-
-/* dont allow to define it second time in stdarg.h */
-#define __VARARGS_DEFINED
-
-#include <sys/types.h>
-
-/**
- * va_arg macro for MIPS32 - problem is that 64 bit values must be aligned on an 8-byte boundary (32bit values not)
- * To satisfy this, paddings must be sometimes inserted. 
- */
-
-typedef uint8_t* va_list;
-
-#define va_start(ap, lst) \
-	((ap) = (va_list)&(lst) + sizeof(lst))
-
-#define va_arg(ap, type)	\
-	(((type *)((ap) = (va_list)( (sizeof(type) <= 4) ? ((uint32_t)((ap) + 2*4 - 1) & (~3)) : ((uint32_t)((ap) + 2*8 -1) & (~7)) )))[-1])
-
-#define va_end(ap)
-
-#endif
-
-/** @}
- */
Index: uspace/lib/libc/arch/mips32eb/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/mips32eb/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/mips32eb/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -31,11 +31,11 @@
 
 TARGET = mips-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32eb/bin
 
 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
-		arch/$(UARCH)/src/fibril.S \
-		arch/$(UARCH)/src/tls.c
+	arch/$(UARCH)/src/fibril.S \
+	arch/$(UARCH)/src/tls.c
 
-CFLAGS += -mips3
+GCC_CFLAGS += -mips3
 LFLAGS += -N
 
Index: pace/lib/libc/arch/mips32eb/include/stackarg.h
===================================================================
--- uspace/lib/libc/arch/mips32eb/include/stackarg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../../mips32/include/stackarg.h
Index: uspace/lib/libc/arch/ppc32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/ppc32/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/ppc32/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -31,5 +31,5 @@
 
 TARGET = ppc-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin
+TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc32/bin
 
 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
@@ -37,5 +37,5 @@
 	arch/$(UARCH)/src/tls.c
 
-CFLAGS += -mcpu=powerpc -msoft-float -m32
+GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
 AFLAGS += -a32
 LFLAGS += -N
Index: uspace/lib/libc/arch/sparc64/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/sparc64/Makefile.inc	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/arch/sparc64/Makefile.inc	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -36,5 +36,5 @@
 	arch/$(UARCH)/src/tls.c
 
-CFLAGS += -mcpu=ultrasparc -m64
+GCC_CFLAGS += -mcpu=ultrasparc -m64
 LFLAGS += -no-check-sections -N
 
Index: uspace/lib/libc/generic/async.c
===================================================================
--- uspace/lib/libc/generic/async.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/async.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -83,5 +83,5 @@
  *
  *     callid = async_get_call(&call);
- *     handle_call(callid, call);
+ *     somehow_handle_the_call(callid, call);
  *     ipc_answer_2(callid, 1, 2, 3);
  *
@@ -94,4 +94,5 @@
 #include <futex.h>
 #include <async.h>
+#include <async_priv.h>
 #include <fibril.h>
 #include <stdio.h>
@@ -107,24 +108,6 @@
 atomic_t async_futex = FUTEX_INITIALIZER;
 
-/** Structures of this type represent a waiting fibril. */
-typedef struct {
-	/** Expiration time. */
-	struct timeval expires;
-	
-	/** If true, this struct is in the timeout list. */
-	bool inlist;
-	
-	/** Timeout list link. */
-	link_t link;
-	
-	/** Identification of and link to the waiting fibril. */
-	fid_t fid;
-	
-	/** If true, this fibril is currently active. */
-	bool active;
-	
-	/** If true, we have timed out. */
-	bool timedout;
-} awaiter_t;
+/** Number of threads waiting for IPC in the kernel. */
+atomic_t threads_in_ipc_wait = { 0 };
 
 typedef struct {
@@ -250,20 +233,20 @@
  *
  */
-static void insert_timeout(awaiter_t *wd)
-{
-	wd->timedout = false;
-	wd->inlist = true;
+void async_insert_timeout(awaiter_t *wd)
+{
+	wd->to_event.occurred = false;
+	wd->to_event.inlist = true;
 	
 	link_t *tmp = timeout_list.next;
 	while (tmp != &timeout_list) {
-		awaiter_t *cur = list_get_instance(tmp, awaiter_t, link);
-		
-		if (tv_gteq(&cur->expires, &wd->expires))
+		awaiter_t *cur;
+		
+		cur = list_get_instance(tmp, awaiter_t, to_event.link);
+		if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires))
 			break;
-		
 		tmp = tmp->next;
 	}
 	
-	list_append(&wd->link, tmp);
+	list_append(&wd->to_event.link, tmp);
 }
 
@@ -312,7 +295,7 @@
 		
 		/* If in timeout list, remove it */
-		if (conn->wdata.inlist) {
-			conn->wdata.inlist = false;
-			list_remove(&conn->wdata.link);
+		if (conn->wdata.to_event.inlist) {
+			conn->wdata.to_event.inlist = false;
+			list_remove(&conn->wdata.to_event.link);
 		}
 		
@@ -402,13 +385,13 @@
 	
 	if (usecs) {
-		gettimeofday(&conn->wdata.expires, NULL);
-		tv_add(&conn->wdata.expires, usecs);
+		gettimeofday(&conn->wdata.to_event.expires, NULL);
+		tv_add(&conn->wdata.to_event.expires, usecs);
 	} else
-		conn->wdata.inlist = false;
+		conn->wdata.to_event.inlist = false;
 	
 	/* If nothing in queue, wait until something arrives */
 	while (list_empty(&conn->msg_queue)) {
 		if (usecs)
-			insert_timeout(&conn->wdata);
+			async_insert_timeout(&conn->wdata);
 		
 		conn->wdata.active = false;
@@ -427,5 +410,5 @@
 		 */
 		futex_down(&async_futex);
-		if ((usecs) && (conn->wdata.timedout)
+		if ((usecs) && (conn->wdata.to_event.occurred)
 		    && (list_empty(&conn->msg_queue))) {
 			/* If we timed out -> exit */
@@ -622,14 +605,15 @@
 	link_t *cur = timeout_list.next;
 	while (cur != &timeout_list) {
-		awaiter_t *waiter = list_get_instance(cur, awaiter_t, link);
-		
-		if (tv_gt(&waiter->expires, &tv))
+		awaiter_t *waiter;
+		
+		waiter = list_get_instance(cur, awaiter_t, to_event.link);
+		if (tv_gt(&waiter->to_event.expires, &tv))
 			break;
-		
+
 		cur = cur->next;
-		
-		list_remove(&waiter->link);
-		waiter->inlist = false;
-		waiter->timedout = true;
+
+		list_remove(&waiter->to_event.link);
+		waiter->to_event.inlist = false;
+		waiter->to_event.occurred = true;
 		
 		/*
@@ -668,19 +652,22 @@
 		if (!list_empty(&timeout_list)) {
 			awaiter_t *waiter = list_get_instance(timeout_list.next,
-			    awaiter_t, link);
+			    awaiter_t, to_event.link);
 			
 			struct timeval tv;
 			gettimeofday(&tv, NULL);
 			
-			if (tv_gteq(&tv, &waiter->expires)) {
+			if (tv_gteq(&tv, &waiter->to_event.expires)) {
 				futex_up(&async_futex);
 				handle_expired_timeouts();
 				continue;
 			} else
-				timeout = tv_sub(&waiter->expires, &tv);
+				timeout = tv_sub(&waiter->to_event.expires,
+				    &tv);
 		} else
 			timeout = SYNCH_NO_TIMEOUT;
 		
 		futex_up(&async_futex);
+
+		atomic_inc(&threads_in_ipc_wait);
 		
 		ipc_call_t call;
@@ -688,4 +675,6 @@
 		    SYNCH_FLAGS_NONE);
 		
+		atomic_dec(&threads_in_ipc_wait);
+
 		if (!callid) {
 			handle_expired_timeouts();
@@ -775,6 +764,6 @@
 	
 	/* Remove message from timeout list */
-	if (msg->wdata.inlist)
-		list_remove(&msg->wdata.link);
+	if (msg->wdata.to_event.inlist)
+		list_remove(&msg->wdata.to_event.link);
 	
 	msg->done = true;
@@ -815,5 +804,5 @@
 	msg->dataptr = dataptr;
 	
-	msg->wdata.inlist = false;
+	msg->wdata.to_event.inlist = false;
 	/* We may sleep in the next method, but it will use its own mechanism */
 	msg->wdata.active = true;
@@ -855,5 +844,5 @@
 	msg->dataptr = dataptr;
 	
-	msg->wdata.inlist = false;
+	msg->wdata.to_event.inlist = false;
 	/* We may sleep in next method, but it will use its own mechanism */
 	msg->wdata.active = true;
@@ -884,5 +873,5 @@
 	msg->wdata.fid = fibril_get_id();
 	msg->wdata.active = false;
-	msg->wdata.inlist = false;
+	msg->wdata.to_event.inlist = false;
 	
 	/* Leave the async_futex locked when entering this function */
@@ -922,10 +911,10 @@
 	}
 	
-	gettimeofday(&msg->wdata.expires, NULL);
-	tv_add(&msg->wdata.expires, timeout);
+	gettimeofday(&msg->wdata.to_event.expires, NULL);
+	tv_add(&msg->wdata.to_event.expires, timeout);
 	
 	msg->wdata.fid = fibril_get_id();
 	msg->wdata.active = false;
-	insert_timeout(&msg->wdata);
+	async_insert_timeout(&msg->wdata);
 	
 	/* Leave the async_futex locked when entering this function */
@@ -963,10 +952,10 @@
 	msg->wdata.active = false;
 	
-	gettimeofday(&msg->wdata.expires, NULL);
-	tv_add(&msg->wdata.expires, timeout);
+	gettimeofday(&msg->wdata.to_event.expires, NULL);
+	tv_add(&msg->wdata.to_event.expires, timeout);
 	
 	futex_down(&async_futex);
 	
-	insert_timeout(&msg->wdata);
+	async_insert_timeout(&msg->wdata);
 	
 	/* Leave the async_futex locked when entering this function */
@@ -1098,4 +1087,248 @@
 }
 
+/** Wrapper for making IPC_M_SHARE_IN calls using the async framework.
+ *
+ * @param phoneid	Phone that will be used to contact the receiving side.
+ * @param dst		Destination address space area base.
+ * @param size		Size of the destination address space area.
+ * @param arg		User defined argument.
+ * @param flags		Storage where the received flags will be stored. Can be
+ *			NULL.
+ *
+ * @return		Zero on success or a negative error code from errno.h.
+ */
+int async_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg,
+    int *flags)
+{
+	int res;
+	sysarg_t tmp_flags;
+	res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
+	    (ipcarg_t) size, arg, NULL, &tmp_flags);
+	if (flags)
+		*flags = tmp_flags;
+	return res;
+}
+
+/** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls
+ * so that the user doesn't have to remember the meaning of each IPC argument.
+ *
+ * So far, this wrapper is to be used from within a connection fibril.
+ *
+ * @param callid	Storage where the hash of the IPC_M_SHARE_IN call will
+ * 			be stored.
+ * @param size		Destination address space area size.	
+ *
+ * @return		Non-zero on success, zero on failure.
+ */
+int async_share_in_receive(ipc_callid_t *callid, size_t *size)
+{
+	ipc_call_t data;
+	
+	assert(callid);
+	assert(size);
+
+	*callid = async_get_call(&data);
+	if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN)
+		return 0;
+	*size = (size_t) IPC_GET_ARG2(data);
+	return 1;
+}
+
+/** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
+ * so that the user doesn't have to remember the meaning of each IPC argument.
+ *
+ * @param callid	Hash of the IPC_M_DATA_READ call to answer.
+ * @param src		Source address space base.
+ * @param flags		Flags to be used for sharing. Bits can be only cleared.
+ *
+ * @return		Zero on success or a value from @ref errno.h on failure.
+ */
+int async_share_in_finalize(ipc_callid_t callid, void *src, int flags)
+{
+	return ipc_share_in_finalize(callid, src, flags);
+}
+
+/** Wrapper for making IPC_M_SHARE_OUT calls using the async framework.
+ *
+ * @param phoneid	Phone that will be used to contact the receiving side.
+ * @param src		Source address space area base address.
+ * @param flags		Flags to be used for sharing. Bits can be only cleared.
+ *
+ * @return		Zero on success or a negative error code from errno.h.
+ */
+int async_share_out_start(int phoneid, void *src, int flags)
+{
+	return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,
+	    (ipcarg_t) flags);
+}
+
+/** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls
+ * so that the user doesn't have to remember the meaning of each IPC argument.
+ *
+ * So far, this wrapper is to be used from within a connection fibril.
+ *
+ * @param callid	Storage where the hash of the IPC_M_SHARE_OUT call will
+ * 			be stored.
+ * @param size		Storage where the source address space area size will be
+ *			stored.
+ * @param flags		Storage where the sharing flags will be stored.
+ *
+ * @return		Non-zero on success, zero on failure.
+ */
+int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)
+{
+	ipc_call_t data;
+	
+	assert(callid);
+	assert(size);
+	assert(flags);
+
+	*callid = async_get_call(&data);
+	if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT)
+		return 0;
+	*size = (size_t) IPC_GET_ARG2(data);
+	*flags = (int) IPC_GET_ARG3(data);
+	return 1;
+}
+
+/** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
+ * so that the user doesn't have to remember the meaning of each IPC argument.
+ *
+ * @param callid	Hash of the IPC_M_DATA_WRITE call to answer.
+ * @param dst		Destination address space area base address.	
+ *
+ * @return		Zero on success or a value from @ref errno.h on failure.
+ */
+int async_share_out_finalize(ipc_callid_t callid, void *dst)
+{
+	return ipc_share_out_finalize(callid, dst);
+}
+
+
+/** Wrapper for making IPC_M_DATA_READ calls using the async framework.
+ *
+ * @param phoneid	Phone that will be used to contact the receiving side.
+ * @param dst		Address of the beginning of the destination buffer.
+ * @param size		Size of the destination buffer.
+ *
+ * @return		Zero on success or a negative error code from errno.h.
+ */
+int async_data_read_start(int phoneid, void *dst, size_t size)
+{
+	return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,
+	    (ipcarg_t) size);
+}
+
+/** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls
+ * so that the user doesn't have to remember the meaning of each IPC argument.
+ *
+ * So far, this wrapper is to be used from within a connection fibril.
+ *
+ * @param callid	Storage where the hash of the IPC_M_DATA_READ call will
+ * 			be stored.
+ * @param size		Storage where the maximum size will be stored. Can be
+ *			NULL.
+ *
+ * @return		Non-zero on success, zero on failure.
+ */
+int async_data_read_receive(ipc_callid_t *callid, size_t *size)
+{
+	ipc_call_t data;
+	
+	assert(callid);
+
+	*callid = async_get_call(&data);
+	if (IPC_GET_METHOD(data) != IPC_M_DATA_READ)
+		return 0;
+	if (size)
+		*size = (size_t) IPC_GET_ARG2(data);
+	return 1;
+}
+
+/** Wrapper for answering the IPC_M_DATA_READ calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
+ * so that the user doesn't have to remember the meaning of each IPC argument.
+ *
+ * @param callid	Hash of the IPC_M_DATA_READ call to answer.
+ * @param src		Source address for the IPC_M_DATA_READ call.
+ * @param size		Size for the IPC_M_DATA_READ call. Can be smaller than
+ *			the maximum size announced by the sender.
+ *
+ * @return		Zero on success or a value from @ref errno.h on failure.
+ */
+int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
+{
+	return ipc_data_read_finalize(callid, src, size);
+}
+
+/** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.
+ *
+ * @param phoneid	Phone that will be used to contact the receiving side.
+ * @param src		Address of the beginning of the source buffer.
+ * @param size		Size of the source buffer.
+ *
+ * @return		Zero on success or a negative error code from errno.h.
+ */
+int async_data_write_start(int phoneid, const void *src, size_t size)
+{
+	return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,
+	    (ipcarg_t) size);
+}
+
+/** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls
+ * so that the user doesn't have to remember the meaning of each IPC argument.
+ *
+ * So far, this wrapper is to be used from within a connection fibril.
+ *
+ * @param callid	Storage where the hash of the IPC_M_DATA_WRITE call will
+ * 			be stored.
+ * @param size		Storage where the suggested size will be stored. May be
+ *			NULL
+ *
+ * @return		Non-zero on success, zero on failure.
+ */
+int async_data_write_receive(ipc_callid_t *callid, size_t *size)
+{
+	ipc_call_t data;
+	
+	assert(callid);
+
+	*callid = async_get_call(&data);
+	if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)
+		return 0;
+	if (size)
+		*size = (size_t) IPC_GET_ARG2(data);
+	return 1;
+}
+
+/** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
+ * so that the user doesn't have to remember the meaning of each IPC argument.
+ *
+ * @param callid	Hash of the IPC_M_DATA_WRITE call to answer.
+ * @param dst		Final destination address for the IPC_M_DATA_WRITE call.
+ * @param size		Final size for the IPC_M_DATA_WRITE call.
+ *
+ * @return		Zero on success or a value from @ref errno.h on failure.
+ */
+int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
+{
+	return ipc_data_write_finalize(callid, dst, size);
+}
+
 /** @}
  */
Index: uspace/lib/libc/generic/devmap.c
===================================================================
--- uspace/lib/libc/generic/devmap.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/devmap.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -105,5 +105,5 @@
 	aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
 	
-	ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
+	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
 	
 	if (retval != EOK) {
@@ -143,5 +143,5 @@
 	    &answer);
 	
-	ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
+	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
 	
 	if (retval != EOK) {
@@ -180,5 +180,5 @@
 	    &answer);
 	
-	ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
+	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
 	
 	if (retval != EOK) {
@@ -271,5 +271,5 @@
 	aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
 	
-	ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
+	ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t));
 	
 	if (retval != EOK) {
Index: uspace/lib/libc/generic/fibril_sync.c
===================================================================
--- uspace/lib/libc/generic/fibril_sync.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/fibril_sync.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -36,7 +36,23 @@
 #include <fibril.h>
 #include <async.h>
+#include <async_priv.h>
 #include <adt/list.h>
 #include <futex.h>
+#include <sys/time.h>
+#include <errno.h>
 #include <assert.h>
+
+static void optimize_execution_power(void)
+{
+	/*
+	 * When waking up a worker fibril previously blocked in fibril
+	 * synchronization, chances are that there is an idle manager fibril
+	 * waiting for IPC, that could start executing the awakened worker
+	 * fibril right away. We try to detect this and bring the manager
+	 * fibril back to fruitful work.
+	 */
+	if (atomic_get(&threads_in_ipc_wait) > 0)
+		ipc_poke();
+}
 
 void fibril_mutex_initialize(fibril_mutex_t *fm)
@@ -50,6 +66,11 @@
 	futex_down(&async_futex);
 	if (fm->counter-- <= 0) {
-		fibril_t *f = (fibril_t *) fibril_get_id();
-		list_append(&f->link, &fm->waiters);
+		awaiter_t wdata;
+
+		wdata.fid = fibril_get_id();
+		wdata.active = false;
+		wdata.wu_event.inlist = true;
+		link_initialize(&wdata.wu_event.link);
+		list_append(&wdata.wu_event.link, &fm->waiters);
 		fibril_switch(FIBRIL_TO_MANAGER);
 	} else {
@@ -77,11 +98,14 @@
 	if (fm->counter++ < 0) {
 		link_t *tmp;
-		fibril_t *f;
+		awaiter_t *wdp;
 	
 		assert(!list_empty(&fm->waiters));
 		tmp = fm->waiters.next;
-		f = list_get_instance(tmp, fibril_t, link);
-		list_remove(&f->link);
-		fibril_add_ready((fid_t) f);
+		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
+		wdp->active = true;
+		wdp->wu_event.inlist = false;
+		list_remove(&wdp->wu_event.link);
+		fibril_add_ready(wdp->fid);
+		optimize_execution_power();
 	}
 }
@@ -106,6 +130,12 @@
 	if (frw->writers) {
 		fibril_t *f = (fibril_t *) fibril_get_id();
+		awaiter_t wdata;
+
+		wdata.fid = (fid_t) f;
+		wdata.active = false;
+		wdata.wu_event.inlist = true;
+		link_initialize(&wdata.wu_event.link);
 		f->flags &= ~FIBRIL_WRITER;
-		list_append(&f->link, &frw->waiters);
+		list_append(&wdata.wu_event.link, &frw->waiters);
 		fibril_switch(FIBRIL_TO_MANAGER);
 	} else {
@@ -120,6 +150,12 @@
 	if (frw->writers || frw->readers) {
 		fibril_t *f = (fibril_t *) fibril_get_id();
+		awaiter_t wdata;
+
+		wdata.fid = (fid_t) f;
+		wdata.active = false;
+		wdata.wu_event.inlist = true;
+		link_initialize(&wdata.wu_event.link);
 		f->flags |= FIBRIL_WRITER;
-		list_append(&f->link, &frw->waiters);
+		list_append(&wdata.wu_event.link, &frw->waiters);
 		fibril_switch(FIBRIL_TO_MANAGER);
 	} else {
@@ -144,17 +180,27 @@
 	while (!list_empty(&frw->waiters)) {
 		link_t *tmp = frw->waiters.next;
-		fibril_t *f = list_get_instance(tmp, fibril_t, link);
+		awaiter_t *wdp;
+		fibril_t *f;
+		
+		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
+		f = (fibril_t *) wdp->fid;
 		
 		if (f->flags & FIBRIL_WRITER) {
 			if (frw->readers)
 				break;
-			list_remove(&f->link);
-			fibril_add_ready((fid_t) f);
+			wdp->active = true;
+			wdp->wu_event.inlist = false;
+			list_remove(&wdp->wu_event.link);
+			fibril_add_ready(wdp->fid);
 			frw->writers++;
+			optimize_execution_power();
 			break;
 		} else {
-			list_remove(&f->link);
-			fibril_add_ready((fid_t) f);
+			wdp->active = true;
+			wdp->wu_event.inlist = false;
+			list_remove(&wdp->wu_event.link);
+			fibril_add_ready(wdp->fid);
 			frw->readers++;
+			optimize_execution_power();
 		}
 	}
@@ -178,13 +224,51 @@
 }
 
-void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm)
-{
-	fibril_t *f = (fibril_t *) fibril_get_id();
-
-	futex_down(&async_futex);
-	list_append(&f->link, &fcv->waiters);
+int
+fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm,
+    suseconds_t timeout)
+{
+	awaiter_t wdata;
+
+	if (timeout < 0)
+		return ETIMEOUT;
+
+	wdata.fid = fibril_get_id();
+	wdata.active = false;
+	
+	wdata.to_event.inlist = timeout > 0;
+	wdata.to_event.occurred = false;
+	link_initialize(&wdata.to_event.link);
+
+	wdata.wu_event.inlist = true;
+	link_initialize(&wdata.wu_event.link);
+
+	futex_down(&async_futex);
+	if (timeout) {
+		gettimeofday(&wdata.to_event.expires, NULL);
+		tv_add(&wdata.to_event.expires, timeout);
+		async_insert_timeout(&wdata);
+	}
+	list_append(&wdata.wu_event.link, &fcv->waiters);
 	_fibril_mutex_unlock_unsafe(fm);
 	fibril_switch(FIBRIL_TO_MANAGER);
 	fibril_mutex_lock(fm);
+
+	/* async_futex not held after fibril_switch() */
+	futex_down(&async_futex);
+	if (wdata.to_event.inlist)
+		list_remove(&wdata.to_event.link);
+	if (wdata.wu_event.inlist)
+		list_remove(&wdata.wu_event.link);
+	futex_up(&async_futex);
+	
+	return wdata.to_event.occurred ? ETIMEOUT : EOK;
+}
+
+void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm)
+{
+	int rc;
+
+	rc = fibril_condvar_wait_timeout(fcv, fm, 0);
+	assert(rc == EOK);
 }
 
@@ -192,14 +276,19 @@
 {
 	link_t *tmp;
-	fibril_t *f;
+	awaiter_t *wdp;
 
 	futex_down(&async_futex);
 	while (!list_empty(&fcv->waiters)) {
 		tmp = fcv->waiters.next;
-		f = list_get_instance(tmp, fibril_t, link);
-		list_remove(&f->link);
-		fibril_add_ready((fid_t) f);
-		if (once)
-			break;
+		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
+		list_remove(&wdp->wu_event.link);
+		wdp->wu_event.inlist = false;
+		if (!wdp->active) {
+			wdp->active = true;
+			fibril_add_ready(wdp->fid);
+			optimize_execution_power();
+			if (once)
+				break;
+		}
 	}
 	futex_up(&async_futex);
Index: uspace/lib/libc/generic/io/console.c
===================================================================
--- uspace/lib/libc/generic/io/console.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/io/console.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -45,7 +45,15 @@
 }
 
-int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols)
+int console_get_size(int phone, int *cols, int *rows)
 {
-	return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols);
+	ipcarg_t cols_v;
+	ipcarg_t rows_v;
+	int rc;
+
+	rc = async_req_0_2(phone, CONSOLE_GET_SIZE, &cols_v, &rows_v);
+
+	*cols = (int) cols_v;
+	*rows = (int) rows_v;
+	return rc;
 }
 
@@ -86,7 +94,7 @@
 }
 
-void console_goto(int phone, ipcarg_t row, ipcarg_t col)
+void console_goto(int phone, int col, int row)
 {
-	async_msg_2(phone, CONSOLE_GOTO, row, col);
+	async_msg_2(phone, CONSOLE_GOTO, col, row);
 }
 
Index: uspace/lib/libc/generic/io/klog.c
===================================================================
--- uspace/lib/libc/generic/io/klog.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/io/klog.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -42,5 +42,10 @@
 size_t klog_write(const void *buf, size_t size)
 {
-	return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
+	ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
+	
+	if (ret >= 0)
+		return (size_t) ret;
+	
+	return 0;
 }
 
Index: uspace/lib/libc/generic/ipc.c
===================================================================
--- uspace/lib/libc/generic/ipc.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/ipc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -565,4 +565,10 @@
 }
 
+/** Interrupt one thread of this task from waiting for IPC. */
+void ipc_poke(void)
+{
+	__SYSCALL0(SYS_IPC_POKE);
+}
+
 /** Ask destination to do a callback connection.
  *
@@ -724,5 +730,5 @@
 	int res;
 	sysarg_t tmp_flags;
-	res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
+	res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
 	    (ipcarg_t) size, arg, NULL, &tmp_flags);
 	if (flags)
@@ -731,31 +737,4 @@
 }
 
-/** Wrapper for receiving the IPC_M_SHARE_IN calls.
- *
- * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls
- * so that the user doesn't have to remember the meaning of each IPC argument.
- *
- * So far, this wrapper is to be used from within a connection fibril.
- *
- * @param callid	Storage where the hash of the IPC_M_SHARE_IN call will
- * 			be stored.
- * @param size		Destination address space area size.	
- *
- * @return		Non-zero on success, zero on failure.
- */
-int ipc_share_in_receive(ipc_callid_t *callid, size_t *size)
-{
-	ipc_call_t data;
-	
-	assert(callid);
-	assert(size);
-
-	*callid = async_get_call(&data);
-	if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN)
-		return 0;
-	*size = (size_t) IPC_GET_ARG2(data);
-	return 1;
-}
-
 /** Wrapper for answering the IPC_M_SHARE_IN calls.
  *
@@ -784,37 +763,6 @@
 int ipc_share_out_start(int phoneid, void *src, int flags)
 {
-	return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,
+	return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,
 	    (ipcarg_t) flags);
-}
-
-/** Wrapper for receiving the IPC_M_SHARE_OUT calls.
- *
- * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls
- * so that the user doesn't have to remember the meaning of each IPC argument.
- *
- * So far, this wrapper is to be used from within a connection fibril.
- *
- * @param callid	Storage where the hash of the IPC_M_SHARE_OUT call will
- * 			be stored.
- * @param size		Storage where the source address space area size will be
- *			stored.
- * @param flags		Storage where the sharing flags will be stored.
- *
- * @return		Non-zero on success, zero on failure.
- */
-int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)
-{
-	ipc_call_t data;
-	
-	assert(callid);
-	assert(size);
-	assert(flags);
-
-	*callid = async_get_call(&data);
-	if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT)
-		return 0;
-	*size = (size_t) IPC_GET_ARG2(data);
-	*flags = (int) IPC_GET_ARG3(data);
-	return 1;
 }
 
@@ -845,34 +793,6 @@
 int ipc_data_read_start(int phoneid, void *dst, size_t size)
 {
-	return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,
+	return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,
 	    (ipcarg_t) size);
-}
-
-/** Wrapper for receiving the IPC_M_DATA_READ calls.
- *
- * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls
- * so that the user doesn't have to remember the meaning of each IPC argument.
- *
- * So far, this wrapper is to be used from within a connection fibril.
- *
- * @param callid	Storage where the hash of the IPC_M_DATA_READ call will
- * 			be stored.
- * @param size		Storage where the maximum size will be stored. Can be
- *			NULL.
- *
- * @return		Non-zero on success, zero on failure.
- */
-int ipc_data_read_receive(ipc_callid_t *callid, size_t *size)
-{
-	ipc_call_t data;
-	
-	assert(callid);
-
-	*callid = async_get_call(&data);
-	if (IPC_GET_METHOD(data) != IPC_M_DATA_READ)
-		return 0;
-	if (size)
-		*size = (size_t) IPC_GET_ARG2(data);
-	return 1;
 }
 
@@ -904,34 +824,6 @@
 int ipc_data_write_start(int phoneid, const void *src, size_t size)
 {
-	return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,
+	return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,
 	    (ipcarg_t) size);
-}
-
-/** Wrapper for receiving the IPC_M_DATA_WRITE calls.
- *
- * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls
- * so that the user doesn't have to remember the meaning of each IPC argument.
- *
- * So far, this wrapper is to be used from within a connection fibril.
- *
- * @param callid	Storage where the hash of the IPC_M_DATA_WRITE call will
- * 			be stored.
- * @param size		Storage where the suggested size will be stored. May be
- *			NULL
- *
- * @return		Non-zero on success, zero on failure.
- */
-int ipc_data_write_receive(ipc_callid_t *callid, size_t *size)
-{
-	ipc_call_t data;
-	
-	assert(callid);
-
-	*callid = async_get_call(&data);
-	if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)
-		return 0;
-	if (size)
-		*size = (size_t) IPC_GET_ARG2(data);
-	return 1;
 }
 
Index: uspace/lib/libc/generic/libc.c
===================================================================
--- uspace/lib/libc/generic/libc.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/libc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -83,4 +83,5 @@
 		argv = __pcb->argv;
 		__stdio_init(__pcb->filc, __pcb->filv);
+		(void) chdir(__pcb->cwd);
 	}
 	
Index: uspace/lib/libc/generic/loader.c
===================================================================
--- uspace/lib/libc/generic/loader.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/loader.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -90,5 +90,40 @@
 	ipc_call_t answer;
 	aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
-	int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
+	int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return rc;
+	}
+	
+	ipcarg_t retval;
+	async_wait_for(req, &retval);
+	return (int) retval;
+}
+
+/** Set current working directory for the loaded task.
+ *
+ * Sets the current working directory for the loaded task.
+ *
+ * @param ldr  Loader connection structure.
+ *
+ * @return Zero on success or negative error code.
+ *
+ */
+int loader_set_cwd(loader_t *ldr)
+{
+	char *cwd;
+	size_t len;
+
+	cwd = (char *) malloc(MAX_PATH_LEN + 1);
+	if (!cwd)
+		return ENOMEM;
+	if (!getcwd(cwd, MAX_PATH_LEN + 1))
+		str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 
+	len = str_length(cwd);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer);
+	int rc = async_data_write_start(ldr->phone_id, cwd, len);
+	free(cwd);
 	if (rc != EOK) {
 		async_wait_for(req, NULL);
@@ -123,5 +158,5 @@
 	ipc_call_t answer;
 	aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
-	int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len);
+	int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
 	if (rc != EOK) {
 		async_wait_for(req, NULL);
@@ -178,5 +213,5 @@
 	ipc_call_t answer;
 	aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
-	ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
+	ipcarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
 	if (rc != EOK) {
 		async_wait_for(req, NULL);
@@ -232,5 +267,5 @@
 	ipc_call_t answer;
 	aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
-	ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf,
+	ipcarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf,
 	    count * sizeof(fdi_node_t));
 	if (rc != EOK) {
Index: uspace/lib/libc/generic/malloc.c
===================================================================
--- uspace/lib/libc/generic/malloc.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/malloc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -353,4 +353,14 @@
 }
 
+void *calloc(const size_t nmemb, const size_t size)
+{
+	void *block = malloc(nmemb * size);
+	if (block == NULL)
+		return NULL;
+
+	memset(block, 0, nmemb * size);
+	return block;
+}
+
 void *malloc(const size_t size)
 {
Index: uspace/lib/libc/generic/task.c
===================================================================
--- uspace/lib/libc/generic/task.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/task.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -89,4 +89,9 @@
 		goto error;
 	
+	/* Send spawner's current working directory. */
+	rc = loader_set_cwd(ldr);
+	if (rc != EOK)
+		goto error;
+	
 	/* Send program pathname. */
 	rc = loader_set_pathname(ldr, path);
@@ -98,5 +103,4 @@
 	if (rc != EOK)
 		goto error;
-	
 	
 	/* Send default files */
Index: uspace/lib/libc/generic/vfs/vfs.c
===================================================================
--- uspace/lib/libc/generic/vfs/vfs.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/generic/vfs/vfs.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -57,7 +57,7 @@
 static futex_t cwd_futex = FUTEX_INITIALIZER;
 
-DIR *cwd_dir = NULL;
-char *cwd_path = NULL;
-size_t cwd_size = 0;
+static int cwd_fd = -1;
+static char *cwd_path = NULL;
+static size_t cwd_size = 0;
 
 char *absolutize(const char *path, size_t *retlen)
@@ -140,5 +140,5 @@
 	
 	req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
-	rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);
+	rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
 	if (rc != EOK) {
 		async_wait_for(req, &rc_orig);
@@ -152,5 +152,5 @@
 	}
 	
-	rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));
+	rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
 	if (rc != EOK) {
 		async_wait_for(req, &rc_orig);
@@ -164,5 +164,5 @@
 	}
 
-	rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
+	rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
 	if (rc != EOK) {
 		async_wait_for(req, &rc_orig);
@@ -197,37 +197,30 @@
 }
 
-static int _open(const char *path, int lflag, int oflag, ...)
-{
-	ipcarg_t rc;
+static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
+{
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	vfs_connect();
+	
 	ipc_call_t answer;
-	aid_t req;
-	
-	size_t pa_size;
-	char *pa = absolutize(path, &pa_size);
-	if (!pa)
-		return ENOMEM;
-	
-	futex_down(&vfs_phone_futex);
-	async_serialize_start();
-	vfs_connect();
-	
-	req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
-	rc = ipc_data_write_start(vfs_phone, pa, pa_size);
+	aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
+	ipcarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
+	
 	if (rc != EOK) {
 		ipcarg_t rc_orig;
-	
-		async_wait_for(req, &rc_orig);
-		async_serialize_end();
-		futex_up(&vfs_phone_futex);
-		free(pa);
-		if (rc_orig == EOK)
-			return (int) rc;
-		else
-			return (int) rc_orig;
-	}
-	async_wait_for(req, &rc);
-	async_serialize_end();
-	futex_up(&vfs_phone_futex);
-	free(pa);
+		async_wait_for(req, &rc_orig);
+		
+		async_serialize_end();
+		futex_up(&vfs_phone_futex);
+		
+		if (rc_orig == EOK)
+			return (int) rc;
+		else
+			return (int) rc_orig;
+	}
+	
+	async_wait_for(req, &rc);
+	async_serialize_end();
+	futex_up(&vfs_phone_futex);
 	
 	if (rc != EOK)
@@ -239,5 +232,13 @@
 int open(const char *path, int oflag, ...)
 {
-	return _open(path, L_FILE, oflag);
+	size_t abs_size;
+	char *abs = absolutize(path, &abs_size);
+	if (!abs)
+		return ENOMEM;
+	
+	int ret = open_internal(abs, abs_size, L_FILE, oflag);
+	free(abs);
+	
+	return ret;
 }
 
@@ -290,5 +291,5 @@
 	
 	req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
-	rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);
+	rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
 	if (rc != EOK) {
 		ipcarg_t rc_orig;
@@ -322,5 +323,5 @@
 	
 	req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
-	rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte);
+	rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
 	if (rc != EOK) {
 		ipcarg_t rc_orig;
@@ -402,5 +403,5 @@
 	
 	req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
-	rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
+	rc = async_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
 	if (rc != EOK) {
 		ipcarg_t rc_orig;
@@ -437,5 +438,5 @@
 	
 	req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
-	rc = ipc_data_write_start(vfs_phone, pa, pa_size);
+	rc = async_data_write_start(vfs_phone, pa, pa_size);
 	if (rc != EOK) {
 		async_wait_for(req, &rc_orig);
@@ -448,5 +449,5 @@
 			return (int) rc_orig;
 	}
-	rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));
+	rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
 	if (rc != EOK) {
 		async_wait_for(req, &rc_orig);
@@ -471,9 +472,21 @@
 	if (!dirp)
 		return NULL;
-	dirp->fd = _open(dirname, L_DIRECTORY, 0);
-	if (dirp->fd < 0) {
+	
+	size_t abs_size;
+	char *abs = absolutize(dirname, &abs_size);
+	if (!abs) {
+		free(dirp);
+		return ENOMEM;
+	}
+	
+	int ret = open_internal(abs, abs_size, L_DIRECTORY, 0);
+	free(abs);
+	
+	if (ret < 0) {
 		free(dirp);
 		return NULL;
 	}
+	
+	dirp->fd = ret;
 	return dirp;
 }
@@ -514,5 +527,5 @@
 	
 	req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
-	rc = ipc_data_write_start(vfs_phone, pa, pa_size);
+	rc = async_data_write_start(vfs_phone, pa, pa_size);
 	if (rc != EOK) {
 		ipcarg_t rc_orig;
@@ -549,5 +562,5 @@
 	
 	req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
-	rc = ipc_data_write_start(vfs_phone, pa, pa_size);
+	rc = async_data_write_start(vfs_phone, pa, pa_size);
 	if (rc != EOK) {
 		ipcarg_t rc_orig;
@@ -602,5 +615,5 @@
 	
 	req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
-	rc = ipc_data_write_start(vfs_phone, olda, olda_size);
+	rc = async_data_write_start(vfs_phone, olda, olda_size);
 	if (rc != EOK) {
 		async_wait_for(req, &rc_orig);
@@ -614,5 +627,5 @@
 			return (int) rc_orig;
 	}
-	rc = ipc_data_write_start(vfs_phone, newa, newa_size);
+	rc = async_data_write_start(vfs_phone, newa, newa_size);
 	if (rc != EOK) {
 		async_wait_for(req, &rc_orig);
@@ -636,26 +649,29 @@
 int chdir(const char *path)
 {
-	size_t pa_size;
-	char *pa = absolutize(path, &pa_size);
-	if (!pa)
-		return ENOMEM;
-
-	DIR *d = opendir(pa);
-	if (!d) {
-		free(pa);
+	size_t abs_size;
+	char *abs = absolutize(path, &abs_size);
+	if (!abs)
+		return ENOMEM;
+	
+	int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC);
+	
+	if (fd < 0) {
+		free(abs);
 		return ENOENT;
 	}
-
+	
 	futex_down(&cwd_futex);
-	if (cwd_dir) {
-		closedir(cwd_dir);
-		cwd_dir = NULL;
-		free(cwd_path);	
-		cwd_path = NULL;
-		cwd_size = 0;
-	}
-	cwd_dir = d;
-	cwd_path = pa;
-	cwd_size = pa_size;
+	
+	if (cwd_fd >= 0)
+		close(cwd_fd);
+	
+	
+	if (cwd_path)
+		free(cwd_path);
+	
+	cwd_fd = fd;
+	cwd_path = abs;
+	cwd_size = abs_size;
+	
 	futex_up(&cwd_futex);
 	return EOK;
@@ -664,13 +680,17 @@
 char *getcwd(char *buf, size_t size)
 {
-	if (!size)
+	if (size == 0)
 		return NULL;
+	
 	futex_down(&cwd_futex);
-	if (size < cwd_size + 1) {
+	
+	if ((cwd_size == 0) || (size < cwd_size + 1)) {
 		futex_up(&cwd_futex);
 		return NULL;
 	}
+	
 	str_cpy(buf, size, cwd_path);
 	futex_up(&cwd_futex);
+	
 	return buf;
 }
@@ -705,4 +725,22 @@
 }
 
+int dup2(int oldfd, int newfd)
+{
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	vfs_connect();
+	
+	ipcarg_t ret;
+	ipcarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
+	
+	async_serialize_end();
+	futex_up(&vfs_phone_futex);
+	
+	if (rc == EOK)
+		return (int) ret;
+	
+	return (int) rc;
+}
+
 /** @}
  */
Index: uspace/lib/libc/include/async.h
===================================================================
--- uspace/lib/libc/include/async.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/async.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -47,4 +47,6 @@
 extern atomic_t async_futex;
 
+extern atomic_t threads_in_ipc_wait;
+
 extern int __async_init(void);
 extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
@@ -257,4 +259,29 @@
 }
 
+/*
+ * User-friendly wrappers for async_share_in_start().
+ */
+#define async_share_in_start_0_0(phoneid, dst, size) \
+	async_share_in_start((phoneid), (dst), (size), 0, NULL)
+#define async_share_in_start_0_1(phoneid, dst, size, flags) \
+	async_share_in_start((phoneid), (dst), (size), 0, (flags))
+#define async_share_in_start_1_0(phoneid, dst, size, arg) \
+	async_share_in_start((phoneid), (dst), (size), (arg), NULL)
+#define async_share_in_start_1_1(phoneid, dst, size, arg, flags) \
+	async_share_in_start((phoneid), (dst), (size), (arg), (flags))
+
+extern int async_share_in_start(int, void *, size_t, ipcarg_t, int *);
+extern int async_share_in_receive(ipc_callid_t *, size_t *);
+extern int async_share_in_finalize(ipc_callid_t, void *, int );
+extern int async_share_out_start(int, void *, int);
+extern int async_share_out_receive(ipc_callid_t *, size_t *, int *);
+extern int async_share_out_finalize(ipc_callid_t, void *);
+extern int async_data_read_start(int, void *, size_t);
+extern int async_data_read_receive(ipc_callid_t *, size_t *);
+extern int async_data_read_finalize(ipc_callid_t, const void *, size_t);
+extern int async_data_write_start(int, const void *, size_t);
+extern int async_data_write_receive(ipc_callid_t *, size_t *);
+extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
+
 #endif
 
Index: uspace/lib/libc/include/async_priv.h
===================================================================
--- uspace/lib/libc/include/async_priv.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/libc/include/async_priv.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ASYNC_PRIV_H_
+#define LIBC_ASYNC_PRIV_H_
+
+#include <adt/list.h>
+#include <fibril.h>
+#include <sys/time.h>
+#include <bool.h>
+
+/** Structures of this type are used to track the timeout events. */
+typedef struct {
+	/** If true, this struct is in the timeout list. */
+	bool inlist;
+	
+	/** Timeout list link. */
+	link_t link;
+	
+	/** If true, we have timed out. */
+	bool occurred;
+
+	/** Expiration time. */
+	struct timeval expires;
+} to_event_t;
+
+/** Structures of this type are used to track the wakeup events. */
+typedef struct {
+	/** If true, this struct is in a synchronization object wait queue. */
+	bool inlist;
+	
+	/** Wait queue linkage. */
+	link_t link;
+} wu_event_t;
+
+
+/** Structures of this type represent a waiting fibril. */
+typedef struct {
+	/** Identification of and link to the waiting fibril. */
+	fid_t fid;
+	
+	/** If true, this fibril is currently active. */
+	bool active;
+
+	/** Timeout wait data. */
+	to_event_t to_event;
+	/** Wakeup wait data. */
+	wu_event_t wu_event;
+} awaiter_t;
+
+extern void async_insert_timeout(awaiter_t *wd);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/fcntl.h
===================================================================
--- uspace/lib/libc/include/fcntl.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/fcntl.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -43,4 +43,5 @@
 #define O_RDWR    32
 #define O_WRONLY  64
+#define O_DESC    128
 
 extern int open(const char *, int, ...);
Index: uspace/lib/libc/include/fibril_sync.h
===================================================================
--- uspace/lib/libc/include/fibril_sync.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/fibril_sync.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -40,4 +40,5 @@
 #include <adt/list.h>
 #include <libarch/tls.h>
+#include <sys/time.h>
 
 typedef struct {
@@ -95,4 +96,6 @@
 
 extern void fibril_condvar_initialize(fibril_condvar_t *);
+extern int fibril_condvar_wait_timeout(fibril_condvar_t *, fibril_mutex_t *,
+    suseconds_t);
 extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *);
 extern void fibril_condvar_signal(fibril_condvar_t *);
Index: uspace/lib/libc/include/io/console.h
===================================================================
--- uspace/lib/libc/include/io/console.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/io/console.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -68,6 +68,6 @@
 extern void console_clear(int phone);
 
-extern int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols);
-extern void console_goto(int phone, ipcarg_t row, ipcarg_t col);
+extern int console_get_size(int phone, int *cols, int *rows);
+extern void console_goto(int phone, int col, int row);
 
 extern void console_set_style(int phone, int style);
Index: uspace/lib/libc/include/ipc/bd.h
===================================================================
--- uspace/lib/libc/include/ipc/bd.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/ipc/bd.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -39,6 +39,7 @@
 
 typedef enum {
-	BD_READ_BLOCK = IPC_FIRST_USER_METHOD,
-	BD_WRITE_BLOCK
+	BD_GET_BLOCK_SIZE = IPC_FIRST_USER_METHOD,
+	BD_READ_BLOCKS,
+	BD_WRITE_BLOCKS
 } bd_request_t;
 
Index: uspace/lib/libc/include/ipc/ipc.h
===================================================================
--- uspace/lib/libc/include/ipc/ipc.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/ipc/ipc.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -192,4 +192,5 @@
 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int);
 extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t);
+extern void ipc_poke(void);
 
 static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data)
@@ -282,14 +283,10 @@
 
 extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *);
-extern int ipc_share_in_receive(ipc_callid_t *, size_t *);
 extern int ipc_share_in_finalize(ipc_callid_t, void *, int );
 extern int ipc_share_out_start(int, void *, int);
-extern int ipc_share_out_receive(ipc_callid_t *, size_t *, int *);
 extern int ipc_share_out_finalize(ipc_callid_t, void *);
 extern int ipc_data_read_start(int, void *, size_t);
-extern int ipc_data_read_receive(ipc_callid_t *, size_t *);
 extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t);
 extern int ipc_data_write_start(int, const void *, size_t);
-extern int ipc_data_write_receive(ipc_callid_t *, size_t *);
 extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t);
 
Index: uspace/lib/libc/include/ipc/loader.h
===================================================================
--- uspace/lib/libc/include/ipc/loader.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/ipc/loader.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -41,4 +41,5 @@
 	LOADER_HELLO = IPC_FIRST_USER_METHOD,
 	LOADER_GET_TASKID,
+	LOADER_SET_CWD,
 	LOADER_SET_PATHNAME,
 	LOADER_SET_ARGS,
Index: uspace/lib/libc/include/ipc/vfs.h
===================================================================
--- uspace/lib/libc/include/ipc/vfs.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/ipc/vfs.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -73,5 +73,6 @@
 	VFS_IN_UNLINK,
 	VFS_IN_RENAME,
-	VFS_IN_STAT
+	VFS_IN_STAT,
+	VFS_IN_DUP
 } vfs_in_request_t;
 
Index: uspace/lib/libc/include/loader/loader.h
===================================================================
--- uspace/lib/libc/include/loader/loader.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/loader/loader.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -49,4 +49,5 @@
 extern loader_t *loader_connect(void);
 extern int loader_get_task_id(loader_t *, task_id_t *);
+extern int loader_set_cwd(loader_t *);
 extern int loader_set_pathname(loader_t *, const char *);
 extern int loader_set_args(loader_t *, char *const[]);
Index: uspace/lib/libc/include/loader/pcb.h
===================================================================
--- uspace/lib/libc/include/loader/pcb.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/loader/pcb.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -52,4 +52,7 @@
 	/** Program entry point. */
 	entry_point_t entry;
+
+	/** Current working directory. */
+	char *cwd;
 	
 	/** Number of command-line arguments. */
Index: uspace/lib/libc/include/malloc.h
===================================================================
--- uspace/lib/libc/include/malloc.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/malloc.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -42,4 +42,5 @@
 
 extern void *malloc(const size_t size);
+extern void *calloc(const size_t nmemb, const size_t size);
 extern void *memalign(const size_t align, const size_t size);
 extern void *realloc(const void *addr, const size_t size);
Index: uspace/lib/libc/include/stdarg.h
===================================================================
--- uspace/lib/libc/include/stdarg.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/stdarg.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -37,16 +37,10 @@
 
 #include <sys/types.h>
-#include <libarch/stackarg.h>
-
-#ifndef __VARARGS_DEFINED
-# define __VARARGS_DEFINED
 
 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)
-
-# endif
+#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: uspace/lib/libc/include/unistd.h
===================================================================
--- uspace/lib/libc/include/unistd.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libc/include/unistd.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -51,4 +51,6 @@
 #endif
 
+extern int dup2(int oldfd, int newfd);
+
 extern ssize_t write(int, const void *, size_t);
 extern ssize_t read(int, void *, size_t);
Index: uspace/lib/libfs/Makefile
===================================================================
--- uspace/lib/libfs/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libfs/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -28,40 +28,13 @@
 #
 
-## Common compiler flags
-#
+include Makefile.common
 
-LIBC_PREFIX = ../libc
+.PHONY: all clean
 
-## Setup toolchain
-#
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -Iinclude
-
-## Sources
-#
-
-SOURCES = \
-	libfs.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend
-
-all: libfs.a
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f libfs.a Makefile.depend
+	rm -f $(DEPEND) $(DEPEND_PREV) $(LIBFS)
 	find . -name '*.o' -follow -exec rm \{\} \;
-
-depend:
-	-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
-
-libfs.a: depend $(OBJECTS)
-	$(AR) rc libfs.a $(OBJECTS)
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
Index: uspace/lib/libfs/Makefile.build
===================================================================
--- uspace/lib/libfs/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/libfs/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	libfs.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(LIBFS)
+
+-include $(DEPEND)
+
+$(LIBFS): $(OBJECTS)
+	$(AR) rc $@ $(OBJECTS)
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/lib/libfs/Makefile.common
===================================================================
--- uspace/lib/libfs/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/libfs/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../libc
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+LIBFS = libfs.a
Index: uspace/lib/libfs/libfs.c
===================================================================
--- uspace/lib/libfs/libfs.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libfs/libfs.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -46,4 +46,19 @@
 #include <sys/stat.h>
 
+#define on_error(rc, action) \
+	do { \
+		if ((rc) != EOK) \
+			action; \
+	} while (0)
+
+#define combine_rc(rc1, rc2) \
+	((rc1) == EOK ? (rc2) : (rc1))
+
+#define answer_and_return(rid, rc) \
+	do { \
+		ipc_answer_0((rid), (rc)); \
+		return; \
+	} while (0)
+
 /** Register file system server.
  *
@@ -76,5 +91,5 @@
 	 * Send our VFS info structure to VFS.
 	 */
-	int rc = ipc_data_write_start(vfs_phone, info, sizeof(*info)); 
+	int rc = async_data_write_start(vfs_phone, info, sizeof(*info)); 
 	if (rc != EOK) {
 		async_wait_for(req, NULL);
@@ -99,5 +114,5 @@
 	 * Request sharing the Path Lookup Buffer with VFS.
 	 */
-	rc = ipc_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);
+	rc = async_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);
 	if (rc) {
 		async_wait_for(req, NULL);
@@ -154,5 +169,5 @@
 	ipc_answer_0(callid, EOK);	/* acknowledge the mountee_phone */
 	
-	res = ipc_data_write_receive(&callid, NULL);
+	res = async_data_write_receive(&callid, NULL);
 	if (!res) {
 		ipc_hangup(mountee_phone);
@@ -162,9 +177,10 @@
 	}
 
-	fs_node_t *fn = ops->node_get(mp_dev_handle, mp_fs_index);
-	if (!fn) {
+	fs_node_t *fn;
+	res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
+	if (res != EOK || !fn) {
 		ipc_hangup(mountee_phone);
-		ipc_answer_0(callid, ENOENT);
-		ipc_answer_0(rid, ENOENT);
+		ipc_answer_0(callid, combine_rc(res, ENOENT));
+		ipc_answer_0(rid, combine_rc(res, ENOENT));
 		return;
 	}
@@ -172,5 +188,5 @@
 	if (fn->mp_data.mp_active) {
 		ipc_hangup(mountee_phone);
-		ops->node_put(fn);
+		(void) ops->node_put(fn);
 		ipc_answer_0(callid, EBUSY);
 		ipc_answer_0(rid, EBUSY);
@@ -179,7 +195,7 @@
 
 	rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
-	if (rc != 0) {
+	if (rc != EOK) {
 		ipc_hangup(mountee_phone);
-		ops->node_put(fn);
+		(void) ops->node_put(fn);
 		ipc_answer_0(callid, rc);
 		ipc_answer_0(rid, rc);
@@ -230,4 +246,5 @@
 	char component[NAME_MAX + 1];
 	int len;
+	int rc;
 
 	if (last < next)
@@ -235,6 +252,9 @@
 
 	fs_node_t *par = NULL;
-	fs_node_t *cur = ops->root_get(dev_handle);
+	fs_node_t *cur = NULL;
 	fs_node_t *tmp = NULL;
+
+	rc = ops->root_get(&cur, dev_handle);
+	on_error(rc, goto out_with_answer);
 
 	if (cur->mp_data.mp_active) {
@@ -242,5 +262,5 @@
 		    next, last, cur->mp_data.dev_handle, lflag, index,
 		    IPC_FF_ROUTE_FROM_ME);
-		ops->node_put(cur);
+		(void) ops->node_put(cur);
 		return;
 	}
@@ -249,5 +269,12 @@
 		next++;		/* eat slash */
 	
-	while (next <= last && ops->has_children(cur)) {
+	while (next <= last) {
+		bool has_children;
+
+		rc = ops->has_children(&has_children, cur);
+		on_error(rc, goto out_with_answer);
+		if (!has_children)
+			break;
+
 		/* collect the component */
 		len = 0;
@@ -267,5 +294,7 @@
 
 		/* match the component */
-		tmp = ops->match(cur, component);
+		rc = ops->match(&tmp, cur, component);
+		on_error(rc, goto out_with_answer);
+
 		if (tmp && tmp->mp_data.mp_active) {
 			if (next > last)
@@ -277,8 +306,8 @@
 			    VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
 			    lflag, index, IPC_FF_ROUTE_FROM_ME);
-			ops->node_put(cur);
-			ops->node_put(tmp);
+			(void) ops->node_put(cur);
+			(void) ops->node_put(tmp);
 			if (par)
-				ops->node_put(par);
+				(void) ops->node_put(par);
 			return;
 		}
@@ -300,16 +329,15 @@
 				fs_node_t *fn;
 				if (lflag & L_CREATE)
-					fn = ops->create(dev_handle, lflag);
+					rc = ops->create(&fn, dev_handle,
+					    lflag);
 				else
-					fn = ops->node_get(dev_handle,
+					rc = ops->node_get(&fn, dev_handle,
 					    index);
+				on_error(rc, goto out_with_answer);
 				if (fn) {
-					int rc;
-
 					rc = ops->link(cur, fn, component);
 					if (rc != EOK) {
-						if (lflag & L_CREATE) {
-							(void)ops->destroy(fn);
-						}
+						if (lflag & L_CREATE)
+							(void) ops->destroy(fn);
 						ipc_answer_0(rid, rc);
 					} else {
@@ -319,5 +347,5 @@
 						    ops->size_get(fn),
 						    ops->lnkcnt_get(fn));
-						ops->node_put(fn);
+						(void) ops->node_put(fn);
 					}
 				} else {
@@ -330,6 +358,8 @@
 		}
 
-		if (par)
-			ops->node_put(par);
+		if (par) {
+			rc = ops->node_put(par);
+			on_error(rc, goto out_with_answer);
+		}
 
 		/* descend one level */
@@ -340,5 +370,12 @@
 
 	/* handle miss: excessive components */
-	if (next <= last && !ops->has_children(cur)) {
+	if (next <= last) {
+		bool has_children;
+
+		rc = ops->has_children(&has_children, cur);
+		on_error(rc, goto out_with_answer);
+		if (has_children)
+			goto skip_miss;
+
 		if (lflag & (L_CREATE | L_LINK)) {
 			if (!ops->is_directory(cur)) {
@@ -368,14 +405,13 @@
 			fs_node_t *fn;
 			if (lflag & L_CREATE)
-				fn = ops->create(dev_handle, lflag);
+				rc = ops->create(&fn, dev_handle, lflag);
 			else
-				fn = ops->node_get(dev_handle, index);
+				rc = ops->node_get(&fn, dev_handle, index);
+			on_error(rc, goto out_with_answer);
 			if (fn) {
-				int rc;
-
 				rc = ops->link(cur, fn, component);
 				if (rc != EOK) {
 					if (lflag & L_CREATE)
-						(void)ops->destroy(fn);
+						(void) ops->destroy(fn);
 					ipc_answer_0(rid, rc);
 				} else {
@@ -385,5 +421,5 @@
 					    ops->size_get(fn),
 					    ops->lnkcnt_get(fn));
-					ops->node_put(fn);
+					(void) ops->node_put(fn);
 				}
 			} else {
@@ -395,10 +431,11 @@
 		goto out;
 	}
+skip_miss:
 
 	/* handle hit */
 	if (lflag & L_UNLINK) {
 		unsigned old_lnkcnt = ops->lnkcnt_get(cur);
-		int res = ops->unlink(par, cur, component);
-		ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
+		rc = ops->unlink(par, cur, component);
+		ipc_answer_5(rid, (ipcarg_t)rc, fs_handle, dev_handle,
 		    ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
 		goto out;
@@ -418,14 +455,20 @@
 	}
 
-	ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur),
-	    ops->size_get(cur), ops->lnkcnt_get(cur));
+out_with_answer:
+	if (rc == EOK) {
+		ipc_answer_5(rid, EOK, fs_handle, dev_handle,
+		    ops->index_get(cur), ops->size_get(cur),
+		    ops->lnkcnt_get(cur));
+	} else {
+		ipc_answer_0(rid, rc);
+	}
 
 out:
 	if (par)
-		ops->node_put(par);
+		(void) ops->node_put(par);
 	if (cur)
-		ops->node_put(cur);
+		(void) ops->node_put(cur);
 	if (tmp)
-		ops->node_put(tmp);
+		(void) ops->node_put(tmp);
 }
 
@@ -435,9 +478,13 @@
 	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
 	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
-	fs_node_t *fn = ops->node_get(dev_handle, index);
+	fs_node_t *fn;
+	int rc;
+
+	rc = ops->node_get(&fn, dev_handle, index);
+	on_error(rc, answer_and_return(rid, rc));
 
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_read_receive(&callid, &size) ||
+	if (!async_data_read_receive(&callid, &size) ||
 	    size != sizeof(struct stat)) {
 		ipc_answer_0(callid, EINVAL);
@@ -456,5 +503,5 @@
 	stat.size = ops->size_get(fn);
 
-	ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
+	async_data_read_finalize(callid, &stat, sizeof(struct stat));
 	ipc_answer_0(rid, EOK);
 }
@@ -473,16 +520,19 @@
 	dev_handle_t dev_handle = IPC_GET_ARG1(*request);
 	fs_index_t index = IPC_GET_ARG2(*request);
-	
-	fs_node_t *node = ops->node_get(dev_handle, index);
-	
-	if (node == NULL) {
+	fs_node_t *fn;
+	int rc;
+	
+	rc = ops->node_get(&fn, dev_handle, index);
+	on_error(rc, answer_and_return(rid, rc));
+	
+	if (fn == NULL) {
 		ipc_answer_0(rid, ENOENT);
 		return;
 	}
 	
-	ipc_answer_5(rid, EOK, fs_handle, dev_handle, index,
-	    ops->size_get(node), ops->lnkcnt_get(node));
-	
-	ops->node_put(node);
+	ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn),
+	    (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
+	
+	(void) ops->node_put(fn);
 }
 
Index: uspace/lib/libfs/libfs.h
===================================================================
--- uspace/lib/libfs/libfs.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/libfs/libfs.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -56,16 +56,25 @@
 
 typedef struct {
-	fs_node_t * (* match)(fs_node_t *, const char *);
-	fs_node_t * (* node_get)(dev_handle_t, fs_index_t);
-	void (* node_put)(fs_node_t *);
-	fs_node_t * (* create)(dev_handle_t, int);
+	/*
+	 * The first set of methods are functions that return an integer error
+	 * code. If some additional return value is to be returned, the first
+	 * argument holds the output argument.
+	 */
+	int (* root_get)(fs_node_t **, dev_handle_t);
+	int (* match)(fs_node_t **, fs_node_t *, const char *);
+	int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t);
+	int (* node_put)(fs_node_t *);
+	int (* create)(fs_node_t **, dev_handle_t, int);
 	int (* destroy)(fs_node_t *);
 	int (* link)(fs_node_t *, fs_node_t *, const char *);
 	int (* unlink)(fs_node_t *, fs_node_t *, const char *);
+	int (* has_children)(bool *, fs_node_t *);
+	/*
+	 * The second set of methods are usually mere getters that do not return
+	 * an integer error code.
+	 */
 	fs_index_t (* index_get)(fs_node_t *);
 	size_t (* size_get)(fs_node_t *);
 	unsigned (* lnkcnt_get)(fs_node_t *);
-	bool (* has_children)(fs_node_t *);
-	fs_node_t *(* root_get)(dev_handle_t);
 	char (* plb_get_char)(unsigned pos);
 	bool (* is_directory)(fs_node_t *);
Index: uspace/lib/softfloat/Makefile
===================================================================
--- uspace/lib/softfloat/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/softfloat/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,56 +28,13 @@
 #
 
-## Common compiler flags
-#
+include Makefile.common
 
-LIBC_PREFIX = ../libc
+.PHONY: all clean
 
-## Setup toolchain
-#
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -Iinclude -Iarch/$(UARCH)/include/
-
-## Sources
-#
-
-GENERIC_SOURCES = \
-	generic/add.c \
-	generic/common.c \
-	generic/comparison.c \
-	generic/conversion.c \
-	generic/div.c \
-	generic/mul.c \
-	generic/other.c \
-	generic/softfloat.c \
-	generic/sub.c
-
-ARCH_SOURCES =
-
-GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
-
-.PHONY: all clean depend
-
-all: libsoftfloat.a
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f libsoftfloat.a Makefile.depend
-	find generic/ -name '*.o' -follow -exec rm \{\} \;
-
-depend:
-	-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-
-libsoftfloat.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
-	$(AR) rc libsoftfloat.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(LIBSOFTFLOAT)
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/lib/softfloat/Makefile.build
===================================================================
--- uspace/lib/softfloat/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/softfloat/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -Iinclude -Iarch/$(UARCH)/include/
+
+## Sources
+#
+
+SOURCES = \
+	generic/add.c \
+	generic/common.c \
+	generic/comparison.c \
+	generic/conversion.c \
+	generic/div.c \
+	generic/mul.c \
+	generic/other.c \
+	generic/softfloat.c \
+	generic/sub.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(LIBSOFTFLOAT)
+
+-include $(DEPEND)
+
+$(LIBSOFTFLOAT): $(OBJECTS)
+	$(AR) rc $@ $(OBJECTS)
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/lib/softfloat/Makefile.common
===================================================================
--- uspace/lib/softfloat/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/softfloat/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../libc
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+LIBSOFTFLOAT = libsoftfloat.a
Index: uspace/lib/softint/Makefile
===================================================================
--- uspace/lib/softint/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/lib/softint/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,48 +28,13 @@
 #
 
-## Common compiler flags
-#
+include Makefile.common
 
-LIBC_PREFIX = ../libc
+.PHONY: all clean
 
-## Setup toolchain
-#
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -Iinclude
-
-## Sources
-#
-
-ARCH_SOURCES =
-
-GENERIC_SOURCES = \
-	generic/division.c
-
-GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
-
-.PHONY: all clean depend
-
-all: libsoftint.a
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f libsoftint.a Makefile.depend
-	find generic/ -name '*.o' -follow -exec rm \{\} \;
-
-depend:
-	-makedepend -f - -- $(DEPEMD_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-
-libsoftint.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
-	$(AR) rc libsoftint.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(LIBSOFTINT)
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/lib/softint/Makefile.build
===================================================================
--- uspace/lib/softint/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/softint/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -Iinclude
+
+## Sources
+#
+
+SOURCES = \
+	generic/division.c\
+	generic/multiplication.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(LIBSOFTINT)
+
+-include $(DEPEND)
+
+$(LIBSOFTINT): $(OBJECTS)
+	$(AR) rc $@ $(OBJECTS)
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/lib/softint/Makefile.common
===================================================================
--- uspace/lib/softint/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/softint/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../libc
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+LIBSOFTINT = libsoftint.a
Index: uspace/lib/softint/generic/multiplication.c
===================================================================
--- uspace/lib/softint/generic/multiplication.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/softint/generic/multiplication.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2009 Josef Cejka
+ * 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 softint
+ * @{
+ */ 
+/**
+ * @file
+ * SW implementation of 32 and 64 bit multiplication.
+ */
+
+#include <multiplication.h>
+#include <stdint.h> 
+
+/** Set 1 to return MAX_INT64 or MIN_INT64 on overflow */
+#ifndef SOFTINT_CHECK_OF
+# define SOFTINT_CHECK_OF 0
+#endif
+
+/**
+ * Multiply two integers and return long long as result. 
+ * This function is overflow safe.
+ * @param a
+ * @param b
+ * @result
+ */
+static unsigned long long mul(unsigned int a, unsigned int b) {
+	unsigned int a1, a2, b1, b2;
+	unsigned long long t1, t2, t3;	
+
+	a1 = a >> 16;
+	a2 = a & MAX_UINT16;
+	b1 = b >> 16;
+	b2 = b & MAX_UINT16;
+
+	t1 = a1 * b1;
+	t2 = a1*b2;
+	t2 += a2*b1;
+	t3 = a2*b2;
+
+	t3 = (((t1 << 16) + t2) << 16) + t3; 
+
+	return t3;
+}
+
+/** Emulate multiplication of two 64-bit long long integers.
+ *
+ */
+long long __muldi3 (long long a, long long b)
+{
+	long long result;
+	unsigned long long t1,t2;
+	unsigned long long a1, a2, b1, b2;
+	char neg = 0;
+
+	if (a < 0) {
+		neg = !neg;
+		a = -a;
+	}
+
+	if (b < 0) {
+		neg = !neg;
+		b = -b;
+	}
+
+	a1 = a >> 32;
+	b1 = b >> 32;
+
+	a2 = a & (MAX_UINT32);
+	b2 = b & (MAX_UINT32);
+
+	if (SOFTINT_CHECK_OF && (a1 != 0) && (b1 != 0)) {
+		// error, overflow
+		return (neg?MIN_INT64:MAX_INT64);
+	}
+
+	// (if OF checked) a1 or b1 is zero => result fits in 64 bits, no need to another overflow check
+	t1 = mul(a1,b2) + mul(b1,a2);	
+
+	if (SOFTINT_CHECK_OF && t1 > MAX_UINT32) {
+		// error, overflow
+		return (neg?MIN_INT64:MAX_INT64);
+	}
+
+	t1 = t1 << 32;
+	t2 = mul(a2,b2);
+	t2 += t1;
+
+	/* t2 & (1ull << 63) - if this bit is set in unsigned long long,
+	 * result does not fit in signed one */
+	if (SOFTINT_CHECK_OF && ((t2 < t1) || (t2 & (1ull << 63)))) {
+		// error, overflow
+		return (neg?MIN_INT64:MAX_INT64);
+	}
+
+	result = t2;
+
+	if (neg) {
+		result = -result;
+	}
+
+	return result;
+}	
+
+/** @}
+ */
Index: uspace/lib/softint/include/multiplication.h
===================================================================
--- uspace/lib/softint/include/multiplication.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/lib/softint/include/multiplication.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009 Josef Cejka
+ * 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 softint
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#ifndef __SOFTINT_MULTIPLICATION_H__
+#define __SOFTINT_MULTIPLICATION_H__
+
+/* 64 bit multiplication */
+long long __muldi3(long long a, long long b);
+
+#endif
+
+/** @}
+ */
+
+
Index: uspace/srv/bd/ata_bd/Makefile
===================================================================
--- uspace/srv/bd/ata_bd/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/ata_bd/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
+.PHONY: all clean
 
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = ata_bd
-SOURCES = \
-	ata_bd.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/bd/ata_bd/Makefile.build
===================================================================
--- uspace/srv/bd/ata_bd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/bd/ata_bd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	ata_bd.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/bd/ata_bd/Makefile.common
===================================================================
--- uspace/srv/bd/ata_bd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/bd/ata_bd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = ata_bd
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -35,6 +35,12 @@
  * @brief ATA disk driver
  *
- * This driver currently works only with CHS addressing and uses PIO.
- * Currently based on the (now obsolete) ATA-1, ATA-2 standards.
+ * This driver supports CHS, 28-bit and 48-bit LBA addressing. It only uses
+ * PIO transfers. There is no support DMA, the PACKET feature set or any other
+ * fancy features such as S.M.A.R.T, removable devices, etc.
+ *
+ * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7
+ * standards, as published by the ANSI, NCITS and INCITS standards bodies,
+ * which are freely available. This driver contains no vendor-specific
+ * code at this moment.
  *
  * The driver services a single controller which can have up to two disks
@@ -50,4 +56,5 @@
 #include <as.h>
 #include <fibril_sync.h>
+#include <string.h>
 #include <devmap.h>
 #include <sys/types.h>
@@ -55,4 +62,5 @@
 #include <bool.h>
 #include <task.h>
+#include <macros.h>
 
 #include "ata_bd.h"
@@ -79,11 +87,17 @@
 static int ata_bd_init(void);
 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
-static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
+static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
     void *buf);
-static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
+static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
+    const void *buf);
+static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt,
     void *buf);
-static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
+static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
     const void *buf);
-static int drive_identify(int drive_id, disk_t *d);
+static int disk_init(disk_t *d, int disk_id);
+static int drive_identify(int drive_id, void *buf);
+static void disk_print_summary(disk_t *d);
+static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
+static void coord_sc_program(const block_coord_t *bc, uint16_t scnt);
 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
     unsigned timeout);
@@ -97,5 +111,5 @@
 	printf(NAME ": ATA disk driver\n");
 
-	printf("I/O address 0x%x\n", cmd_physical);
+	printf("I/O address 0x%p/0x%p\n", ctl_physical, cmd_physical);
 
 	if (ata_bd_init() != EOK)
@@ -106,9 +120,8 @@
 		fflush(stdout);
 
-		rc = drive_identify(i, &disk[i]);
+		rc = disk_init(&disk[i], i);
 
 		if (rc == EOK) {
-			printf("%u cylinders, %u heads, %u sectors\n",
-			    disk[i].cylinders, disk[i].heads, disk[i].sectors);
+			disk_print_summary(&disk[i]);
 		} else {
 			printf("Not found.\n");
@@ -147,4 +160,32 @@
 }
 
+/** Print one-line device summary. */
+static void disk_print_summary(disk_t *d)
+{
+	uint64_t mbytes;
+
+	printf("%s: ", d->model);
+
+	switch (d->amode) {
+	case am_chs:
+		printf("CHS %u cylinders, %u heads, %u sectors",
+		    disk->geom.cylinders, disk->geom.heads, disk->geom.sectors);
+		break;
+	case am_lba28:
+		printf("LBA-28");
+		break;
+	case am_lba48:
+		printf("LBA-48");
+		break;
+	}
+
+	printf(" %llu blocks", d->blocks, d->blocks / (2 * 1024));
+
+	mbytes = d->blocks / (2 * 1024);
+	if (mbytes > 0)
+		printf(" %llu MB.", mbytes);
+
+	printf("\n");
+}
 
 /** Register driver and enable device I/O. */
@@ -190,6 +231,6 @@
 	int flags;
 	int retval;
-	off_t idx;
-	size_t size;
+	uint64_t ba;
+	size_t cnt;
 	int disk_id, i;
 
@@ -211,5 +252,5 @@
 	ipc_answer_0(iid, EOK);
 
-	if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
+	if (!async_share_out_receive(&callid, &comm_size, &flags)) {
 		ipc_answer_0(callid, EHANGUP);
 		return;
@@ -222,5 +263,5 @@
 	}
 
-	(void) ipc_share_out_finalize(callid, fs_va);
+	(void) async_share_out_finalize(callid, fs_va);
 
 	while (1) {
@@ -232,15 +273,27 @@
 			ipc_answer_0(callid, EOK);
 			return;
-		case BD_READ_BLOCK:
-		case BD_WRITE_BLOCK:
-			idx = IPC_GET_ARG1(call);
-			size = IPC_GET_ARG2(call);
-			if (size > comm_size) {
-				retval = EINVAL;
+		case BD_READ_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
+				retval = ELIMIT;
 				break;
 			}
-			retval = ata_bd_rdwr(disk_id, method, idx,
-			    size, fs_va);
+			retval = ata_bd_read_blocks(disk_id, ba, cnt, fs_va);
 			break;
+		case BD_WRITE_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
+				retval = ELIMIT;
+				break;
+			}
+			retval = ata_bd_write_blocks(disk_id, ba, cnt, fs_va);
+			break;
+		case BD_GET_BLOCK_SIZE:
+			ipc_answer_1(callid, EOK, block_size);
+			continue;
 		default:
 			retval = EINVAL;
@@ -251,40 +304,121 @@
 }
 
-/** Transfer a logical block from/to the device.
- *
- * @param disk_id	Device index (0 or 1)
- * @param method	@c BD_READ_BLOCK or @c BD_WRITE_BLOCK
- * @param blk_idx	Index of the first block.
- * @param size		Size of the logical block.
- * @param buf		Data buffer.
- *
- * @return EOK on success, EIO on error.
- */
-static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t blk_idx, size_t size,
-    void *buf)
-{
+/** Initialize a disk.
+ *
+ * Probes for a disk, determines its parameters and initializes
+ * the disk structure.
+ */
+static int disk_init(disk_t *d, int disk_id)
+{
+	identify_data_t idata;
+	uint8_t model[40];
+	uint16_t w;
+	uint8_t c;
+	size_t pos, len;
 	int rc;
-	size_t now;
-
-	while (size > 0) {
-		now = size < block_size ? size : block_size;
-		if (now != block_size)
-			return EINVAL;
-
-		if (method == BD_READ_BLOCK)
-			rc = ata_bd_read_block(disk_id, blk_idx, 1, buf);
-		else
-			rc = ata_bd_write_block(disk_id, blk_idx, 1, buf);
-
+	unsigned i;
+
+	rc = drive_identify(disk_id, &idata);
+	if (rc != EOK) {
+		d->present = false;
+		return rc;
+	}
+
+	if ((idata.caps & cap_lba) == 0) {
+		/* Device only supports CHS addressing. */
+		d->amode = am_chs;
+
+		d->geom.cylinders = idata.cylinders;
+		d->geom.heads = idata.heads;
+		d->geom.sectors = idata.sectors;
+
+		d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors;
+	} else if ((idata.cmd_set1 & cs1_addr48) == 0) {
+		/* Device only supports LBA-28 addressing. */
+		d->amode = am_lba28;
+
+		d->geom.cylinders = 0;
+		d->geom.heads = 0;
+		d->geom.sectors = 0;
+
+		d->blocks =
+		     (uint32_t) idata.total_lba28_0 | 
+		    ((uint32_t) idata.total_lba28_1 << 16);
+	} else {
+		/* Device supports LBA-48 addressing. */
+		d->amode = am_lba48;
+
+		d->geom.cylinders = 0;
+		d->geom.heads = 0;
+		d->geom.sectors = 0;
+
+		d->blocks =
+		     (uint64_t) idata.total_lba48_0 |
+		    ((uint64_t) idata.total_lba48_1 << 16) |
+		    ((uint64_t) idata.total_lba48_2 << 32) | 
+		    ((uint64_t) idata.total_lba48_3 << 48);
+	}
+
+	/*
+	 * Convert model name to string representation.
+	 */
+	for (i = 0; i < 20; i++) {
+		w = idata.model_name[i];
+		model[2 * i] = w >> 8;
+		model[2 * i + 1] = w & 0x00ff;
+	}
+
+	len = 40;
+	while (len > 0 && model[len - 1] == 0x20)
+		--len;
+
+	pos = 0;
+	for (i = 0; i < len; ++i) {
+		c = model[i];
+		if (c >= 0x80) c = '?';
+
+		chr_encode(c, d->model, &pos, 40);
+	}
+	d->model[pos] = '\0';
+
+	d->present = true;
+	fibril_mutex_initialize(&d->lock);
+
+	return EOK;
+}
+
+/** Read multiple blocks from the device. */
+static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
+    void *buf) {
+
+	int rc;
+
+	while (cnt > 0) {
+		rc = ata_bd_read_block(disk_id, ba, 1, buf);
 		if (rc != EOK)
 			return rc;
 
+		++ba;
+		--cnt;
 		buf += block_size;
-		blk_idx++;
-
-		if (size > block_size)
-			size -= block_size;
-		else
-			size = 0;
+	}
+
+	return EOK;
+}
+
+/** Write multiple blocks to the device. */
+static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
+    const void *buf) {
+
+	int rc;
+
+	while (cnt > 0) {
+		rc = ata_bd_write_block(disk_id, ba, 1, buf);
+		if (rc != EOK)
+			return rc;
+
+		++ba;
+		--cnt;
+		buf += block_size;
 	}
 
@@ -294,11 +428,11 @@
 /** Issue IDENTIFY command.
  *
- * This is used to detect whether an ATA device is present and if so,
- * to determine its parameters. The parameters are written to @a d.
+ * Reads @c identify data into the provided buffer. This is used to detect
+ * whether an ATA device is present and if so, to determine its parameters.
  *
  * @param disk_id	Device ID, 0 or 1.
- * @param d		Device structure to store parameters in.
- */
-static int drive_identify(int disk_id, disk_t *d)
+ * @param buf		Pointer to a 512-byte buffer.
+ */
+static int drive_identify(int disk_id, void *buf)
 {
 	uint16_t data;
@@ -308,5 +442,4 @@
 
 	drv_head = ((disk_id != 0) ? DHR_DRV : 0);
-	d->present = false;
 
 	if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
@@ -330,100 +463,4 @@
 
 	if ((status & SR_DRQ) != 0) {
-//		for (i = 0; i < block_size / 2; i++) {
-//			data = pio_read_16(&cmd->data_port);
-//			((uint16_t *) buf)[i] = data;
-//		}
-
-		for (i = 0; i < block_size / 2; i++) {
-			data = pio_read_16(&cmd->data_port);
-
-			switch (i) {
-			case 1: d->cylinders = data; break;
-			case 3: d->heads = data; break;
-			case 6: d->sectors = data; break;
-			}
-		}
-	}
-
-	if ((status & SR_ERR) != 0)
-		return EIO;
-
-	d->blocks = d->cylinders * d->heads * d->sectors;
-
-	d->present = true;
-	fibril_mutex_initialize(&d->lock);
-
-	return EOK;
-}
-
-/** Read a physical from the device.
- *
- * @param disk_id	Device index (0 or 1)
- * @param blk_idx	Index of the first block.
- * @param blk_cnt	Number of blocks to transfer.
- * @param buf		Buffer for holding the data.
- *
- * @return EOK on success, EIO on error.
- */
-static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
-    void *buf)
-{
-	size_t i;
-	uint16_t data;
-	uint8_t status;
-	uint64_t c, h, s;
-	uint64_t idx;
-	uint8_t drv_head;
-	disk_t *d;
-
-	d = &disk[disk_id];
-
-	/* Check device bounds. */
-	if (blk_idx >= d->blocks)
-		return EINVAL;
-
-	/* Compute CHS. */
-	c = blk_idx / (d->heads * d->sectors);
-	idx = blk_idx % (d->heads * d->sectors);
-
-	h = idx / d->sectors;
-	s = 1 + (idx % d->sectors);
-
-	/* New value for Drive/Head register */
-	drv_head =
-	    ((disk_id != 0) ? DHR_DRV : 0) |
-	    (h & 0x0f);
-
-	fibril_mutex_lock(&d->lock);
-
-	/* Program a Read Sectors operation. */
-
-	if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&d->lock);
-		return EIO;
-	}
-
-	pio_write_8(&cmd->drive_head, drv_head);
-
-	if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
-		fibril_mutex_unlock(&d->lock);
-		return EIO;
-	}
-
-	pio_write_8(&cmd->sector_count, 1);
-	pio_write_8(&cmd->sector_number, s);
-	pio_write_8(&cmd->cylinder_low, c & 0xff);
-	pio_write_8(&cmd->cylinder_high, c >> 16);
-
-	pio_write_8(&cmd->command, CMD_READ_SECTORS);
-
-	if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&d->lock);
-		return EIO;
-	}
-
-	if ((status & SR_DRQ) != 0) {
-		/* Read data from the device buffer. */
-
 		for (i = 0; i < block_size / 2; i++) {
 			data = pio_read_16(&cmd->data_port);
@@ -435,48 +472,42 @@
 		return EIO;
 
-	fibril_mutex_unlock(&d->lock);
-	return EOK;
-}
-
-/** Write a physical block to the device.
+	return EOK;
+}
+
+/** Read a physical from the device.
  *
  * @param disk_id	Device index (0 or 1)
- * @param blk_idx	Index of the first block.
- * @param blk_cnt	Number of blocks to transfer.
- * @param buf		Buffer holding the data to write.
+ * @param ba		Address the first block.
+ * @param cnt		Number of blocks to transfer.
+ * @param buf		Buffer for holding the data.
  *
  * @return EOK on success, EIO on error.
  */
-static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
-    const void *buf)
+static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt,
+    void *buf)
 {
 	size_t i;
+	uint16_t data;
 	uint8_t status;
-	uint64_t c, h, s;
-	uint64_t idx;
 	uint8_t drv_head;
 	disk_t *d;
+	block_coord_t bc;
 
 	d = &disk[disk_id];
-
-	/* Check device bounds. */
-	if (blk_idx >= d->blocks)
+	bc.h = 0;	/* Silence warning. */
+
+	/* Compute block coordinates. */
+	if (coord_calc(d, ba, &bc) != EOK)
 		return EINVAL;
-
-	/* Compute CHS. */
-	c = blk_idx / (d->heads * d->sectors);
-	idx = blk_idx % (d->heads * d->sectors);
-
-	h = idx / d->sectors;
-	s = 1 + (idx % d->sectors);
 
 	/* New value for Drive/Head register */
 	drv_head =
 	    ((disk_id != 0) ? DHR_DRV : 0) |
-	    (h & 0x0f);
+	    ((d->amode != am_chs) ? DHR_LBA : 0) |
+	    (bc.h & 0x0f);
 
 	fibril_mutex_lock(&d->lock);
 
-	/* Program a Write Sectors operation. */
+	/* Program a Read Sectors operation. */
 
 	if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
@@ -492,10 +523,83 @@
 	}
 
-	pio_write_8(&cmd->sector_count, 1);
-	pio_write_8(&cmd->sector_number, s);
-	pio_write_8(&cmd->cylinder_low, c & 0xff);
-	pio_write_8(&cmd->cylinder_high, c >> 16);
-
-	pio_write_8(&cmd->command, CMD_WRITE_SECTORS);
+	/* Program block coordinates into the device. */
+	coord_sc_program(&bc, 1);
+
+	pio_write_8(&cmd->command, d->amode == am_lba48 ?
+	    CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
+
+	if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
+
+	if ((status & SR_DRQ) != 0) {
+		/* Read data from the device buffer. */
+
+		for (i = 0; i < block_size / 2; i++) {
+			data = pio_read_16(&cmd->data_port);
+			((uint16_t *) buf)[i] = data;
+		}
+	}
+
+	if ((status & SR_ERR) != 0)
+		return EIO;
+
+	fibril_mutex_unlock(&d->lock);
+	return EOK;
+}
+
+/** Write a physical block to the device.
+ *
+ * @param disk_id	Device index (0 or 1)
+ * @param ba		Address of the first block.
+ * @param cnt		Number of blocks to transfer.
+ * @param buf		Buffer holding the data to write.
+ *
+ * @return EOK on success, EIO on error.
+ */
+static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
+    const void *buf)
+{
+	size_t i;
+	uint8_t status;
+	uint8_t drv_head;
+	disk_t *d;
+	block_coord_t bc;
+
+	d = &disk[disk_id];
+	bc.h = 0;	/* Silence warning. */
+
+	/* Compute block coordinates. */
+	if (coord_calc(d, ba, &bc) != EOK)
+		return EINVAL;
+
+	/* New value for Drive/Head register */
+	drv_head =
+	    ((disk_id != 0) ? DHR_DRV : 0) |
+	    ((d->amode != am_chs) ? DHR_LBA : 0) |
+	    (bc.h & 0x0f);
+
+	fibril_mutex_lock(&d->lock);
+
+	/* Program a Write Sectors operation. */
+
+	if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
+
+	pio_write_8(&cmd->drive_head, drv_head);
+
+	if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
+
+	/* Program block coordinates into the device. */
+	coord_sc_program(&bc, 1);
+
+	pio_write_8(&cmd->command, d->amode == am_lba48 ?
+	    CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
 
 	if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
@@ -518,4 +622,79 @@
 
 	return EOK;
+}
+
+/** Calculate block coordinates.
+ *
+ * Calculates block coordinates in the best coordinate system supported
+ * by the device. These can be later programmed into the device using
+ * @c coord_sc_program().
+ *
+ * @return EOK on success or EINVAL if block index is past end of device.
+ */
+static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc)
+{
+	uint64_t c;
+	uint64_t idx;
+
+	/* Check device bounds. */
+	if (ba >= d->blocks)
+		return EINVAL;
+
+	bc->amode = d->amode;
+
+	switch (d->amode) {
+	case am_chs:
+		/* Compute CHS coordinates. */
+		c = ba / (d->geom.heads * d->geom.sectors);
+		idx = ba % (d->geom.heads * d->geom.sectors);
+
+		bc->cyl_lo = c & 0xff;
+		bc->cyl_hi = (c >> 8) & 0xff;
+		bc->h      = (idx / d->geom.sectors) & 0x0f;
+		bc->sector = (1 + (idx % d->geom.sectors)) & 0xff;
+		break;
+
+	case am_lba28:
+		/* Compute LBA-28 coordinates. */
+		bc->c0 = ba & 0xff;		/* bits 0-7 */
+		bc->c1 = (ba >> 8) & 0xff;	/* bits 8-15 */
+		bc->c2 = (ba >> 16) & 0xff;	/* bits 16-23 */
+		bc->h  = (ba >> 24) & 0x0f;	/* bits 24-27 */
+		break;
+
+	case am_lba48:
+		/* Compute LBA-48 coordinates. */
+		bc->c0 = ba & 0xff;		/* bits 0-7 */
+		bc->c1 = (ba >> 8) & 0xff;	/* bits 8-15 */
+		bc->c2 = (ba >> 16) & 0xff;	/* bits 16-23 */
+		bc->c3 = (ba >> 24) & 0xff;	/* bits 24-31 */
+		bc->c4 = (ba >> 32) & 0xff;	/* bits 32-39 */
+		bc->c5 = (ba >> 40) & 0xff;	/* bits 40-47 */
+		bc->h  = 0;
+		break;
+	}
+
+	return EOK;
+}
+
+/** Program block coordinates and sector count into ATA registers.
+ *
+ * Note that bc->h must be programmed separately into the device/head register.
+ */
+static void coord_sc_program(const block_coord_t *bc, uint16_t scnt)
+{
+	if (bc->amode == am_lba48) {
+		/* Write high-order bits. */
+		pio_write_8(&cmd->sector_count, scnt >> 8);
+		pio_write_8(&cmd->sector_number, bc->c3);
+		pio_write_8(&cmd->cylinder_low, bc->c4);
+		pio_write_8(&cmd->cylinder_high, bc->c5);
+	}
+
+	/* Write low-order bits. */
+	pio_write_8(&cmd->sector_count, scnt & 0x00ff);
+	pio_write_8(&cmd->sector_number, bc->c0);
+	pio_write_8(&cmd->cylinder_low, bc->c1);
+	pio_write_8(&cmd->cylinder_high, bc->c2);
 }
 
Index: uspace/srv/bd/ata_bd/ata_bd.h
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/ata_bd/ata_bd.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -38,4 +38,5 @@
 #include <sys/types.h>
 #include <fibril_sync.h>
+#include <string.h>
 
 enum {
@@ -115,5 +116,6 @@
 
 enum drive_head_bits {
-	DHR_DRV		= 0x10
+	DHR_LBA		= 0x40,	/**< Use LBA addressing mode */
+	DHR_DRV		= 0x10	/**< Select device 1 */
 };
 
@@ -130,7 +132,9 @@
 
 enum ata_command {
-	CMD_IDENTIFY_DRIVE	= 0xEC,
 	CMD_READ_SECTORS	= 0x20,
-	CMD_WRITE_SECTORS	= 0x30
+	CMD_READ_SECTORS_EXT	= 0x24,
+	CMD_WRITE_SECTORS	= 0x30,
+	CMD_WRITE_SECTORS_EXT	= 0x34,
+	CMD_IDENTIFY_DRIVE	= 0xEC
 };
 
@@ -142,10 +146,143 @@
 };
 
+/** Data returned from @c identify command. */
+typedef struct {
+	uint16_t gen_conf;
+	uint16_t cylinders;
+	uint16_t _res2;
+	uint16_t heads;
+	uint16_t _vs4;
+	uint16_t _vs5;
+	uint16_t sectors;
+	uint16_t _vs7;
+	uint16_t _vs8;
+	uint16_t _vs9;
+
+	uint16_t serial_number[10];
+	uint16_t _vs20;
+	uint16_t _vs21;
+	uint16_t vs_bytes;
+	uint16_t firmware_rev[4];
+	uint16_t model_name[20];
+
+	uint16_t max_rw_multiple;
+	uint16_t _res48;
+	uint16_t caps;
+	uint16_t _res50;
+	uint16_t pio_timing;
+	uint16_t dma_timing;
+
+	uint16_t validity;
+	uint16_t cur_cyl;
+	uint16_t cur_heads;
+	uint16_t cur_sectors;
+	uint16_t cur_capacity0;
+	uint16_t cur_capacity1;
+	uint16_t mss;
+	uint16_t total_lba28_0;
+	uint16_t total_lba28_1;
+	uint16_t sw_dma;
+	uint16_t mw_dma;
+	uint16_t pio_modes;
+	uint16_t min_mw_dma_cycle;
+	uint16_t rec_mw_dma_cycle;
+	uint16_t min_raw_pio_cycle;
+	uint16_t min_iordy_pio_cycle;
+
+	uint16_t _res69;
+	uint16_t _res70;
+	uint16_t _res71;
+	uint16_t _res72;
+	uint16_t _res73;
+	uint16_t _res74;
+
+	uint16_t queue_depth;
+	uint16_t _res76[1 + 79 - 76];
+	uint16_t version_maj;
+	uint16_t version_min;
+	uint16_t cmd_set0;
+	uint16_t cmd_set1;
+	uint16_t csf_sup_ext;
+	uint16_t csf_enabled0;
+	uint16_t csf_enabled1;
+	uint16_t csf_default;
+	uint16_t udma;
+
+	uint16_t _res89[1 + 99 - 89];
+
+	/* Total number of blocks in LBA-48 addressing */
+	uint16_t total_lba48_0;
+	uint16_t total_lba48_1;
+	uint16_t total_lba48_2;
+	uint16_t total_lba48_3;
+
+	/* Note: more fields are defined in ATA/ATAPI-7 */
+	uint16_t _res104[1 + 127 - 104];
+	uint16_t _vs128[1 + 159 - 128];
+	uint16_t _res160[1 + 255 - 160];
+} identify_data_t;
+
+enum ata_caps {
+	cap_iordy	= 0x0800,
+	cap_iordy_cbd	= 0x0400,
+	cap_lba		= 0x0200,
+	cap_dma		= 0x0100
+};
+
+/** Bits of @c identify_data_t.cmd_set1 */
+enum ata_cs1 {
+	cs1_addr48	= 0x0400	/**< 48-bit address feature set */
+};
+
+/** Block addressing mode. */
+enum addr_mode {
+	am_chs,		/**< CHS block addressing */
+	am_lba28,	/**< LBA-28 block addressing */
+	am_lba48	/**< LBA-48 block addressing */
+};
+
+/** Block coordinates */
+typedef struct {
+	/** Addressing mode used */
+	enum addr_mode amode;
+
+	union {
+		/** CHS coordinates */
+		struct {
+			uint8_t sector;
+			uint8_t cyl_lo;
+			uint8_t cyl_hi;
+		};
+		/** LBA coordinates */
+		struct {
+			uint8_t c0;
+			uint8_t c1;
+			uint8_t c2;
+			uint8_t c3;
+			uint8_t c4;
+			uint8_t c5;
+		};
+	};
+
+	/** Lower 4 bits for device/head register */
+	uint8_t h;
+} block_coord_t;
+
 typedef struct {
 	bool present;
-	unsigned heads;
-	unsigned cylinders;
-	unsigned sectors;
+	enum addr_mode amode;
+
+	/*
+	 * Geometry. Only valid if operating in CHS mode.
+	 */
+	struct {
+		unsigned heads;
+		unsigned cylinders;
+		unsigned sectors;
+	} geom;
+
 	uint64_t blocks;
+
+	char model[STR_BOUNDS(40) + 1];
 
 	fibril_mutex_t lock;
Index: uspace/srv/bd/file_bd/Makefile
===================================================================
--- uspace/srv/bd/file_bd/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/file_bd/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
+.PHONY: all clean
 
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = file_bd
-SOURCES = \
-	file_bd.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/bd/file_bd/Makefile.build
===================================================================
--- uspace/srv/bd/file_bd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/bd/file_bd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	file_bd.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/bd/file_bd/Makefile.common
===================================================================
--- uspace/srv/bd/file_bd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/bd/file_bd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = file_bd
Index: uspace/srv/bd/file_bd/file_bd.c
===================================================================
--- uspace/srv/bd/file_bd/file_bd.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/file_bd/file_bd.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -51,8 +51,9 @@
 #include <bool.h>
 #include <task.h>
+#include <macros.h>
 
 #define NAME "file_bd"
 
-static size_t comm_size;
+static const size_t block_size = 512;
 static FILE *img;
 
@@ -62,6 +63,6 @@
 static int file_bd_init(const char *fname);
 static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
-static int file_bd_read(off_t blk_idx, size_t size, void *buf);
-static int file_bd_write(off_t blk_idx, size_t size, void *buf);
+static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf);
+static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
 
 int main(int argc, char **argv)
@@ -120,13 +121,14 @@
 	ipc_call_t call;
 	ipcarg_t method;
+	size_t comm_size;
 	int flags;
 	int retval;
-	off_t idx;
-	size_t size;
+	uint64_t ba;
+	size_t cnt;
 
 	/* Answer the IPC_M_CONNECT_ME_TO call. */
 	ipc_answer_0(iid, EOK);
 
-	if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
+	if (!async_share_out_receive(&callid, &comm_size, &flags)) {
 		ipc_answer_0(callid, EHANGUP);
 		return;
@@ -139,5 +141,5 @@
 	}
 
-	(void) ipc_share_out_finalize(callid, fs_va);
+	(void) async_share_out_finalize(callid, fs_va);
 
 	while (1) {
@@ -149,17 +151,27 @@
 			ipc_answer_0(callid, EOK);
 			return;
-		case BD_READ_BLOCK:
-		case BD_WRITE_BLOCK:
-			idx = IPC_GET_ARG1(call);
-			size = IPC_GET_ARG2(call);
-			if (size > comm_size) {
-				retval = EINVAL;
+		case BD_READ_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
+				retval = ELIMIT;
 				break;
 			}
-			if (method == BD_READ_BLOCK)
-				retval = file_bd_read(idx, size, fs_va);
-			else
-				retval = file_bd_write(idx, size, fs_va);
+			retval = file_bd_read_blocks(ba, cnt, fs_va);
 			break;
+		case BD_WRITE_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
+				retval = ELIMIT;
+				break;
+			}
+			retval = file_bd_write_blocks(ba, cnt, fs_va);
+			break;
+		case BD_GET_BLOCK_SIZE:
+			ipc_answer_1(callid, EOK, block_size);
+			continue;
 		default:
 			retval = EINVAL;
@@ -170,5 +182,6 @@
 }
 
-static int file_bd_read(off_t blk_idx, size_t size, void *buf)
+/** Read blocks from the device. */
+static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf)
 {
 	size_t n_rd;
@@ -176,6 +189,6 @@
 	fibril_mutex_lock(&dev_lock);
 
-	fseek(img, blk_idx * size, SEEK_SET);
-	n_rd = fread(buf, 1, size, img);
+	fseek(img, ba * block_size, SEEK_SET);
+	n_rd = fread(buf, block_size, cnt, img);
 
 	if (ferror(img)) {
@@ -186,11 +199,12 @@
 	fibril_mutex_unlock(&dev_lock);
 
-	if (n_rd < size) 
-		return EINVAL;	/* Read beyond end of disk */
+	if (n_rd < cnt)
+		return EINVAL;	/* Read beyond end of device */
 
 	return EOK;
 }
 
-static int file_bd_write(off_t blk_idx, size_t size, void *buf)
+/** Write blocks to the device. */
+static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
 {
 	size_t n_wr;
@@ -198,8 +212,8 @@
 	fibril_mutex_lock(&dev_lock);
 
-	fseek(img, blk_idx * size, SEEK_SET);
-	n_wr = fread(buf, 1, size, img);
-
-	if (ferror(img) || n_wr < size) {
+	fseek(img, ba * block_size, SEEK_SET);
+	n_wr = fread(buf, block_size, cnt, img);
+
+	if (ferror(img) || n_wr < cnt) {
 		fibril_mutex_unlock(&dev_lock);
 		return EIO;	/* Write error */
Index: uspace/srv/bd/gxe_bd/Makefile
===================================================================
--- uspace/srv/bd/gxe_bd/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/gxe_bd/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
+.PHONY: all clean
 
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = gxe_bd
-SOURCES = \
-	gxe_bd.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/bd/gxe_bd/Makefile.build
===================================================================
--- uspace/srv/bd/gxe_bd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/bd/gxe_bd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	gxe_bd.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/bd/gxe_bd/Makefile.common
===================================================================
--- uspace/srv/bd/gxe_bd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/bd/gxe_bd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = gxe_bd
Index: uspace/srv/bd/gxe_bd/gxe_bd.c
===================================================================
--- uspace/srv/bd/gxe_bd/gxe_bd.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/gxe_bd/gxe_bd.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -47,4 +47,5 @@
 #include <sys/types.h>
 #include <errno.h>
+#include <macros.h>
 #include <task.h>
 
@@ -97,10 +98,10 @@
 static int gxe_bd_init(void);
 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
-static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
+static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
     void *buf);
-static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size,
-    void *buf);
-static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
+static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
     const void *buf);
+static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf);
+static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf);
 
 int main(int argc, char **argv)
@@ -163,6 +164,6 @@
 	int flags;
 	int retval;
-	off_t idx;
-	size_t size;
+	uint64_t ba;
+	unsigned cnt;
 	int disk_id, i;
 
@@ -184,5 +185,10 @@
 	ipc_answer_0(iid, EOK);
 
-	if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
+	if (!async_share_out_receive(&callid, &comm_size, &flags)) {
+		ipc_answer_0(callid, EHANGUP);
+		return;
+	}
+
+	if (comm_size < block_size) {
 		ipc_answer_0(callid, EHANGUP);
 		return;
@@ -195,5 +201,5 @@
 	}
 
-	(void) ipc_share_out_finalize(callid, fs_va);
+	(void) async_share_out_finalize(callid, fs_va);
 
 	while (1) {
@@ -205,15 +211,27 @@
 			ipc_answer_0(callid, EOK);
 			return;
-		case BD_READ_BLOCK:
-		case BD_WRITE_BLOCK:
-			idx = IPC_GET_ARG1(call);
-			size = IPC_GET_ARG2(call);
-			if (size > comm_size) {
-				retval = EINVAL;
+		case BD_READ_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
+				retval = ELIMIT;
 				break;
 			}
-			retval = gx_bd_rdwr(disk_id, method, idx * size,
-			    size, fs_va);
+			retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va);
 			break;
+		case BD_WRITE_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
+				retval = ELIMIT;
+				break;
+			}
+			retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va);
+			break;
+		case BD_GET_BLOCK_SIZE:
+			ipc_answer_1(callid, EOK, block_size);
+			continue;
 		default:
 			retval = EINVAL;
@@ -224,43 +242,55 @@
 }
 
-static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
-    void *buf)
-{
+/** Read multiple blocks from the device. */
+static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
+    void *buf) {
+
 	int rc;
-	size_t now;
-
-	while (size > 0) {
-		now = size < block_size ? size : block_size;
-
-		if (method == BD_READ_BLOCK)
-			rc = gxe_bd_read_block(disk_id, offset, now, buf);
-		else
-			rc = gxe_bd_write_block(disk_id, offset, now, buf);
-
+
+	while (cnt > 0) {
+		rc = gxe_bd_read_block(disk_id, ba, buf);
 		if (rc != EOK)
 			return rc;
 
+		++ba;
+		--cnt;
 		buf += block_size;
-		offset += block_size;
-
-		if (size > block_size)
-			size -= block_size;
-		else
-			size = 0;
-	}
-
-	return EOK;
-}
-
-static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size,
-    void *buf)
+	}
+
+	return EOK;
+}
+
+/** Write multiple blocks to the device. */
+static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
+    const void *buf) {
+
+	int rc;
+
+	while (cnt > 0) {
+		rc = gxe_bd_write_block(disk_id, ba, buf);
+		if (rc != EOK)
+			return rc;
+
+		++ba;
+		--cnt;
+		buf += block_size;
+	}
+
+	return EOK;
+}
+
+/** Read a block from the device. */
+static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf)
 {
 	uint32_t status;
+	uint64_t byte_addr;
 	size_t i;
 	uint32_t w;
 
+	byte_addr = ba * block_size;
+
 	fibril_mutex_lock(&dev_lock[disk_id]);
-	pio_write_32(&dev->offset_lo, (uint32_t) offset);
-	pio_write_32(&dev->offset_hi, offset >> 32);
+	pio_write_32(&dev->offset_lo, (uint32_t) byte_addr);
+	pio_write_32(&dev->offset_hi, byte_addr >> 32);
 	pio_write_32(&dev->disk_id, disk_id);
 	pio_write_32(&dev->control, CTL_READ_START);
@@ -272,5 +302,5 @@
 	}
 
-	for (i = 0; i < size; i++) {
+	for (i = 0; i < block_size; i++) {
 		((uint8_t *) buf)[i] = w = pio_read_8(&dev->buffer[i]);
 	}
@@ -280,17 +310,21 @@
 }
 
-static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
-    const void *buf)
+/** Write a block to the device. */
+static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf)
 {
 	uint32_t status;
+	uint64_t byte_addr;
 	size_t i;
 
-	for (i = 0; i < size; i++) {
+	byte_addr = ba * block_size;
+
+	fibril_mutex_lock(&dev_lock[disk_id]);
+
+	for (i = 0; i < block_size; i++) {
 		pio_write_8(&dev->buffer[i], ((const uint8_t *) buf)[i]);
 	}
 
-	fibril_mutex_lock(&dev_lock[disk_id]);
-	pio_write_32(&dev->offset_lo, (uint32_t) offset);
-	pio_write_32(&dev->offset_hi, offset >> 32);
+	pio_write_32(&dev->offset_lo, (uint32_t) byte_addr);
+	pio_write_32(&dev->offset_hi, byte_addr >> 32);
 	pio_write_32(&dev->disk_id, disk_id);
 	pio_write_32(&dev->control, CTL_WRITE_START);
Index: uspace/srv/bd/rd/Makefile
===================================================================
--- uspace/srv/bd/rd/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/rd/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
+.PHONY: all clean
 
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = rd
-SOURCES = \
-	rd.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/bd/rd/Makefile.build
===================================================================
--- uspace/srv/bd/rd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/bd/rd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	rd.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/bd/rd/Makefile.common
===================================================================
--- uspace/srv/bd/rd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/bd/rd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = rd
Index: uspace/srv/bd/rd/rd.c
===================================================================
--- uspace/srv/bd/rd/rd.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/bd/rd/rd.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -55,11 +55,18 @@
 #include <devmap.h>
 #include <ipc/bd.h>
+#include <macros.h>
 
 #define NAME "rd"
 
-/** Pointer to the ramdisk's image. */
+/** Pointer to the ramdisk's image */
 static void *rd_addr;
-/** Size of the ramdisk. */
+/** Size of the ramdisk */
 static size_t rd_size;
+
+/** Block size */
+static const size_t block_size = 512;
+
+static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf);
+static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
 
 /**
@@ -82,7 +89,7 @@
 	int retval;
 	void *fs_va = NULL;
-	off_t offset;
-	size_t block_size;
-	size_t maxblock_size;
+	uint64_t ba;
+	size_t cnt;
+	size_t comm_size;
 
 	/*
@@ -95,8 +102,8 @@
 	 */
 	int flags;
-	if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) {
-		fs_va = as_get_mappable_page(maxblock_size);
+	if (async_share_out_receive(&callid, &comm_size, &flags)) {
+		fs_va = as_get_mappable_page(comm_size);
 		if (fs_va) {
-			(void) ipc_share_out_finalize(callid, fs_va);
+			(void) async_share_out_finalize(callid, fs_va);
 		} else {
 			ipc_answer_0(callid, EHANGUP);
@@ -123,48 +130,27 @@
 			ipc_answer_0(callid, EOK);
 			return;
-		case BD_READ_BLOCK:
-			offset = IPC_GET_ARG1(call);
-			block_size = IPC_GET_ARG2(call);
-			if (block_size > maxblock_size) {
-				/*
-				 * Maximum block size exceeded.
-				 */
+		case BD_READ_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
 				retval = ELIMIT;
 				break;
 			}
-			if (offset * block_size > rd_size - block_size) {
-				/*
-				 * Reading past the end of the device.
-				 */
+			retval = rd_read_blocks(ba, cnt, fs_va);
+			break;
+		case BD_WRITE_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
 				retval = ELIMIT;
 				break;
 			}
-			fibril_rwlock_read_lock(&rd_lock);
-			memcpy(fs_va, rd_addr + offset * block_size, block_size);
-			fibril_rwlock_read_unlock(&rd_lock);
-			retval = EOK;
+			retval = rd_write_blocks(ba, cnt, fs_va);
 			break;
-		case BD_WRITE_BLOCK:
-			offset = IPC_GET_ARG1(call);
-			block_size = IPC_GET_ARG2(call);
-			if (block_size > maxblock_size) {
-				/*
-				 * Maximum block size exceeded.
-				 */
-				retval = ELIMIT;
-				break;
-			}
-			if (offset * block_size > rd_size - block_size) {
-				/*
-				 * Writing past the end of the device.
-				 */
-				retval = ELIMIT;
-				break;
-			}
-			fibril_rwlock_write_lock(&rd_lock);
-			memcpy(rd_addr + offset * block_size, fs_va, block_size);
-			fibril_rwlock_write_unlock(&rd_lock);
-			retval = EOK;
-			break;
+		case BD_GET_BLOCK_SIZE:
+			ipc_answer_1(callid, EOK, block_size);
+			continue;
 		default:
 			/*
@@ -181,4 +167,34 @@
 }
 
+/** Read blocks from the device. */
+static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf)
+{
+	if ((ba + cnt) * block_size > rd_size) {
+		/* Reading past the end of the device. */
+		return ELIMIT;
+	}
+
+	fibril_rwlock_read_lock(&rd_lock);
+	memcpy(buf, rd_addr + ba * block_size, block_size * cnt);
+	fibril_rwlock_read_unlock(&rd_lock);
+
+	return EOK;
+}
+
+/** Write blocks to the device. */
+static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
+{
+	if ((ba + cnt) * block_size > rd_size) {
+		/* Writing past the end of the device. */
+		return ELIMIT;
+	}
+
+	fibril_rwlock_write_lock(&rd_lock);
+	memcpy(rd_addr + ba * block_size, buf, block_size * cnt);
+	fibril_rwlock_write_unlock(&rd_lock);
+
+	return EOK;
+}
+
 /** Prepare the ramdisk image for operation. */
 static bool rd_init(void)
Index: uspace/srv/cir/fhc/Makefile
===================================================================
--- uspace/srv/cir/fhc/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/cir/fhc/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
+.PHONY: all clean
 
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = fhc
-SOURCES = \
-	fhc.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/cir/fhc/Makefile.build
===================================================================
--- uspace/srv/cir/fhc/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/cir/fhc/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	fhc.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/cir/fhc/Makefile.common
===================================================================
--- uspace/srv/cir/fhc/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/cir/fhc/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = fhc
Index: uspace/srv/cir/obio/Makefile
===================================================================
--- uspace/srv/cir/obio/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/cir/obio/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
+.PHONY: all clean
 
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = obio
-SOURCES = \
-	obio.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/cir/obio/Makefile.build
===================================================================
--- uspace/srv/cir/obio/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/cir/obio/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	obio.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/cir/obio/Makefile.common
===================================================================
--- uspace/srv/cir/obio/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/cir/obio/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = obio
Index: uspace/srv/console/Makefile
===================================================================
--- uspace/srv/console/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/console/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,73 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I.
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = console
-
-GENERIC_SOURCES = \
-	console.c \
-	screenbuffer.c \
-	keybuffer.c \
-	gcons.c
-
-IMAGES = \
-	gfx/helenos.ppm \
-	gfx/nameic.ppm \
-	gfx/cons_selected.ppm \
-	gfx/cons_idle.ppm \
-	gfx/cons_has_data.ppm \
-	gfx/cons_kernel.ppm \
-	gfx/anim_1.ppm \
-	gfx/anim_2.ppm \
-	gfx/anim_3.ppm \
-	gfx/anim_4.ppm
-
-GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) \
-	$(addsuffix .o,$(basename $(IMAGES)))
-
-OBJECTS := $(GENERIC_OBJECTS)
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-%.o: %.ppm
-	$(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) $< $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/console/Makefile.build
===================================================================
--- uspace/srv/console/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/console/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,79 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	console.c \
+	screenbuffer.c \
+	keybuffer.c \
+	gcons.c
+
+IMAGES = \
+	gfx/helenos.ppm \
+	gfx/nameic.ppm \
+	gfx/cons_selected.ppm \
+	gfx/cons_idle.ppm \
+	gfx/cons_has_data.ppm \
+	gfx/cons_kernel.ppm \
+	gfx/anim_1.ppm \
+	gfx/anim_2.ppm \
+	gfx/anim_3.ppm \
+	gfx/anim_4.ppm
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) $(addsuffix .o,$(basename $(IMAGES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+%.o: %.ppm
+	$(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) $< $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/console/Makefile.common
===================================================================
--- uspace/srv/console/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/console/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = console
Index: uspace/srv/console/console.c
===================================================================
--- uspace/srv/console/console.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/console/console.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -40,5 +40,4 @@
 #include <ipc/services.h>
 #include <errno.h>
-#include <keybuffer.h>
 #include <ipc/console.h>
 #include <unistd.h>
@@ -55,4 +54,5 @@
 #include "console.h"
 #include "gcons.h"
+#include "keybuffer.h"
 #include "screenbuffer.h"
 
@@ -429,5 +429,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -442,5 +442,5 @@
 	}
 	
-	(void) ipc_data_write_finalize(callid, buf, size);
+	(void) async_data_write_finalize(callid, buf, size);
 	
 	async_serialize_start();
@@ -464,5 +464,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_read_receive(&callid, &size)) {
+	if (!async_data_read_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -489,5 +489,5 @@
 	
 	if (pos == size) {
-		(void) ipc_data_read_finalize(callid, buf, size);
+		(void) async_data_read_finalize(callid, buf, size);
 		ipc_answer_1(rid, EOK, size);
 		free(buf);
@@ -713,5 +713,5 @@
 	
 	if (interbuffer) {
-		if (ipc_share_out_start(fb_info.phone, interbuffer,
+		if (async_share_out_start(fb_info.phone, interbuffer,
 		    AS_AREA_READ) != EOK) {
 			as_area_destroy(interbuffer);
Index: uspace/srv/console/gcons.c
===================================================================
--- uspace/srv/console/gcons.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/console/gcons.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -339,5 +339,5 @@
 		goto exit;
 	
-	rc = ipc_share_out_start(fbphone, shm, PROTO_READ);
+	rc = async_share_out_start(fbphone, shm, PROTO_READ);
 	if (rc)
 		goto drop;
@@ -409,5 +409,5 @@
 		goto exit;
 	
-	rc = ipc_share_out_start(fbphone, shm, PROTO_READ);
+	rc = async_share_out_start(fbphone, shm, PROTO_READ);
 	if (rc)
 		goto drop;
Index: uspace/srv/console/keybuffer.c
===================================================================
--- uspace/srv/console/keybuffer.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/console/keybuffer.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -35,6 +35,6 @@
  */
 
-#include <keybuffer.h>
 #include <futex.h>
+#include "keybuffer.h"
 
 atomic_t keybuffer_futex = FUTEX_INITIALIZER;
Index: uspace/srv/console/screenbuffer.c
===================================================================
--- uspace/srv/console/screenbuffer.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/console/screenbuffer.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -33,8 +33,8 @@
  */
 
-#include <screenbuffer.h>
 #include <io/style.h>
 #include <malloc.h>
 #include <unistd.h>
+#include "screenbuffer.h"
 
 /** Store one character to screenbuffer.
Index: uspace/srv/devmap/Makefile
===================================================================
--- uspace/srv/devmap/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/devmap/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,51 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = devmap
-SOURCES = \
-	devmap.c 
-
-CFLAGS += -D$(UARCH)
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/devmap/Makefile.build
===================================================================
--- uspace/srv/devmap/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/devmap/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	devmap.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/devmap/Makefile.common
===================================================================
--- uspace/srv/devmap/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/devmap/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = devmap
Index: uspace/srv/devmap/devmap.c
===================================================================
--- uspace/srv/devmap/devmap.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/devmap/devmap.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -213,5 +213,5 @@
 	ipc_callid_t callid;
 	size_t name_size;
-	if (!ipc_data_write_receive(&callid, &name_size)) {
+	if (!async_data_write_receive(&callid, &name_size)) {
 		free(driver);
 		ipc_answer_0(callid, EREFUSED);
@@ -241,5 +241,5 @@
 	 * Send confirmation to sender and get data into buffer.
 	 */
-	if (ipc_data_write_finalize(callid, driver->name, name_size) != EOK) {
+	if (async_data_write_finalize(callid, driver->name, name_size) != EOK) {
 		free(driver->name);
 		free(driver);
@@ -358,5 +358,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		free(device);
 		ipc_answer_0(iid, EREFUSED);
@@ -381,5 +381,5 @@
 	}
 	
-	ipc_data_write_finalize(callid, device->name, size);
+	async_data_write_finalize(callid, device->name, size);
 	device->name[size] = 0;
 	
@@ -466,5 +466,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EREFUSED);
 		ipc_answer_0(iid, EREFUSED);
@@ -491,5 +491,5 @@
 	 * Send confirmation to sender and get data into buffer.
 	 */
-	ipcarg_t retval = ipc_data_write_finalize(callid, name, size);
+	ipcarg_t retval = async_data_write_finalize(callid, name, size);
 	if (retval != EOK) {
 		ipc_answer_0(iid, EREFUSED);
@@ -553,5 +553,5 @@
 	 * size_t name_size = str_size(device->name);
 	 *
-	 * int rc = ipc_data_write_send(phone, device->name, name_size);
+	 * int rc = async_data_write_send(phone, device->name, name_size);
 	 * if (rc != EOK) {
 	 *     async_wait_for(req, NULL);
@@ -576,5 +576,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_read_receive(&callid, &size)) {
+	if (!async_data_read_receive(&callid, &size)) {
 		ipc_answer_0(callid, EREFUSED);
 		ipc_answer_0(iid, EREFUSED);
@@ -608,5 +608,5 @@
 	}
 	
-	ipcarg_t retval = ipc_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t));
+	ipcarg_t retval = async_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t));
 	if (retval != EOK) {
 		ipc_answer_0(iid, EREFUSED);
Index: uspace/srv/fb/Makefile
===================================================================
--- uspace/srv/fb/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fb/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,89 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = fb
-SOURCES = \
-	main.c \
-	ppm.c
-
-ifneq ($(UARCH),ia64)
-	SOURCES += fb.c \
-		font-8x16.c
-	CFLAGS += -DFB_ENABLED
-endif
-
-ifeq ($(UARCH),ia32)
-	SOURCES += ega.c
-	CFLAGS += -DEGA_ENABLED
-endif
-
-ifeq ($(UARCH),ia64)
-	SOURCES += ega.c \
-		ski.c \
-		serial_console.c
-	CFLAGS += -DSKI_ENABLED
-	CFLAGS += -DEGA_ENABLED
-endif
-
-ifeq ($(UARCH),amd64)
-	SOURCES += ega.c
-	CFLAGS += -DEGA_ENABLED
-endif
-
-ifeq ($(UARCH),mips32)
-	SOURCES += msim.c \
-		serial_console.c
-	CFLAGS += -DMSIM_ENABLED
-endif
-
-ifeq ($(UARCH),sparc64)
-	SOURCES += sgcn.c \
-		serial_console.c
-	CFLAGS += -DSGCN_ENABLED
-endif
-
-CFLAGS += -D$(UARCH)
-
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/fb/Makefile.build
===================================================================
--- uspace/srv/fb/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/fb/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,100 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	main.c \
+	ppm.c
+
+ifneq ($(UARCH),ia64)
+	SOURCES += fb.c \
+		font-8x16.c
+	CFLAGS += -DFB_ENABLED
+endif
+
+ifeq ($(UARCH),ia32)
+	SOURCES += ega.c
+	CFLAGS += -DEGA_ENABLED
+endif
+
+ifeq ($(UARCH),ia64)
+	SOURCES += ega.c \
+		ski.c \
+		serial_console.c
+	CFLAGS += -DSKI_ENABLED
+	CFLAGS += -DEGA_ENABLED
+endif
+
+ifeq ($(UARCH),amd64)
+	SOURCES += ega.c
+	CFLAGS += -DEGA_ENABLED
+endif
+
+ifeq ($(UARCH),mips32)
+	SOURCES += msim.c \
+		serial_console.c
+	CFLAGS += -DMSIM_ENABLED
+endif
+
+ifeq ($(UARCH),sparc64)
+	SOURCES += sgcn.c \
+		serial_console.c
+	CFLAGS += -DSGCN_ENABLED
+endif
+
+CFLAGS += -D$(UARCH)
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/fb/Makefile.common
===================================================================
--- uspace/srv/fb/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/fb/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = fb
Index: uspace/srv/fs/devfs/Makefile
===================================================================
--- uspace/srv/fs/devfs/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/devfs/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,56 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../../lib/libc
-LIBFS_PREFIX = ../../../lib/libfs
-SOFTINT_PREFIX = ../../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I $(LIBFS_PREFIX) 
-
-LIBS = \
-	$(LIBFS_PREFIX)/libfs.a \
-	$(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = devfs
-SOURCES = \
-	devfs.c \
-	devfs_ops.c
-
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/fs/devfs/Makefile.build
===================================================================
--- uspace/srv/fs/devfs/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/fs/devfs/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I$(LIBFS_PREFIX)
+
+## Sources
+#
+
+SOURCES = \
+	devfs.c \
+	devfs_ops.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/fs/devfs/Makefile.common
===================================================================
--- uspace/srv/fs/devfs/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/fs/devfs/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+LIBFS_PREFIX = ../../../lib/libfs
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBFS_PREFIX)/libfs.a $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = devfs
Index: uspace/srv/fs/devfs/devfs.c
===================================================================
--- uspace/srv/fs/devfs/devfs.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/devfs/devfs.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -44,4 +44,5 @@
 #include <async.h>
 #include <errno.h>
+#include <task.h>
 #include <libfs.h>
 #include "devfs.h"
@@ -51,5 +52,5 @@
 
 static vfs_info_t devfs_vfs_info = {
-	.name = "devfs",
+	.name = NAME,
 };
 
@@ -131,4 +132,5 @@
 	
 	printf(NAME ": Accepting connections\n");
+	task_retval(0);
 	async_manager();
 	
Index: uspace/srv/fs/devfs/devfs_ops.c
===================================================================
--- uspace/srv/fs/devfs/devfs_ops.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/devfs/devfs_ops.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -108,5 +108,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -121,5 +121,5 @@
 	}
 	
-	ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
+	ipcarg_t retval = async_data_write_finalize(callid, opts, size);
 	if (retval != EOK) {
 		ipc_answer_0(rid, retval);
@@ -286,5 +286,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_read_receive(&callid, &size) ||
+	if (!async_data_read_receive(&callid, &size) ||
 	    size != sizeof(struct stat)) {
 		ipc_answer_0(callid, EINVAL);
@@ -315,5 +315,5 @@
 	}
 
-	ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
+	async_data_read_finalize(callid, &stat, sizeof(struct stat));
 	ipc_answer_0(rid, EOK);
 }
@@ -340,5 +340,5 @@
 		
 		ipc_callid_t callid;
-		if (!ipc_data_read_receive(&callid, NULL)) {
+		if (!async_data_read_receive(&callid, NULL)) {
 			fibril_mutex_unlock(&devices_mutex);
 			ipc_answer_0(callid, EINVAL);
@@ -367,5 +367,5 @@
 		ipc_callid_t callid;
 		size_t size;
-		if (!ipc_data_read_receive(&callid, &size)) {
+		if (!async_data_read_receive(&callid, &size)) {
 			ipc_answer_0(callid, EINVAL);
 			ipc_answer_0(rid, EINVAL);
@@ -384,5 +384,5 @@
 		
 		if (pos < max) {
-			ipc_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
+			async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
 		} else {
 			ipc_answer_0(callid, ENOENT);
@@ -418,5 +418,5 @@
 		
 		ipc_callid_t callid;
-		if (!ipc_data_write_receive(&callid, NULL)) {
+		if (!async_data_write_receive(&callid, NULL)) {
 			fibril_mutex_unlock(&devices_mutex);
 			ipc_answer_0(callid, EINVAL);
Index: uspace/srv/fs/fat/Makefile
===================================================================
--- uspace/srv/fs/fat/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/fat/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,60 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../../lib/libc
-LIBFS_PREFIX = ../../../lib/libfs
-LIBBLOCK_PREFIX = ../../../lib/libblock
-SOFTINT_PREFIX = ../../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX)
-
-LIBS = \
-	$(LIBFS_PREFIX)/libfs.a \
-	$(LIBBLOCK_PREFIX)/libblock.a \
-	$(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = fat
-SOURCES = \
-	fat.c \
-	fat_ops.c \
-	fat_idx.c \
-	fat_dentry.c \
-	fat_fat.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/fs/fat/Makefile.build
===================================================================
--- uspace/srv/fs/fat/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/fs/fat/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I$(LIBFS_PREFIX) -I$(LIBBLOCK_PREFIX)
+
+## Sources
+#
+
+SOURCES = \
+	fat.c \
+	fat_ops.c \
+	fat_idx.c \
+	fat_dentry.c \
+	fat_fat.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/fs/fat/Makefile.common
===================================================================
--- uspace/srv/fs/fat/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/fs/fat/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+LIBFS_PREFIX = ../../../lib/libfs
+LIBBLOCK_PREFIX = ../../../lib/libblock
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBFS_PREFIX)/libfs.a $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = fat
Index: uspace/srv/fs/fat/fat.c
===================================================================
--- uspace/srv/fs/fat/fat.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/fat/fat.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -43,11 +43,13 @@
 #include <errno.h>
 #include <unistd.h>
+#include <task.h>
 #include <stdio.h>
 #include <libfs.h>
 #include "../../vfs/vfs.h"
 
+#define NAME	"fat"
 
 vfs_info_t fat_vfs_info = {
-	.name = "fat",
+	.name = NAME,
 };
 
@@ -83,5 +85,5 @@
 	}
 	
-	dprintf("VFS-FAT connection established.\n");
+	dprintf(NAME ": connection opened\n");
 	while (1) {
 		ipc_callid_t callid;
@@ -137,5 +139,5 @@
 	int rc;
 
-	printf("fat: HelenOS FAT file system server.\n");
+	printf(NAME ": HelenOS FAT file system server\n");
 
 	rc = fat_idx_init();
@@ -145,5 +147,5 @@
 	vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
 	if (vfs_phone < EOK) {
-		printf("fat: failed to connect to VFS\n");
+		printf(NAME ": failed to connect to VFS\n");
 		return -1;
 	}
@@ -155,7 +157,6 @@
 	}
 	
-	dprintf("FAT filesystem registered, fs_handle=%d.\n",
-	    fat_reg.fs_handle);
-
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
 	async_manager();
 	/* not reached */
@@ -163,5 +164,5 @@
 
 err:
-	printf("Failed to register the FAT file system (%d)\n", rc);
+	printf(NAME ": Failed to register file system (%d)\n", rc);
 	return rc;
 }
Index: uspace/srv/fs/fat/fat.h
===================================================================
--- uspace/srv/fs/fat/fat.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/fat/fat.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -89,5 +89,5 @@
 			uint16_t	signature;
 		} __attribute__ ((packed));
-		struct {
+		struct fat32 {
 			/* FAT32 only */
 			/** Sectors per FAT. */
@@ -215,5 +215,5 @@
 extern void fat_sync(ipc_callid_t, ipc_call_t *);
 
-extern fat_idx_t *fat_idx_get_new(dev_handle_t);
+extern int fat_idx_get_new(fat_idx_t **, dev_handle_t);
 extern fat_idx_t *fat_idx_get_by_pos(dev_handle_t, fat_cluster_t, unsigned);
 extern fat_idx_t *fat_idx_get_by_index(dev_handle_t, fs_index_t);
Index: uspace/srv/fs/fat/fat_fat.c
===================================================================
--- uspace/srv/fs/fat/fat_fat.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/fat/fat_fat.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -61,12 +61,15 @@
  * @param dev_handle	Device handle of the device with the file.
  * @param firstc	First cluster to start the walk with.
- * @param lastc		If non-NULL, output argument hodling the last cluster number visited.
+ * @param lastc		If non-NULL, output argument hodling the last cluster
+ *			number visited.
+ * @param numc		If non-NULL, output argument holding the number of
+ *			clusters seen during the walk.
  * @param max_clusters	Maximum number of clusters to visit.	
  *
- * @return		Number of clusters seen during the walk.
- */
-uint16_t 
+ * @return		EOK on success or a negative error code.
+ */
+int 
 fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
-    fat_cluster_t *lastc, uint16_t max_clusters)
+    fat_cluster_t *lastc, uint16_t *numc, uint16_t max_clusters)
 {
 	block_t *b;
@@ -75,4 +78,5 @@
 	uint16_t clusters = 0;
 	fat_cluster_t clst = firstc;
+	int rc;
 
 	bps = uint16_t_le2host(bs->bps);
@@ -83,5 +87,7 @@
 		if (lastc)
 			*lastc = firstc;
-		return 0;
+		if (numc)
+			*numc = 0;
+		return EOK;
 	}
 
@@ -96,8 +102,12 @@
 		fidx = clst % (bps / sizeof(fat_cluster_t));
 		/* read FAT1 */
-		b = block_get(dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE);
+		rc = block_get(&b, dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE);
+		if (rc != EOK)
+			return rc;
 		clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
 		assert(clst != FAT_CLST_BAD);
-		block_put(b);
+		rc = block_put(b);
+		if (rc != EOK)
+			return rc;
 		clusters++;
 	}
@@ -105,10 +115,13 @@
 	if (lastc && clst < FAT_CLST_LAST1)
 		*lastc = clst;
-
-	return clusters;
+	if (numc)
+		*numc = clusters;
+
+	return EOK;
 }
 
 /** Read block from file located on a FAT file system.
  *
+ * @param block		Pointer to a block pointer for storing result.
  * @param bs		Buffer holding the boot sector of the file system.
  * @param dev_handle	Device handle of the file system.
@@ -118,11 +131,10 @@
  * @param flags		Flags passed to libblock.
  *
- * @return		Block structure holding the requested block.
- */
-block_t *
-_fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
-    bn_t bn, int flags)
-{
-	block_t *b;
+ * @return		EOK on success or a negative error code.
+ */
+int
+_fat_block_get(block_t **block, fat_bs_t *bs, dev_handle_t dev_handle,
+    fat_cluster_t firstc, bn_t bn, int flags)
+{
 	unsigned bps;
 	unsigned rscnt;		/* block address of the first FAT */
@@ -131,6 +143,8 @@
 	unsigned sf;
 	unsigned ssa;		/* size of the system area */
-	unsigned clusters, max_clusters;
+	uint16_t clusters;
+	unsigned max_clusters;
 	fat_cluster_t lastc;
+	int rc;
 
 	bps = uint16_t_le2host(bs->bps);
@@ -146,17 +160,20 @@
 		/* root directory special case */
 		assert(bn < rds);
-		b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn, flags);
-		return b;
+		rc = block_get(block, dev_handle, rscnt + bs->fatcnt * sf + bn,
+		    flags);
+		return rc;
 	}
 
 	max_clusters = bn / bs->spc;
-	clusters = fat_cluster_walk(bs, dev_handle, firstc, &lastc,
+	rc = fat_cluster_walk(bs, dev_handle, firstc, &lastc, &clusters,
 	    max_clusters);
+	if (rc != EOK)
+		return rc;
 	assert(clusters == max_clusters);
 
-	b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc +
-	    bn % bs->spc, flags);
-
-	return b;
+	rc = block_get(block, dev_handle,
+	    ssa + (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags);
+
+	return rc;
 }
 
@@ -170,6 +187,8 @@
  *			this argument is ignored.
  * @param pos		Position in the last node block.
- */
-void fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos)
+ *
+ * @return		EOK on success or a negative error code.
+ */
+int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos)
 {
 	uint16_t bps;
@@ -177,4 +196,5 @@
 	block_t *b;
 	off_t o, boundary;
+	int rc;
 
 	bps = uint16_t_le2host(bs->bps);
@@ -188,21 +208,31 @@
 	    	int flags = (o % bps == 0) ?
 		    BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE;
-		b = fat_block_get(bs, nodep, o / bps, flags);
+		rc = fat_block_get(&b, bs, nodep, o / bps, flags);
+		if (rc != EOK)
+			return rc;
 		memset(b->data + o % bps, 0, bps - o % bps);
 		b->dirty = true;		/* need to sync node */
-		block_put(b);
+		rc = block_put(b);
+		if (rc != EOK)
+			return rc;
 	}
 	
 	if (o >= pos)
-		return;
+		return EOK;
 	
 	/* zero out the initial part of the new cluster chain */
 	for (o = boundary; o < pos; o += bps) {
-		b = _fat_block_get(bs, nodep->idx->dev_handle, mcl,
+		rc = _fat_block_get(&b, bs, nodep->idx->dev_handle, mcl,
 		    (o - boundary) / bps, BLOCK_FLAGS_NOREAD);
+		if (rc != EOK)
+			return rc;
 		memset(b->data, 0, min(bps, pos - o));
 		b->dirty = true;		/* need to sync node */
-		block_put(b);
-	}
+		rc = block_put(b);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
 }
 
@@ -212,25 +242,30 @@
  * @param dev_handle	Device handle for the file system.
  * @param clst		Cluster which to get.
- *
- * @return		Value found in the cluster.
- */
-fat_cluster_t
-fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst)
+ * @param value		Output argument holding the value of the cluster.
+ *
+ * @return		EOK or a negative error code.
+ */
+int
+fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst,
+    fat_cluster_t *value)
 {
 	block_t *b;
 	uint16_t bps;
 	uint16_t rscnt;
-	fat_cluster_t *cp, value;
+	fat_cluster_t *cp;
+	int rc;
 
 	bps = uint16_t_le2host(bs->bps);
 	rscnt = uint16_t_le2host(bs->rscnt);
 
-	b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps,
-	    BLOCK_FLAGS_NONE);
+	rc = block_get(&b, dev_handle, rscnt +
+	    (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
+	if (rc != EOK)
+		return rc;
 	cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
-	value = uint16_t_le2host(*cp);
-	block_put(b);
-	
-	return value;
+	*value = uint16_t_le2host(*cp);
+	rc = block_put(b);
+	
+	return rc;
 }
 
@@ -242,6 +277,8 @@
  * @param clst		Cluster which is to be set.
  * @param value		Value to set the cluster with.
- */
-void
+ *
+ * @return		EOK on success or a negative error code.
+ */
+int
 fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
     fat_cluster_t clst, fat_cluster_t value)
@@ -252,4 +289,5 @@
 	uint16_t sf;
 	fat_cluster_t *cp;
+	int rc;
 
 	bps = uint16_t_le2host(bs->bps);
@@ -258,10 +296,13 @@
 
 	assert(fatno < bs->fatcnt);
-	b = block_get(dev_handle, rscnt + sf * fatno +
+	rc = block_get(&b, dev_handle, rscnt + sf * fatno +
 	    (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
+	if (rc != EOK)
+		return rc;
 	cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
 	*cp = host2uint16_t_le(value);
 	b->dirty = true;		/* need to sync block */
-	block_put(b);
+	rc = block_put(b);
+	return rc;
 }
 
@@ -272,17 +313,24 @@
  * @param lifo		Chain of allocated clusters.
  * @param nclsts	Number of clusters in the lifo chain.
- */
-void fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle,
+ *
+ * @return		EOK on success or a negative error code.
+ */
+int fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle,
     fat_cluster_t *lifo, unsigned nclsts)
 {
 	uint8_t fatno;
 	unsigned c;
+	int rc;
 
 	for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) {
 		for (c = 0; c < nclsts; c++) {
-			fat_set_cluster(bs, dev_handle, fatno, lifo[c],
+			rc = fat_set_cluster(bs, dev_handle, fatno, lifo[c],
 			    c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]);
+			if (rc != EOK)
+				return rc;
 		}
 	}
+
+	return EOK;
 }
 
@@ -311,8 +359,13 @@
 	uint16_t rscnt;
 	uint16_t sf;
+	uint16_t ts;
+	unsigned rde;
+	unsigned rds;
+	unsigned ssa;
 	block_t *blk;
 	fat_cluster_t *lifo;	/* stack for storing free cluster numbers */ 
 	unsigned found = 0;	/* top of the free cluster number stack */
 	unsigned b, c, cl; 
+	int rc;
 
 	lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t));
@@ -323,4 +376,10 @@
 	rscnt = uint16_t_le2host(bs->rscnt);
 	sf = uint16_t_le2host(bs->sec_per_fat);
+	rde = uint16_t_le2host(bs->root_ent_max);
+	ts = uint16_t_le2host(bs->totsec16);
+
+	rds = (sizeof(fat_dentry_t) * rde) / bps;
+	rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
+	ssa = rscnt + bs->fatcnt * sf + rds;
 	
 	/*
@@ -329,6 +388,21 @@
 	fibril_mutex_lock(&fat_alloc_lock);
 	for (b = 0, cl = 0; b < sf; b++) {
-		blk = block_get(dev_handle, rscnt + b, BLOCK_FLAGS_NONE);
+		rc = block_get(&blk, dev_handle, rscnt + b, BLOCK_FLAGS_NONE);
+		if (rc != EOK)
+			goto error;
 		for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {
+			/*
+			 * Check if the cluster is physically there. This check
+			 * becomes necessary when the file system is created
+			 * with fewer total sectors than how many is inferred
+			 * from the size of the file allocation table.
+			 */
+			if ((cl - 2) * bs->spc + ssa >= ts) {
+				rc = block_put(blk);
+				if (rc != EOK)
+					goto error;
+				goto out;
+			}
+
 			fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
 			if (uint16_t_le2host(*clst) == FAT_CLST_RES0) {
@@ -344,8 +418,12 @@
 				if (++found == nclsts) {
 					/* we are almost done */
-					block_put(blk);
+					rc = block_put(blk);
+					if (rc != EOK)
+						goto error;
 					/* update the shadow copies of FAT */
-					fat_alloc_shadow_clusters(bs,
+					rc = fat_alloc_shadow_clusters(bs,
 					    dev_handle, lifo, nclsts);
+					if (rc != EOK)
+						goto error;
 					*mcl = lifo[found - 1];
 					*lcl = lifo[0];
@@ -356,6 +434,13 @@
 			}
 		}
-		block_put(blk);
-	}
+		rc = block_put(blk);
+		if (rc != EOK) {
+error:
+			fibril_mutex_unlock(&fat_alloc_lock);
+			free(lifo);
+			return rc;
+		}
+	}
+out:
 	fibril_mutex_unlock(&fat_alloc_lock);
 
@@ -365,6 +450,10 @@
 	 */
 	while (found--) {
-		fat_set_cluster(bs, dev_handle, FAT1, lifo[found],
+		rc = fat_set_cluster(bs, dev_handle, FAT1, lifo[found],
 		    FAT_CLST_RES0);
+		if (rc != EOK) {
+			free(lifo);
+			return rc;
+		}
 	}
 	
@@ -378,20 +467,31 @@
  * @param dev_handle	Device handle of the file system.
  * @param firstc	First cluster in the chain which is to be freed.
- */
-void
+ *
+ * @return		EOK on success or a negative return code.
+ */
+int
 fat_free_clusters(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc)
 {
 	unsigned fatno;
 	fat_cluster_t nextc;
+	int rc;
 
 	/* Mark all clusters in the chain as free in all copies of FAT. */
 	while (firstc < FAT_CLST_LAST1) {
 		assert(firstc >= FAT_CLST_FIRST && firstc < FAT_CLST_BAD);
-		nextc = fat_get_cluster(bs, dev_handle, firstc);
-		for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
-			fat_set_cluster(bs, dev_handle, fatno, firstc,
+		rc = fat_get_cluster(bs, dev_handle, firstc, &nextc);
+		if (rc != EOK)
+			return rc;
+		for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
+			rc = fat_set_cluster(bs, dev_handle, fatno, firstc,
 			    FAT_CLST_RES0);
+			if (rc != EOK)
+				return rc;
+		}
+
 		firstc = nextc;
 	}
+
+	return EOK;
 }
 
@@ -401,21 +501,35 @@
  * @param nodep		Node representing the file.
  * @param mcl		First cluster of the cluster chain to append.
- */
-void fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl)
+ *
+ * @return		EOK on success or a negative error code.
+ */
+int fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl)
 {
 	dev_handle_t dev_handle = nodep->idx->dev_handle;
 	fat_cluster_t lcl;
+	uint16_t numc;
 	uint8_t fatno;
-
-	if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl,
-	    (uint16_t) -1) == 0) {
+	int rc;
+
+	rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, &numc,
+	    (uint16_t) -1);
+	if (rc != EOK)
+		return rc;
+
+	if (numc == 0) {
 		/* No clusters allocated to the node yet. */
 		nodep->firstc = mcl;
 		nodep->dirty = true;		/* need to sync node */
-		return;
-	}
-
-	for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
-		fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl);
+		return EOK;
+	}
+
+	for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
+		rc = fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl,
+		    mcl);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
 }
 
@@ -427,11 +541,17 @@
  *			argument is FAT_CLST_RES0, then all clusters will
  *			be chopped off.
- */
-void fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc)
-{
+ *
+ * @return		EOK on success or a negative return code.
+ */
+int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc)
+{
+	int rc;
+
 	dev_handle_t dev_handle = nodep->idx->dev_handle;
 	if (lastc == FAT_CLST_RES0) {
 		/* The node will have zero size and no clusters allocated. */
-		fat_free_clusters(bs, dev_handle, nodep->firstc);
+		rc = fat_free_clusters(bs, dev_handle, nodep->firstc);
+		if (rc != EOK)
+			return rc;
 		nodep->firstc = FAT_CLST_RES0;
 		nodep->dirty = true;		/* need to sync node */
@@ -440,16 +560,26 @@
 		unsigned fatno;
 
-		nextc = fat_get_cluster(bs, dev_handle, lastc);
+		rc = fat_get_cluster(bs, dev_handle, lastc, &nextc);
+		if (rc != EOK)
+			return rc;
 
 		/* Terminate the cluster chain in all copies of FAT. */
-		for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
-			fat_set_cluster(bs, dev_handle, fatno, lastc, FAT_CLST_LAST1);
+		for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
+			rc = fat_set_cluster(bs, dev_handle, fatno, lastc,
+			    FAT_CLST_LAST1);
+			if (rc != EOK)
+				return rc;
+		}
 
 		/* Free all following clusters. */
-		fat_free_clusters(bs, dev_handle, nextc);
-	}
-}
-
-void
+		rc = fat_free_clusters(bs, dev_handle, nextc);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
+}
+
+int
 fat_zero_cluster(struct fat_bs *bs, dev_handle_t dev_handle, fat_cluster_t c)
 {
@@ -457,13 +587,21 @@
 	block_t *b;
 	unsigned bps;
+	int rc;
 
 	bps = uint16_t_le2host(bs->bps);
 	
 	for (i = 0; i < bs->spc; i++) {
-		b = _fat_block_get(bs, dev_handle, c, i, BLOCK_FLAGS_NOREAD);
+		rc = _fat_block_get(&b, bs, dev_handle, c, i,
+		    BLOCK_FLAGS_NOREAD);
+		if (rc != EOK)
+			return rc;
 		memset(b->data, 0, bps);
 		b->dirty = true;
-		block_put(b);
-	}
+		rc = block_put(b);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
 }
 
Index: uspace/srv/fs/fat/fat_fat.h
===================================================================
--- uspace/srv/fs/fat/fat_fat.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/fat/fat_fat.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -59,30 +59,32 @@
 typedef uint16_t fat_cluster_t;
 
-#define fat_clusters_get(bs, dh, fc) \
-    fat_cluster_walk((bs), (dh), (fc), NULL, (uint16_t) -1)
-extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t,
-    fat_cluster_t *, uint16_t);
+#define fat_clusters_get(numc, bs, dh, fc) \
+    fat_cluster_walk((bs), (dh), (fc), NULL, (numc), (uint16_t) -1)
+extern int fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t,
+    fat_cluster_t *, uint16_t *, uint16_t);
 
-#define fat_block_get(bs, np, bn, flags) \
-    _fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn), (flags))
+#define fat_block_get(b, bs, np, bn, flags) \
+    _fat_block_get((b), (bs), (np)->idx->dev_handle, (np)->firstc, (bn), \
+    (flags))
 
-extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t,
+extern int _fat_block_get(block_t **, struct fat_bs *, dev_handle_t,
     fat_cluster_t, bn_t, int);
   
-extern void fat_append_clusters(struct fat_bs *, struct fat_node *,
+extern int fat_append_clusters(struct fat_bs *, struct fat_node *,
     fat_cluster_t);
-extern void fat_chop_clusters(struct fat_bs *, struct fat_node *,
+extern int fat_chop_clusters(struct fat_bs *, struct fat_node *,
     fat_cluster_t);
 extern int fat_alloc_clusters(struct fat_bs *, dev_handle_t, unsigned,
     fat_cluster_t *, fat_cluster_t *);
-extern void fat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t);
-extern void fat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t,
+extern int fat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t);
+extern int fat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t,
     fat_cluster_t *, unsigned);
-extern fat_cluster_t fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
-extern void fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned,
+extern int fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t,
+    fat_cluster_t *);
+extern int fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned,
     fat_cluster_t, fat_cluster_t);
-extern void fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,
+extern int fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,
     off_t);
-extern void fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
+extern int fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
 
 #endif
Index: uspace/srv/fs/fat/fat_idx.c
===================================================================
--- uspace/srv/fs/fat/fat_idx.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/fat/fat_idx.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -339,5 +339,5 @@
 }
 
-static fat_idx_t *fat_idx_create(dev_handle_t dev_handle)
+static int fat_idx_create(fat_idx_t **fidxp, dev_handle_t dev_handle)
 {
 	fat_idx_t *fidx;
@@ -345,8 +345,8 @@
 	fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
 	if (!fidx) 
-		return NULL;
+		return ENOMEM;
 	if (!fat_index_alloc(dev_handle, &fidx->index)) {
 		free(fidx);
-		return NULL;
+		return ENOSPC;
 	}
 		
@@ -359,16 +359,18 @@
 	fidx->nodep = NULL;
 
-	return fidx;
-}
-
-fat_idx_t *fat_idx_get_new(dev_handle_t dev_handle)
+	*fidxp = fidx;
+	return EOK;
+}
+
+int fat_idx_get_new(fat_idx_t **fidxp, dev_handle_t dev_handle)
 {
 	fat_idx_t *fidx;
+	int rc;
 
 	fibril_mutex_lock(&used_lock);
-	fidx = fat_idx_create(dev_handle);
-	if (!fidx) {
+	rc = fat_idx_create(&fidx, dev_handle);
+	if (rc != EOK) {
 		fibril_mutex_unlock(&used_lock);
-		return NULL;
+		return rc;
 	}
 		
@@ -382,5 +384,6 @@
 	fibril_mutex_unlock(&used_lock);
 
-	return fidx;
+	*fidxp = fidx;
+	return EOK;
 }
 
@@ -401,6 +404,8 @@
 		fidx = hash_table_get_instance(l, fat_idx_t, uph_link);
 	} else {
-		fidx = fat_idx_create(dev_handle);
-		if (!fidx) {
+		int rc;
+
+		rc = fat_idx_create(&fidx, dev_handle);
+		if (rc != EOK) {
 			fibril_mutex_unlock(&used_lock);
 			return NULL;
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -65,4 +65,26 @@
 static LIST_INITIALIZE(ffn_head);
 
+/*
+ * Forward declarations of FAT libfs operations.
+ */
+static int fat_root_get(fs_node_t **, dev_handle_t);
+static int fat_match(fs_node_t **, fs_node_t *, const char *);
+static int fat_node_get(fs_node_t **, dev_handle_t, fs_index_t);
+static int fat_node_put(fs_node_t *);
+static int fat_create_node(fs_node_t **, dev_handle_t, int);
+static int fat_destroy_node(fs_node_t *);
+static int fat_link(fs_node_t *, fs_node_t *, const char *);
+static int fat_unlink(fs_node_t *, fs_node_t *, const char *);
+static int fat_has_children(bool *, fs_node_t *);
+static fs_index_t fat_index_get(fs_node_t *);
+static size_t fat_size_get(fs_node_t *);
+static unsigned fat_lnkcnt_get(fs_node_t *);
+static char fat_plb_get_char(unsigned);
+static bool fat_is_directory(fs_node_t *);
+static bool fat_is_file(fs_node_t *node);
+
+/*
+ * Helper functions.
+ */
 static void fat_node_initialize(fat_node_t *node)
 {
@@ -78,5 +100,5 @@
 }
 
-static void fat_node_sync(fat_node_t *node)
+static int fat_node_sync(fat_node_t *node)
 {
 	block_t *b;
@@ -85,4 +107,5 @@
 	uint16_t bps;
 	unsigned dps;
+	int rc;
 	
 	assert(node->dirty);
@@ -93,6 +116,8 @@
 	
 	/* Read the block that contains the dentry of interest. */
-	b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc,
+	rc = _fat_block_get(&b, bs, node->idx->dev_handle, node->idx->pfc,
 	    (node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
+	if (rc != EOK)
+		return rc;
 
 	d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps);
@@ -108,11 +133,13 @@
 	
 	b->dirty = true;		/* need to sync block */
-	block_put(b);
-}
-
-static fat_node_t *fat_node_get_new(void)
+	rc = block_put(b);
+	return rc;
+}
+
+static int fat_node_get_new(fat_node_t **nodepp)
 {
 	fs_node_t *fn;
 	fat_node_t *nodep;
+	int rc;
 
 	fibril_mutex_lock(&ffn_mutex);
@@ -130,6 +157,15 @@
 		list_remove(&nodep->ffn_link);
 		fibril_mutex_unlock(&ffn_mutex);
-		if (nodep->dirty)
-			fat_node_sync(nodep);
+		if (nodep->dirty) {
+			rc = fat_node_sync(nodep);
+			if (rc != EOK) {
+				idxp_tmp->nodep = NULL;
+				fibril_mutex_unlock(&nodep->lock);
+				fibril_mutex_unlock(&idxp_tmp->lock);
+				free(nodep->bp);
+				free(nodep);
+				return rc;
+			}
+		}
 		idxp_tmp->nodep = NULL;
 		fibril_mutex_unlock(&nodep->lock);
@@ -142,9 +178,9 @@
 		fn = (fs_node_t *)malloc(sizeof(fs_node_t));
 		if (!fn)
-			return NULL;
+			return ENOMEM;
 		nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
 		if (!nodep) {
 			free(fn);
-			return NULL;
+			return ENOMEM;
 		}
 	}
@@ -154,5 +190,6 @@
 	nodep->bp = fn;
 	
-	return nodep;
+	*nodepp = nodep;
+	return EOK;
 }
 
@@ -161,5 +198,5 @@
  * @param idxp		Locked index structure.
  */
-static fat_node_t *fat_node_get_core(fat_idx_t *idxp)
+static int fat_node_get_core(fat_node_t **nodepp, fat_idx_t *idxp)
 {
 	block_t *b;
@@ -170,4 +207,5 @@
 	unsigned spc;
 	unsigned dps;
+	int rc;
 
 	if (idxp->nodep) {
@@ -177,8 +215,12 @@
 		 */
 		fibril_mutex_lock(&idxp->nodep->lock);
-		if (!idxp->nodep->refcnt++)
+		if (!idxp->nodep->refcnt++) {
+			fibril_mutex_lock(&ffn_mutex);
 			list_remove(&idxp->nodep->ffn_link);
+			fibril_mutex_unlock(&ffn_mutex);
+		}
 		fibril_mutex_unlock(&idxp->nodep->lock);
-		return idxp->nodep;
+		*nodepp = idxp->nodep;
+		return EOK;
 	}
 
@@ -189,7 +231,7 @@
 	assert(idxp->pfc);
 
-	nodep = fat_node_get_new();
-	if (!nodep)
-		return NULL;
+	rc = fat_node_get_new(&nodep);
+	if (rc != EOK)
+		return rc;
 
 	bs = block_bb_get(idxp->dev_handle);
@@ -199,7 +241,10 @@
 
 	/* Read the block that contains the dentry of interest. */
-	b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc,
+	rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc,
 	    (idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
-	assert(b);
+	if (rc != EOK) {
+		(void) fat_node_put(FS_NODE(nodep));
+		return rc;
+	}
 
 	d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps);
@@ -216,6 +261,12 @@
 		 * size of the directory by walking the FAT.
 		 */
-		nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle,
+		uint16_t clusters;
+		rc = fat_clusters_get(&clusters, bs, idxp->dev_handle,
 		    uint16_t_le2host(d->firstc));
+		if (rc != EOK) {
+			(void) fat_node_put(FS_NODE(nodep));
+			return rc;
+		}
+		nodep->size = bps * spc * clusters;
 	} else {
 		nodep->type = FAT_FILE;
@@ -226,5 +277,9 @@
 	nodep->refcnt = 1;
 
-	block_put(b);
+	rc = block_put(b);
+	if (rc != EOK) {
+		(void) fat_node_put(FS_NODE(nodep));
+		return rc;
+	}
 
 	/* Link the idx structure with the node structure. */
@@ -232,25 +287,7 @@
 	idxp->nodep = nodep;
 
-	return nodep;
-}
-
-/*
- * Forward declarations of FAT libfs operations.
- */
-static fs_node_t *fat_node_get(dev_handle_t, fs_index_t);
-static void fat_node_put(fs_node_t *);
-static fs_node_t *fat_create_node(dev_handle_t, int);
-static int fat_destroy_node(fs_node_t *);
-static int fat_link(fs_node_t *, fs_node_t *, const char *);
-static int fat_unlink(fs_node_t *, fs_node_t *, const char *);
-static fs_node_t *fat_match(fs_node_t *, const char *);
-static fs_index_t fat_index_get(fs_node_t *);
-static size_t fat_size_get(fs_node_t *);
-static unsigned fat_lnkcnt_get(fs_node_t *);
-static bool fat_has_children(fs_node_t *);
-static fs_node_t *fat_root_get(dev_handle_t);
-static char fat_plb_get_char(unsigned);
-static bool fat_is_directory(fs_node_t *);
-static bool fat_is_file(fs_node_t *node);
+	*nodepp = nodep;
+	return EOK;
+}
 
 /*
@@ -258,324 +295,10 @@
  */
 
-/** Instantiate a FAT in-core node. */
-fs_node_t *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
-{
-	fat_node_t *nodep;
-	fat_idx_t *idxp;
-
-	idxp = fat_idx_get_by_index(dev_handle, index);
-	if (!idxp)
-		return NULL;
-	/* idxp->lock held */
-	nodep = fat_node_get_core(idxp);
-	fibril_mutex_unlock(&idxp->lock);
-	return FS_NODE(nodep);
-}
-
-void fat_node_put(fs_node_t *fn)
-{
-	fat_node_t *nodep = FAT_NODE(fn);
-	bool destroy = false;
-
-	fibril_mutex_lock(&nodep->lock);
-	if (!--nodep->refcnt) {
-		if (nodep->idx) {
-			fibril_mutex_lock(&ffn_mutex);
-			list_append(&nodep->ffn_link, &ffn_head);
-			fibril_mutex_unlock(&ffn_mutex);
-		} else {
-			/*
-			 * The node does not have any index structure associated
-			 * with itself. This can only mean that we are releasing
-			 * the node after a failed attempt to allocate the index
-			 * structure for it.
-			 */
-			destroy = true;
-		}
-	}
-	fibril_mutex_unlock(&nodep->lock);
-	if (destroy) {
-		free(nodep->bp);
-		free(nodep);
-	}
-}
-
-fs_node_t *fat_create_node(dev_handle_t dev_handle, int flags)
-{
-	fat_idx_t *idxp;
-	fat_node_t *nodep;
-	fat_bs_t *bs;
-	fat_cluster_t mcl, lcl;
-	uint16_t bps;
-	int rc;
-
-	bs = block_bb_get(dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	if (flags & L_DIRECTORY) {
-		/* allocate a cluster */
-		rc = fat_alloc_clusters(bs, dev_handle, 1, &mcl, &lcl);
-		if (rc != EOK) 
-			return NULL;
-	}
-
-	nodep = fat_node_get_new();
-	if (!nodep) {
-		fat_free_clusters(bs, dev_handle, mcl);	
-		return NULL;
-	}
-	idxp = fat_idx_get_new(dev_handle);
-	if (!idxp) {
-		fat_free_clusters(bs, dev_handle, mcl);	
-		fat_node_put(FS_NODE(nodep));
-		return NULL;
-	}
-	/* idxp->lock held */
-	if (flags & L_DIRECTORY) {
-		/* Populate the new cluster with unused dentries. */
-		fat_zero_cluster(bs, dev_handle, mcl);
-		nodep->type = FAT_DIRECTORY;
-		nodep->firstc = mcl;
-		nodep->size = bps * bs->spc;
-	} else {
-		nodep->type = FAT_FILE;
-		nodep->firstc = FAT_CLST_RES0;
-		nodep->size = 0;
-	}
-	nodep->lnkcnt = 0;	/* not linked anywhere */
-	nodep->refcnt = 1;
-	nodep->dirty = true;
-
-	nodep->idx = idxp;
-	idxp->nodep = nodep;
-
-	fibril_mutex_unlock(&idxp->lock);
-	return FS_NODE(nodep);
-}
-
-int fat_destroy_node(fs_node_t *fn)
-{
-	fat_node_t *nodep = FAT_NODE(fn);
-	fat_bs_t *bs;
-
-	/*
-	 * The node is not reachable from the file system. This means that the
-	 * link count should be zero and that the index structure cannot be
-	 * found in the position hash. Obviously, we don't need to lock the node
-	 * nor its index structure.
-	 */
-	assert(nodep->lnkcnt == 0);
-
-	/*
-	 * The node may not have any children.
-	 */
-	assert(fat_has_children(fn) == false);
-
-	bs = block_bb_get(nodep->idx->dev_handle);
-	if (nodep->firstc != FAT_CLST_RES0) {
-		assert(nodep->size);
-		/* Free all clusters allocated to the node. */
-		fat_free_clusters(bs, nodep->idx->dev_handle, nodep->firstc);
-	}
-
-	fat_idx_destroy(nodep->idx);
-	free(nodep->bp);
-	free(nodep);
-	return EOK;
-}
-
-int fat_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
-{
-	fat_node_t *parentp = FAT_NODE(pfn);
-	fat_node_t *childp = FAT_NODE(cfn);
-	fat_dentry_t *d;
-	fat_bs_t *bs;
-	block_t *b;
-	unsigned i, j;
-	uint16_t bps;
-	unsigned dps;
-	unsigned blocks;
-	fat_cluster_t mcl, lcl;
-	int rc;
-
-	fibril_mutex_lock(&childp->lock);
-	if (childp->lnkcnt == 1) {
-		/*
-		 * On FAT, we don't support multiple hard links.
-		 */
-		fibril_mutex_unlock(&childp->lock);
-		return EMLINK;
-	}
-	assert(childp->lnkcnt == 0);
-	fibril_mutex_unlock(&childp->lock);
-
-	if (!fat_dentry_name_verify(name)) {
-		/*
-		 * Attempt to create unsupported name.
-		 */
-		return ENOTSUP;
-	}
-
-	/*
-	 * Get us an unused parent node's dentry or grow the parent and allocate
-	 * a new one.
-	 */
-	
-	fibril_mutex_lock(&parentp->idx->lock);
-	bs = block_bb_get(parentp->idx->dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	dps = bps / sizeof(fat_dentry_t);
-
-	blocks = parentp->size / bps;
-
-	for (i = 0; i < blocks; i++) {
-		b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
-		for (j = 0; j < dps; j++) {
-			d = ((fat_dentry_t *)b->data) + j;
-			switch (fat_classify_dentry(d)) {
-			case FAT_DENTRY_SKIP:
-			case FAT_DENTRY_VALID:
-				/* skipping used and meta entries */
-				continue;
-			case FAT_DENTRY_FREE:
-			case FAT_DENTRY_LAST:
-				/* found an empty slot */
-				goto hit;
-			}
-		}
-		block_put(b);
-	}
-	j = 0;
-	
-	/*
-	 * We need to grow the parent in order to create a new unused dentry.
-	 */
-	if (parentp->firstc == FAT_CLST_ROOT) {
-		/* Can't grow the root directory. */
-		fibril_mutex_unlock(&parentp->idx->lock);
-		return ENOSPC;
-	}
-	rc = fat_alloc_clusters(bs, parentp->idx->dev_handle, 1, &mcl, &lcl);
-	if (rc != EOK) {
-		fibril_mutex_unlock(&parentp->idx->lock);
-		return rc;
-	}
-	fat_zero_cluster(bs, parentp->idx->dev_handle, mcl);
-	fat_append_clusters(bs, parentp, mcl);
-	parentp->size += bps * bs->spc;
-	parentp->dirty = true;		/* need to sync node */
-	b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
-	d = (fat_dentry_t *)b->data;
-
-hit:
-	/*
-	 * At this point we only establish the link between the parent and the
-	 * child.  The dentry, except of the name and the extension, will remain
-	 * uninitialized until the corresponding node is synced. Thus the valid
-	 * dentry data is kept in the child node structure.
-	 */
-	memset(d, 0, sizeof(fat_dentry_t));
-	fat_dentry_name_set(d, name);
-	b->dirty = true;		/* need to sync block */
-	block_put(b);
-	fibril_mutex_unlock(&parentp->idx->lock);
-
-	fibril_mutex_lock(&childp->idx->lock);
-	
-	/*
-	 * If possible, create the Sub-directory Identifier Entry and the
-	 * Sub-directory Parent Pointer Entry (i.e. "." and ".."). These entries
-	 * are not mandatory according to Standard ECMA-107 and HelenOS VFS does
-	 * not use them anyway, so this is rather a sign of our good will.
-	 */
-	b = fat_block_get(bs, childp, 0, BLOCK_FLAGS_NONE);
-	d = (fat_dentry_t *)b->data;
-	if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
-	    str_cmp(d->name, FAT_NAME_DOT) == 0) {
-	   	memset(d, 0, sizeof(fat_dentry_t));
-	   	str_cpy(d->name, 8, FAT_NAME_DOT);
-		str_cpy(d->ext, 3, FAT_EXT_PAD);
-		d->attr = FAT_ATTR_SUBDIR;
-		d->firstc = host2uint16_t_le(childp->firstc);
-		/* TODO: initialize also the date/time members. */
-	}
-	d++;
-	if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
-	    str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) {
-		memset(d, 0, sizeof(fat_dentry_t));
-		str_cpy(d->name, 8, FAT_NAME_DOT_DOT);
-		str_cpy(d->ext, 3, FAT_EXT_PAD);
-		d->attr = FAT_ATTR_SUBDIR;
-		d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
-		    host2uint16_t_le(FAT_CLST_RES0) :
-		    host2uint16_t_le(parentp->firstc);
-		/* TODO: initialize also the date/time members. */
-	}
-	b->dirty = true;		/* need to sync block */
-	block_put(b);
-
-	childp->idx->pfc = parentp->firstc;
-	childp->idx->pdi = i * dps + j;
-	fibril_mutex_unlock(&childp->idx->lock);
-
-	fibril_mutex_lock(&childp->lock);
-	childp->lnkcnt = 1;
-	childp->dirty = true;		/* need to sync node */
-	fibril_mutex_unlock(&childp->lock);
-
-	/*
-	 * Hash in the index structure into the position hash.
-	 */
-	fat_idx_hashin(childp->idx);
-
-	return EOK;
-}
-
-int fat_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
-{
-	fat_node_t *parentp = FAT_NODE(pfn);
-	fat_node_t *childp = FAT_NODE(cfn);
-	fat_bs_t *bs;
-	fat_dentry_t *d;
-	uint16_t bps;
-	block_t *b;
-
-	if (!parentp)
-		return EBUSY;
-	
-	if (fat_has_children(cfn))
-		return ENOTEMPTY;
-
-	fibril_mutex_lock(&parentp->lock);
-	fibril_mutex_lock(&childp->lock);
-	assert(childp->lnkcnt == 1);
-	fibril_mutex_lock(&childp->idx->lock);
-	bs = block_bb_get(childp->idx->dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-
-	b = _fat_block_get(bs, childp->idx->dev_handle, childp->idx->pfc,
-	    (childp->idx->pdi * sizeof(fat_dentry_t)) / bps,
-	    BLOCK_FLAGS_NONE);
-	d = (fat_dentry_t *)b->data +
-	    (childp->idx->pdi % (bps / sizeof(fat_dentry_t)));
-	/* mark the dentry as not-currently-used */
-	d->name[0] = FAT_DENTRY_ERASED;
-	b->dirty = true;		/* need to sync block */
-	block_put(b);
-
-	/* remove the index structure from the position hash */
-	fat_idx_hashout(childp->idx);
-	/* clear position information */
-	childp->idx->pfc = FAT_CLST_RES0;
-	childp->idx->pdi = 0;
-	fibril_mutex_unlock(&childp->idx->lock);
-	childp->lnkcnt = 0;
-	childp->dirty = true;
-	fibril_mutex_unlock(&childp->lock);
-	fibril_mutex_unlock(&parentp->lock);
-
-	return EOK;
-}
-
-fs_node_t *fat_match(fs_node_t *pfn, const char *component)
+int fat_root_get(fs_node_t **rfn, dev_handle_t dev_handle)
+{
+	return fat_node_get(rfn, dev_handle, 0);
+}
+
+int fat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
 {
 	fat_bs_t *bs;
@@ -588,4 +311,5 @@
 	fat_dentry_t *d;
 	block_t *b;
+	int rc;
 
 	fibril_mutex_lock(&parentp->idx->lock);
@@ -595,5 +319,9 @@
 	blocks = parentp->size / bps;
 	for (i = 0; i < blocks; i++) {
-		b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
+		rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
+		if (rc != EOK) {
+			fibril_mutex_unlock(&parentp->idx->lock);
+			return rc;
+		}
 		for (j = 0; j < dps; j++) { 
 			d = ((fat_dentry_t *)b->data) + j;
@@ -603,7 +331,9 @@
 				continue;
 			case FAT_DENTRY_LAST:
-				block_put(b);
+				/* miss */
+				rc = block_put(b);
 				fibril_mutex_unlock(&parentp->idx->lock);
-				return NULL;
+				*rfn = NULL;
+				return rc;
 			default:
 			case FAT_DENTRY_VALID:
@@ -629,36 +359,420 @@
 					 * run out of 32-bit indices.
 					 */
-					block_put(b);
-					return NULL;
+					rc = block_put(b);
+					return (rc == EOK) ? ENOMEM : rc;
 				}
-				nodep = fat_node_get_core(idx);
+				rc = fat_node_get_core(&nodep, idx);
 				fibril_mutex_unlock(&idx->lock);
-				block_put(b);
-				return FS_NODE(nodep);
+				if (rc != EOK) {
+					(void) block_put(b);
+					return rc;
+				}
+				*rfn = FS_NODE(nodep);
+				rc = block_put(b);
+				if (rc != EOK)
+					(void) fat_node_put(*rfn);
+				return rc;
 			}
 		}
-		block_put(b);
+		rc = block_put(b);
+		if (rc != EOK) {
+			fibril_mutex_unlock(&parentp->idx->lock);
+			return rc;
+		}
 	}
 
 	fibril_mutex_unlock(&parentp->idx->lock);
-	return NULL;
-}
-
-fs_index_t fat_index_get(fs_node_t *fn)
-{
-	return FAT_NODE(fn)->idx->index;
-}
-
-size_t fat_size_get(fs_node_t *fn)
-{
-	return FAT_NODE(fn)->size;
-}
-
-unsigned fat_lnkcnt_get(fs_node_t *fn)
-{
-	return FAT_NODE(fn)->lnkcnt;
-}
-
-bool fat_has_children(fs_node_t *fn)
+	*rfn = NULL;
+	return EOK;
+}
+
+/** Instantiate a FAT in-core node. */
+int fat_node_get(fs_node_t **rfn, dev_handle_t dev_handle, fs_index_t index)
+{
+	fat_node_t *nodep;
+	fat_idx_t *idxp;
+	int rc;
+
+	idxp = fat_idx_get_by_index(dev_handle, index);
+	if (!idxp) {
+		*rfn = NULL;
+		return EOK;
+	}
+	/* idxp->lock held */
+	rc = fat_node_get_core(&nodep, idxp);
+	fibril_mutex_unlock(&idxp->lock);
+	if (rc == EOK)
+		*rfn = FS_NODE(nodep);
+	return rc;
+}
+
+int fat_node_put(fs_node_t *fn)
+{
+	fat_node_t *nodep = FAT_NODE(fn);
+	bool destroy = false;
+
+	fibril_mutex_lock(&nodep->lock);
+	if (!--nodep->refcnt) {
+		if (nodep->idx) {
+			fibril_mutex_lock(&ffn_mutex);
+			list_append(&nodep->ffn_link, &ffn_head);
+			fibril_mutex_unlock(&ffn_mutex);
+		} else {
+			/*
+			 * The node does not have any index structure associated
+			 * with itself. This can only mean that we are releasing
+			 * the node after a failed attempt to allocate the index
+			 * structure for it.
+			 */
+			destroy = true;
+		}
+	}
+	fibril_mutex_unlock(&nodep->lock);
+	if (destroy) {
+		free(nodep->bp);
+		free(nodep);
+	}
+	return EOK;
+}
+
+int fat_create_node(fs_node_t **rfn, dev_handle_t dev_handle, int flags)
+{
+	fat_idx_t *idxp;
+	fat_node_t *nodep;
+	fat_bs_t *bs;
+	fat_cluster_t mcl, lcl;
+	uint16_t bps;
+	int rc;
+
+	bs = block_bb_get(dev_handle);
+	bps = uint16_t_le2host(bs->bps);
+	if (flags & L_DIRECTORY) {
+		/* allocate a cluster */
+		rc = fat_alloc_clusters(bs, dev_handle, 1, &mcl, &lcl);
+		if (rc != EOK)
+			return rc;
+		/* populate the new cluster with unused dentries */
+		rc = fat_zero_cluster(bs, dev_handle, mcl);
+		if (rc != EOK) {
+			(void) fat_free_clusters(bs, dev_handle, mcl);
+			return rc;
+		}
+	}
+
+	rc = fat_node_get_new(&nodep);
+	if (rc != EOK) {
+		(void) fat_free_clusters(bs, dev_handle, mcl);
+		return rc;
+	}
+	rc = fat_idx_get_new(&idxp, dev_handle);
+	if (rc != EOK) {
+		(void) fat_free_clusters(bs, dev_handle, mcl);	
+		(void) fat_node_put(FS_NODE(nodep));
+		return rc;
+	}
+	/* idxp->lock held */
+	if (flags & L_DIRECTORY) {
+		nodep->type = FAT_DIRECTORY;
+		nodep->firstc = mcl;
+		nodep->size = bps * bs->spc;
+	} else {
+		nodep->type = FAT_FILE;
+		nodep->firstc = FAT_CLST_RES0;
+		nodep->size = 0;
+	}
+	nodep->lnkcnt = 0;	/* not linked anywhere */
+	nodep->refcnt = 1;
+	nodep->dirty = true;
+
+	nodep->idx = idxp;
+	idxp->nodep = nodep;
+
+	fibril_mutex_unlock(&idxp->lock);
+	*rfn = FS_NODE(nodep);
+	return EOK;
+}
+
+int fat_destroy_node(fs_node_t *fn)
+{
+	fat_node_t *nodep = FAT_NODE(fn);
+	fat_bs_t *bs;
+	bool has_children;
+	int rc;
+
+	/*
+	 * The node is not reachable from the file system. This means that the
+	 * link count should be zero and that the index structure cannot be
+	 * found in the position hash. Obviously, we don't need to lock the node
+	 * nor its index structure.
+	 */
+	assert(nodep->lnkcnt == 0);
+
+	/*
+	 * The node may not have any children.
+	 */
+	rc = fat_has_children(&has_children, fn);
+	if (rc != EOK)
+		return rc;
+	assert(!has_children);
+
+	bs = block_bb_get(nodep->idx->dev_handle);
+	if (nodep->firstc != FAT_CLST_RES0) {
+		assert(nodep->size);
+		/* Free all clusters allocated to the node. */
+		rc = fat_free_clusters(bs, nodep->idx->dev_handle,
+		    nodep->firstc);
+	}
+
+	fat_idx_destroy(nodep->idx);
+	free(nodep->bp);
+	free(nodep);
+	return rc;
+}
+
+int fat_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
+{
+	fat_node_t *parentp = FAT_NODE(pfn);
+	fat_node_t *childp = FAT_NODE(cfn);
+	fat_dentry_t *d;
+	fat_bs_t *bs;
+	block_t *b;
+	unsigned i, j;
+	uint16_t bps;
+	unsigned dps;
+	unsigned blocks;
+	fat_cluster_t mcl, lcl;
+	int rc;
+
+	fibril_mutex_lock(&childp->lock);
+	if (childp->lnkcnt == 1) {
+		/*
+		 * On FAT, we don't support multiple hard links.
+		 */
+		fibril_mutex_unlock(&childp->lock);
+		return EMLINK;
+	}
+	assert(childp->lnkcnt == 0);
+	fibril_mutex_unlock(&childp->lock);
+
+	if (!fat_dentry_name_verify(name)) {
+		/*
+		 * Attempt to create unsupported name.
+		 */
+		return ENOTSUP;
+	}
+
+	/*
+	 * Get us an unused parent node's dentry or grow the parent and allocate
+	 * a new one.
+	 */
+	
+	fibril_mutex_lock(&parentp->idx->lock);
+	bs = block_bb_get(parentp->idx->dev_handle);
+	bps = uint16_t_le2host(bs->bps);
+	dps = bps / sizeof(fat_dentry_t);
+
+	blocks = parentp->size / bps;
+
+	for (i = 0; i < blocks; i++) {
+		rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
+		if (rc != EOK) {
+			fibril_mutex_unlock(&parentp->idx->lock);
+			return rc;
+		}
+		for (j = 0; j < dps; j++) {
+			d = ((fat_dentry_t *)b->data) + j;
+			switch (fat_classify_dentry(d)) {
+			case FAT_DENTRY_SKIP:
+			case FAT_DENTRY_VALID:
+				/* skipping used and meta entries */
+				continue;
+			case FAT_DENTRY_FREE:
+			case FAT_DENTRY_LAST:
+				/* found an empty slot */
+				goto hit;
+			}
+		}
+		rc = block_put(b);
+		if (rc != EOK) {
+			fibril_mutex_unlock(&parentp->idx->lock);
+			return rc;
+		}
+	}
+	j = 0;
+	
+	/*
+	 * We need to grow the parent in order to create a new unused dentry.
+	 */
+	if (parentp->firstc == FAT_CLST_ROOT) {
+		/* Can't grow the root directory. */
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return ENOSPC;
+	}
+	rc = fat_alloc_clusters(bs, parentp->idx->dev_handle, 1, &mcl, &lcl);
+	if (rc != EOK) {
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return rc;
+	}
+	rc = fat_zero_cluster(bs, parentp->idx->dev_handle, mcl);
+	if (rc != EOK) {
+		(void) fat_free_clusters(bs, parentp->idx->dev_handle, mcl);
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return rc;
+	}
+	rc = fat_append_clusters(bs, parentp, mcl);
+	if (rc != EOK) {
+		(void) fat_free_clusters(bs, parentp->idx->dev_handle, mcl);
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return rc;
+	}
+	parentp->size += bps * bs->spc;
+	parentp->dirty = true;		/* need to sync node */
+	rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
+	if (rc != EOK) {
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return rc;
+	}
+	d = (fat_dentry_t *)b->data;
+
+hit:
+	/*
+	 * At this point we only establish the link between the parent and the
+	 * child.  The dentry, except of the name and the extension, will remain
+	 * uninitialized until the corresponding node is synced. Thus the valid
+	 * dentry data is kept in the child node structure.
+	 */
+	memset(d, 0, sizeof(fat_dentry_t));
+	fat_dentry_name_set(d, name);
+	b->dirty = true;		/* need to sync block */
+	rc = block_put(b);
+	fibril_mutex_unlock(&parentp->idx->lock);
+	if (rc != EOK) 
+		return rc;
+
+	fibril_mutex_lock(&childp->idx->lock);
+	
+	/*
+	 * If possible, create the Sub-directory Identifier Entry and the
+	 * Sub-directory Parent Pointer Entry (i.e. "." and ".."). These entries
+	 * are not mandatory according to Standard ECMA-107 and HelenOS VFS does
+	 * not use them anyway, so this is rather a sign of our good will.
+	 */
+	rc = fat_block_get(&b, bs, childp, 0, BLOCK_FLAGS_NONE);
+	if (rc != EOK) {
+		/*
+		 * Rather than returning an error, simply skip the creation of
+		 * these two entries.
+		 */
+		goto skip_dots;
+	}
+	d = (fat_dentry_t *)b->data;
+	if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
+	    str_cmp(d->name, FAT_NAME_DOT) == 0) {
+	   	memset(d, 0, sizeof(fat_dentry_t));
+	   	str_cpy(d->name, 8, FAT_NAME_DOT);
+		str_cpy(d->ext, 3, FAT_EXT_PAD);
+		d->attr = FAT_ATTR_SUBDIR;
+		d->firstc = host2uint16_t_le(childp->firstc);
+		/* TODO: initialize also the date/time members. */
+	}
+	d++;
+	if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
+	    str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) {
+		memset(d, 0, sizeof(fat_dentry_t));
+		str_cpy(d->name, 8, FAT_NAME_DOT_DOT);
+		str_cpy(d->ext, 3, FAT_EXT_PAD);
+		d->attr = FAT_ATTR_SUBDIR;
+		d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
+		    host2uint16_t_le(FAT_CLST_RES0) :
+		    host2uint16_t_le(parentp->firstc);
+		/* TODO: initialize also the date/time members. */
+	}
+	b->dirty = true;		/* need to sync block */
+	/*
+	 * Ignore the return value as we would have fallen through on error
+	 * anyway.
+	 */
+	(void) block_put(b);
+skip_dots:
+
+	childp->idx->pfc = parentp->firstc;
+	childp->idx->pdi = i * dps + j;
+	fibril_mutex_unlock(&childp->idx->lock);
+
+	fibril_mutex_lock(&childp->lock);
+	childp->lnkcnt = 1;
+	childp->dirty = true;		/* need to sync node */
+	fibril_mutex_unlock(&childp->lock);
+
+	/*
+	 * Hash in the index structure into the position hash.
+	 */
+	fat_idx_hashin(childp->idx);
+
+	return EOK;
+}
+
+int fat_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
+{
+	fat_node_t *parentp = FAT_NODE(pfn);
+	fat_node_t *childp = FAT_NODE(cfn);
+	fat_bs_t *bs;
+	fat_dentry_t *d;
+	uint16_t bps;
+	block_t *b;
+	bool has_children;
+	int rc;
+
+	if (!parentp)
+		return EBUSY;
+	
+	rc = fat_has_children(&has_children, cfn);
+	if (rc != EOK)
+		return rc;
+	if (has_children)
+		return ENOTEMPTY;
+
+	fibril_mutex_lock(&parentp->lock);
+	fibril_mutex_lock(&childp->lock);
+	assert(childp->lnkcnt == 1);
+	fibril_mutex_lock(&childp->idx->lock);
+	bs = block_bb_get(childp->idx->dev_handle);
+	bps = uint16_t_le2host(bs->bps);
+
+	rc = _fat_block_get(&b, bs, childp->idx->dev_handle, childp->idx->pfc,
+	    (childp->idx->pdi * sizeof(fat_dentry_t)) / bps,
+	    BLOCK_FLAGS_NONE);
+	if (rc != EOK) 
+		goto error;
+	d = (fat_dentry_t *)b->data +
+	    (childp->idx->pdi % (bps / sizeof(fat_dentry_t)));
+	/* mark the dentry as not-currently-used */
+	d->name[0] = FAT_DENTRY_ERASED;
+	b->dirty = true;		/* need to sync block */
+	rc = block_put(b);
+	if (rc != EOK)
+		goto error;
+
+	/* remove the index structure from the position hash */
+	fat_idx_hashout(childp->idx);
+	/* clear position information */
+	childp->idx->pfc = FAT_CLST_RES0;
+	childp->idx->pdi = 0;
+	fibril_mutex_unlock(&childp->idx->lock);
+	childp->lnkcnt = 0;
+	childp->dirty = true;
+	fibril_mutex_unlock(&childp->lock);
+	fibril_mutex_unlock(&parentp->lock);
+
+	return EOK;
+
+error:
+	fibril_mutex_unlock(&parentp->idx->lock);
+	fibril_mutex_unlock(&childp->lock);
+	fibril_mutex_unlock(&childp->idx->lock);
+	return rc;
+}
+
+int fat_has_children(bool *has_children, fs_node_t *fn)
 {
 	fat_bs_t *bs;
@@ -669,7 +783,10 @@
 	block_t *b;
 	unsigned i, j;
-
-	if (nodep->type != FAT_DIRECTORY)
-		return false;
+	int rc;
+
+	if (nodep->type != FAT_DIRECTORY) {
+		*has_children = false;
+		return EOK;
+	}
 	
 	fibril_mutex_lock(&nodep->idx->lock);
@@ -683,5 +800,9 @@
 		fat_dentry_t *d;
 	
-		b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE);
+		rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE);
+		if (rc != EOK) {
+			fibril_mutex_unlock(&nodep->idx->lock);
+			return rc;
+		}
 		for (j = 0; j < dps; j++) {
 			d = ((fat_dentry_t *)b->data) + j;
@@ -691,27 +812,42 @@
 				continue;
 			case FAT_DENTRY_LAST:
-				block_put(b);
+				rc = block_put(b);
 				fibril_mutex_unlock(&nodep->idx->lock);
-				return false;
+				*has_children = false;
+				return rc;
 			default:
 			case FAT_DENTRY_VALID:
-				block_put(b);
+				rc = block_put(b);
 				fibril_mutex_unlock(&nodep->idx->lock);
-				return true;
+				*has_children = true;
+				return rc;
 			}
-			block_put(b);
+		}
+		rc = block_put(b);
+		if (rc != EOK) {
 			fibril_mutex_unlock(&nodep->idx->lock);
-			return true;
-		}
-		block_put(b);
+			return rc;	
+		}
 	}
 
 	fibril_mutex_unlock(&nodep->idx->lock);
-	return false;
-}
-
-fs_node_t *fat_root_get(dev_handle_t dev_handle)
-{
-	return fat_node_get(dev_handle, 0);
+	*has_children = false;
+	return EOK;
+}
+
+
+fs_index_t fat_index_get(fs_node_t *fn)
+{
+	return FAT_NODE(fn)->idx->index;
+}
+
+size_t fat_size_get(fs_node_t *fn)
+{
+	return FAT_NODE(fn)->size;
+}
+
+unsigned fat_lnkcnt_get(fs_node_t *fn)
+{
+	return FAT_NODE(fn)->lnkcnt;
 }
 
@@ -733,4 +869,5 @@
 /** libfs operations */
 libfs_ops_t fat_libfs_ops = {
+	.root_get = fat_root_get,
 	.match = fat_match,
 	.node_get = fat_node_get,
@@ -740,9 +877,8 @@
 	.link = fat_link,
 	.unlink = fat_unlink,
+	.has_children = fat_has_children,
 	.index_get = fat_index_get,
 	.size_get = fat_size_get,
 	.lnkcnt_get = fat_lnkcnt_get,
-	.has_children = fat_has_children,
-	.root_get = fat_root_get,
 	.plb_get_char =	fat_plb_get_char,
 	.is_directory = fat_is_directory,
@@ -766,5 +902,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -777,5 +913,5 @@
 		return;
 	}
-	ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
+	ipcarg_t retval = async_data_write_finalize(callid, opts, size);
 	if (retval != EOK) {
 		ipc_answer_0(rid, retval);
@@ -799,5 +935,5 @@
 
 	/* prepare the boot block */
-	rc = block_bb_read(dev_handle, BS_BLOCK * BS_SIZE, BS_SIZE);
+	rc = block_bb_read(dev_handle, BS_BLOCK);
 	if (rc != EOK) {
 		block_fini(dev_handle);
@@ -895,5 +1031,5 @@
 	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
 	off_t pos = (off_t)IPC_GET_ARG3(*request);
-	fs_node_t *fn = fat_node_get(dev_handle, index);
+	fs_node_t *fn;
 	fat_node_t *nodep;
 	fat_bs_t *bs;
@@ -901,5 +1037,11 @@
 	size_t bytes;
 	block_t *b;
-
+	int rc;
+
+	rc = fat_node_get(&fn, dev_handle, index);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 	if (!fn) {
 		ipc_answer_0(rid, ENOENT);
@@ -910,5 +1052,5 @@
 	ipc_callid_t callid;
 	size_t len;
-	if (!ipc_data_read_receive(&callid, &len)) {
+	if (!async_data_read_receive(&callid, &len)) {
 		fat_node_put(fn);
 		ipc_answer_0(callid, EINVAL);
@@ -929,13 +1071,24 @@
 			/* reading beyond the EOF */
 			bytes = 0;
-			(void) ipc_data_read_finalize(callid, NULL, 0);
+			(void) async_data_read_finalize(callid, NULL, 0);
 		} else {
 			bytes = min(len, bps - pos % bps);
 			bytes = min(bytes, nodep->size - pos);
-			b = fat_block_get(bs, nodep, pos / bps,
+			rc = fat_block_get(&b, bs, nodep, pos / bps,
 			    BLOCK_FLAGS_NONE);
-			(void) ipc_data_read_finalize(callid, b->data + pos % bps,
+			if (rc != EOK) {
+				fat_node_put(fn);
+				ipc_answer_0(callid, rc);
+				ipc_answer_0(rid, rc);
+				return;
+			}
+			(void) async_data_read_finalize(callid, b->data + pos % bps,
 			    bytes);
-			block_put(b);
+			rc = block_put(b);
+			if (rc != EOK) {
+				fat_node_put(fn);
+				ipc_answer_0(rid, rc);
+				return;
+			}
 		}
 	} else {
@@ -959,5 +1112,8 @@
 			off_t o;
 
-			b = fat_block_get(bs, nodep, bnum, BLOCK_FLAGS_NONE);
+			rc = fat_block_get(&b, bs, nodep, bnum,
+			    BLOCK_FLAGS_NONE);
+			if (rc != EOK)
+				goto err;
 			for (o = pos % (bps / sizeof(fat_dentry_t));
 			    o < bps / sizeof(fat_dentry_t);
@@ -969,28 +1125,41 @@
 					continue;
 				case FAT_DENTRY_LAST:
-					block_put(b);
+					rc = block_put(b);
+					if (rc != EOK)
+						goto err;
 					goto miss;
 				default:
 				case FAT_DENTRY_VALID:
 					fat_dentry_name_get(d, name);
-					block_put(b);
+					rc = block_put(b);
+					if (rc != EOK)
+						goto err;
 					goto hit;
 				}
 			}
-			block_put(b);
+			rc = block_put(b);
+			if (rc != EOK)
+				goto err;
 			bnum++;
 		}
 miss:
-		fat_node_put(fn);
-		ipc_answer_0(callid, ENOENT);
-		ipc_answer_1(rid, ENOENT, 0);
-		return;
+		rc = fat_node_put(fn);
+		ipc_answer_0(callid, rc != EOK ? rc : ENOENT);
+		ipc_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
+		return;
+
+err:
+		(void) fat_node_put(fn);
+		ipc_answer_0(callid, rc);
+		ipc_answer_0(rid, rc);
+		return;
+
 hit:
-		(void) ipc_data_read_finalize(callid, name, str_size(name) + 1);
+		(void) async_data_read_finalize(callid, name, str_size(name) + 1);
 		bytes = (pos - spos) + 1;
 	}
 
-	fat_node_put(fn);
-	ipc_answer_1(rid, EOK, (ipcarg_t)bytes);
+	rc = fat_node_put(fn);
+	ipc_answer_1(rid, rc, (ipcarg_t)bytes);
 }
 
@@ -1000,8 +1169,8 @@
 	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
 	off_t pos = (off_t)IPC_GET_ARG3(*request);
-	fs_node_t *fn = fat_node_get(dev_handle, index);
+	fs_node_t *fn;
 	fat_node_t *nodep;
 	fat_bs_t *bs;
-	size_t bytes;
+	size_t bytes, size;
 	block_t *b;
 	uint16_t bps;
@@ -1010,5 +1179,11 @@
 	off_t boundary;
 	int flags = BLOCK_FLAGS_NONE;
-	
+	int rc;
+	
+	rc = fat_node_get(&fn, dev_handle, index);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 	if (!fn) {
 		ipc_answer_0(rid, ENOENT);
@@ -1019,6 +1194,6 @@
 	ipc_callid_t callid;
 	size_t len;
-	if (!ipc_data_write_receive(&callid, &len)) {
-		fat_node_put(fn);
+	if (!async_data_write_receive(&callid, &len)) {
+		(void) fat_node_put(fn);
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -1050,16 +1225,34 @@
 		 * next block size boundary.
 		 */
-		fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos);
-		b = fat_block_get(bs, nodep, pos / bps, flags);
-		(void) ipc_data_write_finalize(callid, b->data + pos % bps,
+		rc = fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos);
+		if (rc != EOK) {
+			(void) fat_node_put(fn);
+			ipc_answer_0(callid, rc);
+			ipc_answer_0(rid, rc);
+			return;
+		}
+		rc = fat_block_get(&b, bs, nodep, pos / bps, flags);
+		if (rc != EOK) {
+			(void) fat_node_put(fn);
+			ipc_answer_0(callid, rc);
+			ipc_answer_0(rid, rc);
+			return;
+		}
+		(void) async_data_write_finalize(callid, b->data + pos % bps,
 		    bytes);
 		b->dirty = true;		/* need to sync block */
-		block_put(b);
+		rc = block_put(b);
+		if (rc != EOK) {
+			(void) fat_node_put(fn);
+			ipc_answer_0(rid, rc);
+			return;
+		}
 		if (pos + bytes > nodep->size) {
 			nodep->size = pos + bytes;
 			nodep->dirty = true;	/* need to sync node */
 		}
-		ipc_answer_2(rid, EOK, bytes, nodep->size);	
-		fat_node_put(fn);
+		size = nodep->size;
+		rc = fat_node_put(fn);
+		ipc_answer_2(rid, rc, bytes, nodep->size);
 		return;
 	} else {
@@ -1068,5 +1261,4 @@
 		 * clusters for the node and zero them out.
 		 */
-		int status;
 		unsigned nclsts;
 		fat_cluster_t mcl, lcl; 
@@ -1074,29 +1266,55 @@
 		nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
 		/* create an independent chain of nclsts clusters in all FATs */
-		status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
-		if (status != EOK) {
+		rc = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
+		if (rc != EOK) {
 			/* could not allocate a chain of nclsts clusters */
-			fat_node_put(fn);
-			ipc_answer_0(callid, status);
-			ipc_answer_0(rid, status);
+			(void) fat_node_put(fn);
+			ipc_answer_0(callid, rc);
+			ipc_answer_0(rid, rc);
 			return;
 		}
 		/* zero fill any gaps */
-		fat_fill_gap(bs, nodep, mcl, pos);
-		b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc,
+		rc = fat_fill_gap(bs, nodep, mcl, pos);
+		if (rc != EOK) {
+			(void) fat_free_clusters(bs, dev_handle, mcl);
+			(void) fat_node_put(fn);
+			ipc_answer_0(callid, rc);
+			ipc_answer_0(rid, rc);
+			return;
+		}
+		rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc,
 		    flags);
-		(void) ipc_data_write_finalize(callid, b->data + pos % bps,
+		if (rc != EOK) {
+			(void) fat_free_clusters(bs, dev_handle, mcl);
+			(void) fat_node_put(fn);
+			ipc_answer_0(callid, rc);
+			ipc_answer_0(rid, rc);
+			return;
+		}
+		(void) async_data_write_finalize(callid, b->data + pos % bps,
 		    bytes);
 		b->dirty = true;		/* need to sync block */
-		block_put(b);
+		rc = block_put(b);
+		if (rc != EOK) {
+			(void) fat_free_clusters(bs, dev_handle, mcl);
+			(void) fat_node_put(fn);
+			ipc_answer_0(rid, rc);
+			return;
+		}
 		/*
 		 * Append the cluster chain starting in mcl to the end of the
 		 * node's cluster chain.
 		 */
-		fat_append_clusters(bs, nodep, mcl);
-		nodep->size = pos + bytes;
+		rc = fat_append_clusters(bs, nodep, mcl);
+		if (rc != EOK) {
+			(void) fat_free_clusters(bs, dev_handle, mcl);
+			(void) fat_node_put(fn);
+			ipc_answer_0(rid, rc);
+			return;
+		}
+		nodep->size = size = pos + bytes;
 		nodep->dirty = true;		/* need to sync node */
-		ipc_answer_2(rid, EOK, bytes, nodep->size);
-		fat_node_put(fn);
+		rc = fat_node_put(fn);
+		ipc_answer_2(rid, rc, bytes, size);
 		return;
 	}
@@ -1108,5 +1326,5 @@
 	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
 	size_t size = (off_t)IPC_GET_ARG3(*request);
-	fs_node_t *fn = fat_node_get(dev_handle, index);
+	fs_node_t *fn;
 	fat_node_t *nodep;
 	fat_bs_t *bs;
@@ -1116,4 +1334,9 @@
 	int rc;
 
+	rc = fat_node_get(&fn, dev_handle, index);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 	if (!fn) {
 		ipc_answer_0(rid, ENOENT);
@@ -1147,10 +1370,16 @@
 		 */
 		if (size == 0) {
-			fat_chop_clusters(bs, nodep, FAT_CLST_RES0);
+			rc = fat_chop_clusters(bs, nodep, FAT_CLST_RES0);
+			if (rc != EOK)
+				goto out;
 		} else {
 			fat_cluster_t lastc;
-			(void) fat_cluster_walk(bs, dev_handle, nodep->firstc,
-			    &lastc, (size - 1) / bpc);
-			fat_chop_clusters(bs, nodep, lastc);
+			rc = fat_cluster_walk(bs, dev_handle, nodep->firstc,
+			    &lastc, NULL, (size - 1) / bpc);
+			if (rc != EOK)
+				goto out;
+			rc = fat_chop_clusters(bs, nodep, lastc);
+			if (rc != EOK)
+				goto out;
 		}
 		nodep->size = size;
@@ -1158,4 +1387,5 @@
 		rc = EOK;	
 	}
+out:
 	fat_node_put(fn);
 	ipc_answer_0(rid, rc);
@@ -1172,7 +1402,12 @@
 	dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
 	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
+	fs_node_t *fn;
 	int rc;
 
-	fs_node_t *fn = fat_node_get(dev_handle, index);
+	rc = fat_node_get(&fn, dev_handle, index);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 	if (!fn) {
 		ipc_answer_0(rid, ENOENT);
Index: uspace/srv/fs/tmpfs/Makefile
===================================================================
--- uspace/srv/fs/tmpfs/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/tmpfs/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,58 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../../lib/libc
-LIBFS_PREFIX = ../../../lib/libfs
-LIBBLOCK_PREFIX = ../../../lib/libblock
-SOFTINT_PREFIX = ../../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX)
-
-LIBS = \
-	$(LIBFS_PREFIX)/libfs.a \
-	$(LIBBLOCK_PREFIX)/libblock.a \
-	$(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = tmpfs
-SOURCES = \
-	tmpfs.c \
-	tmpfs_ops.c \
-	tmpfs_dump.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/fs/tmpfs/Makefile.build
===================================================================
--- uspace/srv/fs/tmpfs/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/fs/tmpfs/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I$(LIBFS_PREFIX) -I$(LIBBLOCK_PREFIX)
+
+## Sources
+#
+
+SOURCES = \
+	tmpfs.c \
+	tmpfs_ops.c \
+	tmpfs_dump.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/fs/tmpfs/Makefile.common
===================================================================
--- uspace/srv/fs/tmpfs/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/fs/tmpfs/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+LIBFS_PREFIX = ../../../lib/libfs
+LIBBLOCK_PREFIX = ../../../lib/libblock
+SOFTINT_PREFIX = ../../../lib/softint
+LIBS = $(LIBFS_PREFIX)/libfs.a $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = tmpfs
Index: uspace/srv/fs/tmpfs/tmpfs.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/tmpfs/tmpfs.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -48,4 +48,5 @@
 #include <unistd.h>
 #include <stdio.h>
+#include <task.h>
 #include <libfs.h>
 #include "../../vfs/vfs.h"
@@ -55,5 +56,5 @@
 
 vfs_info_t tmpfs_vfs_info = {
-	.name = "tmpfs",
+	.name = NAME,
 };
 
@@ -90,5 +91,5 @@
 	}
 	
-	dprintf("VFS-TMPFS connection established.\n");
+	dprintf(NAME ": connection opened\n");
 	while (1) {
 		ipc_callid_t callid;
@@ -162,4 +163,5 @@
 
 	printf(NAME ": Accepting connections\n");
+	task_retval(0);
 	async_manager();
 	/* not reached */
Index: uspace/srv/fs/tmpfs/tmpfs_dump.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_dump.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/tmpfs/tmpfs_dump.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -47,5 +47,5 @@
 #include <byteorder.h>
 
-#define TMPFS_BLOCK_SIZE	1024
+#define TMPFS_COMM_SIZE		1024
 
 struct rdentry {
@@ -69,5 +69,5 @@
 		
 		if (block_seqread(dev, bufpos, buflen, pos, &entry,
-		    sizeof(entry), TMPFS_BLOCK_SIZE) != EOK)
+		    sizeof(entry)) != EOK)
 			return false;
 		
@@ -82,6 +82,6 @@
 				return false;
 			
-			fn = ops->create(dev, L_FILE);
-			if (fn == NULL) {
+			rc = ops->create(&fn, dev, L_FILE);
+			if (rc != EOK || fn == NULL) {
 				free(fname);
 				return false;
@@ -89,6 +89,6 @@
 			
 			if (block_seqread(dev, bufpos, buflen, pos, fname,
-			    entry.len, TMPFS_BLOCK_SIZE) != EOK) {
-				ops->destroy(fn);
+			    entry.len) != EOK) {
+				(void) ops->destroy(fn);
 				free(fname);
 				return false;
@@ -98,5 +98,5 @@
 			rc = ops->link(pfn, fn, fname);
 			if (rc != EOK) {
-				ops->destroy(fn);
+				(void) ops->destroy(fn);
 				free(fname);
 				return false;
@@ -105,5 +105,5 @@
 			
 			if (block_seqread(dev, bufpos, buflen, pos, &size,
-			    sizeof(size), TMPFS_BLOCK_SIZE) != EOK)
+			    sizeof(size)) != EOK)
 				return false;
 			
@@ -117,5 +117,5 @@
 			nodep->size = size;
 			if (block_seqread(dev, bufpos, buflen, pos, nodep->data,
-			    size, TMPFS_BLOCK_SIZE) != EOK)
+			    size) != EOK)
 				return false;
 			
@@ -126,6 +126,6 @@
 				return false;
 			
-			fn = ops->create(dev, L_DIRECTORY);
-			if (fn == NULL) {
+			rc = ops->create(&fn, dev, L_DIRECTORY);
+			if (rc != EOK || fn == NULL) {
 				free(fname);
 				return false;
@@ -133,6 +133,6 @@
 			
 			if (block_seqread(dev, bufpos, buflen, pos, fname,
-			    entry.len, TMPFS_BLOCK_SIZE) != EOK) {
-				ops->destroy(fn);
+			    entry.len) != EOK) {
+				(void) ops->destroy(fn);
 				free(fname);
 				return false;
@@ -142,5 +142,5 @@
 			rc = ops->link(pfn, fn, fname);
 			if (rc != EOK) {
-				ops->destroy(fn);
+				(void) ops->destroy(fn);
 				free(fname);
 				return false;
@@ -164,7 +164,8 @@
 {
 	libfs_ops_t *ops = &tmpfs_libfs_ops;
+	fs_node_t *fn;
 	int rc;
 
-	rc = block_init(dev, TMPFS_BLOCK_SIZE);
+	rc = block_init(dev, TMPFS_COMM_SIZE);
 	if (rc != EOK)
 		return false; 
@@ -175,6 +176,5 @@
 	
 	char tag[6];
-	if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5,
-	    TMPFS_BLOCK_SIZE) != EOK)
+	if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5) != EOK)
 		goto error;
 	
@@ -183,6 +183,9 @@
 		goto error;
 	
-	if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos,
-	    ops->root_get(dev)))
+	rc = ops->root_get(&fn, dev);
+	if (rc != EOK)
+		goto error;
+
+	if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos, fn))
 		goto error;
 		
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -67,13 +67,24 @@
 
 /* Forward declarations of static functions. */
-static fs_node_t *tmpfs_match(fs_node_t *, const char *);
-static fs_node_t *tmpfs_node_get(dev_handle_t, fs_index_t);
-static void tmpfs_node_put(fs_node_t *);
-static fs_node_t *tmpfs_create_node(dev_handle_t, int);
+static int tmpfs_match(fs_node_t **, fs_node_t *, const char *);
+static int tmpfs_node_get(fs_node_t **, dev_handle_t, fs_index_t);
+static int tmpfs_node_put(fs_node_t *);
+static int tmpfs_create_node(fs_node_t **, dev_handle_t, int);
+static int tmpfs_destroy_node(fs_node_t *);
 static int tmpfs_link_node(fs_node_t *, fs_node_t *, const char *);
 static int tmpfs_unlink_node(fs_node_t *, fs_node_t *, const char *);
-static int tmpfs_destroy_node(fs_node_t *);
 
 /* Implementation of helper functions. */
+static int tmpfs_root_get(fs_node_t **rfn, dev_handle_t dev_handle)
+{
+	return tmpfs_node_get(rfn, dev_handle, TMPFS_SOME_ROOT); 
+}
+
+static int tmpfs_has_children(bool *has_children, fs_node_t *fn)
+{
+	*has_children = !list_empty(&TMPFS_NODE(fn)->cs_head);
+	return EOK;
+}
+
 static fs_index_t tmpfs_index_get(fs_node_t *fn)
 {
@@ -89,14 +100,4 @@
 {
 	return TMPFS_NODE(fn)->lnkcnt;
-}
-
-static bool tmpfs_has_children(fs_node_t *fn)
-{
-	return !list_empty(&TMPFS_NODE(fn)->cs_head);
-}
-
-static fs_node_t *tmpfs_root_get(dev_handle_t dev_handle)
-{
-	return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT); 
 }
 
@@ -118,4 +119,5 @@
 /** libfs operations */
 libfs_ops_t tmpfs_libfs_ops = {
+	.root_get = tmpfs_root_get,
 	.match = tmpfs_match,
 	.node_get = tmpfs_node_get,
@@ -125,9 +127,8 @@
 	.link = tmpfs_link_node,
 	.unlink = tmpfs_unlink_node,
+	.has_children = tmpfs_has_children,
 	.index_get = tmpfs_index_get,
 	.size_get = tmpfs_size_get,
 	.lnkcnt_get = tmpfs_lnkcnt_get,
-	.has_children = tmpfs_has_children,
-	.root_get = tmpfs_root_get,
 	.plb_get_char = tmpfs_plb_get_char,
 	.is_directory = tmpfs_is_directory,
@@ -197,7 +198,8 @@
 {
 	fs_node_t *rfn;
+	int rc;
 	
-	rfn = tmpfs_create_node(dev_handle, L_DIRECTORY);
-	if (!rfn) 
+	rc = tmpfs_create_node(&rfn, dev_handle, L_DIRECTORY);
+	if (rc != EOK || !rfn)
 		return false;
 	TMPFS_NODE(rfn)->lnkcnt = 0;	/* FS root is not linked */
@@ -205,5 +207,5 @@
 }
 
-fs_node_t *tmpfs_match(fs_node_t *pfn, const char *component)
+int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
 {
 	tmpfs_node_t *parentp = TMPFS_NODE(pfn);
@@ -212,14 +214,17 @@
 	for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
 	    lnk = lnk->next) {
-		tmpfs_dentry_t *dentryp = list_get_instance(lnk, tmpfs_dentry_t,
-		    link);
-		if (!str_cmp(dentryp->name, component))
-			return FS_NODE(dentryp->node);
-	}
-
-	return NULL;
-}
-
-fs_node_t *tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
+		tmpfs_dentry_t *dentryp;
+		dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
+		if (!str_cmp(dentryp->name, component)) {
+			*rfn = FS_NODE(dentryp->node);
+			return EOK;
+		}
+	}
+
+	*rfn = NULL;
+	return EOK;
+}
+
+int tmpfs_node_get(fs_node_t **rfn, dev_handle_t dev_handle, fs_index_t index)
 {
 	unsigned long key[] = {
@@ -228,30 +233,42 @@
 	};
 	link_t *lnk = hash_table_find(&nodes, key);
-	if (!lnk)
-		return NULL;
-	return FS_NODE(hash_table_get_instance(lnk, tmpfs_node_t, nh_link));
-}
-
-void tmpfs_node_put(fs_node_t *fn)
+	if (lnk) {
+		tmpfs_node_t *nodep;
+		nodep = hash_table_get_instance(lnk, tmpfs_node_t, nh_link);
+		*rfn = FS_NODE(nodep);
+	} else {
+		*rfn = NULL;
+	}
+	return EOK;	
+}
+
+int tmpfs_node_put(fs_node_t *fn)
 {
 	/* nothing to do */
-}
-
-fs_node_t *tmpfs_create_node(dev_handle_t dev_handle, int lflag)
-{
+	return EOK;
+}
+
+int tmpfs_create_node(fs_node_t **rfn, dev_handle_t dev_handle, int lflag)
+{
+	fs_node_t *rootfn;
+	int rc;
+
 	assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
 
 	tmpfs_node_t *nodep = malloc(sizeof(tmpfs_node_t));
 	if (!nodep)
-		return NULL;
+		return ENOMEM;
 	tmpfs_node_initialize(nodep);
 	nodep->bp = malloc(sizeof(fs_node_t));
 	if (!nodep->bp) {
 		free(nodep);
-		return NULL;
+		return ENOMEM;
 	}
 	fs_node_initialize(nodep->bp);
 	nodep->bp->data = nodep;	/* link the FS and TMPFS nodes */
-	if (!tmpfs_root_get(dev_handle))
+
+	rc = tmpfs_root_get(&rootfn, dev_handle);
+	assert(rc == EOK);
+	if (!rootfn)
 		nodep->index = TMPFS_SOME_ROOT;
 	else
@@ -269,5 +286,26 @@
 	};
 	hash_table_insert(&nodes, key, &nodep->nh_link);
-	return FS_NODE(nodep);
+	*rfn = FS_NODE(nodep);
+	return EOK;
+}
+
+int tmpfs_destroy_node(fs_node_t *fn)
+{
+	tmpfs_node_t *nodep = TMPFS_NODE(fn);
+	
+	assert(!nodep->lnkcnt);
+	assert(list_empty(&nodep->cs_head));
+
+	unsigned long key[] = {
+		[NODES_KEY_INDEX] = nodep->index,
+		[NODES_KEY_DEV] = nodep->dev_handle
+	};
+	hash_table_remove(&nodes, key, 2);
+
+	if (nodep->type == TMPFS_FILE)
+		free(nodep->data);
+	free(nodep->bp);
+	free(nodep);
+	return EOK;
 }
 
@@ -343,32 +381,13 @@
 }
 
-int tmpfs_destroy_node(fs_node_t *fn)
-{
-	tmpfs_node_t *nodep = TMPFS_NODE(fn);
-	
-	assert(!nodep->lnkcnt);
-	assert(list_empty(&nodep->cs_head));
-
-	unsigned long key[] = {
-		[NODES_KEY_INDEX] = nodep->index,
-		[NODES_KEY_DEV] = nodep->dev_handle
-	};
-	hash_table_remove(&nodes, key, 2);
-
-	if (nodep->type == TMPFS_FILE)
-		free(nodep->data);
-	free(nodep->bp);
-	free(nodep);
-	return EOK;
-}
-
 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
 {
 	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
+	int rc;
 
 	/* accept the mount options */
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -381,5 +400,5 @@
 		return;
 	}
-	ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
+	ipcarg_t retval = async_data_write_finalize(callid, opts, size);
 	if (retval != EOK) {
 		ipc_answer_0(rid, retval);
@@ -395,5 +414,8 @@
 	}
 
-	tmpfs_node_t *rootp = TMPFS_NODE(tmpfs_root_get(dev_handle));
+	fs_node_t *rootfn;
+	rc = tmpfs_root_get(&rootfn, dev_handle);
+	assert(rc == EOK);
+	tmpfs_node_t *rootp = TMPFS_NODE(rootfn);
 	if (str_cmp(opts, "restore") == 0) {
 		if (tmpfs_restore(dev_handle))
@@ -445,5 +467,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_read_receive(&callid, &size)) {
+	if (!async_data_read_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);	
 		ipc_answer_0(rid, EINVAL);
@@ -454,5 +476,5 @@
 	if (nodep->type == TMPFS_FILE) {
 		bytes = max(0, min(nodep->size - pos, size));
-		(void) ipc_data_read_finalize(callid, nodep->data + pos,
+		(void) async_data_read_finalize(callid, nodep->data + pos,
 		    bytes);
 	} else {
@@ -481,5 +503,5 @@
 		dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
 
-		(void) ipc_data_read_finalize(callid, dentryp->name,
+		(void) async_data_read_finalize(callid, dentryp->name,
 		    str_size(dentryp->name) + 1);
 		bytes = 1;
@@ -519,5 +541,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);	
 		ipc_answer_0(rid, EINVAL);
@@ -530,5 +552,5 @@
 	if (pos + size <= nodep->size) {
 		/* The file size is not changing. */
-		(void) ipc_data_write_finalize(callid, nodep->data + pos, size);
+		(void) async_data_write_finalize(callid, nodep->data + pos, size);
 		ipc_answer_2(rid, EOK, size, nodep->size);
 		return;
@@ -552,5 +574,5 @@
 	nodep->size += delta;
 	nodep->data = newdata;
-	(void) ipc_data_write_finalize(callid, nodep->data + pos, size);
+	(void) async_data_write_finalize(callid, nodep->data + pos, size);
 	ipc_answer_2(rid, EOK, size, nodep->size);
 }
Index: uspace/srv/kbd/Makefile
===================================================================
--- uspace/srv/kbd/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/kbd/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,159 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -Iinclude
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = kbd
-GENERIC_SOURCES = \
-	generic/kbd.c \
-	genarch/gsp.c \
-	genarch/stroke.c
-
-ARCH_SOURCES =
-GENARCH_SOURCES = \
-	layout/cz.c \
-	layout/us_qwerty.c \
-	layout/us_dvorak.c
-
-ifeq ($(UARCH), amd64)
-	GENARCH_SOURCES += \
-		port/i8042.c \
-		ctl/pc.c
-endif
-
-ifeq ($(UARCH), arm32)
-ifeq ($(MACHINE), testarm)
-	GENARCH_SOURCES += \
-		port/gxemul.c
-	
-	ifeq ($(CONFIG_FB), y)
-		GENARCH_SOURCES += \
-			ctl/gxe_fb.c
-	else
-		GENARCH_SOURCES += \
-			ctl/stty.c
-	endif
-endif
-ifeq ($(MACHINE), integratorcp)
-	 GENARCH_SOURCES += \
-		port/pl050.c \
-		ctl/pl050.c
-endif
-endif
-
-ifeq ($(UARCH), ia32)
-	GENARCH_SOURCES += \
-		port/i8042.c \
-		ctl/pc.c
-endif
-
-ifeq ($(MACHINE), i460GX)
-	GENARCH_SOURCES += \
-		port/i8042.c \
-		ctl/pc.c
-endif
-
-ifeq ($(MACHINE), ski)
-	GENARCH_SOURCES += \
-		port/ski.c \
-		ctl/stty.c
-endif
-
-ifeq ($(MACHINE), msim)
-	GENARCH_SOURCES += \
-		port/msim.c \
-		ctl/stty.c
-endif
-
-ifeq ($(MACHINE), lgxemul)
-	GENARCH_SOURCES += \
-		port/gxemul.c
-	
-	ifeq ($(CONFIG_FB), y)
-		GENARCH_SOURCES += \
-			ctl/gxe_fb.c
-	else
-		GENARCH_SOURCES += \
-			ctl/stty.c
-	endif
-endif
-
-ifeq ($(MACHINE), bgxemul)
-	GENARCH_SOURCES += \
-		port/gxemul.c
-	
-	ifeq ($(CONFIG_FB), y)
-		GENARCH_SOURCES += \
-			ctl/gxe_fb.c
-	else
-		GENARCH_SOURCES += \
-			ctl/stty.c
-	endif
-endif
-
-ifeq ($(UARCH), ppc32)
-	GENARCH_SOURCES += \
-		port/dummy.c \
-		ctl/stty.c
-endif
-
-ifeq ($(UARCH), sparc64)
-	ifeq ($(MACHINE),serengeti)
-		GENARCH_SOURCES += \
-			port/sgcn.c \
-			ctl/stty.c
-	else
-		GENARCH_SOURCES += \
-			port/sun.c \
-			port/z8530.c \
-			port/ns16550.c \
-			ctl/sun.c
-	endif
-endif
-
-GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
-ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
-GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
-
-OBJECTS := $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(GENARCH_OBJECTS)
-
-.PHONY: all clean depend disasm links
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/kbd/Makefile.build
===================================================================
--- uspace/srv/kbd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/kbd/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,164 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -Iinclude
+
+## Sources
+#
+
+SOURCES = \
+	generic/kbd.c \
+	genarch/gsp.c \
+	genarch/stroke.c \
+	layout/cz.c \
+	layout/us_qwerty.c \
+	layout/us_dvorak.c
+
+ifeq ($(UARCH),amd64)
+	SOURCES += \
+		port/i8042.c \
+		ctl/pc.c
+endif
+
+ifeq ($(UARCH),arm32)
+	ifeq ($(MACHINE),testarm)
+		SOURCES += \
+			port/gxemul.c
+		
+		ifeq ($(CONFIG_FB),y)
+			SOURCES += \
+				ctl/gxe_fb.c
+		else
+			SOURCES += \
+				ctl/stty.c
+		endif
+	endif
+	ifeq ($(MACHINE),integratorcp)
+		SOURCES += \
+			port/pl050.c \
+			ctl/pl050.c
+	endif
+endif
+
+ifeq ($(UARCH),ia32)
+	SOURCES += \
+		port/i8042.c \
+		ctl/pc.c
+endif
+
+ifeq ($(MACHINE),i460GX)
+	SOURCES += \
+		port/i8042.c \
+		ctl/pc.c
+endif
+
+ifeq ($(MACHINE),ski)
+	SOURCES += \
+		port/ski.c \
+		ctl/stty.c
+endif
+
+ifeq ($(MACHINE),msim)
+	SOURCES += \
+		port/msim.c \
+		ctl/stty.c
+endif
+
+ifeq ($(MACHINE),lgxemul)
+	SOURCES += \
+		port/gxemul.c
+	
+	ifeq ($(CONFIG_FB),y)
+		SOURCES += \
+			ctl/gxe_fb.c
+	else
+		SOURCES += \
+			ctl/stty.c
+	endif
+endif
+
+ifeq ($(MACHINE),bgxemul)
+	SOURCES += \
+		port/gxemul.c
+	
+	ifeq ($(CONFIG_FB),y)
+		SOURCES += \
+			ctl/gxe_fb.c
+	else
+		SOURCES += \
+			ctl/stty.c
+	endif
+endif
+
+ifeq ($(UARCH),ppc32)
+	SOURCES += \
+		port/dummy.c \
+		ctl/stty.c
+endif
+
+ifeq ($(UARCH),sparc64)
+	ifeq ($(MACHINE),serengeti)
+		SOURCES += \
+			port/sgcn.c \
+			ctl/stty.c
+	else
+		SOURCES += \
+			port/sun.c \
+			port/z8530.c \
+			port/ns16550.c \
+			ctl/sun.c
+	endif
+endif
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/kbd/Makefile.common
===================================================================
--- uspace/srv/kbd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/kbd/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = kbd
Index: uspace/srv/loader/Makefile
===================================================================
--- uspace/srv/loader/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/loader/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,5 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
-# Copyright (c) 2008 Jiri Svoboda
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -28,56 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-include arch/$(UARCH)/Makefile.inc
-
-CFLAGS += -Iinclude
-
-LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a
-
-## Sources
-#
-
-OUTPUT = loader
-GENERIC_SOURCES = \
-	main.c \
-	elf_load.c \
-	interp.s
-
-SOURCES := $(GENERIC_SOURCES) $(ARCH_SOURCES)
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm arch/$(UARCH)/_link.ld Makefile.depend
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS) arch/$(UARCH)/_link.ld
-	$(LD) -T arch/$(UARCH)/_link.ld $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map
-
-disasm:
-	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
-
-arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in
-	$(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm arch/*/_link.ld
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/loader/Makefile.build
===================================================================
--- uspace/srv/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/loader/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+include arch/$(UARCH)/Makefile.inc
+
+CFLAGS += -Iinclude
+LINK = arch/$(UARCH)/_link.ld
+
+## Sources
+#
+
+GENERIC_SOURCES = \
+	main.c \
+	elf_load.c \
+	interp.s
+
+SOURCES := $(GENERIC_SOURCES) $(ARCH_SOURCES)
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS) $(LINK)
+	$(LD) -T $(LINK) $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map
+
+$(LINK): $(LINK).in
+	$(GCC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+%.o: %.s $(DEPEND)
+	$(AS) $(AFLAGS) $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/loader/Makefile.common
===================================================================
--- uspace/srv/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/loader/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = loader
Index: uspace/srv/loader/arch/ia32/_link.ld.in
===================================================================
--- uspace/srv/loader/arch/ia32/_link.ld.in	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/loader/arch/ia32/_link.ld.in	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -8,5 +8,5 @@
 PHDRS {
 	interp PT_INTERP;
-        text PT_LOAD FILEHDR PHDRS FLAGS(5);
+	text PT_LOAD FILEHDR PHDRS FLAGS(5);
 	data PT_LOAD FLAGS(6);
 }
@@ -16,13 +16,14 @@
 		*(.interp);
 	} :interp
-
+	
 	. = 0x70001000;
-
+	
 	.init ALIGN(0x1000) : SUBALIGN(0x1000) {
 		*(.init);
 	} :text
+	
 	.text : {
 		*(.text);
-                *(.rodata*);
+		*(.rodata*);
 	} :text
 	
@@ -30,9 +31,12 @@
 		*(.data);
 	} :data
+	
 	.tdata : {
 		_tdata_start = .;
 		*(.tdata);
+		*(.gnu.linkonce.tb.*);
 		_tdata_end = .;
 	} :data
+	
 	.tbss : {
 		_tbss_start = .;
@@ -40,11 +44,14 @@
 		_tbss_end = .;
 	} :data
+	
 	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	
 	.bss : {
-                *(COMMON);
-                *(.bss);
+		*(COMMON);
+		*(.bss);
 	} :data
 	
 	. = ALIGN(0x1000);
+	
 	_heap = .;
 	
@@ -52,4 +59,3 @@
 		*(*);
 	}
-
 }
Index: uspace/srv/loader/arch/ia32/ia32.s
===================================================================
--- uspace/srv/loader/arch/ia32/ia32.s	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/loader/arch/ia32/ia32.s	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -40,7 +40,7 @@
 	movl 0x8(%ebp), %eax
 
-	# %ebx := pcb
-	# pcb is passed to the entry point int %ebx
-	mov 0xc(%ebp), %ebx
+	# %edi := pcb
+	# pcb is passed to the entry point in %edi
+	mov 0xc(%ebp), %edi
 
 	# Save a tiny bit of stack space
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/loader/main.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -72,4 +72,7 @@
 static pcb_t pcb;
 
+/** Current working directory */
+static char *cwd = NULL;
+
 /** Number of arguments */
 static int argc = 0;
@@ -102,5 +105,5 @@
 	task_id = task_get_id();
 	
-	if (!ipc_data_read_receive(&callid, &len)) {
+	if (!async_data_read_receive(&callid, &len)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -111,8 +114,36 @@
 		len = sizeof(task_id);
 	
-	ipc_data_read_finalize(callid, &task_id, len);
+	async_data_read_finalize(callid, &task_id, len);
 	ipc_answer_0(rid, EOK);
 }
 
+/** Receive a call setting the current working directory.
+ *
+ * @param rid
+ * @param request
+ */
+static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request)
+{
+	ipc_callid_t callid;
+	size_t len;
+	
+	if (!async_data_write_receive(&callid, &len)) {
+		ipc_answer_0(callid, EINVAL);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+	
+	cwd = malloc(len + 1);
+	if (!cwd) {
+		ipc_answer_0(callid, ENOMEM);
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+	
+	async_data_write_finalize(callid, cwd, len);
+	cwd[len] = '\0';
+	
+	ipc_answer_0(rid, EOK);
+}
 
 /** Receive a call setting pathname of the program to execute.
@@ -127,5 +158,5 @@
 	char *name_buf;
 	
-	if (!ipc_data_write_receive(&callid, &len)) {
+	if (!async_data_write_receive(&callid, &len)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -140,5 +171,5 @@
 	}
 	
-	ipc_data_write_finalize(callid, name_buf, len);
+	async_data_write_finalize(callid, name_buf, len);
 	ipc_answer_0(rid, EOK);
 	
@@ -164,5 +195,5 @@
 	int n;
 	
-	if (!ipc_data_write_receive(&callid, &buf_size)) {
+	if (!async_data_write_receive(&callid, &buf_size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -187,5 +218,5 @@
 	}
 	
-	ipc_data_write_finalize(callid, arg_buf, buf_size);
+	async_data_write_finalize(callid, arg_buf, buf_size);
 	
 	arg_buf[buf_size] = '\0';
@@ -239,5 +270,5 @@
 	ipc_callid_t callid;
 	size_t buf_size;
-	if (!ipc_data_write_receive(&callid, &buf_size)) {
+	if (!async_data_write_receive(&callid, &buf_size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -268,5 +299,5 @@
 	}
 	
-	ipc_data_write_finalize(callid, fil_buf, buf_size);
+	async_data_write_finalize(callid, fil_buf, buf_size);
 	
 	int count = buf_size / sizeof(fdi_node_t);
@@ -312,4 +343,6 @@
 	
 	elf_create_pcb(&prog_info, &pcb);
+	
+	pcb.cwd = cwd;
 	
 	pcb.argc = argc;
@@ -406,4 +439,7 @@
 		case LOADER_GET_TASKID:
 			ldr_get_taskid(callid, &call);
+			continue;
+		case LOADER_SET_CWD:
+			ldr_set_cwd(callid, &call);
 			continue;
 		case LOADER_SET_PATHNAME:
Index: uspace/srv/ns/Makefile
===================================================================
--- uspace/srv/ns/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/ns/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,52 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = ns
-SOURCES = \
-	ns.c \
-	service.c \
-	clonable.c \
-	task.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/ns/Makefile.build
===================================================================
--- uspace/srv/ns/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/ns/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	ns.c \
+	service.c \
+	clonable.c \
+	task.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/ns/Makefile.common
===================================================================
--- uspace/srv/ns/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/ns/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = ns
Index: uspace/srv/ns/service.c
===================================================================
--- uspace/srv/ns/service.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/ns/service.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -156,9 +156,6 @@
 		
 		hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link);
-		ipcarg_t retval = ipc_forward_fast(pr->callid, hs->phone,
-		    pr->arg2, pr->arg3, 0, IPC_FF_NONE);
-		
-		if (!(pr->callid & IPC_CALLID_NOTIFICATION))
-			ipc_answer_0(pr->callid, retval);
+		(void) ipc_forward_fast(pr->callid, hs->phone, pr->arg2,
+		    pr->arg3, 0, IPC_FF_NONE);
 		
 		list_remove(cur);
@@ -242,6 +239,7 @@
 	
 	hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link);
-	retval = ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call),
+	(void) ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call),
 	    IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
+	return;
 	
 out:
Index: uspace/srv/part/mbr_part/Makefile
===================================================================
--- uspace/srv/part/mbr_part/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/part/mbr_part/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+include Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
+
+clean:
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/part/mbr_part/Makefile.build
===================================================================
--- uspace/srv/part/mbr_part/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/part/mbr_part/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I$(LIBBLOCK_PREFIX)
+
+## Sources
+#
+
+SOURCES = \
+	mbr_part.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/part/mbr_part/Makefile.common
===================================================================
--- uspace/srv/part/mbr_part/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/part/mbr_part/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+SOFTINT_PREFIX = ../../../lib/softint
+LIBBLOCK_PREFIX = ../../../lib/libblock
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = mbr_part
Index: uspace/srv/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/part/mbr_part/mbr_part.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/part/mbr_part/mbr_part.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,508 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 bd
+ * @{
+ */
+
+/**
+ * @file
+ * @brief PC MBR partition driver
+ *
+ * Handles the PC MBR partitioning scheme. Uses a block device
+ * and provides one for each partition.
+ *
+ * Limitations:
+ * 
+ * Only works with boot records using LBA. CHS-only records are not
+ * supported.
+ *
+ * Referemces:
+ *	
+ * The source of MBR structures for this driver have been the following
+ * Wikipedia articles:
+ *	- http://en.wikipedia.org/wiki/Master_Boot_Record
+ *	- http://en.wikipedia.org/wiki/Extended_boot_record
+ *
+ * The fact that the extended partition has type 0x05 is pure observation.
+ * (TODO: can it have any other type number?)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ipc/ipc.h>
+#include <ipc/bd.h>
+#include <async.h>
+#include <as.h>
+#include <fibril_sync.h>
+#include <devmap.h>
+#include <sys/types.h>
+#include <libblock.h>
+#include <devmap.h>
+#include <errno.h>
+#include <bool.h>
+#include <byteorder.h>
+#include <assert.h>
+#include <macros.h>
+#include <task.h>
+
+#define NAME "mbr_part"
+
+enum {
+	/** Number of primary partition records */
+	N_PRIMARY	= 4,
+
+	/** Boot record signature */
+	BR_SIGNATURE	= 0xAA55
+};
+
+enum ptype {
+	/** Unused partition entry */
+	PT_UNUSED	= 0x00,
+	/** Extended partition */
+	PT_EXTENDED	= 0x05,
+};
+
+/** Partition */
+typedef struct part {
+	/** Primary partition entry is in use */
+	bool present;
+	/** Address of first block */
+	bn_t start_addr;
+	/** Number of blocks */
+	bn_t length;
+	/** Device representing the partition (outbound device) */
+	dev_handle_t dev;
+	/** Points to next partition structure. */
+	struct part *next;
+} part_t;
+
+/** Structure of a partition table entry */
+typedef struct {
+	uint8_t status;
+	/** CHS of fist block in partition */
+	uint8_t first_chs[3];
+	/** Partition type */
+	uint8_t ptype;
+	/** CHS of last block in partition */
+	uint8_t last_chs[3];
+	/** LBA of first block in partition */
+	uint32_t first_lba;
+	/** Number of blocks in partition */
+	uint32_t length;
+} __attribute__((packed)) pt_entry_t;
+
+/** Structure of a boot-record block */
+typedef struct {
+	/* Area for boot code */
+	uint8_t code_area[440];
+
+	/* Optional media ID */
+	uint32_t media_id;
+
+	uint16_t pad0;
+
+	/** Partition table entries */
+	pt_entry_t pte[N_PRIMARY];
+
+	/** Boot record block signature (@c BR_SIGNATURE) */
+	uint16_t signature;
+} __attribute__((packed)) br_block_t;
+
+
+static size_t block_size;
+
+/** Partitioned device (inbound device) */
+static dev_handle_t indev_handle;
+
+/** List of partitions. This structure is an empty head. */
+static part_t plist_head;
+
+static int mbr_init(const char *dev_name);
+static int mbr_part_read(void);
+static part_t *mbr_part_new(void);
+static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part);
+static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall);
+static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf);
+static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf);
+static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba);
+
+int main(int argc, char **argv)
+{
+	printf(NAME ": PC MBR partition driver\n");
+
+	if (argc != 2) {
+		printf("Expected one argument (device name).\n");
+		return -1;
+	}
+
+	if (mbr_init(argv[1]) != EOK)
+		return -1;
+
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
+	async_manager();
+
+	/* Not reached */
+	return 0;
+}
+
+static int mbr_init(const char *dev_name)
+{
+	int rc;
+	int i;
+	char *name;
+	dev_handle_t dev;
+	uint64_t size_mb;
+	part_t *part;
+
+	rc = devmap_device_get_handle(dev_name, &indev_handle, 0);
+	if (rc != EOK) {
+		printf(NAME ": could not resolve device `%s'.\n", dev_name);
+		return rc;
+	}
+
+	rc = block_init(indev_handle, 2048);
+	if (rc != EOK)  {
+		printf(NAME ": could not init libblock.\n");
+		return rc;
+	}
+
+	/* Determine and verify block size. */
+
+	rc = block_get_bsize(indev_handle, &block_size);
+	if (rc != EOK) {
+		printf(NAME ": error getting block size.\n");
+		return rc;
+	}
+
+	if (block_size < 512 || (block_size % 512) != 0) {
+		printf(NAME ": invalid block size %d.\n");
+		return ENOTSUP;
+	}
+
+	/* Read in partition records. */
+	rc = mbr_part_read();
+	if (rc != EOK)
+		return rc;
+
+	/* Register the driver with device mapper. */
+	rc = devmap_driver_register(NAME, mbr_connection);
+	if (rc != EOK) {
+		printf(NAME ": Unable to register driver.\n");
+		return rc;
+	}
+
+	/*
+	 * Create partition devices.
+	 */
+	i = 0;
+	part = plist_head.next;
+
+	while (part != NULL) {
+		/* Skip absent partitions. */
+		if (!part->present) {
+			part = part->next;
+			++i;
+			continue;
+		}
+
+		asprintf(&name, "%sp%d", dev_name, i);
+		if (name == NULL)
+			return ENOMEM;
+
+		rc = devmap_device_register(name, &dev);
+		if (rc != EOK) {
+			devmap_hangup_phone(DEVMAP_DRIVER);
+			printf(NAME ": Unable to register device %s.\n", name);
+			return rc;
+		}
+
+		size_mb = (part->length * block_size + 1024 * 1024 - 1)
+		    / (1024 * 1024);
+		printf(NAME ": Registered device %s: %llu blocks %llu MB.\n",
+		    name, part->length, size_mb);
+
+		part->dev = dev;
+		free(name);
+
+		part = part->next;
+		++i;
+	}
+
+	return EOK;
+}
+
+/** Read in partition records. */
+static int mbr_part_read(void)
+{
+	int i, rc;
+	br_block_t *brb;
+	uint16_t sgn;
+	uint32_t ba;
+	part_t *ext_part, cp;
+	uint32_t base;
+	part_t *prev, *p;
+
+	brb = malloc(sizeof(br_block_t));
+	if (brb == NULL) {
+		printf(NAME ": Failed allocating memory.\n");
+		return ENOMEM;	
+	}
+
+	/*
+	 * Read primary partition entries.
+	 */
+
+	rc = block_read_direct(indev_handle, 0, 1, brb);
+	if (rc != EOK) {
+		printf(NAME ": Failed reading MBR block.\n");
+		return rc;
+	}
+
+	sgn = uint16_t_le2host(brb->signature);
+	if (sgn != BR_SIGNATURE) {
+		printf(NAME ": Invalid boot record signature 0x%04X.\n", sgn);
+		return EINVAL;
+	}
+
+	ext_part = NULL;
+	plist_head.next = NULL;
+	prev = &plist_head;
+
+	for (i = 0; i < N_PRIMARY; ++i) {
+		p = mbr_part_new();
+		if (p == NULL)
+			return ENOMEM;
+
+		mbr_pte_to_part(0, &brb->pte[i], p);
+		prev->next = p;
+		prev = p;
+
+		if (brb->pte[i].ptype == PT_EXTENDED) {
+			p->present = false;
+			ext_part = p;
+		}
+	}
+
+	if (ext_part == NULL)
+		return EOK;
+
+	printf("Extended partition found.\n");
+
+	/*
+	 * Read extended partition entries.
+	 */
+
+	cp.start_addr = ext_part->start_addr;
+	cp.length = ext_part->length;
+	base = ext_part->start_addr;
+
+	do {
+		/*
+		 * Addressing in the EBR chain is relative to the beginning
+		 * of the extended partition.
+		 */
+		ba = cp.start_addr;
+		rc = block_read_direct(indev_handle, ba, 1, brb);
+		if (rc != EOK) {
+			printf(NAME ": Failed reading EBR block at %u.\n", ba);
+			return rc;
+		}
+
+		sgn = uint16_t_le2host(brb->signature);
+		if (sgn != BR_SIGNATURE) {
+			printf(NAME ": Invalid boot record signature 0x%04X "
+			    " in EBR at %u.\n", sgn, ba);
+			return EINVAL;
+		}
+
+		p = mbr_part_new();
+		if (p == NULL)
+			return ENOMEM;
+
+		/* First PTE is the logical partition itself. */
+		mbr_pte_to_part(base, &brb->pte[0], p);
+		prev->next = p;
+		prev = p;
+
+		/* Second PTE describes next chain element. */
+		mbr_pte_to_part(base, &brb->pte[1], &cp);
+	} while (cp.present);
+
+	return EOK;
+}
+
+/** Allocate a new @c part_t structure. */
+static part_t *mbr_part_new(void)
+{
+	return malloc(sizeof(part_t));
+}
+
+/** Parse partition table entry. */
+static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part)
+{
+	uint32_t sa, len;
+
+	sa = uint32_t_le2host(pte->first_lba);
+	len = uint32_t_le2host(pte->length);
+
+	part->start_addr = base + sa;
+	part->length     = len;
+
+	part->present = (pte->ptype != PT_UNUSED) ? true : false;
+
+	part->dev = 0;
+	part->next = NULL;
+}
+
+static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	size_t comm_size;
+	void *fs_va = NULL;
+	ipc_callid_t callid;
+	ipc_call_t call;
+	ipcarg_t method;
+	dev_handle_t dh;
+	int flags;
+	int retval;
+	uint64_t ba;
+	size_t cnt;
+	part_t *part;
+
+	/* Get the device handle. */
+	dh = IPC_GET_ARG1(*icall);
+
+	/* 
+	 * Determine which partition device is the client connecting to.
+	 * A linear search is not terribly fast, but we only do this
+	 * once for each connection.
+	 */
+	part = plist_head.next;
+	while (part != NULL && part->dev != dh)
+		part = part->next;
+
+	if (part == NULL) {
+		ipc_answer_0(iid, EINVAL);
+		return;
+	}
+
+	assert(part->present == true);
+
+	/* Answer the IPC_M_CONNECT_ME_TO call. */
+	ipc_answer_0(iid, EOK);
+
+	if (!async_share_out_receive(&callid, &comm_size, &flags)) {
+		ipc_answer_0(callid, EHANGUP);
+		return;
+	}
+
+	fs_va = as_get_mappable_page(comm_size);
+	if (fs_va == NULL) {
+		ipc_answer_0(callid, EHANGUP);
+		return;
+	}
+
+	(void) async_share_out_finalize(callid, fs_va);
+
+	while (1) {
+		callid = async_get_call(&call);
+		method = IPC_GET_METHOD(call);
+		switch (method) {
+		case IPC_M_PHONE_HUNGUP:
+			/* The other side has hung up. */
+			ipc_answer_0(callid, EOK);
+			return;
+		case BD_READ_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
+				retval = ELIMIT;
+				break;
+			}
+			retval = mbr_bd_read(part, ba, cnt, fs_va);
+			break;
+		case BD_WRITE_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			if (cnt * block_size > comm_size) {
+				retval = ELIMIT;
+				break;
+			}
+			retval = mbr_bd_write(part, ba, cnt, fs_va);
+			break;
+		case BD_GET_BLOCK_SIZE:
+			ipc_answer_1(callid, EOK, block_size);
+			continue;
+
+		default:
+			retval = EINVAL;
+			break;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+/** Read blocks from partition. */
+static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf)
+{
+	uint64_t gba;
+
+	if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK)
+		return ELIMIT;
+
+	return block_read_direct(indev_handle, gba, cnt, buf);
+}
+
+/** Write blocks to partition. */
+static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf)
+{
+	uint64_t gba;
+
+	if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK)
+		return ELIMIT;
+
+	return block_write_direct(indev_handle, gba, cnt, buf);
+}
+
+/** Translate block segment address with range checking. */
+static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba)
+{
+	if (ba + cnt > p->length)
+		return ELIMIT;
+
+	*gba = p->start_addr + ba;
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/pci/Makefile
===================================================================
--- uspace/srv/pci/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/pci/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+include Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
+
+$(LIBPCI):
+	$(MAKE) -C libpci
+
+clean:
+	$(MAKE) -C libpci clean
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/pci/Makefile.build
===================================================================
--- uspace/srv/pci/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/pci/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	pci.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/pci/Makefile.common
===================================================================
--- uspace/srv/pci/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/pci/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBPCI = libpci/libpci.a
+LIBS = $(LIBPCI) $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = pci
Index: uspace/srv/pci/libpci/Makefile
===================================================================
--- uspace/srv/pci/libpci/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/pci/libpci/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+include Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
+
+clean:
+	rm -f $(DEPEND) $(DEPEND_PREV) $(LIBPCI)
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/pci/libpci/Makefile.build
===================================================================
--- uspace/srv/pci/libpci/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/pci/libpci/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	access.c \
+	generic.c \
+	names.c \
+	i386-ports.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(LIBPCI)
+
+-include $(DEPEND)
+
+$(LIBPCI): $(OBJECTS)
+	$(AR) rc $@ $(OBJECTS)
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/pci/libpci/Makefile.common
===================================================================
--- uspace/srv/pci/libpci/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/pci/libpci/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../../lib/libc
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+LIBPCI = libpci.a
Index: uspace/srv/vfs/Makefile
===================================================================
--- uspace/srv/vfs/Makefile	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/vfs/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006 Martin Decky
-# Copyright (c) 2008 Jakub Jermar
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -28,54 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = vfs
-SOURCES = \
-	vfs.c \
-	vfs_node.c \
-	vfs_file.c \
-	vfs_ops.c \
-	vfs_lookup.c \
-	vfs_register.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/srv/vfs/Makefile.build
===================================================================
--- uspace/srv/vfs/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/vfs/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	vfs.c \
+	vfs_node.c \
+	vfs_file.c \
+	vfs_ops.c \
+	vfs_lookup.c \
+	vfs_register.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/srv/vfs/Makefile.common
===================================================================
--- uspace/srv/vfs/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/srv/vfs/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = vfs
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/vfs/vfs.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -126,4 +126,6 @@
 			vfs_sync(callid, &call);
 			break;
+		case VFS_IN_DUP:
+			vfs_dup(callid, &call);
 		default:
 			ipc_answer_0(callid, ENOTSUP);
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/vfs/vfs.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -186,5 +186,6 @@
 extern bool vfs_files_init(void);
 extern vfs_file_t *vfs_file_get(int);
-extern int vfs_fd_alloc(void);
+extern int vfs_fd_assign(vfs_file_t *file, int fd);
+extern int vfs_fd_alloc(bool desc);
 extern int vfs_fd_free(int);
 
@@ -200,4 +201,5 @@
 extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
 extern void vfs_sync(ipc_callid_t, ipc_call_t *);
+extern void vfs_dup(ipc_callid_t, ipc_call_t *);
 extern void vfs_close(ipc_callid_t, ipc_call_t *);
 extern void vfs_read(ipc_callid_t, ipc_call_t *);
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/vfs/vfs_file.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -76,8 +76,11 @@
 /** Allocate a file descriptor.
  *
- * @return		First available file descriptor or a negative error
- *			code.
- */
-int vfs_fd_alloc(void)
+ * @param desc If true, look for an available file descriptor
+ *             in a descending order.
+ *
+ * @return First available file descriptor or a negative error
+ *         code.
+ */
+int vfs_fd_alloc(bool desc)
 {
 	if (!vfs_files_init())
@@ -85,5 +88,10 @@
 	
 	unsigned int i;
-	for (i = 0; i < MAX_OPEN_FILES; i++) {
+	if (desc)
+		i = MAX_OPEN_FILES - 1;
+	else
+		i = 0;
+	
+	while (true) {
 		if (!files[i]) {
 			files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
@@ -96,4 +104,16 @@
 			return (int) i;
 		}
+		
+		if (desc) {
+			if (i == 0)
+				break;
+			
+			i--;
+		} else {
+			if (i == MAX_OPEN_FILES - 1)
+				break;
+			
+			i++;
+		}
 	}
 	
@@ -118,4 +138,27 @@
 	vfs_file_delref(files[fd]);
 	files[fd] = NULL;
+	
+	return EOK;
+}
+
+/** Assign a file to a file descriptor.
+ *
+ * @param file File to assign.
+ * @param fd   File descriptor to assign to.
+ *
+ * @return EOK on success or EINVAL if fd is an invalid or already
+ *         used file descriptor.
+ *
+ */
+int vfs_fd_assign(vfs_file_t *file, int fd)
+{
+	if (!vfs_files_init())
+		return ENOMEM;
+	
+	if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (files[fd] != NULL))
+		return EINVAL;
+	
+	files[fd] = file;
+	vfs_file_addref(files[fd]);
 	
 	return EOK;
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/vfs/vfs_lookup.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -209,5 +209,4 @@
 	    (ipcarg_t) result->triplet.index, &answer);
 	
-	
 	ipcarg_t rc;
 	async_wait_for(req, &rc);
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/vfs/vfs_ops.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -125,5 +125,5 @@
 			    (ipcarg_t) dev_handle, &answer);
 			/* send the mount options */
-			rc = ipc_data_write_start(phone, (void *)opts,
+			rc = async_data_write_start(phone, (void *)opts,
 			    str_size(opts));
 			if (rc != EOK) {
@@ -207,5 +207,5 @@
 	
 	/* send the mount options */
-	rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
+	rc = async_data_write_start(phone, (void *)opts, str_size(opts));
 	if (rc != EOK) {
 		async_wait_for(msg, NULL);
@@ -268,5 +268,5 @@
 	ipc_callid_t callid;
 	size_t size;
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -290,5 +290,5 @@
 	
 	/* Deliver the mount point. */
-	ipcarg_t retval = ipc_data_write_finalize(callid, mp, size);
+	ipcarg_t retval = async_data_write_finalize(callid, mp, size);
 	if (retval != EOK) {
 		ipc_answer_0(rid, retval);
@@ -299,5 +299,5 @@
 	
 	/* Now we expect to receive the mount options. */
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -324,5 +324,5 @@
 
 	/* Deliver the mount options. */
-	retval = ipc_data_write_finalize(callid, opts, size);
+	retval = async_data_write_finalize(callid, opts, size);
 	if (retval != EOK) {
 		ipc_answer_0(rid, retval);
@@ -337,5 +337,5 @@
 	 * system.
 	 */
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -370,5 +370,5 @@
 	
 	/* Deliver the file system name. */
-	retval = ipc_data_write_finalize(callid, fs_name, size);
+	retval = async_data_write_finalize(callid, fs_name, size);
 	if (retval != EOK) {
 		ipc_answer_0(rid, retval);
@@ -469,5 +469,5 @@
 	
 	ipc_callid_t callid;
-	if (!ipc_data_write_receive(&callid, &len)) {
+	if (!async_data_write_receive(&callid, &len)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -483,5 +483,5 @@
 	
 	int rc;
-	if ((rc = ipc_data_write_finalize(callid, path, len))) {
+	if ((rc = async_data_write_finalize(callid, path, len))) {
 		ipc_answer_0(rid, rc);
 		free(path);
@@ -543,5 +543,5 @@
 	 * structure.
 	 */
-	int fd = vfs_fd_alloc();
+	int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
 	if (fd < 0) {
 		vfs_node_put(node);
@@ -620,5 +620,5 @@
 	 * structure.
 	 */
-	int fd = vfs_fd_alloc();
+	int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
 	if (fd < 0) {
 		vfs_node_put(node);
@@ -679,4 +679,39 @@
 }
 
+static int vfs_close_internal(vfs_file_t *file)
+{
+	/*
+	 * Lock the open file structure so that no other thread can manipulate
+	 * the same open file at a time.
+	 */
+	fibril_mutex_lock(&file->lock);
+	
+	if (file->refcnt <= 1) {
+		/* Only close the file on the destination FS server
+		   if there are no more file descriptors (except the
+		   present one) pointing to this file. */
+		
+		int fs_phone = vfs_grab_phone(file->node->fs_handle);
+		
+		/* Make a VFS_OUT_CLOSE request at the destination FS server. */
+		aid_t msg;
+		ipc_call_t answer;
+		msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
+		    file->node->index, &answer);
+		
+		/* Wait for reply from the FS server. */
+		ipcarg_t rc;
+		async_wait_for(msg, &rc);
+		
+		vfs_release_phone(fs_phone);
+		fibril_mutex_unlock(&file->lock);
+		
+		return IPC_GET_ARG1(answer);
+	}
+	
+	fibril_mutex_unlock(&file->lock);
+	return EOK;
+}
+
 void vfs_close(ipc_callid_t rid, ipc_call_t *request)
 {
@@ -690,30 +725,10 @@
 	}
 	
-	/*
-	 * Lock the open file structure so that no other thread can manipulate
-	 * the same open file at a time.
-	 */
-	fibril_mutex_lock(&file->lock);
-	int fs_phone = vfs_grab_phone(file->node->fs_handle);
-	
-	/* Make a VFS_OUT_CLOSE request at the destination FS server. */
-	aid_t msg;
-	ipc_call_t answer;
-	msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
-	    file->node->index, &answer);
-
-	/* Wait for reply from the FS server. */
-	ipcarg_t rc;
-	async_wait_for(msg, &rc);
-
-	vfs_release_phone(fs_phone);
-	fibril_mutex_unlock(&file->lock);
-	
-	int retval = IPC_GET_ARG1(answer);
-	if (retval != EOK)
-		ipc_answer_0(rid, retval);
-	
-	retval = vfs_fd_free(fd);
-	ipc_answer_0(rid, retval);
+	int ret = vfs_close_internal(file);
+	if (ret != EOK)
+		ipc_answer_0(rid, ret);
+	
+	ret = vfs_fd_free(fd);
+	ipc_answer_0(rid, ret);
 }
 
@@ -747,7 +762,7 @@
 	int res;
 	if (read)
-		res = ipc_data_read_receive(&callid, NULL);
+		res = async_data_read_receive(&callid, NULL);
 	else 
-		res = ipc_data_write_receive(&callid, NULL);
+		res = async_data_write_receive(&callid, NULL);
 	if (!res) {
 		ipc_answer_0(callid, EINVAL);
@@ -934,5 +949,4 @@
 {
 	int fd = IPC_GET_ARG1(*request);
-	size_t size = IPC_GET_ARG2(*request);
 	ipcarg_t rc;
 
@@ -944,5 +958,5 @@
 
 	ipc_callid_t callid;
-	if (!ipc_data_read_receive(&callid, NULL)) {
+	if (!async_data_read_receive(&callid, NULL)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -970,5 +984,5 @@
 	ipc_callid_t callid;
 
-	if (!ipc_data_write_receive(&callid, &len)) {
+	if (!async_data_write_receive(&callid, &len)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -982,5 +996,5 @@
 	}
 	int rc;
-	if ((rc = ipc_data_write_finalize(callid, path, len))) {
+	if ((rc = async_data_write_finalize(callid, path, len))) {
 		ipc_answer_0(rid, rc);
 		free(path);
@@ -989,5 +1003,5 @@
 	path[len] = '\0';
 
-	if (!ipc_data_read_receive(&callid, NULL)) {
+	if (!async_data_read_receive(&callid, NULL)) {
 		free(path);
 		ipc_answer_0(callid, EINVAL);
@@ -1038,5 +1052,5 @@
 	ipc_callid_t callid;
 
-	if (!ipc_data_write_receive(&callid, &len)) {
+	if (!async_data_write_receive(&callid, &len)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -1050,5 +1064,5 @@
 	}
 	int rc;
-	if ((rc = ipc_data_write_finalize(callid, path, len))) {
+	if ((rc = async_data_write_finalize(callid, path, len))) {
 		ipc_answer_0(rid, rc);
 		free(path);
@@ -1075,5 +1089,5 @@
 	ipc_callid_t callid;
 
-	if (!ipc_data_write_receive(&callid, &len)) {
+	if (!async_data_write_receive(&callid, &len)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -1087,5 +1101,5 @@
 	}
 	int rc;
-	if ((rc = ipc_data_write_finalize(callid, path, len))) {
+	if ((rc = async_data_write_finalize(callid, path, len))) {
 		ipc_answer_0(rid, rc);
 		free(path);
@@ -1126,5 +1140,5 @@
 
 	/* Retrieve the old path. */
-	if (!ipc_data_write_receive(&callid, &olen)) {
+	if (!async_data_write_receive(&callid, &olen)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -1137,5 +1151,5 @@
 		return;
 	}
-	if ((rc = ipc_data_write_finalize(callid, old, olen))) {
+	if ((rc = async_data_write_finalize(callid, old, olen))) {
 		ipc_answer_0(rid, rc);
 		free(old);
@@ -1145,5 +1159,5 @@
 	
 	/* Retrieve the new path. */
-	if (!ipc_data_write_receive(&callid, &nlen)) {
+	if (!async_data_write_receive(&callid, &nlen)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -1158,5 +1172,5 @@
 		return;
 	}
-	if ((rc = ipc_data_write_finalize(callid, new, nlen))) {
+	if ((rc = async_data_write_finalize(callid, new, nlen))) {
 		ipc_answer_0(rid, rc);
 		free(old);
@@ -1311,4 +1325,55 @@
 }
 
+void vfs_dup(ipc_callid_t rid, ipc_call_t *request)
+{
+	int oldfd = IPC_GET_ARG1(*request);
+	int newfd = IPC_GET_ARG2(*request);
+	
+	/* Lookup the file structure corresponding to oldfd. */
+	vfs_file_t *oldfile = vfs_file_get(oldfd);
+	if (!oldfile) {
+		ipc_answer_0(rid, EBADF);
+		return;
+	}
+	
+	/* If the file descriptors are the same, do nothing. */
+	if (oldfd == newfd) {
+		ipc_answer_1(rid, EOK, newfd);
+		return;
+	}
+	
+	/*
+	 * Lock the open file structure so that no other thread can manipulate
+	 * the same open file at a time.
+	 */
+	fibril_mutex_lock(&oldfile->lock);
+	
+	/* Lookup an open file structure possibly corresponding to newfd. */
+	vfs_file_t *newfile = vfs_file_get(newfd);
+	if (newfile) {
+		/* Close the originally opened file. */
+		int ret = vfs_close_internal(newfile);
+		if (ret != EOK) {
+			ipc_answer_0(rid, ret);
+			return;
+		}
+		
+		ret = vfs_fd_free(newfd);
+		if (ret != EOK) {
+			ipc_answer_0(rid, ret);
+			return;
+		}
+	}
+	
+	/* Assign the old file to newfd. */
+	int ret = vfs_fd_assign(oldfile, newfd);
+	fibril_mutex_unlock(&oldfile->lock);
+	
+	if (ret != EOK)
+		ipc_answer_0(rid, ret);
+	else
+		ipc_answer_1(rid, EOK, newfd);
+}
+
 /**
  * @}
Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision fcbd1be0f221add9330a1d6c130818a501791166)
+++ uspace/srv/vfs/vfs_register.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -122,5 +122,5 @@
 	 * VFS info structure from the client FS.
 	 */
-	if (!ipc_data_write_receive(&callid, &size)) {
+	if (!async_data_write_receive(&callid, &size)) {
 		/*
 		 * The client doesn't obey the same protocol as we do.
@@ -163,5 +163,5 @@
 	fibril_mutex_initialize(&fs_info->phone_lock);
 		
-	rc = ipc_data_write_finalize(callid, &fs_info->vfs_info, size);
+	rc = async_data_write_finalize(callid, &fs_info->vfs_info, size);
 	if (rc != EOK) {
 		dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n",
@@ -229,5 +229,5 @@
 	 */
 
-	if (!ipc_share_in_receive(&callid, &size)) {
+	if (!async_share_in_receive(&callid, &size)) {
 		dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
 		list_remove(&fs_info->fs_link);
@@ -257,5 +257,5 @@
 	 * Commit to read-only sharing the PLB with the client.
 	 */
-	(void) ipc_share_in_finalize(callid, plb,
+	(void) async_share_in_finalize(callid, plb,
 	    AS_AREA_READ | AS_AREA_CACHEABLE);
 
