Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ HelenOS.config	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -31,4 +31,5 @@
 
 % Platform
+@ "abs32le" abstract 32-bit little endian
 @ "amd64" AMD64/Intel EM64T (PC)
 @ "arm32" ARM 32-bit
@@ -91,4 +92,8 @@
 
 % Kernel architecture
+@ "abs32le"
+! [PLATFORM=abs32le] KARCH (choice)
+
+% Kernel architecture
 @ "amd64"
 ! [PLATFORM=amd64] KARCH (choice)
@@ -130,4 +135,8 @@
 
 % User space architecture
+@ "abs32le"
+! [PLATFORM=abs32le] UARCH (choice)
+
+% User space architecture
 @ "amd64"
 ! [PLATFORM=amd64] UARCH (choice)
@@ -167,4 +176,8 @@
 
 ## Mapping between platform and boot architecture
+
+% Boot architecture
+@ "abs32le"
+! [PLATFORM=abs32le] BARCH (choice)
 
 % Boot architecture
@@ -243,4 +256,9 @@
 ! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice)
 
+% Compiler
+@ "gcc_native" GNU C Compiler (native)
+@ "clang" Clang
+! [PLATFORM=abs32le] COMPILER (choice)
+
 
 ## Kernel configuration
@@ -259,5 +277,5 @@
 
 % Hierarchical page tables support
-! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y)
+! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y)
 
 % Page hash table support
@@ -292,5 +310,5 @@
 
 % Support for SMP
-! [(PLATFORM=ia32&PROCESSOR!=athlon_xp)|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ia64|(PLATFORM=mips32&MACHINE=msim)] CONFIG_SMP (y/n)
+! [(PLATFORM=ia32&PROCESSOR!=athlon_xp)|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ia64|(PLATFORM=mips32&MACHINE=msim)|PLATFORM=abs32le] CONFIG_SMP (y/n)
 
 % Debug build
@@ -486,2 +504,5 @@
 % Mount /data on startup
 ! [CONFIG_START_BD=y] CONFIG_MOUNT_DATA (n/y)
+
+% Write core files
+! CONFIG_WRITE_CORE_FILES (n/y)
Index: Makefile
===================================================================
--- Makefile	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -59,5 +59,5 @@
 
 distclean: clean
-	rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc
+	rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc tools/checkers/*.pyc
 
 clean:
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ boot/Makefile.common	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -56,5 +56,6 @@
 	$(USPACEDIR)/srv/fs/devfs/devfs \
 	$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
-	$(USPACEDIR)/srv/fs/fat/fat
+	$(USPACEDIR)/srv/fs/fat/fat \
+	$(USPACEDIR)/srv/taskmon/taskmon
 
 RD_APPS = \
@@ -65,4 +66,5 @@
 	$(USPACEDIR)/app/mkfat/mkfat \
 	$(USPACEDIR)/app/redir/redir \
+	$(USPACEDIR)/app/taskdump/taskdump \
 	$(USPACEDIR)/app/tester/tester \
 	$(USPACEDIR)/app/tetris/tetris \
Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ boot/arch/amd64/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -33,5 +33,5 @@
 	$(USPACEDIR)/srv/hw/char/i8042/i8042 \
 	$(USPACEDIR)/srv/hw/bus/pci/pci \
-	$(USPACEDIR)/srv/hid/c_mouse/c_mouse
+	$(USPACEDIR)/srv/hid/char_mouse/char_ms
 
 MODULES := $(notdir $(COMPONENTS))
Index: boot/arch/ia64/loader/Makefile.common
===================================================================
--- boot/arch/ia64/loader/Makefile.common	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ boot/arch/ia64/loader/Makefile.common	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -49,4 +49,4 @@
 	RD_SRVS += \
 		$(USPACEDIR)/srv/hw/char/i8042/i8042 \
-		$(USPACEDIR)/srv/hid/c_mouse/c_mouse
+		$(USPACEDIR)/srv/hid/char_mouse/char_ms
 endif
Index: boot/arch/ppc32/loader/Makefile.common
===================================================================
--- boot/arch/ppc32/loader/Makefile.common	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ boot/arch/ppc32/loader/Makefile.common	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -43,2 +43,6 @@
 KERNELDIR = ../../../../kernel
 USPACEDIR = ../../../../uspace
+
+RD_SRVS += \
+	$(USPACEDIR)/srv/hid/adb_mouse/adb_ms \
+	$(USPACEDIR)/srv/hw/bus/cuda_adb/cuda_adb
Index: defaults/special/Makefile.config
===================================================================
--- defaults/special/Makefile.config	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ defaults/special/Makefile.config	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,29 @@
+# RAM disk format
+RDFMT = fat
+
+# Compiler
+COMPILER = gcc_native
+
+# Support for SMP
+CONFIG_SMP = y
+
+# Debug build
+CONFIG_DEBUG = y
+
+# Support for userspace debuggers
+CONFIG_UDEBUG = y
+
+# Kernel console support
+CONFIG_KCONSOLE = y
+
+# Kernel symbol information
+CONFIG_SYMTAB = y
+
+# Detailed kernel logging
+CONFIG_LOG = n
+
+# Compile kernel tests
+CONFIG_TEST = y
+
+# Load disk drivers on startup
+CONFIG_START_BD = n
Index: defaults/special/abs32le/Makefile.config
===================================================================
--- defaults/special/abs32le/Makefile.config	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ defaults/special/abs32le/Makefile.config	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,2 @@
+# Platform
+PLATFORM = abs32le
Index: kernel/arch/abs32le/Makefile.inc
===================================================================
--- kernel/arch/abs32le/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2010 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
+#
+
+BITS = 32
+ENDIANESS = LE
+
+ARCH_SOURCES = \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/proc/scheduler.c \
+	arch/$(KARCH)/src/proc/task.c \
+	arch/$(KARCH)/src/proc/thread.c \
+	arch/$(KARCH)/src/abs32le.c \
+	arch/$(KARCH)/src/userspace.c \
+	arch/$(KARCH)/src/cpu/cpu.c \
+	arch/$(KARCH)/src/ddi/ddi.c \
+	arch/$(KARCH)/src/smp/smp.c \
+	arch/$(KARCH)/src/mm/as.c \
+	arch/$(KARCH)/src/mm/frame.c \
+	arch/$(KARCH)/src/mm/page.c \
+	arch/$(KARCH)/src/mm/tlb.c
Index: kernel/arch/abs32le/_link.ld.in
===================================================================
--- kernel/arch/abs32le/_link.ld.in	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/_link.ld.in	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,39 @@
+SECTIONS {
+	.text : {
+		ktext_start = .;
+		*(.text);
+		ktext_end = .;
+	}
+	.data : {
+		kdata_start = .;
+		*(.data);                       /* initialized data */
+		hardcoded_ktext_size = .;
+		LONG(ktext_end - ktext_start);
+		hardcoded_kdata_size = .;
+		LONG(kdata_end - kdata_start);
+		hardcoded_load_address = .;
+		LONG(hardcoded_load_address);
+		*(.bss);                        /* uninitialized static variables */
+		*(COMMON);                      /* global variables */
+		
+		*(.rodata*);
+		*(.sdata);
+		*(.reginfo);
+		. = ALIGN(8);
+		symbol_table = .;
+		*(symtab.*);
+	}
+	.sbss : {
+		*(.sbss);
+		*(.scommon);
+	}
+	
+	kdata_end = .;
+	
+	/DISCARD/ : {
+		*(.mdebug*);
+		*(.pdr);
+		*(.comment);
+		*(.note);
+	}
+}
Index: kernel/arch/abs32le/include/arch.h
===================================================================
--- kernel/arch/abs32le/include/arch.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/arch.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_ARCH_H_
+#define KERN_abs32le_ARCH_H_
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/asm.h
===================================================================
--- kernel/arch/abs32le/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_ASM_H_
+#define KERN_abs32le_ASM_H_
+
+#include <arch/types.h>
+#include <typedefs.h>
+#include <config.h>
+
+extern void interrupt_handlers(void);
+
+extern void enable_l_apic_in_msr(void);
+
+
+extern void asm_delay_loop(uint32_t);
+extern void asm_fake_loop(uint32_t);
+
+
+static inline __attribute__((noreturn)) void cpu_halt(void)
+{
+	/* On real hardware this should stop processing further
+	   instructions on the CPU (and possibly putting it into
+	   low-power mode) without any possibility of exitting
+	   this function. */
+	
+	while (true);
+}
+
+static inline void cpu_sleep(void)
+{
+	/* On real hardware this should put the CPU into low-power
+	   mode. However, the CPU is free to continue processing
+	   futher instructions any time. The CPU also wakes up
+	   upon an interrupt. */
+}
+
+static inline void pio_write_8(ioport8_t *port, uint8_t val)
+{
+}
+
+/** Word to port
+ *
+ * Output word to port
+ *
+ * @param port Port to write to
+ * @param val Value to write
+ *
+ */
+static inline void pio_write_16(ioport16_t *port, uint16_t val)
+{
+}
+
+/** Double word to port
+ *
+ * Output double word to port
+ *
+ * @param port Port to write to
+ * @param val Value to write
+ *
+ */
+static inline void pio_write_32(ioport32_t *port, uint32_t val)
+{
+}
+
+/** Byte from port
+ *
+ * Get byte from port
+ *
+ * @param port Port to read from
+ * @return Value read
+ *
+ */
+static inline uint8_t pio_read_8(ioport8_t *port)
+{
+	return 0;
+}
+
+/** Word from port
+ *
+ * Get word from port
+ *
+ * @param port Port to read from
+ * @return Value read
+ *
+ */
+static inline uint16_t pio_read_16(ioport16_t *port)
+{
+	return 0;
+}
+
+/** Double word from port
+ *
+ * Get double word from port
+ *
+ * @param port Port to read from
+ * @return Value read
+ *
+ */
+static inline uint32_t pio_read_32(ioport32_t *port)
+{
+	return 0;
+}
+
+static inline ipl_t interrupts_enable(void)
+{
+	/* On real hardware this unconditionally enables preemption
+	   by internal and external interrupts.
+	   
+	   The return value stores the previous interrupt level. */
+	
+	return 0;
+}
+
+static inline ipl_t interrupts_disable(void)
+{
+	/* On real hardware this disables preemption by the usual
+	   set of internal and external interrupts. This does not
+	   apply to special non-maskable interrupts and sychronous
+	   CPU exceptions.
+	   
+	   The return value stores the previous interrupt level. */
+	
+	return 0;
+}
+
+static inline void interrupts_restore(ipl_t ipl)
+{
+	/* On real hardware this either enables or disables preemption
+	   according to the interrupt level value from the argument. */
+}
+
+static inline ipl_t interrupts_read(void)
+{
+	/* On real hardware the return value stores the current interrupt
+	   level. */
+	
+	return 0;
+}
+
+static inline uintptr_t get_stack_base(void)
+{
+	/* On real hardware this returns the address of the bottom
+	   of the current CPU stack. The the_t structure is stored
+	   on the bottom of stack and this is used to identify the
+	   current CPU, current task, current thread and current
+	   address space. */
+	
+	return 0;
+}
+
+static inline uintptr_t *get_ip()
+{
+	/* On real hardware this returns the current instruction
+	   pointer value. The value certainly changes with each
+	   instruction, but it can be still used to identify
+	   a specific function. */
+	
+	return 0;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/atomic.h
===================================================================
--- kernel/arch/abs32le/include/atomic.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/atomic.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_ATOMIC_H_
+#define KERN_abs32le_ATOMIC_H_
+
+#include <arch/types.h>
+#include <arch/barrier.h>
+#include <preemption.h>
+
+static inline void atomic_inc(atomic_t *val) {
+	/* On real hardware the increment has to be done
+	   as an atomic action. */
+	
+	val->count++;
+}
+
+static inline void atomic_dec(atomic_t *val) {
+	/* On real hardware the decrement has to be done
+	   as an atomic action. */
+	
+	val->count++;
+}
+
+static inline long atomic_postinc(atomic_t *val)
+{
+	/* On real hardware both the storing of the previous
+	   value and the increment have to be done as a single
+	   atomic action. */
+	
+	long prev = val->count;
+	
+	val->count++;
+	return prev;
+}
+
+static inline long atomic_postdec(atomic_t *val)
+{
+	/* On real hardware both the storing of the previous
+	   value and the decrement have to be done as a single
+	   atomic action. */
+	
+	long prev = val->count;
+	
+	val->count--;
+	return prev;
+}
+
+#define atomic_preinc(val)  (atomic_postinc(val) + 1)
+#define atomic_predec(val)  (atomic_postdec(val) - 1)
+
+static inline uint32_t test_and_set(atomic_t *val) {
+	uint32_t v;
+	
+	asm volatile (
+		"movl $1, %[v]\n"
+		"xchgl %[v], %[count]\n"
+		: [v] "=r" (v), [count] "+m" (val->count)
+	);
+	
+	return v;
+}
+
+/** ia32 specific fast spinlock */
+static inline void atomic_lock_arch(atomic_t *val)
+{
+	uint32_t tmp;
+	
+	preemption_disable();
+	asm volatile (
+		"0:\n"
+		"pause\n"        /* Pentium 4's HT love this instruction */
+		"mov %[count], %[tmp]\n"
+		"testl %[tmp], %[tmp]\n"
+		"jnz 0b\n"       /* lightweight looping on locked spinlock */
+		
+		"incl %[tmp]\n"  /* now use the atomic operation */
+		"xchgl %[count], %[tmp]\n"
+		"testl %[tmp], %[tmp]\n"
+		"jnz 0b\n"
+		: [count] "+m" (val->count), [tmp] "=&r" (tmp)
+	);
+	/*
+	 * Prevent critical section code from bleeding out this way up.
+	 */
+	CS_ENTER_BARRIER();
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/barrier.h
===================================================================
--- kernel/arch/abs32le/include/barrier.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/barrier.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,99 @@
+/*
+ * 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_BARRIER_H_
+#define KERN_ia32_BARRIER_H_
+
+/*
+ * NOTE:
+ * No barriers for critical section (i.e. spinlock) on IA-32 are needed:
+ * - spinlock_lock() and spinlock_trylock() use serializing XCHG instruction
+ * - writes cannot pass reads on IA-32 => spinlock_unlock() needs no barriers
+ */
+
+/*
+ * Provisions are made to prevent compiler from reordering instructions itself.
+ */
+
+#define CS_ENTER_BARRIER()  asm volatile ("" ::: "memory")
+#define CS_LEAVE_BARRIER()  asm volatile ("" ::: "memory")
+
+static inline void cpuid_serialization(void)
+{
+	asm volatile (
+		"xorl %%eax, %%eax\n"
+		"cpuid\n"
+		::: "eax", "ebx", "ecx", "edx", "memory"
+	);
+}
+
+#if defined(CONFIG_FENCES_P4)
+	#define memory_barrier()  asm volatile ("mfence\n" ::: "memory")
+	#define read_barrier()    asm volatile ("lfence\n" ::: "memory")
+	#ifdef CONFIG_WEAK_MEMORY
+		#define write_barrier()  asm volatile ("sfence\n" ::: "memory")
+	#else
+		#define write_barrier()  asm volatile ("" ::: "memory");
+	#endif
+#elif defined(CONFIG_FENCES_P3)
+	#define memory_barrier()  cpuid_serialization()
+	#define read_barrier()    cpuid_serialization()
+	#ifdef CONFIG_WEAK_MEMORY
+		#define write_barrier()  asm volatile ("sfence\n" ::: "memory")
+	#else
+		#define write_barrier()  asm volatile ("" ::: "memory");
+	#endif
+#else
+	#define memory_barrier()  cpuid_serialization()
+	#define read_barrier()    cpuid_serialization()
+	#ifdef CONFIG_WEAK_MEMORY
+		#define write_barrier()  cpuid_serialization()
+	#else
+		#define write_barrier()  asm volatile ("" ::: "memory");
+	#endif
+#endif
+
+/*
+ * On ia32, the hardware takes care about instruction and data cache coherence,
+ * even on SMP systems.  We issue a write barrier to be sure that writes
+ * queueing in the store buffer drain to the memory (even though it would be
+ * sufficient for them to drain to the D-cache).
+ */
+#define smc_coherence(a)           write_barrier()
+#define smc_coherence_block(a, l)  write_barrier()
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/context.h
===================================================================
--- kernel/arch/abs32le/include/context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_CONTEXT_H_
+#define KERN_abs32le_CONTEXT_H_
+
+#define STACK_ITEM_SIZE  4
+#define SP_DELTA         0
+
+#define context_set(ctx, pc, stack, size) \
+    context_set_generic(ctx, pc, stack, size)
+
+/*
+ * On real hardware this stores the registers which
+ * need to be preserved across function calls.
+ */
+typedef struct {
+	uintptr_t sp;
+	uintptr_t pc;
+	ipl_t ipl;
+} context_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/context_offset.h
===================================================================
--- kernel/arch/abs32le/include/context_offset.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/context_offset.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_CONTEXT_OFFSET_H_
+#define KERN_abs32le_CONTEXT_OFFSET_H_
+
+#define OFFSET_PC  0x00
+
+#ifdef KERNEL
+	#define OFFSET_IPL 0x04
+#else
+	#define OFFSET_TLS 0x04
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/cpu.h
===================================================================
--- kernel/arch/abs32le/include/cpu.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/cpu.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_CPU_H_
+#define KERN_abs32le_CPU_H_
+
+/*
+ * On real hardware this structure stores
+ * information specific to the current
+ * CPU model.
+ */
+typedef struct {
+} cpu_arch_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/cycle.h
===================================================================
--- kernel/arch/abs32le/include/cycle.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/cycle.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_CYCLE_H_
+#define KERN_abs32le_CYCLE_H_
+
+static inline uint64_t get_cycle(void)
+{
+	return 0;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/debug.h
===================================================================
--- kernel/arch/abs32le/include/debug.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/debug.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 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 abs32ledebug
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_DEBUG_H_
+#define KERN_abs32le_DEBUG_H_
+
+#include <arch/asm.h>
+
+#define HERE  get_ip()
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/elf.h
===================================================================
--- kernel/arch/abs32le/include/elf.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/elf.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_ELF_H_
+#define KERN_abs32le_ELF_H_
+
+#define ELF_MACHINE        EM_NO
+#define ELF_DATA_ENCODING  ELFDATA2LSB
+#define ELF_CLASS          ELFCLASS32
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/faddr.h
===================================================================
--- kernel/arch/abs32le/include/faddr.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/faddr.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_FADDR_H_
+#define KERN_abs32le_FADDR_H_
+
+#include <arch/types.h>
+
+#define FADDR(fptr)  ((uintptr_t) (fptr))
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/fpu_context.h
===================================================================
--- kernel/arch/abs32le/include/fpu_context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/fpu_context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_FPU_CONTEXT_H_
+#define KERN_abs32le_FPU_CONTEXT_H_
+
+#include <arch/types.h>
+
+#define FPU_CONTEXT_ALIGN  16
+
+/*
+ * On real hardware this stores the FPU registers
+ * which are part of the CPU context.
+ */
+typedef struct {
+} fpu_context_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/interrupt.h
===================================================================
--- kernel/arch/abs32le/include/interrupt.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/interrupt.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2010 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 abs32leinterrupt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_INTERRUPT_H_
+#define KERN_abs32le_INTERRUPT_H_
+
+#include <arch/types.h>
+
+#define IVT_ITEMS  0
+#define IVT_FIRST  0
+
+#define VECTOR_TLB_SHOOTDOWN_IPI  0
+
+/*
+ * On real hardware this stores the registers which
+ * need to be preserved during interupts.
+ */
+typedef struct istate {
+	uintptr_t ip;
+	uintptr_t fp;
+	uint32_t stack[];
+} istate_t;
+
+static inline int istate_from_uspace(istate_t *istate)
+{
+	/* On real hardware this checks whether the interrupted
+	   context originated from user space. */
+	
+	return !(istate->ip & 0x80000000);
+}
+
+static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+{
+	/* On real hardware this sets the instruction pointer. */
+	
+	istate->ip = retaddr;
+}
+
+static inline unative_t istate_get_pc(istate_t *istate)
+{
+	/* On real hardware this returns the instruction pointer. */
+	
+	return istate->ip;
+}
+
+static inline unative_t istate_get_fp(istate_t *istate)
+{
+	/* On real hardware this returns the frame pointer. */
+	
+	return istate->fp;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/memstr.h
===================================================================
--- kernel/arch/abs32le/include/memstr.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/memstr.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_MEMSTR_H_
+#define KERN_abs32le_MEMSTR_H_
+
+#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
+
+extern void memsetw(void *, size_t, uint16_t);
+extern void memsetb(void *, size_t, uint8_t);
+
+extern int memcmp(const void *, const void *, size_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/mm/as.h
===================================================================
--- kernel/arch/abs32le/include/mm/as.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/mm/as.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010 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 abs32lemm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_AS_H_
+#define KERN_abs32le_AS_H_
+
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+
+#define KERNEL_ADDRESS_SPACE_START_ARCH  ((unsigned long) 0x80000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    ((unsigned long) 0xffffffff)
+#define USER_ADDRESS_SPACE_START_ARCH    ((unsigned long) 0x00000000)
+#define USER_ADDRESS_SPACE_END_ARCH      ((unsigned long) 0x7fffffff)
+
+#define USTACK_ADDRESS_ARCH  (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))
+
+typedef struct {
+} as_arch_t;
+
+#include <genarch/mm/as_pt.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_install_arch(as)
+#define as_deinstall_arch(as)
+#define as_invalidate_translation_cache(as, page, cnt)
+
+extern void as_arch_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/mm/asid.h
===================================================================
--- kernel/arch/abs32le/include/mm/asid.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/mm/asid.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 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 abc32lemm
+ * @{
+ */
+
+#ifndef KERN_abs32le_ASID_H_
+#define KERN_abs32le_ASID_H_
+
+#include <arch/types.h>
+
+typedef uint32_t asid_t;
+
+#define ASID_MAX_ARCH  3
+
+#define asid_get()      (ASID_START + 1)
+#define asid_put(asid)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/mm/frame.h
===================================================================
--- kernel/arch/abs32le/include/mm/frame.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/mm/frame.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010 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 abs32lemm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_FRAME_H_
+#define KERN_abs32le_FRAME_H_
+
+#define FRAME_WIDTH  12  /* 4K */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
+
+#ifdef KERNEL
+#ifndef __ASM__
+
+#include <arch/types.h>
+
+extern void frame_arch_init(void);
+extern void physmem_print(void);
+
+#endif /* __ASM__ */
+#endif /* KERNEL */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/mm/page.h
===================================================================
--- kernel/arch/abs32le/include/mm/page.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/mm/page.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2010 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 abs32lemm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_PAGE_H_
+#define KERN_abs32le_PAGE_H_
+
+#include <arch/mm/frame.h>
+
+#define PAGE_WIDTH  FRAME_WIDTH
+#define PAGE_SIZE   FRAME_SIZE
+
+#ifdef KERNEL
+
+#ifndef __ASM__
+	#define KA2PA(x)  (((uintptr_t) (x)) - 0x80000000)
+	#define PA2KA(x)  (((uintptr_t) (x)) + 0x80000000)
+#else
+	#define KA2PA(x)  ((x) - 0x80000000)
+	#define PA2KA(x)  ((x) + 0x80000000)
+#endif
+
+/*
+ * This is an example of 2-level page tables (PTL1 and PTL2 are left out)
+ * on top of the generic 4-level page table interface.
+ */
+
+/* Number of entries in each level. */
+#define PTL0_ENTRIES_ARCH  1024
+#define PTL1_ENTRIES_ARCH  0
+#define PTL2_ENTRIES_ARCH  0
+#define PTL3_ENTRIES_ARCH  1024
+
+/* Page table sizes for each level. */
+#define PTL0_SIZE_ARCH  ONE_FRAME
+#define PTL1_SIZE_ARCH  0
+#define PTL2_SIZE_ARCH  0
+#define PTL3_SIZE_ARCH  ONE_FRAME
+
+/* Macros calculating indices for each level. */
+#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 22) & 0x3ff)
+#define PTL1_INDEX_ARCH(vaddr)  0
+#define PTL2_INDEX_ARCH(vaddr)  0
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x3ff)
+
+/* Get PTE address accessors for each level. */
+#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
+	((pte_t *) ((((pte_t *) (ptl0))[(i)].frame_address) << 12))
+#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
+	(ptl1)
+#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
+	(ptl2)
+#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
+	((uintptr_t) ((((pte_t *) (ptl3))[(i)].frame_address) << 12))
+
+/* Set PTE address accessors for each level. */
+#define SET_PTL0_ADDRESS_ARCH(ptl0)
+#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
+	(((pte_t *) (ptl0))[(i)].frame_address = (a) >> 12)
+#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
+#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
+#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
+	(((pte_t *) (ptl3))[(i)].frame_address = (a) >> 12)
+
+/* Get PTE flags accessors for each level. */
+#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
+	get_pt_flags((pte_t *) (ptl0), (size_t) (i))
+#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
+	PAGE_PRESENT
+#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
+	PAGE_PRESENT
+#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
+	get_pt_flags((pte_t *) (ptl3), (size_t) (i))
+
+/* Set PTE flags accessors for each level. */
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)	\
+	set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
+#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
+#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
+#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
+	set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
+
+/* Macros for querying the last level entries. */
+#define PTE_VALID_ARCH(p) \
+	(*((uint32_t *) (p)) != 0)
+#define PTE_PRESENT_ARCH(p) \
+	((p)->present != 0)
+#define PTE_GET_FRAME_ARCH(p) \
+	((p)->frame_address << FRAME_WIDTH)
+#define PTE_WRITABLE_ARCH(p) \
+	((p)->writeable != 0)
+#define PTE_EXECUTABLE_ARCH(p)  1
+
+#ifndef __ASM__
+
+#include <mm/mm.h>
+#include <arch/interrupt.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+/* Page fault error codes. */
+
+/** When bit on this position is 0, the page fault was caused by a not-present
+ * page.
+ */
+#define PFERR_CODE_P		(1 << 0)
+
+/** When bit on this position is 1, the page fault was caused by a write. */
+#define PFERR_CODE_RW		(1 << 1)
+
+/** When bit on this position is 1, the page fault was caused in user mode. */
+#define PFERR_CODE_US		(1 << 2)
+
+/** When bit on this position is 1, a reserved bit was set in page directory. */ 
+#define PFERR_CODE_RSVD		(1 << 3)	
+
+/** Page Table Entry. */
+typedef struct {
+	unsigned present : 1;
+	unsigned writeable : 1;
+	unsigned uaccessible : 1;
+	unsigned page_write_through : 1;
+	unsigned page_cache_disable : 1;
+	unsigned accessed : 1;
+	unsigned dirty : 1;
+	unsigned pat : 1;
+	unsigned global : 1;
+	unsigned soft_valid : 1;	/**< Valid content even if the present bit is not set. */
+	unsigned avl : 2;
+	unsigned frame_address : 20;
+} __attribute__ ((packed)) pte_t;
+
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+{
+	pte_t *p = &pt[i];
+	
+	return ((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT |
+	    (!p->present) << PAGE_PRESENT_SHIFT |
+	    p->uaccessible << PAGE_USER_SHIFT |
+	    1 << PAGE_READ_SHIFT |
+	    p->writeable << PAGE_WRITE_SHIFT |
+	    1 << PAGE_EXEC_SHIFT |
+	    p->global << PAGE_GLOBAL_SHIFT);
+}
+
+static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+{
+	pte_t *p = &pt[i];
+	
+	p->page_cache_disable = !(flags & PAGE_CACHEABLE);
+	p->present = !(flags & PAGE_NOT_PRESENT);
+	p->uaccessible = (flags & PAGE_USER) != 0;
+	p->writeable = (flags & PAGE_WRITE) != 0;
+	p->global = (flags & PAGE_GLOBAL) != 0;
+	
+	/*
+	 * Ensure that there is at least one bit set even if the present bit is
+	 * cleared.
+	 */
+	p->soft_valid = true;
+}
+
+extern void page_arch_init(void);
+extern void page_fault(int n, istate_t *istate);
+
+#endif /* __ASM__ */
+
+#endif /* KERNEL */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/mm/tlb.h
===================================================================
--- kernel/arch/abs32le/include/mm/tlb.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/mm/tlb.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010 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 abs32lemm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_TLB_H_
+#define KERN_abs32le_TLB_H_
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/proc/task.h
===================================================================
--- kernel/arch/abs32le/include/proc/task.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/proc/task.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 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 abs32leproc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_TASK_H_
+#define KERN_abs32le_TASK_H_
+
+#include <arch/types.h>
+#include <adt/bitmap.h>
+
+/*
+ * On real hardware this structure stores task information
+ * specific to the architecture.
+ */
+typedef struct {
+} task_arch_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/proc/thread.h
===================================================================
--- kernel/arch/abs32le/include/proc/thread.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/proc/thread.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 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 abs32leproc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_THREAD_H_
+#define KERN_abs32le_THREAD_H_
+
+#include <arch/types.h>
+
+typedef struct {
+} thread_arch_t;
+
+#define thr_constructor_arch(thr)
+#define thr_destructor_arch(thr)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/include/types.h
===================================================================
--- kernel/arch/abs32le/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_abs32le_TYPES_H_
+#define KERN_abs32le_TYPES_H_
+
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef signed long long int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef uint32_t size_t;
+
+typedef uint32_t uintptr_t;
+typedef uint32_t pfn_t;
+
+typedef uint32_t ipl_t;
+
+typedef uint32_t unative_t;
+typedef int32_t native_t;
+
+typedef struct {
+} fncptr_t;
+
+#define PRIp  "x"  /**< Format for uintptr_t. */
+#define PRIs  "u"  /**< Format for size_t. */
+
+#define PRId8   "d"    /**< Format for int8_t. */
+#define PRId16  "d"    /**< Format for int16_t. */
+#define PRId32  "d"    /**< Format for int32_t. */
+#define PRId64  "lld"  /**< Format for int64_t. */
+#define PRIdn   "d"    /**< Format for native_t. */
+
+#define PRIu8   "u"    /**< Format for uint8_t. */
+#define PRIu16  "u"    /**< Format for uint16_t. */
+#define PRIu32  "u"    /**< Format for uint32_t. */
+#define PRIu64  "llu"  /**< Format for uint64_t. */
+#define PRIun   "u"    /**< Format for unative_t. */
+
+#define PRIx8   "x"    /**< Format for hexadecimal (u)int8_t. */
+#define PRIx16  "x"    /**< Format for hexadecimal (u)int16_t. */
+#define PRIx32  "x"    /**< Format for hexadecimal (u)uint32_t. */
+#define PRIx64  "llx"  /**< Format for hexadecimal (u)int64_t. */
+#define PRIxn   "x"    /**< Format for hexadecimal (u)native_t. */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/abs32le.c
===================================================================
--- kernel/arch/abs32le/src/abs32le.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/abs32le.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#include <arch.h>
+#include <arch/types.h>
+#include <arch/context.h>
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+
+#include <func.h>
+#include <config.h>
+#include <context.h>
+#include <interrupt.h>
+#include <ddi/irq.h>
+#include <proc/thread.h>
+#include <syscall/syscall.h>
+#include <console/console.h>
+#include <sysinfo/sysinfo.h>
+#include <memstr.h>
+
+void arch_pre_mm_init(void)
+{
+}
+
+void arch_post_mm_init(void)
+{
+	if (config.cpu_active == 1) {
+		/* Initialize IRQ routing */
+		irq_init(0, 0);
+		
+		/* Merge all memory zones to 1 big zone */
+		zone_merge_all();
+	}
+}
+
+void arch_post_cpu_init()
+{
+}
+
+void arch_pre_smp_init(void)
+{
+}
+
+void arch_post_smp_init(void)
+{
+}
+
+void calibrate_delay_loop(void)
+{
+}
+
+unative_t sys_tls_set(unative_t addr)
+{
+	return 0;
+}
+
+/** Construct function pointer
+ *
+ * @param fptr   function pointer structure
+ * @param addr   function address
+ * @param caller calling function address
+ *
+ * @return address of the function pointer
+ *
+ */
+void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
+{
+	return addr;
+}
+
+void arch_reboot(void)
+{
+}
+
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
+void memsetb(void *dst, size_t cnt, uint8_t val)
+{
+	_memsetb(dst, cnt, val);
+}
+
+void memsetw(void *dst, size_t cnt, uint16_t val)
+{
+	_memsetw(dst, cnt, val);
+}
+
+void panic_printf(char *fmt, ...)
+{
+	va_list args;
+	
+	va_start(args, fmt);
+	vprintf(fmt, args);
+	va_end(args);
+	
+	halt();
+}
+
+int context_save_arch(context_t *ctx)
+{
+	return 1;
+}
+
+void context_restore_arch(context_t *ctx)
+{
+	while (true);
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/cpu/cpu.c
===================================================================
--- kernel/arch/abs32le/src/cpu/cpu.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/cpu/cpu.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/cpu.h>
+#include <arch.h>
+#include <arch/types.h>
+#include <print.h>
+#include <fpu_context.h>
+
+
+void fpu_disable(void)
+{
+}
+
+void fpu_enable(void)
+{
+}
+
+void cpu_arch_init(void)
+{
+}
+
+void cpu_identify(void)
+{
+}
+
+void cpu_print_report(cpu_t* cpu)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/ddi/ddi.c
===================================================================
--- kernel/arch/abs32le/src/ddi/ddi.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/ddi/ddi.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 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 abs32leddi
+ * @{
+ */
+/** @file
+ *  @brief DDI.
+ */
+
+#include <ddi/ddi.h>
+#include <proc/task.h>
+#include <arch/types.h>
+
+/** Enable I/O space range for task.
+ *
+ */
+int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/debug/stacktrace.c
===================================================================
--- kernel/arch/abs32le/src/debug/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/debug/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+bool kernel_frame_pointer_validate(uintptr_t fp)
+{
+	return true;;
+}
+
+bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return true;
+}
+
+bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return true;
+}
+
+bool uspace_frame_pointer_validate(uintptr_t fp)
+{
+	return true;
+}
+
+bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return true;
+}
+
+bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return true;
+}
+
+uintptr_t frame_pointer_get(void)
+{
+	return 0;
+}
+
+uintptr_t program_counter_get(void)
+{
+	return 0;
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/mm/as.c
===================================================================
--- kernel/arch/abs32le/src/mm/as.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/mm/as.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 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 abs32lemm
+ * @{
+ */
+
+#include <mm/as.h>
+#include <arch/mm/as.h>
+#include <genarch/mm/page_pt.h>
+
+void as_arch_init(void)
+{
+	as_operations = &as_pt_operations;
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/mm/frame.c
===================================================================
--- kernel/arch/abs32le/src/mm/frame.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/mm/frame.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010 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 abs32lemm
+ * @{
+ */
+
+#include <mm/frame.h>
+#include <arch/mm/frame.h>
+#include <mm/as.h>
+#include <config.h>
+#include <panic.h>
+#include <debug.h>
+#include <align.h>
+#include <macros.h>
+
+#include <print.h>
+
+size_t hardcoded_unmapped_ktext_size = 0;
+size_t hardcoded_unmapped_kdata_size = 0;
+
+void physmem_print(void)
+{
+}
+
+
+void frame_arch_init(void)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/mm/page.c
===================================================================
--- kernel/arch/abs32le/src/mm/page.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/mm/page.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010 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 abs32lemm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/page.h>
+#include <genarch/mm/page_pt.h>
+#include <arch/mm/frame.h>
+#include <mm/frame.h>
+#include <mm/page.h>
+#include <mm/as.h>
+#include <arch/types.h>
+#include <align.h>
+#include <config.h>
+#include <func.h>
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+#include <debug.h>
+#include <memstr.h>
+#include <print.h>
+#include <interrupt.h>
+
+void page_arch_init(void)
+{
+	if (config.cpu_active == 1)
+		page_mapping_operations = &pt_mapping_operations;
+}
+
+
+uintptr_t hw_map(uintptr_t physaddr, size_t size)
+{
+	return physaddr;
+}
+
+void page_fault(int n __attribute__((unused)), istate_t *istate)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/mm/tlb.c
===================================================================
--- kernel/arch/abs32le/src/mm/tlb.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/mm/tlb.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010 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 abs32lemm
+ * @{
+ */
+
+#include <mm/tlb.h>
+#include <arch/mm/asid.h>
+#include <arch/asm.h>
+#include <arch/types.h>
+
+void tlb_invalidate_all(void)
+{
+}
+
+void tlb_invalidate_asid(asid_t asid __attribute__((unused)))
+{
+	tlb_invalidate_all();
+}
+
+void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt)
+{
+	tlb_invalidate_all();
+}
+
+void tlb_arch_init(void)
+{
+}
+
+void tlb_print(void)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/proc/scheduler.c
===================================================================
--- kernel/arch/abs32le/src/proc/scheduler.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/proc/scheduler.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010 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 abs32leproc
+ * @{
+ */
+/** @file
+ */
+
+#include <proc/scheduler.h>
+
+void before_task_runs_arch(void)
+{
+}
+
+void before_thread_runs_arch(void)
+{
+}
+
+void after_thread_ran_arch(void)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/proc/task.c
===================================================================
--- kernel/arch/abs32le/src/proc/task.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/proc/task.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 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 abs32leproc
+ * @{
+ */
+/** @file
+ */
+
+#include <proc/task.h>
+
+void task_create_arch(task_t *t)
+{
+}
+
+void task_destroy_arch(task_t *t)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/proc/thread.c
===================================================================
--- kernel/arch/abs32le/src/proc/thread.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/proc/thread.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010 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 abs32leproc
+ * @{
+ */
+/** @file
+ */
+
+#include <proc/thread.h>
+
+void thread_create_arch(thread_t *t)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/smp/smp.c
===================================================================
--- kernel/arch/abs32le/src/smp/smp.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/smp/smp.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#include <smp/smp.h>
+
+void smp_init(void)
+{
+}
+
+void kmp(void *arg)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/abs32le/src/userspace.c
===================================================================
--- kernel/arch/abs32le/src/userspace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ kernel/arch/abs32le/src/userspace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 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 abs32le
+ * @{
+ */
+/** @file
+ */
+
+#include <userspace.h>
+#include <arch/types.h>
+#include <arch.h>
+#include <proc/uarg.h>
+#include <mm/as.h>
+
+
+void userspace(uspace_arg_t *kernel_uarg)
+{
+	/* On real hardware this switches the CPU to user
+	   space mode and jumps to kernel_uarg->uspace_entry. */
+	
+	while (true);
+}
+
+/** @}
+ */
Index: kernel/arch/amd64/include/asm.h
===================================================================
--- kernel/arch/amd64/include/asm.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/amd64/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -68,11 +68,11 @@
 }
 
-static inline void cpu_halt(void)
-{
-	asm volatile (
-		"0:\n"
-		"	hlt\n"
-		"	jmp 0b\n"
-	);
+static inline void __attribute__((noreturn)) cpu_halt(void)
+{
+	while (true) {
+		asm volatile (
+			"hlt\n"
+		);
+	}
 }
 
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/amd64/src/amd64.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -278,4 +278,9 @@
 }
 
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
 /** @}
  */
Index: kernel/arch/arm32/include/asm.h
===================================================================
--- kernel/arch/arm32/include/asm.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/arm32/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -96,5 +96,5 @@
 }
 
-extern void cpu_halt(void);
+extern void cpu_halt(void) __attribute__((noreturn));
 extern void asm_delay_loop(uint32_t t);
 extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg,
Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/arm32/src/arm32.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -155,5 +155,6 @@
 void cpu_halt(void)
 {
-	machine_cpu_halt();
+	while (true)
+		machine_cpu_halt();
 }
 
@@ -162,5 +163,5 @@
 {
 	/* not implemented */
-	while (1);
+	while (true);
 }
 
@@ -179,4 +180,9 @@
 }
 
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
 /** @}
  */
Index: kernel/arch/ia32/include/asm.h
===================================================================
--- kernel/arch/ia32/include/asm.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/ia32/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -60,11 +60,11 @@
  *
  */
-static inline void cpu_halt(void)
-{
-	asm volatile (
-		"0:\n"
-		"	hlt\n"
-		"	jmp 0b\n"
-	);
+static inline __attribute__((noreturn)) void cpu_halt(void)
+{
+	while (true) {
+		asm volatile (
+			"hlt\n"
+		);
+	}
 }
 
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/ia32/src/ia32.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -234,4 +234,9 @@
 }
 
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
 /** @}
  */
Index: kernel/arch/ia64/include/asm.h
===================================================================
--- kernel/arch/ia64/include/asm.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/ia64/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -428,5 +428,5 @@
 }
 
-extern void cpu_halt(void);
+extern void cpu_halt(void) __attribute__((noreturn));
 extern void cpu_sleep(void);
 extern void asm_delay_loop(uint32_t t);
Index: kernel/arch/ia64/include/context.h
===================================================================
--- kernel/arch/ia64/include/context.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/ia64/include/context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -48,8 +48,4 @@
  */
 #define SP_DELTA	(0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
-
-#ifdef context_set
-#undef context_set
-#endif
 
 /* RSE stack starts at the bottom of memory stack. */
Index: kernel/arch/ia64/src/ia64.c
===================================================================
--- kernel/arch/ia64/src/ia64.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/ia64/src/ia64.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -44,4 +44,5 @@
 #include <arch/stack.h>
 #include <arch/mm/page.h>
+#include <interrupt.h>
 #include <mm/as.h>
 #include <config.h>
@@ -280,4 +281,9 @@
 }
 
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
 /** @}
  */
Index: kernel/arch/mips32/include/asm.h
===================================================================
--- kernel/arch/mips32/include/asm.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/mips32/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -66,5 +66,5 @@
 }
 
-extern void cpu_halt(void);
+extern void cpu_halt(void) __attribute__((noreturn));
 extern void asm_delay_loop(uint32_t t);
 extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg,
Index: kernel/arch/mips32/include/context.h
===================================================================
--- kernel/arch/mips32/include/context.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/mips32/include/context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -42,10 +42,12 @@
  * Put one item onto the stack to support get_stack_base() and align it up.
  */
-#define SP_DELTA	(0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
-
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
 #ifndef __ASM__
 
 #include <arch/types.h>
+
+#define context_set(ctx, pc, stack, size) \
+    context_set_generic(ctx, pc, stack, size)
 
 /*
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/mips32/src/mips32.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -46,4 +46,5 @@
 #include <sysinfo/sysinfo.h>
 #include <arch/interrupt.h>
+#include <interrupt.h>
 #include <console/chardev.h>
 #include <arch/barrier.h>
@@ -257,4 +258,9 @@
 }
 
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
 /** @}
  */
Index: kernel/arch/ppc32/include/asm.h
===================================================================
--- kernel/arch/ppc32/include/asm.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/ppc32/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32	
+/** @addtogroup ppc32
  * @{
  */
@@ -146,37 +146,36 @@
 }
 
-void cpu_halt(void);
-void asm_delay_loop(uint32_t t);
-
+extern void cpu_halt(void) __attribute__((noreturn));
+extern void asm_delay_loop(uint32_t t);
 extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
 
 static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
-	*port = v;	
+	*port = v;
 }
 
 static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
-	*port = v;	
+	*port = v;
 }
 
 static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
-	*port = v;	
+	*port = v;
 }
 
 static inline uint8_t pio_read_8(ioport8_t *port)
 {
-	return *port; 
+	return *port;
 }
 
 static inline uint16_t pio_read_16(ioport16_t *port)
 {
-	return *port; 
+	return *port;
 }
 
 static inline uint32_t pio_read_32(ioport32_t *port)
 {
-	return *port; 
+	return *port;
 }
 
Index: kernel/arch/ppc32/include/context.h
===================================================================
--- kernel/arch/ppc32/include/context.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/ppc32/include/context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32	
+/** @addtogroup ppc32
  * @{
  */
@@ -38,5 +38,8 @@
 #include <arch/types.h>
 
-#define SP_DELTA	16
+#define SP_DELTA  16
+
+#define context_set(ctx, pc, stack, size) \
+    context_set_generic(ctx, pc, stack, size)
 
 typedef struct {
@@ -68,5 +71,5 @@
 	
 	ipl_t ipl;
-} __attribute__ ((packed)) context_t;
+} __attribute__((packed)) context_t;
 
 #endif
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/ppc32/src/ppc32.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -39,4 +39,5 @@
 #include <genarch/kbrd/kbrd.h>
 #include <arch/interrupt.h>
+#include <interrupt.h>
 #include <genarch/fb/fb.h>
 #include <genarch/fb/visuals.h>
@@ -47,4 +48,5 @@
 #include <proc/uarg.h>
 #include <console/console.h>
+#include <sysinfo/sysinfo.h>
 #include <ddi/irq.h>
 #include <arch/drivers/pic.h>
@@ -58,4 +60,7 @@
 
 bootinfo_t bootinfo;
+
+static cir_t pic_cir;
+static void *pic_cir_arg;
 
 /** Performs ppc32-specific initialization before main_bsp() is called. */
@@ -186,8 +191,7 @@
 	if (assigned_address) {
 		/* Initialize PIC */
-		cir_t cir;
-		void *cir_arg;
-		pic_init(assigned_address[0].addr, PAGE_SIZE, &cir, &cir_arg);
-		
+		pic_init(assigned_address[0].addr, PAGE_SIZE, &pic_cir,
+		    &pic_cir_arg);
+
 #ifdef CONFIG_MAC_KBD
 		uintptr_t pa = assigned_address[0].addr + 0x16000;
@@ -201,5 +205,5 @@
 		/* Initialize I/O controller */
 		cuda_instance_t *cuda_instance =
-		    cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
+		    cuda_init(cuda, IRQ_CUDA, pic_cir, pic_cir_arg);
 		if (cuda_instance) {
 			kbrd_instance_t *kbrd_instance = kbrd_init();
@@ -211,4 +215,14 @@
 			}
 		}
+
+		/*
+		 * This is the necessary evil until the userspace driver is entirely
+		 * self-sufficient.
+		 */
+		sysinfo_set_item_val("cuda", NULL, true);
+		sysinfo_set_item_val("cuda.inr", NULL, IRQ_CUDA);
+		sysinfo_set_item_val("cuda.address.physical", NULL, pa);
+		sysinfo_set_item_val("cuda.address.kernel", NULL,
+		    (uintptr_t) cuda);
 #endif
 	}
@@ -216,4 +230,11 @@
 	/* Consider only a single device for now */
 	return false;
+}
+
+void irq_initialize_arch(irq_t *irq)
+{
+	irq->cir = pic_cir;
+	irq->cir_arg = pic_cir_arg;
+	irq->preack = true;
 }
 
Index: kernel/arch/sparc64/include/asm.h
===================================================================
--- kernel/arch/sparc64/include/asm.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/sparc64/include/asm.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -430,5 +430,5 @@
 }
 
-extern void cpu_halt(void);
+extern void cpu_halt(void) __attribute__((noreturn));
 extern void cpu_sleep(void);
 extern void asm_delay_loop(const uint32_t usec);
Index: kernel/arch/sparc64/include/context.h
===================================================================
--- kernel/arch/sparc64/include/context.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/sparc64/include/context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -42,8 +42,4 @@
 #define SP_DELTA	(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
-#ifdef context_set
-#undef context_set
-#endif
-
 #define context_set(c, _pc, stack, size)			\
 	(c)->pc = ((uintptr_t) _pc) - 8;			\
Index: kernel/arch/sparc64/src/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sparc64.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/arch/sparc64/src/sparc64.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -44,4 +44,5 @@
 #include <arch/mm/page.h>
 #include <arch/stack.h>
+#include <interrupt.h>
 #include <genarch/ofw/ofw_tree.h>
 #include <userspace.h>
@@ -166,4 +167,9 @@
 }
 
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
 /** @}
  */
Index: kernel/generic/include/context.h
===================================================================
--- kernel/generic/include/context.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/include/context.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -39,13 +39,10 @@
 #include <arch/context.h>
 
+#define context_set_generic(ctx, _pc, stack, size) \
+	(ctx)->pc = (uintptr_t) (_pc); \
+	(ctx)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
 
-#ifndef context_set
-#define context_set(c, _pc, stack, size) 	\
-	(c)->pc = (uintptr_t) (_pc);		\
-	(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
-#endif /* context_set */
-
-extern int context_save_arch(context_t *c) __attribute__ ((returns_twice));
-extern void context_restore_arch(context_t *c) __attribute__ ((noreturn));
+extern int context_save_arch(context_t *ctx) __attribute__((returns_twice));
+extern void context_restore_arch(context_t *ctx) __attribute__((noreturn));
 
 /** Save register context.
@@ -73,9 +70,10 @@
  * saved like that would therefore lead to a disaster.
  *
- * @param c		Context structure.
+ * @param ctx Context structure.
  *
- * @return		context_save() returns 1, context_restore() returns 0.
+ * @return context_save() returns 1, context_restore() returns 0.
+ *
  */
-#define context_save(c)   context_save_arch(c)
+#define context_save(ctx)  context_save_arch(ctx)
 
 /** Restore register context.
@@ -88,9 +86,9 @@
  * being return value.
  *
- * @param c		Context structure.
+ * @param ctx Context structure.
  */
-static inline void context_restore(context_t *c)
+static inline void context_restore(context_t *ctx)
 {
-	context_restore_arch(c);
+	context_restore_arch(ctx);
 }
 
Index: kernel/generic/include/func.h
===================================================================
--- kernel/generic/include/func.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/include/func.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -41,5 +41,5 @@
 extern atomic_t haltstate;
 
-extern void halt(void);
+extern void halt(void) __attribute__((noreturn));
 extern unative_t atoi(const char *text);
 extern void order(const uint64_t val, uint64_t *rv, char *suffix);
Index: kernel/generic/include/interrupt.h
===================================================================
--- kernel/generic/include/interrupt.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/include/interrupt.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -46,20 +46,10 @@
 typedef void (* iroutine)(int n, istate_t *istate);
 
-#define fault_if_from_uspace(istate, fmt, ...) \
-{ \
-	if (istate_from_uspace(istate)) { \
-		task_t *task = TASK; \
-		printf("Task %s (%" PRIu64 ") killed due to an exception at " \
-		    "program counter %p.\n", task->name, task->taskid, istate_get_pc(istate)); \
-		stack_trace_istate(istate); \
-		printf("Kill message: " fmt "\n", ##__VA_ARGS__); \
-		task_kill(task->taskid); \
-		thread_exit(); \
-	} \
-}
-
+extern void fault_if_from_uspace(istate_t *istate, char *fmt, ...);
 extern iroutine exc_register(int n, const char *name, iroutine f);
 extern void exc_dispatch(int n, istate_t *t);
 void exc_init(void);
+
+extern void irq_initialize_arch(irq_t *irq);
 
 #endif
Index: kernel/generic/include/ipc/event_types.h
===================================================================
--- kernel/generic/include/ipc/event_types.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/include/ipc/event_types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -37,6 +37,10 @@
 
 typedef enum event_type {
+	/** New data available in kernel log */
 	EVENT_KLOG = 0,
+	/** Returning from kernel console to userspace */
 	EVENT_KCONSOLE,
+	/** A thread has faulted and will be terminated */
+	EVENT_FAULT,
 	EVENT_END
 } event_type_t;
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/include/mm/as.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,4 +36,10 @@
 #define KERN_AS_H_
 
+#ifdef KERNEL
+#include <arch/types.h>
+#else
+#include <sys/types.h>
+#endif
+
 /** Address space area flags. */
 #define AS_AREA_READ		1
@@ -41,4 +47,16 @@
 #define AS_AREA_EXEC		4
 #define AS_AREA_CACHEABLE	8
+
+/** Address space area info exported to userspace. */
+typedef struct {
+	/** Starting address */
+	uintptr_t start_addr;
+
+	/** Area size */
+	size_t size;
+
+	/** Area flags */
+	int flags;
+} as_area_info_t;
 
 #ifdef KERNEL
@@ -268,4 +286,5 @@
 
 /* Introspection functions. */
+extern void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize);
 extern void as_print(as_t *as);
 
Index: kernel/generic/include/stacktrace.h
===================================================================
--- kernel/generic/include/stacktrace.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/include/stacktrace.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -60,5 +60,5 @@
  */
 extern uintptr_t frame_pointer_get(void);
-extern uintptr_t program_counter_get();
+extern uintptr_t program_counter_get(void);
 
 extern bool kernel_frame_pointer_validate(uintptr_t);
Index: kernel/generic/include/udebug/udebug.h
===================================================================
--- kernel/generic/include/udebug/udebug.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/include/udebug/udebug.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -83,4 +83,15 @@
 UDEBUG_M_ARGS_READ,
 
+/** Read thread's userspace register state (istate_t).
+ *
+ * - ARG2 - thread identification
+ * - ARG3 - destination address in the caller's address space
+ *
+ * or, on error, retval will be
+ * - ENOENT - thread does not exist
+ * - EBUSY - register state not available
+ */
+UDEBUG_M_REGS_READ,
+
 /** Read the list of the debugged tasks's threads.
  *
@@ -97,4 +108,31 @@
 UDEBUG_M_THREAD_READ,
 
+/** Read the name of the debugged task.
+ *
+ * - ARG2 - destination address in the caller's address space
+ * - ARG3 - size of receiving buffer in bytes
+ *
+ * The kernel fills the buffer with a non-terminated string.
+ *
+ * - ARG2 - number of bytes that were actually copied
+ * - ARG3 - number of bytes of the complete data
+ *
+ */
+UDEBUG_M_NAME_READ,
+
+/** Read the list of the debugged task's address space areas.
+ *
+ * - ARG2 - destination address in the caller's address space
+ * - ARG3 - size of receiving buffer in bytes
+ *
+ * The kernel fills the buffer with a series of as_area_info_t structures.
+ * Upon answer, the kernel will set:
+ *
+ * - ARG2 - number of bytes that were actually copied
+ * - ARG3 - number of bytes of the complete data
+ *
+ */
+UDEBUG_M_AREAS_READ,
+
 /** Read the debugged tasks's memory.
  *
@@ -108,5 +146,5 @@
 } udebug_method_t;
 
-				
+
 typedef enum {
 	UDEBUG_EVENT_FINISHED = 1,	/**< Debuging session has finished */
@@ -139,4 +177,5 @@
 
 #include <synch/mutex.h>
+#include <synch/condvar.h>
 #include <arch/interrupt.h>
 #include <atomic.h>
@@ -181,4 +220,5 @@
 	bool stoppable;		/**< thread is stoppable */
 	bool active;		/**< thread is in a debugging session */
+	condvar_t active_cv;
 } udebug_thread_t;
 
@@ -202,4 +242,5 @@
 
 int udebug_task_cleanup(struct task *ta);
+void udebug_thread_fault(void);
 
 #endif
Index: kernel/generic/include/udebug/udebug_ops.h
===================================================================
--- kernel/generic/include/udebug/udebug_ops.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/include/udebug/udebug_ops.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -45,6 +45,10 @@
 int udebug_stop(thread_t *t, call_t *call);
 
-int udebug_thread_read(void **buffer, size_t buf_size, size_t *n);
+int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored,
+    size_t *needed);
+int udebug_name_read(char **data, size_t *data_size);
 int udebug_args_read(thread_t *t, void **buffer);
+
+int udebug_regs_read(thread_t *t, void **buffer);
 
 int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer);
Index: kernel/generic/src/ddi/irq.c
===================================================================
--- kernel/generic/src/ddi/irq.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/src/ddi/irq.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -74,4 +74,5 @@
 #include <synch/spinlock.h>
 #include <console/console.h>
+#include <interrupt.h>
 #include <memstr.h>
 #include <arch.h>
@@ -169,4 +170,6 @@
 	irq->inr = -1;
 	irq->devno = -1;
+
+	irq_initialize_arch(irq);
 }
 
Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/src/interrupt/interrupt.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -44,4 +44,8 @@
 #include <console/console.h>
 #include <console/cmd.h>
+#include <ipc/event.h>
+#include <synch/mutex.h>
+#include <time/delay.h>
+#include <macros.h>
 #include <panic.h>
 #include <print.h>
@@ -107,4 +111,46 @@
 	fault_if_from_uspace(istate, "Unhandled exception %d.", n);
 	panic("Unhandled exception %d.", n);
+}
+
+/** Terminate thread and task if exception came from userspace. */
+void fault_if_from_uspace(istate_t *istate, char *fmt, ...)
+{
+	task_t *task = TASK;
+	va_list args;
+
+	if (!istate_from_uspace(istate))
+		return;
+
+	printf("Task %s (%" PRIu64 ") killed due to an exception at "
+	    "program counter %p.\n", task->name, task->taskid,
+	    istate_get_pc(istate));
+
+	stack_trace_istate(istate);
+
+	printf("Kill message: ");
+	va_start(args, fmt);
+	vprintf(fmt, args);
+	va_end(args);
+	printf("\n");
+
+	/*
+	 * Userspace can subscribe for FAULT events to take action
+	 * whenever a thread faults. (E.g. take a dump, run a debugger).
+	 * The notification is always available, but unless Udebug is enabled,
+	 * that's all you get.
+	 */
+	if (event_is_subscribed(EVENT_FAULT)) {
+		/* Notify the subscriber that a fault occurred. */
+		event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),
+		    UPPER32(TASK->taskid), (unative_t) THREAD);
+
+#ifdef CONFIG_UDEBUG
+		/* Wait for a debugging session. */
+		udebug_thread_fault();
+#endif
+	}
+
+	task_kill(task->taskid);
+	thread_exit();
 }
 
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/src/ipc/ipc.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -212,8 +212,10 @@
  *
  * @param call		Call structure to be answered.
- */
-static void _ipc_answer_free_call(call_t *call)
+ * @param selflocked	If true, then TASK->answebox is locked.
+ */
+static void _ipc_answer_free_call(call_t *call, bool selflocked)
 {
 	answerbox_t *callerbox = call->callerbox;
+	bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
 
 	call->flags |= IPC_CALL_ANSWERED;
@@ -226,7 +228,9 @@
 	}
 
-	spinlock_lock(&callerbox->lock);
+	if (do_lock)
+		spinlock_lock(&callerbox->lock);
 	list_append(&call->link, &callerbox->answers);
-	spinlock_unlock(&callerbox->lock);
+	if (do_lock)
+		spinlock_unlock(&callerbox->lock);
 	waitq_wakeup(&callerbox->wq, WAKEUP_FIRST);
 }
@@ -244,5 +248,5 @@
 	spinlock_unlock(&box->lock);
 	/* Send back answer */
-	_ipc_answer_free_call(call);
+	_ipc_answer_free_call(call, false);
 }
 
@@ -261,5 +265,5 @@
 	atomic_inc(&phone->active_calls);
 	IPC_SET_RETVAL(call->data, err);
-	_ipc_answer_free_call(call);
+	_ipc_answer_free_call(call, false);
 }
 
@@ -300,5 +304,5 @@
 		if (call->flags & IPC_CALL_FORWARDED) {
 			IPC_SET_RETVAL(call->data, EFORWARD);
-			_ipc_answer_free_call(call);
+			_ipc_answer_free_call(call, false);
 		} else {
 			if (phone->state == IPC_PHONE_HUNGUP)
@@ -455,5 +459,5 @@
 
 		IPC_SET_RETVAL(call->data, EHANGUP);
-		_ipc_answer_free_call(call);
+		_ipc_answer_free_call(call, true);
 	}
 }
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/src/mm/as.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -1920,4 +1920,70 @@
 }
 
+/** Get list of adress space areas.
+ *
+ * @param as		Address space.
+ * @param obuf		Place to save pointer to returned buffer.
+ * @param osize		Place to save size of returned buffer.
+ */
+void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)
+{
+	ipl_t ipl;
+	size_t area_cnt, area_idx, i;
+	link_t *cur;
+
+	as_area_info_t *info;
+	size_t isize;
+
+	ipl = interrupts_disable();
+	mutex_lock(&as->lock);
+
+	/* First pass, count number of areas. */
+
+	area_cnt = 0;
+
+	for (cur = as->as_area_btree.leaf_head.next;
+	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+		btree_node_t *node;
+
+		node = list_get_instance(cur, btree_node_t, leaf_link);
+		area_cnt += node->keys;
+	}
+
+        isize = area_cnt * sizeof(as_area_info_t);
+	info = malloc(isize, 0);
+
+	/* Second pass, record data. */
+
+	area_idx = 0;
+
+	for (cur = as->as_area_btree.leaf_head.next;
+	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+		btree_node_t *node;
+
+		node = list_get_instance(cur, btree_node_t, leaf_link);
+
+		for (i = 0; i < node->keys; i++) {
+			as_area_t *area = node->value[i];
+
+			ASSERT(area_idx < area_cnt);
+			mutex_lock(&area->lock);
+
+			info[area_idx].start_addr = area->base;
+			info[area_idx].size = FRAMES2SIZE(area->pages);
+			info[area_idx].flags = area->flags;
+			++area_idx;
+
+			mutex_unlock(&area->lock);
+		}
+	}
+
+	mutex_unlock(&as->lock);
+	interrupts_restore(ipl);
+
+	*obuf = info;
+	*osize = isize;
+}
+
+
 /** Print out information about address space.
  *
Index: kernel/generic/src/udebug/udebug.c
===================================================================
--- kernel/generic/src/udebug/udebug.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/src/udebug/udebug.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -69,4 +69,5 @@
 	mutex_initialize(&ut->lock, MUTEX_PASSIVE);
 	waitq_initialize(&ut->go_wq);
+	condvar_initialize(&ut->active_cv);
 
 	ut->go_call = NULL;
@@ -446,6 +447,9 @@
 				waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST);
 			}
+			mutex_unlock(&t->udebug.lock);
+			condvar_broadcast(&t->udebug.active_cv);
+		} else {
+			mutex_unlock(&t->udebug.lock);
 		}
-		mutex_unlock(&t->udebug.lock);
 	}
 
@@ -456,4 +460,29 @@
 }
 
+/** Wait for debugger to handle a fault in this thread.
+ *
+ * When a thread faults and someone is subscribed to the FAULT kernel event,
+ * this function is called to wait for a debugging session to give userspace
+ * a chance to examine the faulting thead/task. When the debugging session
+ * is over, this function returns (so that thread/task cleanup can continue).
+ */
+void udebug_thread_fault(void)
+{
+	udebug_stoppable_begin();
+
+	/* Wait until a debugger attends to us. */
+	mutex_lock(&THREAD->udebug.lock);
+	while (!THREAD->udebug.active)
+		condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
+	mutex_unlock(&THREAD->udebug.lock);
+
+	/* Make sure the debugging session is over before proceeding. */
+	mutex_lock(&THREAD->udebug.lock);
+	while (THREAD->udebug.active)
+		condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
+	mutex_unlock(&THREAD->udebug.lock);
+
+	udebug_stoppable_end();
+}
 
 /** @}
Index: kernel/generic/src/udebug/udebug_ipc.c
===================================================================
--- kernel/generic/src/udebug/udebug_ipc.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/src/udebug/udebug_ipc.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -41,4 +41,5 @@
 #include <proc/task.h>
 #include <proc/thread.h>
+#include <mm/as.h>
 #include <arch.h>
 #include <errno.h>
@@ -165,11 +166,53 @@
 static void udebug_receive_thread_read(call_t *call)
 {
+	uintptr_t uspace_addr;
+	size_t buf_size;
+	void *buffer;
+	size_t copied, needed;
+	int rc;
+
+	uspace_addr = IPC_GET_ARG2(call->data);	/* Destination address */
+	buf_size = IPC_GET_ARG3(call->data);	/* Dest. buffer size */
+
+	/*
+	 * Read thread list. Variable n will be filled with actual number
+	 * of threads times thread-id size.
+	 */
+	rc = udebug_thread_read(&buffer, buf_size, &copied, &needed);
+	if (rc < 0) {
+		IPC_SET_RETVAL(call->data, rc);
+		ipc_answer(&TASK->kb.box, call);
+		return;
+	}
+
+	/*
+	 * Make use of call->buffer to transfer data to caller's userspace
+	 */
+
+	IPC_SET_RETVAL(call->data, 0);
+	/* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	   same code in process_answer() can be used 
+	   (no way to distinguish method in answer) */
+	IPC_SET_ARG1(call->data, uspace_addr);
+	IPC_SET_ARG2(call->data, copied);
+	IPC_SET_ARG3(call->data, needed);
+	call->buffer = buffer;
+
+	ipc_answer(&TASK->kb.box, call);
+}
+
+/** Process a NAME_READ call.
+ *
+ * Returns a string containing the name of the task.
+ *
+ * @param call	The call structure.
+ */
+static void udebug_receive_name_read(call_t *call)
+{
 	unative_t uspace_addr;
 	unative_t to_copy;
-	unsigned total_bytes;
-	unsigned buf_size;
-	void *buffer;
-	size_t n;
-	int rc;
+	size_t data_size;
+	size_t buf_size;
+	void *data;
 
 	uspace_addr = IPC_GET_ARG2(call->data);	/* Destination address */
@@ -177,20 +220,12 @@
 
 	/*
-	 * Read thread list. Variable n will be filled with actual number
-	 * of threads times thread-id size.
-	 */
-	rc = udebug_thread_read(&buffer, buf_size, &n);
-	if (rc < 0) {
-		IPC_SET_RETVAL(call->data, rc);
-		ipc_answer(&TASK->kb.box, call);
-		return;
-	}
-
-	total_bytes = n;
-
-	/* Copy MAX(buf_size, total_bytes) bytes */
-
-	if (buf_size > total_bytes)
-		to_copy = total_bytes;
+	 * Read task name.
+	 */
+	udebug_name_read((char **) &data, &data_size);
+
+	/* Copy MAX(buf_size, data_size) bytes */
+
+	if (buf_size > data_size)
+		to_copy = data_size;
 	else
 		to_copy = buf_size;
@@ -207,9 +242,57 @@
 	IPC_SET_ARG2(call->data, to_copy);
 
-	IPC_SET_ARG3(call->data, total_bytes);
-	call->buffer = buffer;
-
-	ipc_answer(&TASK->kb.box, call);
-}
+	IPC_SET_ARG3(call->data, data_size);
+	call->buffer = data;
+
+	ipc_answer(&TASK->kb.box, call);
+}
+
+/** Process an AREAS_READ call.
+ *
+ * Returns a list of address space areas in the current task, as an array
+ * of as_area_info_t structures.
+ *
+ * @param call	The call structure.
+ */
+static void udebug_receive_areas_read(call_t *call)
+{
+	unative_t uspace_addr;
+	unative_t to_copy;
+	size_t data_size;
+	size_t buf_size;
+	void *data;
+
+	uspace_addr = IPC_GET_ARG2(call->data);	/* Destination address */
+	buf_size = IPC_GET_ARG3(call->data);	/* Dest. buffer size */
+
+	/*
+	 * Read area list.
+	 */
+	as_get_area_info(AS, (as_area_info_t **) &data, &data_size);
+
+	/* Copy MAX(buf_size, data_size) bytes */
+
+	if (buf_size > data_size)
+		to_copy = data_size;
+	else
+		to_copy = buf_size;
+
+	/*
+	 * Make use of call->buffer to transfer data to caller's userspace
+	 */
+
+	IPC_SET_RETVAL(call->data, 0);
+	/* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	   same code in process_answer() can be used 
+	   (no way to distinguish method in answer) */
+	IPC_SET_ARG1(call->data, uspace_addr);
+	IPC_SET_ARG2(call->data, to_copy);
+
+	IPC_SET_ARG3(call->data, data_size);
+	call->buffer = data;
+
+	ipc_answer(&TASK->kb.box, call);
+}
+
 
 /** Process an ARGS_READ call.
@@ -250,4 +333,45 @@
 	ipc_answer(&TASK->kb.box, call);
 }
+
+/** Receive a REGS_READ call.
+ *
+ * Reads the thread's register state (istate structure).
+ */
+static void udebug_receive_regs_read(call_t *call)
+{
+	thread_t *t;
+	unative_t uspace_addr;
+	unative_t to_copy;
+	void *buffer;
+	int rc;
+
+	t = (thread_t *) IPC_GET_ARG2(call->data);
+
+	rc = udebug_regs_read(t, &buffer);
+	if (rc < 0) {
+		IPC_SET_RETVAL(call->data, rc);
+		ipc_answer(&TASK->kb.box, call);
+		return;
+	}
+
+	/*
+	 * Make use of call->buffer to transfer data to caller's userspace
+	 */
+
+	uspace_addr = IPC_GET_ARG3(call->data);
+	to_copy = sizeof(istate_t);
+
+	IPC_SET_RETVAL(call->data, 0);
+	/* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	   same code in process_answer() can be used 
+	   (no way to distinguish method in answer) */
+	IPC_SET_ARG1(call->data, uspace_addr);
+	IPC_SET_ARG2(call->data, to_copy);
+
+	call->buffer = buffer;
+
+	ipc_answer(&TASK->kb.box, call);
+}
+
 
 /** Process an MEM_READ call.
@@ -331,7 +455,16 @@
 		udebug_receive_thread_read(call);
 		break;
+	case UDEBUG_M_NAME_READ:
+		udebug_receive_name_read(call);
+		break;
+	case UDEBUG_M_AREAS_READ:
+		udebug_receive_areas_read(call);
+		break;
 	case UDEBUG_M_ARGS_READ:
 		udebug_receive_args_read(call);
 		break;
+	case UDEBUG_M_REGS_READ:
+		udebug_receive_regs_read(call);
+		break;
 	case UDEBUG_M_MEM_READ:
 		udebug_receive_mem_read(call);
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -46,4 +46,5 @@
 #include <errno.h>
 #include <print.h>
+#include <string.h>
 #include <syscall/copy.h>
 #include <ipc/ipc.h>
@@ -209,7 +210,11 @@
 
 		mutex_lock(&t->udebug.lock);
-		if ((t->flags & THREAD_FLAG_USPACE) != 0)
+		if ((t->flags & THREAD_FLAG_USPACE) != 0) {
 			t->udebug.active = true;
-		mutex_unlock(&t->udebug.lock);
+			mutex_unlock(&t->udebug.lock);
+			condvar_broadcast(&t->udebug.active_cv);
+		} else {
+			mutex_unlock(&t->udebug.lock);
+		}
 	}
 
@@ -355,6 +360,7 @@
  *
  * If the sequence is longer than @a buf_size bytes, only as much hashes
- * as can fit are copied. The number of thread hashes copied is stored
- * in @a n.
+ * as can fit are copied. The number of bytes copied is stored in @a stored.
+ * The total number of thread bytes that could have been saved had there been
+ * enough space is stored in @a needed.
  *
  * The rationale for having @a buf_size is that this function is only
@@ -364,12 +370,15 @@
  * @param buffer	The buffer for storing thread hashes.
  * @param buf_size	Buffer size in bytes.
- * @param n		The actual number of hashes copied will be stored here.
- */
-int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
+ * @param stored	The actual number of bytes copied will be stored here.
+ * @param needed	Total number of hashes that could have been saved.
+ */
+int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored,
+    size_t *needed)
 {
 	thread_t *t;
 	link_t *cur;
 	unative_t tid;
-	unsigned copied_ids;
+	size_t copied_ids;
+	size_t extra_ids;
 	ipl_t ipl;
 	unative_t *id_buffer;
@@ -380,5 +389,5 @@
 
 	/* Allocate a buffer to hold thread IDs */
-	id_buffer = malloc(buf_size, 0);
+	id_buffer = malloc(buf_size + 1, 0);
 
 	mutex_lock(&TASK->udebug.lock);
@@ -396,10 +405,8 @@
 	max_ids = buf_size / sizeof(unative_t);
 	copied_ids = 0;
+	extra_ids = 0;
 
 	/* FIXME: make sure the thread isn't past debug shutdown... */
 	for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
-		/* Do not write past end of buffer */
-		if (copied_ids >= max_ids) break;
-
 		t = list_get_instance(cur, thread_t, th_link);
 
@@ -409,8 +416,13 @@
 
 		/* Not interested in kernel threads. */
-		if ((flags & THREAD_FLAG_USPACE) != 0) {
+		if ((flags & THREAD_FLAG_USPACE) == 0)
+			continue;
+
+		if (copied_ids < max_ids) {
 			/* Using thread struct pointer as identification hash */
 			tid = (unative_t) t;
 			id_buffer[copied_ids++] = tid;
+		} else {
+			extra_ids++;
 		}
 	}
@@ -422,5 +434,29 @@
 
 	*buffer = id_buffer;
-	*n = copied_ids * sizeof(unative_t);
+	*stored = copied_ids * sizeof(unative_t);
+	*needed = (copied_ids + extra_ids) * sizeof(unative_t);
+
+	return 0;
+}
+
+/** Read task name.
+ *
+ * Returns task name as non-terminated string in a newly allocated buffer.
+ * Also returns the size of the data.
+ *
+ * @param data		Place to store pointer to newly allocated block.
+ * @param data_size	Place to store size of the data.
+ *
+ * @returns		EOK.
+ */
+int udebug_name_read(char **data, size_t *data_size)
+{
+	size_t name_size;
+
+	name_size = str_size(TASK->name) + 1;
+	*data = malloc(name_size, 0);
+	*data_size = name_size;
+
+	memcpy(*data, TASK->name, name_size);
 
 	return 0;
@@ -437,5 +473,8 @@
  * this function will fail with an EINVAL error code.
  *
- * @param buffer	The buffer for storing thread hashes.
+ * @param t		Thread where call arguments are to be read.
+ * @param buffer	Place to store pointer to new buffer.
+ * @return		EOK on success, ENOENT if @a t is invalid, EINVAL
+ *			if thread state is not valid for this operation.
  */
 int udebug_args_read(thread_t *t, void **buffer)
@@ -469,4 +508,48 @@
 }
 
+/** Read the register state of the thread.
+ *
+ * The contents of the thread's istate structure are copied to a newly
+ * allocated buffer and a pointer to it is written to @a buffer. The size of
+ * the buffer will be sizeof(istate_t).
+ *
+ * Currently register state cannot be read if the thread is inside a system
+ * call (as opposed to an exception). This is an implementation limit.
+ *
+ * @param t		Thread whose state is to be read.
+ * @param buffer	Place to store pointer to new buffer.
+ * @return		EOK on success, ENOENT if @a t is invalid, EINVAL
+ *			if thread is not in valid state, EBUSY if istate
+ *			is not available.
+ */
+int udebug_regs_read(thread_t *t, void **buffer)
+{
+	istate_t *state, *state_buf;
+	int rc;
+
+	/* Prepare a buffer to hold the data. */
+	state_buf = malloc(sizeof(istate_t), 0);
+
+	/* On success, this will lock t->udebug.lock */
+	rc = _thread_op_begin(t, false);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	state = t->udebug.uspace_state;
+	if (state == NULL) {
+		_thread_op_end(t);
+		return EBUSY;
+	}
+
+	/* Copy to the allocated buffer */
+	memcpy(state_buf, state, sizeof(istate_t));
+
+	_thread_op_end(t);
+
+	*buffer = (void *) state_buf;
+	return 0;
+}
+
 /** Read the memory of the debugged task.
  *
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ tools/toolchain.sh	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -142,5 +142,5 @@
 	
 	BINUTILS_VERSION="2.20"
-	GCC_VERSION="4.4.2"
+	GCC_VERSION="4.4.3"
 	
 	BINUTILS="binutils-${BINUTILS_VERSION}.tar.bz2"
@@ -165,7 +165,7 @@
 	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"
+	download_check "${GCC_SOURCE}" "${GCC_CORE}" "054b66f315b3d04ad06544ce26e72365"
+	download_check "${GCC_SOURCE}" "${GCC_OBJC}" "34711c4de46eaf79aa018206dbec4389"
+	download_check "${GCC_SOURCE}" "${GCC_CPP}" "cd179ec4f05ee17ce76464da25a2674c"
 	
 	echo ">>> Removing previous content"
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -40,4 +40,5 @@
 	app/mkfat \
 	app/redir \
+	app/taskdump \
 	app/tester \
 	app/tetris \
@@ -47,4 +48,5 @@
 	srv/loader \
 	srv/ns \
+	srv/taskmon \
 	srv/vfs \
 	srv/bd/ata_bd \
@@ -57,6 +59,7 @@
 	srv/fs/tmpfs \
 	srv/fs/devfs \
+	srv/hid/adb_mouse \
 	srv/hid/console \
-	srv/hid/c_mouse \
+	srv/hid/char_mouse \
 	srv/hid/fb \
 	srv/hid/kbd \
@@ -69,4 +72,8 @@
 ifeq ($(UARCH),ia32)
 	DIRS += srv/hw/bus/pci
+endif
+
+ifeq ($(UARCH),ppc32)
+	DIRS += srv/hw/bus/cuda_adb
 endif
 
Index: uspace/app/bdsh/Makefile
===================================================================
--- uspace/app/bdsh/Makefile	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/bdsh/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -48,4 +48,5 @@
 	cmds/modules/mv/mv.c \
 	cmds/modules/mount/mount.c \
+	cmds/modules/unmount/unmount.c \
 	cmds/modules/kcon/kcon.c \
 	cmds/builtins/exit/exit.c \
Index: uspace/app/bdsh/cmds/modules/module_aliases.h
===================================================================
--- uspace/app/bdsh/cmds/modules/module_aliases.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/bdsh/cmds/modules/module_aliases.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -14,4 +14,5 @@
 char *mod_aliases[] = {
 	"ren", "mv",
+	"umount", "unmount",
 	NULL, NULL
 };
Index: uspace/app/bdsh/cmds/modules/modules.h
===================================================================
--- uspace/app/bdsh/cmds/modules/modules.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/bdsh/cmds/modules/modules.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -31,4 +31,5 @@
 #include "mv/entry.h"
 #include "mount/entry.h"
+#include "unmount/entry.h"
 #include "kcon/entry.h"
 
@@ -51,4 +52,5 @@
 #include "mv/mv_def.h"
 #include "mount/mount_def.h"
+#include "unmount/unmount_def.h"
 #include "kcon/kcon_def.h"
 
Index: uspace/app/bdsh/cmds/modules/unmount/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/unmount/entry.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/bdsh/cmds/modules/unmount/entry.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,9 @@
+#ifndef UNMOUNT_ENTRY_H
+#define UNMOUNT_ENTRY_H
+
+/* Entry points for the unmount command */
+extern int cmd_unmount(char **);
+extern void help_cmd_unmount(unsigned int);
+
+#endif /* UNMOUNT_ENTRY_H */
+
Index: uspace/app/bdsh/cmds/modules/unmount/unmount.c
===================================================================
--- uspace/app/bdsh/cmds/modules/unmount/unmount.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/bdsh/cmds/modules/unmount/unmount.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 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 <stdio.h>
+#include <stdlib.h>
+#include <vfs/vfs.h>
+#include <errno.h>
+#include "config.h"
+#include "util.h"
+#include "errors.h"
+#include "entry.h"
+#include "unmount.h"
+#include "cmds.h"
+
+static const char *cmdname = "unmount";
+
+/* Dispays help for unmount in various levels */
+void help_cmd_unmount(unsigned int level)
+{
+	if (level == HELP_SHORT) {
+		printf("'%s' unmount a file system.\n", cmdname);
+	} else {
+		help_cmd_unmount(HELP_SHORT);
+		printf("Usage:  %s <mp>\n", cmdname);
+	}
+	return;
+}
+
+/* Main entry point for unmount, accepts an array of arguments */
+int cmd_unmount(char **argv)
+{
+	unsigned int argc;
+	int rc;
+
+	argc = cli_count_args(argv);
+
+	if (argc != 2) {
+		printf("%s: invalid number of arguments.\n",
+		    cmdname);
+		return CMD_FAILURE;
+	}
+
+	rc = unmount(argv[1]);
+	if (rc != EOK) {
+		printf("Unable to unmount %s (rc=%d)\n", argv[1]);
+		return CMD_FAILURE;
+	}
+
+	return CMD_SUCCESS;
+}
+
Index: uspace/app/bdsh/cmds/modules/unmount/unmount.h
===================================================================
--- uspace/app/bdsh/cmds/modules/unmount/unmount.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/bdsh/cmds/modules/unmount/unmount.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,8 @@
+#ifndef UNMOUNT_H
+#define UNMOUNT_H
+
+/* Prototypes for the unmount command, excluding entry points */
+
+
+#endif /* UNMOUNT_H */
+
Index: uspace/app/bdsh/cmds/modules/unmount/unmount_def.h
===================================================================
--- uspace/app/bdsh/cmds/modules/unmount/unmount_def.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/bdsh/cmds/modules/unmount/unmount_def.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,14 @@
+{
+	"unmount",
+	"The unmount command",
+	&cmd_unmount,
+	&help_cmd_unmount,
+},
+
+{
+	"umount",
+	NULL,
+	&cmd_unmount,
+	&help_cmd_unmount,
+},
+
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/init/init.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -94,14 +94,5 @@
 static bool mount_devfs(void)
 {
-	char null[MAX_DEVICE_NAME];
-	int null_id = devmap_null_create();
-	
-	if (null_id == -1) {
-		printf(NAME ": Unable to create null device\n");
-		return false;
-	}
-	
-	snprintf(null, MAX_DEVICE_NAME, "null/%d", null_id);
-	int rc = mount("devfs", DEVFS_MOUNT_POINT, null, "", IPC_FLAG_BLOCKING);
+	int rc = mount("devfs", DEVFS_MOUNT_POINT, "", "", IPC_FLAG_BLOCKING);
 	
 	switch (rc) {
@@ -111,17 +102,13 @@
 	case EBUSY:
 		printf(NAME ": Device filesystem already mounted\n");
-		devmap_null_destroy(null_id);
 		return false;
 	case ELIMIT:
 		printf(NAME ": Unable to mount device filesystem\n");
-		devmap_null_destroy(null_id);
 		return false;
 	case ENOENT:
 		printf(NAME ": Unknown filesystem type (devfs)\n");
-		devmap_null_destroy(null_id);
 		return false;
 	default:
 		printf(NAME ": Error mounting device filesystem (%d)\n", rc);
-		devmap_null_destroy(null_id);
 		return false;
 	}
@@ -184,8 +171,8 @@
 {
 	char *argv[3];
-	char hid_in[MAX_DEVICE_NAME];
+	char hid_in[DEVMAP_NAME_MAXLEN];
 	int rc;
 	
-	snprintf(hid_in, MAX_DEVICE_NAME, "%s/%s", DEVFS_MOUNT_POINT, dev);
+	snprintf(hid_in, DEVMAP_NAME_MAXLEN, "%s/%s", DEVFS_MOUNT_POINT, dev);
 	
 	printf(NAME ": Spawning %s with %s\n", SRV_CONSOLE, hid_in);
@@ -209,8 +196,8 @@
 {
 	char *argv[4];
-	char term[MAX_DEVICE_NAME];
+	char term[DEVMAP_NAME_MAXLEN];
 	int rc;
 	
-	snprintf(term, MAX_DEVICE_NAME, "%s/%s", DEVFS_MOUNT_POINT, dev);
+	snprintf(term, DEVMAP_NAME_MAXLEN, "%s/%s", DEVFS_MOUNT_POINT, dev);
 	
 	printf(NAME ": Spawning %s with %s %s\n", APP_GETTERM, term, app);
@@ -233,4 +220,18 @@
 }
 
+static void mount_scratch(void)
+{
+	int rc;
+
+	printf("Trying to mount null/0 on /scratch... ");
+	fflush(stdout);
+
+	rc = mount("tmpfs", "/scratch", "null/0", "", 0);
+	if (rc == EOK)
+		printf("OK\n");
+	else
+		printf("Failed\n");
+}
+
 static void mount_data(void)
 {
@@ -255,6 +256,12 @@
 		return -1;
 	}
+
+	/* Make sure tmpfs is running. */
+	if (str_cmp(STRING(RDFMT), "tmpfs") != 0) {
+		spawn("/srv/tmpfs");
+	}
 	
 	spawn("/srv/devfs");
+	spawn("/srv/taskmon");
 	
 	if (!mount_devfs()) {
@@ -262,9 +269,13 @@
 		return -2;
 	}
+
+	mount_scratch();
 	
 	spawn("/srv/fhc");
 	spawn("/srv/obio");
+	srv_start("/srv/cuda_adb");
 	srv_start("/srv/i8042");
-	srv_start("/srv/c_mouse");
+	srv_start("/srv/adb_ms");
+	srv_start("/srv/char_ms");
 
 	spawn("/srv/fb");
@@ -298,5 +309,5 @@
 	getterm("term/vc5", "/app/bdsh");
 	getterm("term/vc6", "/app/klog");
-	
+
 	return 0;
 }
Index: uspace/app/init/init.h
===================================================================
--- uspace/app/init/init.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/init/init.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -39,6 +39,4 @@
 #define NAME  "init"
 
-#define MAX_DEVICE_NAME  32
-
 #endif
 
Index: uspace/app/mkfat/mkfat.c
===================================================================
--- uspace/app/mkfat/mkfat.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/mkfat/mkfat.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -44,4 +44,7 @@
 #include <devmap.h>
 #include <byteorder.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include <inttypes.h>
 #include <errno.h>
 #include "fat.h"
@@ -157,5 +160,6 @@
 		printf(NAME ": Warning, failed to obtain block device size.\n");
 	} else {
-		printf(NAME ": Block device has %llu blocks.\n", dev_nblocks);
+		printf(NAME ": Block device has %" PRIuBN " blocks.\n",
+		    dev_nblocks);
 		cfg.total_sectors = dev_nblocks;
 	}
Index: uspace/app/taskdump/Makefile
===================================================================
--- uspace/app/taskdump/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/taskdump/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2010 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBC_PREFIX)/libc.a
+EXTRA_CFLAGS = -Iinclude
+
+OUTPUT = taskdump
+
+SOURCES = \
+	elf_core.c \
+	taskdump.c \
+	symtab.c
+
+include ../Makefile.common
Index: uspace/app/taskdump/elf_core.c
===================================================================
--- uspace/app/taskdump/elf_core.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/taskdump/elf_core.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2010 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 taskdump
+ * @{
+ */
+/** @file Write ELF core files.
+ *
+ * Creates ELF core files. Core files do not seem to be specified by some
+ * standard (the System V ABI explicitely states that it does not specify
+ * them).
+ *
+ * Looking at core files produced by Linux, these don't have section headers,
+ * only program headers, although objdump shows them as having sections.
+ * Basically at the beginning there should be a note segment (which we
+ * do not write) and one loadable segment per memory area (which we do write).
+ *
+ * The note segment probably contains register state, etc. -- we don't
+ * deal with these yet. Nevertheless you can use these core files with
+ * objdump or gdb.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <mem.h>
+#include <stdint.h>
+#include <as.h>
+#include <udebug.h>
+#include <macros.h>
+
+#include <elf.h>
+#include "include/elf_core.h"
+
+static off_t align_foff_up(off_t foff, uintptr_t vaddr, size_t page_size);
+static int write_all(int fd, void *data, size_t len);
+static int write_mem_area(int fd, as_area_info_t *area, int phoneid);
+
+#define BUFFER_SIZE 0x1000
+static uint8_t buffer[BUFFER_SIZE];
+
+/** Save ELF core file.
+ *
+ * @param file_name	Name of file to save to.
+ * @param ainfo		Array of @a n memory area info structures.
+ * @param n		Number of memory areas.
+ * @param phoneid	Debugging phone.
+ *
+ * @return		EOK on sucess, ENOENT if file cannot be created,
+ *			ENOMEM on out of memory, EIO on write error.
+ */
+int elf_core_save(const char *file_name, as_area_info_t *ainfo, int n, int phoneid)
+{
+	elf_header_t elf_hdr;
+	off_t foff;
+	size_t n_ph;
+	elf_word flags;
+	elf_segment_header_t *p_hdr;
+
+	int fd;
+	int rc;
+	int i;
+
+	n_ph = n;
+
+	p_hdr = malloc(sizeof(elf_segment_header_t) * n);
+	if (p_hdr == NULL) {
+		printf("Failed allocating memory.\n");
+		return ENOMEM;
+	}
+
+	fd = open(file_name, O_CREAT | O_WRONLY, 0644);
+	if (fd < 0) {
+		printf("Failed opening file.\n");
+		free(p_hdr);
+		return ENOENT;
+	}
+
+	/*
+	 * File layout:
+	 *
+	 * 	ELF header
+	 *	program headers
+	 * repeat:
+	 *	(pad for alignment)
+	 *	segment data
+	 * end repeat
+	 */
+
+	memset(&elf_hdr, 0, sizeof(elf_hdr));
+	elf_hdr.e_ident[EI_MAG0] = ELFMAG0;
+	elf_hdr.e_ident[EI_MAG1] = ELFMAG1;
+	elf_hdr.e_ident[EI_MAG2] = ELFMAG2;
+	elf_hdr.e_ident[EI_MAG3] = ELFMAG3;
+	elf_hdr.e_ident[EI_CLASS] = ELF_CLASS;
+	elf_hdr.e_ident[EI_DATA] = ELF_DATA_ENCODING;
+	elf_hdr.e_ident[EI_VERSION] = EV_CURRENT;
+
+	elf_hdr.e_type = ET_CORE;
+	elf_hdr.e_machine = ELF_MACHINE;
+	elf_hdr.e_version = EV_CURRENT;
+	elf_hdr.e_entry = 0;
+	elf_hdr.e_phoff = sizeof(elf_header_t);
+	elf_hdr.e_shoff = 0;
+	elf_hdr.e_flags = 0;
+	elf_hdr.e_ehsize = sizeof(elf_hdr);
+	elf_hdr.e_phentsize = sizeof(elf_segment_header_t);
+	elf_hdr.e_phnum = n_ph;
+	elf_hdr.e_shentsize = 0;
+	elf_hdr.e_shnum = 0;
+	elf_hdr.e_shstrndx = 0;
+
+	/* foff is used for allocation of file space for segment data. */
+	foff = elf_hdr.e_phoff + n_ph * sizeof(elf_segment_header_t);
+
+	for (i = 1; i <= n; ++i) {
+		foff = align_foff_up(foff, ainfo[i - 1].start_addr, PAGE_SIZE);
+
+		flags = 0;
+		if (ainfo[i - 1].flags & AS_AREA_READ)
+			flags |= PF_R;
+		if (ainfo[i - 1].flags & AS_AREA_WRITE)
+			flags |= PF_W;
+		if (ainfo[i - 1].flags & AS_AREA_EXEC)
+			flags |= PF_X;
+
+		memset(&p_hdr[i - 1], 0, sizeof(p_hdr[i - 1]));
+		p_hdr[i - 1].p_type = PT_LOAD;
+		p_hdr[i - 1].p_offset = foff;
+		p_hdr[i - 1].p_vaddr = ainfo[i - 1].start_addr;
+		p_hdr[i - 1].p_paddr = 0;
+		p_hdr[i - 1].p_filesz = ainfo[i - 1].size;
+		p_hdr[i - 1].p_memsz = ainfo[i - 1].size;
+		p_hdr[i - 1].p_flags = flags;
+		p_hdr[i - 1].p_align = PAGE_SIZE;
+
+		foff += ainfo[i - 1].size;
+	}
+
+	rc = write_all(fd, &elf_hdr, sizeof(elf_hdr));
+	if (rc != EOK) {
+		printf("Failed writing ELF header.\n");
+		free(p_hdr);
+		return EIO;
+	}
+
+	for (i = 0; i < n_ph; ++i) {
+		rc = write_all(fd, &p_hdr[i], sizeof(p_hdr[i]));
+		if (rc != EOK) {
+			printf("Failed writing program header.\n");
+			free(p_hdr);
+			return EIO;
+		}
+	}
+
+	for (i = 0; i < n_ph; ++i) {
+		if (lseek(fd, p_hdr[i].p_offset, SEEK_SET) == (off_t) -1) {
+			printf("Failed writing memory data.\n");
+			free(p_hdr);
+			return EIO;
+		}
+		if (write_mem_area(fd, &ainfo[i], phoneid) != EOK) {
+			printf("Failed writing memory data.\n");
+			free(p_hdr);
+			return EIO;
+		}
+	}
+
+	free(p_hdr);
+
+	return EOK;
+}
+
+/** Align file offset up to be congruent with vaddr modulo page size. */
+static off_t align_foff_up(off_t foff, uintptr_t vaddr, size_t page_size)
+{
+	off_t rfo, rva;
+	off_t advance;
+
+	rva = vaddr % page_size;
+	rfo = foff % page_size;
+
+	advance = (rva >= rfo) ? rva - rfo : (page_size + rva - rfo);
+	return foff + advance;
+}
+
+/** Write memory area from application to core file.
+ *
+ * @param fd		File to write to.
+ * @param area		Memory area info structure.
+ * @param phoneid	Debugging phone.
+ *
+ * @return		EOK on success, EIO on failure.
+ */
+static int write_mem_area(int fd, as_area_info_t *area, int phoneid)
+{
+	size_t to_copy;
+	size_t total;
+	uintptr_t addr;
+	int rc;
+
+	addr = area->start_addr;
+	total = 0;
+
+	while (total < area->size) {
+		to_copy = min(area->size - total, BUFFER_SIZE);
+		rc = udebug_mem_read(phoneid, buffer, addr, to_copy);
+		if (rc < 0) {
+			printf("Failed reading task memory.\n");
+			return EIO;
+		}
+
+		rc = write_all(fd, buffer, to_copy);
+		if (rc != EOK) {
+			printf("Failed writing memory contents.\n");
+			return EIO;
+		}
+
+		addr += to_copy;
+		total += to_copy;
+	}
+
+	return EOK;
+}
+
+/** Write until the buffer is written in its entirety.
+ *
+ * This function fails if it cannot write exactly @a len bytes to the file.
+ *
+ * @param fd		The file to write to.
+ * @param buf		Data, @a len bytes long.
+ * @param len		Number of bytes to write.
+ *
+ * @return		EOK on error, return value from write() if writing
+ *			failed.
+ */
+static int write_all(int fd, void *data, size_t len)
+{
+	int cnt = 0;
+
+	do {
+		data += cnt;
+		len -= cnt;
+		cnt = write(fd, data, len);
+	} while (cnt > 0 && (len - cnt) > 0);
+
+	if (cnt < 0)
+		return cnt;
+
+	if (len - cnt > 0)
+		return EIO;
+
+	return EOK;
+}
+
+
+/** @}
+ */
Index: uspace/app/taskdump/include/elf.h
===================================================================
--- uspace/app/taskdump/include/elf.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/taskdump/include/elf.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2006 Sergey Bondari
+ * 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 ELF_H_
+#define ELF_H_
+
+#include <arch/elf.h>
+#include <sys/types.h>
+
+/**
+ * current ELF version
+ */
+#define	EV_CURRENT	1
+
+/** 
+ * ELF types 
+ */
+#define ET_NONE		0	/* No type */
+#define ET_REL		1	/* Relocatable file */
+#define ET_EXEC		2	/* Executable */
+#define ET_DYN		3	/* Shared object */
+#define ET_CORE		4	/* Core */
+#define ET_LOPROC	0xff00	/* Processor specific */
+#define ET_HIPROC	0xffff	/* Processor specific */
+
+/** 
+ * ELF machine types
+ */
+#define EM_NO		0	/* No machine */
+#define EM_SPARC	2	/* SPARC */
+#define EM_386		3	/* i386 */
+#define EM_MIPS		8	/* MIPS RS3000 */
+#define EM_MIPS_RS3_LE	10	/* MIPS RS3000 LE */
+#define EM_PPC		20	/* PPC32 */
+#define EM_PPC64	21	/* PPC64 */
+#define EM_ARM		40	/* ARM */
+#define EM_SPARCV9	43	/* SPARC64 */
+#define EM_IA_64	50	/* IA-64 */
+#define EM_X86_64	62	/* AMD64/EMT64 */
+
+/**
+ * ELF identification indexes
+ */
+#define EI_MAG0		0
+#define EI_MAG1		1
+#define EI_MAG2		2
+#define EI_MAG3		3
+#define EI_CLASS	4		/* File class */
+#define EI_DATA		5		/* Data encoding */
+#define EI_VERSION	6		/* File version */
+#define EI_OSABI	7
+#define EI_ABIVERSION	8
+#define EI_PAD		9		/* Start of padding bytes */
+#define EI_NIDENT	16		/* ELF identification table size */
+
+/**
+ * ELF magic number
+ */
+#define ELFMAG0		0x7f
+#define ELFMAG1		'E'
+#define ELFMAG2		'L'
+#define ELFMAG3		'F'
+
+/**
+ * ELF file classes
+ */
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+
+/**
+ * ELF data encoding types
+ */
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1		/* Least significant byte first (little endian) */
+#define ELFDATA2MSB	2		/* Most signigicant byte first (big endian) */
+
+/**
+ * ELF error return codes
+ */
+#define EE_OK			0	/* No error */
+#define EE_INVALID		1	/* Invalid ELF image */
+#define	EE_MEMORY		2	/* Cannot allocate address space */
+#define EE_INCOMPATIBLE		3	/* ELF image is not compatible with current architecture */
+#define EE_UNSUPPORTED		4	/* Non-supported ELF (e.g. dynamic ELFs) */
+#define EE_IRRECOVERABLE	5
+
+/**
+ * ELF section types
+ */
+#define SHT_NULL		0
+#define SHT_PROGBITS		1
+#define SHT_SYMTAB		2
+#define SHT_STRTAB		3
+#define SHT_RELA		4
+#define SHT_HASH		5
+#define SHT_DYNAMIC		6
+#define SHT_NOTE		7
+#define SHT_NOBITS		8
+#define SHT_REL			9
+#define SHT_SHLIB		10
+#define SHT_DYNSYM		11
+#define SHT_LOOS		0x60000000
+#define SHT_HIOS		0x6fffffff
+#define SHT_LOPROC		0x70000000
+#define SHT_HIPROC		0x7fffffff
+#define SHT_LOUSER		0x80000000
+#define SHT_HIUSER		0xffffffff
+
+/**
+ * ELF section flags
+ */
+#define SHF_WRITE		0x1 
+#define SHF_ALLOC		0x2
+#define SHF_EXECINSTR		0x4
+#define SHF_TLS			0x400
+#define SHF_MASKPROC		0xf0000000
+
+/** Macros for decomposing elf_symbol.st_info into binging and type */
+#define ELF_ST_BIND(i)		((i) >> 4)
+#define ELF_ST_TYPE(i)		((i) & 0x0f)
+#define ELF_ST_INFO(b, t)	(((b) << 4) + ((t) & 0x0f))
+
+/**
+ * Symbol binding
+ */
+#define STB_LOCAL		0
+#define STB_GLOBAL		1
+#define STB_WEAK		2
+#define STB_LOPROC		13
+#define STB_HIPROC		15
+
+/**
+ * Symbol types
+ */
+#define STT_NOTYPE		0
+#define STT_OBJECT		1
+#define STT_FUNC		2
+#define STT_SECTION		3
+#define STT_FILE		4
+#define STT_LOPROC		13
+#define STT_HIPROC		15
+
+/**
+ * Program segment types
+ */
+#define PT_NULL			0
+#define PT_LOAD			1
+#define PT_DYNAMIC		2
+#define PT_INTERP		3
+#define PT_NOTE			4
+#define PT_SHLIB		5
+#define PT_PHDR			6
+#define PT_LOPROC		0x70000000
+#define PT_HIPROC		0x7fffffff
+
+/**
+ * Program segment attributes.
+ */
+#define PF_X	1
+#define PF_W	2
+#define PF_R	4
+
+/**
+ * ELF data types
+ *
+ * These types are found to be identical in both 32-bit and 64-bit
+ * ELF object file specifications. They are the only types used
+ * in ELF header.
+ */
+typedef uint64_t elf_xword;
+typedef int64_t elf_sxword;
+typedef uint32_t elf_word;
+typedef int32_t elf_sword;
+typedef uint16_t elf_half;
+
+/**
+ * 32-bit ELF data types.
+ *
+ * These types are specific for 32-bit format.
+ */
+typedef uint32_t elf32_addr;
+typedef uint32_t elf32_off;
+
+/**
+ * 64-bit ELF data types.
+ *
+ * These types are specific for 64-bit format.
+ */
+typedef uint64_t elf64_addr;
+typedef uint64_t elf64_off;
+
+/** ELF header */
+struct elf32_header {
+	uint8_t e_ident[EI_NIDENT];
+	elf_half e_type;
+	elf_half e_machine;
+	elf_word e_version;
+	elf32_addr e_entry;
+	elf32_off e_phoff;
+	elf32_off e_shoff;
+	elf_word e_flags;
+	elf_half e_ehsize;
+	elf_half e_phentsize;
+	elf_half e_phnum;
+	elf_half e_shentsize;
+	elf_half e_shnum;
+	elf_half e_shstrndx;
+};
+struct elf64_header {
+	uint8_t e_ident[EI_NIDENT];
+	elf_half e_type;
+	elf_half e_machine;
+	elf_word e_version;
+	elf64_addr e_entry;
+	elf64_off e_phoff;
+	elf64_off e_shoff;
+	elf_word e_flags;
+	elf_half e_ehsize;
+	elf_half e_phentsize;
+	elf_half e_phnum;
+	elf_half e_shentsize;
+	elf_half e_shnum;
+	elf_half e_shstrndx;
+};
+
+/*
+ * ELF segment header.
+ * Segments headers are also known as program headers.
+ */
+struct elf32_segment_header {
+	elf_word p_type;
+	elf32_off p_offset;
+	elf32_addr p_vaddr;
+	elf32_addr p_paddr;
+	elf_word p_filesz;
+	elf_word p_memsz;
+	elf_word p_flags;
+	elf_word p_align;
+};
+struct elf64_segment_header {
+	elf_word p_type;
+	elf_word p_flags;
+	elf64_off p_offset;
+	elf64_addr p_vaddr;
+	elf64_addr p_paddr;
+	elf_xword p_filesz;
+	elf_xword p_memsz;
+	elf_xword p_align;
+};
+
+/*
+ * ELF section header
+ */
+struct elf32_section_header {
+	elf_word sh_name;
+	elf_word sh_type;
+	elf_word sh_flags;
+	elf32_addr sh_addr;
+	elf32_off sh_offset;
+	elf_word sh_size;
+	elf_word sh_link;
+	elf_word sh_info;
+	elf_word sh_addralign;
+	elf_word sh_entsize;
+};
+struct elf64_section_header {
+	elf_word sh_name;
+	elf_word sh_type;
+	elf_xword sh_flags;
+	elf64_addr sh_addr;
+	elf64_off sh_offset;
+	elf_xword sh_size;
+	elf_word sh_link;
+	elf_word sh_info;
+	elf_xword sh_addralign;
+	elf_xword sh_entsize;
+};
+
+/*
+ * ELF symbol table entry
+ */
+struct elf32_symbol {
+	elf_word st_name;
+	elf32_addr st_value;
+	elf_word st_size;
+	uint8_t st_info;
+	uint8_t st_other;
+	elf_half st_shndx;
+};
+struct elf64_symbol {
+	elf_word st_name;
+	uint8_t st_info;
+	uint8_t st_other;
+	elf_half st_shndx;
+	elf64_addr st_value;
+	elf_xword st_size;
+};
+
+#ifdef __32_BITS__ 
+typedef struct elf32_header elf_header_t;
+typedef struct elf32_segment_header elf_segment_header_t;
+typedef struct elf32_section_header elf_section_header_t;
+typedef struct elf32_symbol elf_symbol_t;
+#endif
+#ifdef __64_BITS__
+typedef struct elf64_header elf_header_t;
+typedef struct elf64_segment_header elf_segment_header_t;
+typedef struct elf64_section_header elf_section_header_t;
+typedef struct elf64_symbol elf_symbol_t;
+#endif
+
+extern char *elf_error(unsigned int rc);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/taskdump/include/elf_core.h
===================================================================
--- uspace/app/taskdump/include/elf_core.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/taskdump/include/elf_core.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 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 debug
+ * @{
+ */
+/** @file
+ */
+
+#ifndef ELF_CORE_H_
+#define ELF_CORE_H_
+
+int elf_core_save(const char *file_name, as_area_info_t *ainfo, int n, int phoneid);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/taskdump/include/symtab.h
===================================================================
--- uspace/app/taskdump/include/symtab.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/taskdump/include/symtab.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008 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 debug
+ * @{
+ */
+/** @file
+ */
+
+#ifndef SYMTAB_H_
+#define SYMTAB_H_
+
+#include <sys/types.h>
+#include <elf.h>
+
+typedef struct {
+	/** Symbol section */
+	elf_symbol_t *sym;
+	size_t sym_size;
+	/** String table */
+	char *strtab;
+	size_t strtab_size;
+} symtab_t;
+
+extern int symtab_load(const char *file_name, symtab_t **symtab);
+extern void symtab_delete(symtab_t *st);
+extern int symtab_name_to_addr(symtab_t *st, char *name, uintptr_t *addr);
+extern int symtab_addr_to_name(symtab_t *symtab, uintptr_t addr, char **name,
+    size_t *offs);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/taskdump/symtab.c
===================================================================
--- uspace/app/taskdump/symtab.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/taskdump/symtab.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2010 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 debug
+ * @{
+ */
+/** @file Handling of ELF symbol tables.
+ *
+ * This module allows one to load a symbol table from an ELF file and
+ * use it to lookup symbol names/addresses in both directions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <elf.h>
+#include "include/symtab.h"
+
+static int elf_hdr_check(elf_header_t *hdr);
+static int section_hdr_load(int fd, const elf_header_t *ehdr, int idx,
+    elf_section_header_t *shdr);
+static int chunk_load(int fd, off_t start, off_t size, void **ptr);
+static int read_all(int fd, void *buf, size_t len);
+
+/** Load symbol table from an ELF file.
+ *
+ * @param file_name	Name of the ELF file to read from.
+ * @param symtab	Place to save pointer to new symtab structure.
+ *
+ * @return		EOK on success, ENOENT if file could not be open,
+ *			ENOTSUP if file parsing failed.
+ */
+int symtab_load(const char *file_name, symtab_t **symtab)
+{
+	symtab_t *stab;
+	elf_header_t elf_hdr;
+	elf_section_header_t sec_hdr;
+	off_t shstrt_start, shstrt_size;
+	char *shstrt, *sec_name;
+	void *data;
+
+	int fd;
+	int rc;
+	int i;
+
+	bool load_sec, sec_is_symtab;
+
+	*symtab = NULL;
+
+	stab = calloc(1, sizeof(symtab_t));
+	if (stab == NULL)
+		return ENOMEM;
+
+	fd = open(file_name, O_RDONLY);
+	if (fd < 0) {
+		printf("failed opening file\n");
+		free(stab);
+		return ENOENT;
+	}
+
+	rc = read_all(fd, &elf_hdr, sizeof(elf_header_t));
+	if (rc != EOK) {
+		printf("failed reading elf header\n");
+		free(stab);
+		return EIO;
+	}
+
+	rc = elf_hdr_check(&elf_hdr);
+	if (rc != EOK) {
+		printf("failed header check\n");
+		free(stab);
+		return ENOTSUP;
+	}
+
+	/*
+	 * Load section header string table.
+	 */
+
+	rc = section_hdr_load(fd, &elf_hdr, elf_hdr.e_shstrndx, &sec_hdr);
+	if (rc != EOK) {
+		printf("failed reading shstrt header\n");
+		free(stab);
+		return ENOTSUP;
+	}
+
+	shstrt_start = sec_hdr.sh_offset;
+	shstrt_size = sec_hdr.sh_size;
+
+	rc = chunk_load(fd, shstrt_start, shstrt_size, (void **) &shstrt);
+	if (rc != EOK) {
+		printf("failed loading shstrt\n");
+		free(stab);
+		return ENOTSUP;
+	}
+
+	/* Read all section headers. */
+	for (i = 0; i < elf_hdr.e_shnum; ++i) {
+		rc = section_hdr_load(fd, &elf_hdr, i, &sec_hdr);
+		if (rc != EOK) {
+			free(shstrt);
+			free(stab);
+			return ENOTSUP;
+		}
+
+		sec_name = shstrt + sec_hdr.sh_name;
+		if (str_cmp(sec_name, ".symtab") == 0 &&
+		    sec_hdr.sh_type == SHT_SYMTAB) {
+			load_sec = true;
+			sec_is_symtab = true;
+		} else if (str_cmp(sec_name, ".strtab") == 0 &&
+		    sec_hdr.sh_type == SHT_STRTAB) {
+			load_sec = true;
+			sec_is_symtab = false;
+		} else {
+			load_sec = false;
+		}
+
+		if (load_sec) {
+			rc = chunk_load(fd, sec_hdr.sh_offset, sec_hdr.sh_size,
+			    &data);
+			if (rc != EOK) {
+				free(shstrt);
+				free(stab);
+				return ENOTSUP;
+			}
+
+			if (sec_is_symtab) {
+				stab->sym = data;
+				stab->sym_size = sec_hdr.sh_size;
+			} else {
+				stab->strtab = data;
+				stab->strtab_size = sec_hdr.sh_size;
+			}
+		}
+	}
+
+	free(shstrt);
+	close(fd);
+
+	if (stab->sym == NULL || stab->strtab == NULL) {
+		/* Tables not found. */
+		printf("Symbol table or string table section not found\n");
+		free(stab);
+		return ENOTSUP;
+	}
+
+	*symtab = stab;
+
+	return EOK;
+}
+
+/** Delete a symtab structure.
+ *
+ * Deallocates all resources used by the symbol table.
+ */
+void symtab_delete(symtab_t *st)
+{
+	free(st->sym);
+	st->sym = NULL;
+
+	free(st->strtab);
+	st->strtab = NULL;
+
+	free(st);
+}
+
+/** Convert symbol name to address.
+ *
+ * @param st	Symbol table.
+ * @param name	Name of the symbol.
+ * @param addr	Place to store address for symbol, if found.
+ *
+ * @return	EOK on success, ENOENT if no such symbol was found.
+ */
+int symtab_name_to_addr(symtab_t *st, char *name, uintptr_t *addr)
+{
+	size_t i;
+	char *sname;
+	unsigned stype;
+
+	for (i = 0; i < st->sym_size / sizeof(elf_symbol_t); ++i) {
+		if (st->sym[i].st_name == 0)
+			continue;
+
+		stype = ELF_ST_TYPE(st->sym[i].st_info);
+		if (stype != STT_OBJECT && stype != STT_FUNC)
+			continue;
+
+		sname = st->strtab + st->sym[i].st_name;
+
+		if (str_cmp(sname, name) == 0) {
+			*addr = st->sym[i].st_value;
+			return EOK;
+		}
+	}
+
+	return ENOENT;
+}
+
+/** Convert symbol address to name.
+ *
+ * This function finds the symbol which starts at the highest address
+ * less than or equal to @a addr.
+ *
+ * @param st	Symbol table.
+ * @param addr	Address for lookup.
+ * @param name	Place to store pointer name of symbol, if found.
+ *		This is valid while @a st exists.
+ *
+ * @return	EOK on success or ENOENT if no matching symbol was found.
+ */
+int symtab_addr_to_name(symtab_t *st, uintptr_t addr, char **name,
+    size_t *offs)
+{
+	size_t i;
+	uintptr_t saddr, best_addr;
+	char *sname, *best_name;
+	unsigned stype;
+
+	best_name = NULL;
+	best_addr = 0;
+
+	for (i = 0; i < st->sym_size / sizeof(elf_symbol_t); ++i) {
+		if (st->sym[i].st_name == 0)
+			continue;
+
+		stype = ELF_ST_TYPE(st->sym[i].st_info);
+		if (stype != STT_OBJECT && stype != STT_FUNC &&
+		    stype != STT_NOTYPE) {
+			continue;
+		}
+
+		saddr = st->sym[i].st_value;
+		sname = st->strtab + st->sym[i].st_name;
+
+		/* An ugly hack to filter out some special ARM symbols. */
+		if (sname[0] == '$')
+			continue;
+
+		if (best_name == NULL || (saddr <= addr && saddr > best_addr)) {
+			best_name = sname;
+			best_addr = saddr;
+		}
+	}
+
+	if (best_name == NULL)
+		return ENOENT;
+
+	*name = best_name;
+	*offs = addr - best_addr;
+	return EOK;
+}
+
+/** Check if ELF header is valid.
+ *
+ * @return	EOK on success or negative error code.
+ */
+static int elf_hdr_check(elf_header_t *ehdr)
+{
+	/* TODO */
+	return EOK;
+}
+
+/** Load ELF section header.
+ *
+ * @param fd		File descriptor of ELF file.
+ * @param elf_hdr	Pointer to ELF file header in memory.
+ * @param idx		Index of section whose header to load (0 = first).
+ * @param sec_hdr	Place to store section header data.
+ *
+ * @return		EOK on success or EIO if I/O failed.
+ */
+static int section_hdr_load(int fd, const elf_header_t *elf_hdr, int idx,
+    elf_section_header_t *sec_hdr)
+{
+	int rc;
+
+	rc = lseek(fd, elf_hdr->e_shoff + idx * sizeof(elf_section_header_t),
+	    SEEK_SET);
+	if (rc == (off_t) -1)
+		return EIO;
+
+	rc = read_all(fd, sec_hdr, sizeof(elf_section_header_t));
+	if (rc != EOK)
+		return EIO;
+
+	return EOK;
+}
+
+/** Load a segment of bytes from a file and return it as a new memory block.
+ *
+ * This function fails if it cannot read exactly @a size bytes from the file.
+ *
+ * @param fd		File to read from.
+ * @param start		Position in file where to start reading.
+ * @param size		Number of bytes to read.
+ * @param ptr		Place to store pointer to newly allocated block.
+ *
+ * @return		EOK on success or EIO on failure.
+ */
+static int chunk_load(int fd, off_t start, off_t size, void **ptr)
+{
+	int rc;
+
+	rc = lseek(fd, start, SEEK_SET);
+	if (rc == (off_t) -1) {
+		printf("failed seeking chunk\n");
+		*ptr = NULL;
+		return EIO;
+	}
+
+	*ptr = malloc(size);
+	if (*ptr == NULL) {
+		printf("failed allocating memory\n");
+		return ENOMEM;
+	}
+
+	rc = read_all(fd, *ptr, size);
+	if (rc != EOK) {
+		printf("failed reading chunk\n");
+		free(*ptr);
+		*ptr = NULL;
+		return EIO;
+	}
+
+	return EOK;
+}
+
+/** Read until the buffer is read in its entirety.
+ *
+ * This function fails if it cannot read exactly @a len bytes from the file.
+ *
+ * @param fd		The file to read from.
+ * @param buf		Buffer for storing data, @a len bytes long.
+ * @param len		Number of bytes to read.
+ *
+ * @return		EOK on error, EIO if file is short or return value
+ *			from read() if reading failed.
+ */
+static int read_all(int fd, void *buf, size_t len)
+{
+	int cnt = 0;
+
+	do {
+		buf += cnt;
+		len -= cnt;
+		cnt = read(fd, buf, len);
+	} while (cnt > 0 && (len - cnt) > 0);
+
+	if (cnt < 0)
+		return cnt;
+
+	if (len - cnt > 0)
+		return EIO;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/app/taskdump/taskdump.c
===================================================================
--- uspace/app/taskdump/taskdump.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/app/taskdump/taskdump.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2010 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 taskdump
+ * @{
+ */
+/** @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ipc/ipc.h>
+#include <errno.h>
+#include <udebug.h>
+#include <task.h>
+#include <as.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include <libarch/istate.h>
+#include <macros.h>
+#include <assert.h>
+#include <bool.h>
+
+#include <symtab.h>
+#include <elf_core.h>
+#include <stacktrace.h>
+
+#define LINE_BYTES 16
+
+#define DBUF_SIZE 4096
+static uint8_t data_buf[DBUF_SIZE];
+
+static int phoneid;
+static task_id_t task_id;
+static bool write_core_file;
+static char *core_file_name;
+static char *app_name;
+static symtab_t *app_symtab;
+
+static int connect_task(task_id_t task_id);
+static int parse_args(int argc, char *argv[]);
+static void print_syntax(void);
+static int threads_dump(void);
+static int thread_dump(uintptr_t thash);
+static int areas_dump(void);
+static int area_dump(as_area_info_t *area);
+static void hex_dump(uintptr_t addr, void *buffer, size_t size);
+static int td_read_uintptr(void *arg, uintptr_t addr, uintptr_t *value);
+
+static void autoload_syms(void);
+static char *get_app_task_name(void);
+static char *fmt_sym_address(uintptr_t addr);
+
+int main(int argc, char *argv[])
+{
+	int rc;
+
+	printf("Task Dump Utility\n");
+	write_core_file = false;
+
+	if (parse_args(argc, argv) < 0)
+		return 1;
+
+	rc = connect_task(task_id);
+	if (rc < 0) {
+		printf("Failed connecting to task %" PRIdTASKID ".\n", task_id);
+		return 1;
+	}
+
+	app_name = get_app_task_name();
+	app_symtab = NULL;
+
+	printf("Dumping task '%s' (task ID %" PRIdTASKID ").\n", app_name, task_id);
+	autoload_syms();
+	putchar('\n');
+
+	rc = threads_dump();
+	if (rc < 0)
+		printf("Failed dumping threads.\n");
+
+	rc = areas_dump();
+	if (rc < 0)
+		printf("Failed dumping address space areas.\n");
+
+	udebug_end(phoneid);
+	ipc_hangup(phoneid);
+
+	return 0;
+}
+
+static int connect_task(task_id_t task_id)
+{
+	int rc;
+
+	rc = ipc_connect_kbox(task_id);
+
+	if (rc == ENOTSUP) {
+		printf("You do not have userspace debugging support "
+		    "compiled in the kernel.\n");
+		printf("Compile kernel with 'Support for userspace debuggers' "
+		    "(CONFIG_UDEBUG) enabled.\n");
+		return rc;
+	}
+
+	if (rc < 0) {
+		printf("Error connecting\n");
+		printf("ipc_connect_task(%" PRIdTASKID ") -> %d ", task_id, rc);
+		return rc;
+	}
+
+	phoneid = rc;
+
+	rc = udebug_begin(phoneid);
+	if (rc < 0) {
+		printf("udebug_begin() -> %d\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int parse_args(int argc, char *argv[])
+{
+	char *arg;
+	char *err_p;
+
+	task_id = 0;
+
+	--argc; ++argv;
+
+	while (argc > 0) {
+		arg = *argv;
+		if (arg[0] == '-') {
+			if (arg[1] == 't' && arg[2] == '\0') {
+				/* Task ID */
+				--argc; ++argv;
+				task_id = strtol(*argv, &err_p, 10);
+				if (*err_p) {
+					printf("Task ID syntax error\n");
+					print_syntax();
+					return -1;
+				}
+			} else if (arg[1] == 'c' && arg[2] == '\0') {
+				write_core_file = true;
+
+				--argc; ++argv;
+				core_file_name = *argv;
+			} else {
+				printf("Uknown option '%s'\n", arg[0]);
+				print_syntax();
+				return -1;
+			}
+		} else {
+			break;
+		}
+
+		--argc; ++argv;
+	}
+
+	if (task_id == 0) {
+		printf("Missing task ID argument\n");
+		print_syntax();
+		return -1;
+	}
+
+	if (argc != 0) {
+		printf("Extra arguments\n");
+		print_syntax();
+		return -1;
+	}
+
+	return 0;
+}
+
+static void print_syntax(void)
+{
+	printf("Syntax: taskdump [-c <core_file>] -t <task_id>\n");
+	printf("\t-c <core_file_id>\tName of core file to write.\n");
+	printf("\t-t <task_id>\tWhich task to dump.\n");
+}
+
+static int threads_dump(void)
+{
+	uintptr_t *thash_buf;
+	uintptr_t dummy_buf;
+	size_t buf_size, n_threads;
+
+	size_t copied;
+	size_t needed;
+	size_t i;
+	int rc;
+
+	/* TODO: See why NULL does not work. */
+	rc = udebug_thread_read(phoneid, &dummy_buf, 0, &copied, &needed);
+	if (rc < 0) {
+		printf("udebug_thread_read() -> %d\n", rc);
+		return rc;
+	}
+
+	if (needed == 0) {
+		printf("No threads.\n\n");
+		return 0;
+	}
+
+	buf_size = needed;
+	thash_buf = malloc(buf_size);
+
+	rc = udebug_thread_read(phoneid, thash_buf, buf_size, &copied, &needed);
+	if (rc < 0) {
+		printf("udebug_thread_read() -> %d\n", rc);
+		return rc;
+	}
+
+	assert(copied == buf_size);
+	assert(needed == buf_size);
+
+	n_threads = copied / sizeof(uintptr_t);
+
+	printf("Threads:\n");
+	for (i = 0; i < n_threads; i++) {
+		printf(" [%d] hash: %p\n", 1+i, thash_buf[i]);
+
+		thread_dump(thash_buf[i]);
+	}
+	putchar('\n');
+
+	free(thash_buf);
+
+	return 0;
+}
+
+static int areas_dump(void)
+{
+	as_area_info_t *ainfo_buf;
+	as_area_info_t dummy_buf;
+	size_t buf_size, n_areas;
+
+	size_t copied;
+	size_t needed;
+	size_t i;
+	int rc;
+
+	rc = udebug_areas_read(phoneid, &dummy_buf, 0, &copied, &needed);
+	if (rc < 0) {
+		printf("udebug_areas_read() -> %d\n", rc);
+		return rc;
+	}
+
+	buf_size = needed;
+	ainfo_buf = malloc(buf_size);
+
+	rc = udebug_areas_read(phoneid, ainfo_buf, buf_size, &copied, &needed);
+	if (rc < 0) {
+		printf("udebug_areas_read() -> %d\n", rc);
+		return rc;
+	}
+
+	assert(copied == buf_size);
+	assert(needed == buf_size);
+
+	n_areas = copied / sizeof(as_area_info_t);
+
+	printf("Address space areas:\n");
+	for (i = 0; i < n_areas; i++) {
+		printf(" [%d] flags: %c%c%c%c base: %p size: %p\n", 1+i,
+		    (ainfo_buf[i].flags & AS_AREA_READ) ? 'R' : '-',
+		    (ainfo_buf[i].flags & AS_AREA_WRITE) ? 'W' : '-',
+		    (ainfo_buf[i].flags & AS_AREA_EXEC) ? 'X' : '-',
+		    (ainfo_buf[i].flags & AS_AREA_CACHEABLE) ? 'C' : '-',
+		    ainfo_buf[i].start_addr, ainfo_buf[i].size);
+	}
+
+	putchar('\n');
+
+	if (write_core_file) {
+		printf("Writing core file '%s'\n", core_file_name);
+		rc = elf_core_save(core_file_name, ainfo_buf, n_areas, phoneid);
+		if (rc != EOK) {
+			printf("Failed writing core file.\n");
+			return EIO;
+		}
+	}
+
+	free(ainfo_buf);
+
+	return 0;
+}
+
+static int thread_dump(uintptr_t thash)
+{
+	istate_t istate;
+	uintptr_t pc, fp, nfp;
+	stacktrace_t st;
+	char *sym_pc;
+	int rc;
+
+	rc = udebug_regs_read(phoneid, thash, &istate);
+	if (rc < 0) {
+		printf("Failed reading registers (%d).\n", rc);
+		return EIO;
+	}
+
+	pc = istate_get_pc(&istate);
+	fp = istate_get_fp(&istate);
+
+	sym_pc = fmt_sym_address(pc);
+	printf("Thread %p crashed at %s. FP = %p\n", thash, sym_pc, fp);
+	free(sym_pc);
+
+	st.op_arg = NULL;
+	st.read_uintptr = td_read_uintptr;
+
+	while (stacktrace_fp_valid(&st, fp)) {
+		sym_pc = fmt_sym_address(pc);
+		printf("  %p: %s\n", fp, sym_pc);
+		free(sym_pc);
+
+		rc = stacktrace_ra_get(&st, fp, &pc);
+		if (rc != EOK)
+			return rc;
+
+		rc = stacktrace_fp_prev(&st, fp, &nfp);
+		if (rc != EOK)
+			return rc;
+
+		fp = nfp;
+	}
+
+	return EOK;
+}
+
+static int area_dump(as_area_info_t *area)
+{
+	size_t to_copy;
+	size_t total;
+	uintptr_t addr;
+	int rc;
+
+	addr = area->start_addr;
+	total = 0;
+
+	while (total < area->size) {
+		to_copy = min(area->size - total, DBUF_SIZE);
+		rc = udebug_mem_read(phoneid, data_buf, addr, to_copy);
+		if (rc < 0) {
+			printf("udebug_mem_read() failed.\n");
+			return rc;
+		}
+
+		hex_dump(addr, data_buf, to_copy);
+
+		addr += to_copy;
+		total += to_copy;
+	}
+
+	return EOK;
+}
+
+static void hex_dump(uintptr_t addr, void *buffer, size_t size)
+{
+	uint8_t *data = (uint8_t *) buffer;
+	uint8_t b;
+	size_t pos, i;
+
+	assert(addr % LINE_BYTES == 0);
+	assert(size % LINE_BYTES == 0);
+
+	pos = 0;
+
+	while (pos < size) {
+		printf("%08lx:", addr + pos);
+		for (i = 0; i < LINE_BYTES; ++i) {
+			if (i % 4 == 0) putchar(' ');
+			printf(" %02x", data[pos + i]);
+		}
+		putchar('\t');
+
+		for (i = 0; i < LINE_BYTES; ++i) {
+			b = data[pos + i];
+			if (b >= 32 && b < 127) {
+				putchar(b);
+			} else {
+				putchar(' ');
+			}
+		}
+		putchar('\n');
+		pos += LINE_BYTES;
+	}
+}
+
+static int td_read_uintptr(void *arg, uintptr_t addr, uintptr_t *value)
+{
+	uintptr_t data;
+	int rc;
+
+	(void) arg;
+
+	rc = udebug_mem_read(phoneid, &data, addr, sizeof(data));
+	if (rc < 0) {
+		printf("Warning: udebug_mem_read() failed.\n");
+		return rc;
+	}
+
+	*value = data;
+	return EOK;
+}
+
+/** Attempt to find the right executable file and load the symbol table. */
+static void autoload_syms(void)
+{
+	char *file_name;
+	int rc;
+
+	assert(app_name != NULL);
+	assert(app_symtab == NULL);
+
+	rc = asprintf(&file_name, "/app/%s", app_name);
+	if (rc < 0) {
+		printf("Memory allocation failure.\n");
+		exit(1);
+	}
+
+	rc = symtab_load(file_name, &app_symtab);
+	if (rc == EOK) {
+		printf("Loaded symbol table from %s\n", file_name);
+		free(file_name);
+		return;
+	}
+
+	free(file_name);
+
+	rc = asprintf(&file_name, "/srv/%s", app_name);
+	if (rc < 0) {
+		printf("Memory allocation failure.\n");
+		exit(1);
+	}
+
+	rc = symtab_load(file_name, &app_symtab);
+	if (rc == EOK) {
+		printf("Loaded symbol table from %s\n", file_name);
+		free(file_name);
+		return;
+	}
+
+	free(file_name);
+	printf("Failed autoloading symbol table.\n");
+}
+
+static char *get_app_task_name(void)
+{
+	char dummy_buf;
+	size_t copied, needed, name_size;
+	char *name;
+	int rc;
+
+	rc = udebug_name_read(phoneid, &dummy_buf, 0, &copied, &needed);
+	if (rc < 0)
+		return NULL;
+
+	name_size = needed;
+	name = malloc(name_size + 1);
+	rc = udebug_name_read(phoneid, name, name_size, &copied, &needed);
+	if (rc < 0) {
+		free(name);
+		return NULL;
+	}
+
+	assert(copied == name_size);
+	assert(copied == needed);
+	name[copied] = '\0';
+
+	return name;
+}
+
+/** Format address in symbolic form.
+ *
+ * Formats address as <symbol_name>+<offset> (<address>), if possible,
+ * otherwise as <address>.
+ *
+ * @param addr	Address to format.
+ * @return	Newly allocated string, address in symbolic form.
+ */
+static char *fmt_sym_address(uintptr_t addr)
+{
+	char *name;
+	size_t offs;
+	int rc;
+	char *str;
+
+	if (app_symtab != NULL) {
+		rc = symtab_addr_to_name(app_symtab, addr, &name, &offs);
+	} else {
+		rc = ENOTSUP;
+	}
+
+	if (rc == EOK) {
+		rc = asprintf(&str, "%p (%s+%p)", addr, name, offs);
+	} else {
+		rc = asprintf(&str, "%p", addr);
+	}
+
+	if (rc < 0) {
+		printf("Memory allocation error.\n");
+		exit(1);
+	}
+
+	return str;
+}
+
+/** @}
+ */
Index: uspace/app/tester/vfs/vfs1.c
===================================================================
--- uspace/app/tester/vfs/vfs1.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/tester/vfs/vfs1.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -79,15 +79,8 @@
 	TPRINTF("Created directory %s\n", MOUNT_POINT);
 	
-	char null[MAX_DEVICE_NAME];
-	int null_id = devmap_null_create();
-	
-	if (null_id == -1)
-		return "Unable to create null device";
-	
-	snprintf(null, MAX_DEVICE_NAME, "null/%d", null_id);
-	int rc = mount(FS_TYPE, MOUNT_POINT, null, OPTIONS, FLAGS);
+	int rc = mount(FS_TYPE, MOUNT_POINT, "", OPTIONS, FLAGS);
 	switch (rc) {
 	case EOK:
-		TPRINTF("Mounted /dev/%s as %s on %s\n", null, FS_TYPE, MOUNT_POINT);
+		TPRINTF("Mounted %s on %s\n", FS_TYPE, MOUNT_POINT);
 		break;
 	case EBUSY:
Index: uspace/app/trace/ipcp.c
===================================================================
--- uspace/app/trace/ipcp.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/trace/ipcp.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,4 +36,5 @@
 #include <stdlib.h>
 #include <adt/hash_table.h>
+#include <sys/typefmt.h>
 
 #include "ipc_desc.h"
@@ -200,8 +201,9 @@
 
 	if ((display_mask & DM_IPC) != 0) {
-		printf("Call ID: 0x%lx, phone: %d, proto: %s, method: ", hash,
+		printf("Call ID: %p, phone: %d, proto: %s, method: ", hash,
 			phone, (proto ? proto->name : "n/a"));
 		ipc_m_print(proto, IPC_GET_METHOD(*call));
-		printf(" args: (%lu, %lu, %lu, %lu, %lu)\n", args[1], args[2],
+		printf(" args: (%" PRIuIPCARG ", %" PRIuIPCARG ", %" PRIuIPCARG
+		    ", %" PRIuIPCARG ", %" PRIuIPCARG ")\n", args[1], args[2],
 		    args[3], args[4], args[5]);
 	}
@@ -279,8 +281,10 @@
 
 	if ((display_mask & DM_IPC) != 0) {
-		printf("Response to 0x%lx: retval=%ld, args = (%lu, %lu, %lu, %lu, %lu)\n",
-			hash, retval, IPC_GET_ARG1(*answer),
-			IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer),
-			IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
+		printf("Response to %p: retval=%ld, args = (%" PRIuIPCARG
+		    ", %" PRIuIPCARG ", %" PRIuIPCARG ", %" PRIuIPCARG
+		    ", %" PRIuIPCARG ")\n",
+		    hash, retval, IPC_GET_ARG1(*answer),
+		    IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer),
+		    IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
 	}
 
@@ -336,5 +340,5 @@
 		/* Not a response */
 		if ((display_mask & DM_IPC) != 0) {
-			printf("Not a response (hash 0x%lx)\n", hash);
+			printf("Not a response (hash %p)\n", hash);
 		}
 		return;
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/app/trace/trace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -49,4 +49,6 @@
 #include <io/keycode.h>
 #include <fibril_synch.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
 
 #include <libc.h>
@@ -159,5 +161,5 @@
 	if (rc < 0) {
 		printf("Error connecting\n");
-		printf("ipc_connect_task(%lld) -> %d ", task_id, rc);
+		printf("ipc_connect_task(%" PRIdTASKID ") -> %d ", task_id, rc);
 		return rc;
 	}
@@ -198,5 +200,5 @@
 	printf("Threads:");
 	for (i = 0; i < n_threads; i++) {
-		printf(" [%d] (hash 0x%lx)", 1+i, thread_hash_buf[i]);
+		printf(" [%d] (hash %p)", 1+i, thread_hash_buf[i]);
 	}
 	printf("\ntotal of %u threads\n", tb_needed / sizeof(uintptr_t));
@@ -222,5 +224,5 @@
 	case V_HASH:
 	case V_PTR:
-		printf("0x%08lx", val);
+		printf("%p", val);
 		break;
 
@@ -275,7 +277,7 @@
 
 	putchar('(');
-	if (n > 0) printf("%ld", sc_args[0]);
+	if (n > 0) printf("%" PRIdSYSARG, sc_args[0]);
 	for (i = 1; i < n; i++) {
-		printf(", %ld", sc_args[i]);
+		printf(", %" PRIdSYSARG, sc_args[i]);
 	}
 	putchar(')');
@@ -508,5 +510,5 @@
 	}
 
-	printf("Start tracing thread [%d] (hash 0x%lx).\n", thread_id, thread_hash);
+	printf("Start tracing thread [%d] (hash %p).\n", thread_id, thread_hash);
 
 	while (!abort_trace) {
@@ -552,5 +554,5 @@
 				break;
 			case UDEBUG_EVENT_THREAD_E:
-				printf("Thread 0x%lx exited.\n", val0);
+				printf("Thread %p exited.\n", val0);
 				fibril_mutex_lock(&state_lock);
 				abort_trace = true;
@@ -972,9 +974,9 @@
 	rc = connect_task(task_id);
 	if (rc < 0) {
-		printf("Failed connecting to task %lld.\n", task_id);
+		printf("Failed connecting to task %" PRIdTASKID ".\n", task_id);
 		return 1;
 	}
 
-	printf("Connected to task %lld.\n", task_id);
+	printf("Connected to task %" PRIdTASKID ".\n", task_id);
 
 	if (task_ldr != NULL)
Index: uspace/lib/libblock/libblock.c
===================================================================
--- uspace/lib/libblock/libblock.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libblock/libblock.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -198,13 +198,11 @@
 	assert(devcon);
 	
+	if (devcon->cache)
+		(void) block_cache_fini(dev_handle);
+
 	devcon_remove(devcon);
 
 	if (devcon->bb_buf)
 		free(devcon->bb_buf);
-
-	if (devcon->cache) {
-		hash_table_destroy(&devcon->cache->block_hash);
-		free(devcon->cache);
-	}
 
 	munmap(devcon->comm_area, devcon->comm_size);
@@ -302,4 +300,47 @@
 
 	devcon->cache = cache;
+	return EOK;
+}
+
+int block_cache_fini(dev_handle_t dev_handle)
+{
+	devcon_t *devcon = devcon_search(dev_handle);
+	cache_t *cache;
+	int rc;
+
+	if (!devcon)
+		return ENOENT;
+	if (!devcon->cache)
+		return EOK;
+	cache = devcon->cache;
+	
+	/*
+	 * We are expecting to find all blocks for this device handle on the
+	 * free list, i.e. the block reference count should be zero. Do not
+	 * bother with the cache and block locks because we are single-threaded.
+	 */
+	while (!list_empty(&cache->free_head)) {
+		block_t *b = list_get_instance(cache->free_head.next,
+		    block_t, free_link);
+
+		list_remove(&b->free_link);
+		if (b->dirty) {
+			memcpy(devcon->comm_area, b->data, b->size);
+			rc = write_blocks(devcon, b->boff, 1);
+			if (rc != EOK)
+				return rc;
+		}
+
+		long key = b->boff;
+		hash_table_remove(&cache->block_hash, &key, 1);
+		
+		free(b->data);
+		free(b);
+	}
+
+	hash_table_destroy(&cache->block_hash);
+	devcon->cache = NULL;
+	free(cache);
+
 	return EOK;
 }
Index: uspace/lib/libblock/libblock.h
===================================================================
--- uspace/lib/libblock/libblock.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libblock/libblock.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -100,4 +100,5 @@
 
 extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode);
+extern int block_cache_fini(dev_handle_t);
 
 extern int block_get(block_t **, dev_handle_t, bn_t, int);
Index: uspace/lib/libc/arch/amd64/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/amd64/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/amd64/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -37,5 +37,6 @@
 	arch/$(UARCH)/src/fibril.S \
 	arch/$(UARCH)/src/tls.c \
-	arch/$(UARCH)/src/stacktrace.S
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
 
 GCC_CFLAGS += -fno-omit-frame-pointer
Index: uspace/lib/libc/arch/amd64/include/inttypes.h
===================================================================
--- uspace/lib/libc/arch/amd64/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/amd64/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 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 libcamd64
+ * @{
+ */
+/** @file Macros for format specifiers.
+ *
+ * Macros for formatting stdint types as specified in section
+ * 7.8.1 Macros for format specifiers of the C99 draft specification
+ * (ISO/IEC 9899:201x). Only some macros from the specification are
+ * implemented.
+ */
+
+#ifndef LIBC_amd64_INTTYPES_H_
+#define LIBC_amd64_INTTYPES_H_
+
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "lld"
+#define PRIdPTR "lld"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "llo"
+#define PRIoPTR "llo"
+
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "llu"
+#define PRIuPTR "llu"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "llx"
+#define PRIxPTR "llx"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "llX"
+#define PRIXPTR "llX"
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/amd64/include/istate.h
===================================================================
--- uspace/lib/libc/arch/amd64/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/amd64/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 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 libcamd64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_amd64_ISTATE_H_
+#define LIBC_amd64_ISTATE_H_
+
+#include <sys/types.h>
+
+/** Interrupt context.
+ *
+ * This is a copy of the kernel definition with which it must be kept in sync.
+ */
+typedef struct istate {
+	uint64_t rax;
+	uint64_t rcx;
+	uint64_t rdx;
+	uint64_t rsi;
+	uint64_t rdi;
+	uint64_t r8;
+	uint64_t r9;
+	uint64_t r10;
+	uint64_t r11;
+	uint64_t rbp;
+	uint64_t error_word;
+	uint64_t rip;
+	uint64_t cs;
+	uint64_t rflags;
+	uint64_t stack[]; /* Additional data on stack */
+} istate_t;
+
+static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	return istate->rip;
+}
+
+static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	return istate->rbp;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/amd64/include/types.h
===================================================================
--- uspace/lib/libc/arch/amd64/include/types.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/amd64/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,4 +36,6 @@
 #define LIBC_amd64_TYPES_H_
 
+#define __64_BITS__
+
 typedef unsigned long long sysarg_t;
 
Index: pace/lib/libc/arch/amd64/src/stacktrace.S
===================================================================
--- uspace/lib/libc/arch/amd64/src/stacktrace.S	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,55 +1,0 @@
-#
-# Copyright (c) 2009 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.
-#
-
-.text
-
-.global frame_pointer_get
-.global frame_pointer_prev
-.global frame_pointer_validate
-.global return_address_get
-.global program_counter_get
-
-frame_pointer_get:
-	movq %rbp, %rax
-	ret
-
-frame_pointer_prev:
-	movq (%rdi), %rax
-	ret
-
-frame_pointer_validate:
-	movq %rdi, %rax
-	ret
-
-return_address_get:
-	movq 8(%rdi), %rax
-	ret
-
-program_counter_get:
-	movq (%rsp), %rax
-	ret
Index: uspace/lib/libc/arch/amd64/src/stacktrace.c
===================================================================
--- uspace/lib/libc/arch/amd64/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/amd64/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 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 libcamd64 amd64
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+
+#include <stacktrace.h>
+
+#define FRAME_OFFSET_FP_PREV	0
+#define FRAME_OFFSET_RA		8
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st;
+	return fp != 0;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV, prev);
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/libc/arch/amd64/src/stacktrace_asm.S
===================================================================
--- uspace/lib/libc/arch/amd64/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/amd64/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2009 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.
+#
+
+.text
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+	ret
+
+stacktrace_fp_get:
+	movq %rbp, %rax
+	ret
+
+stacktrace_pc_get:
+	movq (%rsp), %rax
+	ret
Index: uspace/lib/libc/arch/arm32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/arm32/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/arm32/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -38,5 +38,6 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/eabi.S \
-	arch/$(UARCH)/src/stacktrace.S
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
 
 GCC_CFLAGS += -ffixed-r9 -mtp=soft -mapcs-frame -fno-omit-frame-pointer
Index: uspace/lib/libc/arch/arm32/include/inttypes.h
===================================================================
--- uspace/lib/libc/arch/arm32/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/arm32/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 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 libcarm32
+ * @{
+ */
+/** @file Macros for format specifiers.
+ *
+ * Macros for formatting stdint types as specified in section
+ * 7.8.1 Macros for format specifiers of the C99 draft specification
+ * (ISO/IEC 9899:201x). Only some macros from the specification are
+ * implemented.
+ */
+
+#ifndef LIBC_arm32_INTTYPES_H_
+#define LIBC_arm32_INTTYPES_H_
+
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "lld"
+#define PRIdPTR "d"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "llo"
+#define PRIoPTR "o"
+
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "llu"
+#define PRIuPTR "u"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "llx"
+#define PRIxPTR "x"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "llX"
+#define PRIXPTR "X"
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/arm32/include/istate.h
===================================================================
--- uspace/lib/libc/arch/arm32/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/arm32/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010 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 libcarm32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_arm32__ISTATE_H_
+#define LIBC_arm32__ISTATE_H_
+
+#include <sys/types.h>
+
+/** Interrupt context.
+ *
+ * This is a copy of the kernel definition with which it must be kept in sync.
+ */
+typedef struct istate {
+	uint32_t spsr;
+	uint32_t sp;
+	uint32_t lr;
+
+	uint32_t r0;
+	uint32_t r1;
+	uint32_t r2;
+	uint32_t r3;
+	uint32_t r4;
+	uint32_t r5;
+	uint32_t r6;
+	uint32_t r7;
+	uint32_t r8;
+	uint32_t r9;
+	uint32_t r10;
+	uint32_t fp;
+	uint32_t r12;
+
+	uint32_t pc;
+} istate_t;
+
+static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	return istate->pc;
+}
+
+static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	return istate->fp;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/arm32/include/types.h
===================================================================
--- uspace/lib/libc/arch/arm32/include/types.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/arm32/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -37,4 +37,6 @@
 #define LIBC_arm32_TYPES_H_
 
+#define __32_BITS__
+
 typedef unsigned int sysarg_t;
 
Index: pace/lib/libc/arch/arm32/src/stacktrace.S
===================================================================
--- uspace/lib/libc/arch/arm32/src/stacktrace.S	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,55 +1,0 @@
-#
-# Copyright (c) 2009 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.
-#
-
-.text
-
-.global frame_pointer_get
-.global frame_pointer_prev
-.global frame_pointer_validate
-.global return_address_get
-.global program_counter_get
-
-frame_pointer_get:
-	mov r0, fp
-	mov pc, lr
-
-frame_pointer_prev:
-	ldr r0, [r0, #-12]
-	mov pc, lr
-
-frame_pointer_validate:
-	mov pc, lr
-
-return_address_get:
-	ldr r0, [r0, #-4]
-	mov pc, lr
-
-program_counter_get:
-	mov r0, lr 
-	mov pc, lr
-
Index: uspace/lib/libc/arch/arm32/src/stacktrace.c
===================================================================
--- uspace/lib/libc/arch/arm32/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/arm32/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 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 libcarm32 arm32
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+
+#include <stacktrace.h>
+
+#define FRAME_OFFSET_FP_PREV	-12
+#define FRAME_OFFSET_RA		-4
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st;
+	return fp != 0;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV, prev);
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/libc/arch/arm32/src/stacktrace_asm.S
===================================================================
--- uspace/lib/libc/arch/arm32/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/arm32/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2009 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.
+#
+
+.text
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+	mov pc, lr
+
+stacktrace_fp_get:
+	mov r0, fp
+	mov pc, lr
+
+stacktrace_pc_get:
+	mov r0, lr 
+	mov pc, lr
Index: uspace/lib/libc/arch/ia32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/ia32/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/ia32/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -38,5 +38,6 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/setjmp.S \
-	arch/$(UARCH)/src/stacktrace.S
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
 
 GCC_CFLAGS += -march=pentium
Index: uspace/lib/libc/arch/ia32/include/inttypes.h
===================================================================
--- uspace/lib/libc/arch/ia32/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ia32/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 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 libcia32
+ * @{
+ */
+/** @file Macros for format specifiers.
+ *
+ * Macros for formatting stdint types as specified in section
+ * 7.8.1 Macros for format specifiers of the C99 draft specification
+ * (ISO/IEC 9899:201x). Only some macros from the specification are
+ * implemented.
+ */
+
+#ifndef LIBC_ia32_INTTYPES_H_
+#define LIBC_ia32_INTTYPES_H_
+
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "lld"
+#define PRIdPTR "d"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "llo"
+#define PRIoPTR "o"
+
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "llu"
+#define PRIuPTR "u"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "llx"
+#define PRIxPTR "x"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "llX"
+#define PRIXPTR "X"
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ia32/include/istate.h
===================================================================
--- uspace/lib/libc/arch/ia32/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ia32/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 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 debug
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ia32__ISTATE_H_
+#define LIBC_ia32__ISTATE_H_
+
+#include <sys/types.h>
+
+/** Interrupt context.
+ *
+ * This is a copy of the kernel definition with which it must be kept in sync.
+ */
+typedef struct istate {
+	uint32_t eax;
+	uint32_t ecx;
+	uint32_t edx;
+	uint32_t ebp;
+
+	uint32_t gs;
+	uint32_t fs;
+	uint32_t es;
+	uint32_t ds;
+
+	uint32_t error_word;
+	uint32_t eip;
+	uint32_t cs;
+	uint32_t eflags;
+	uint32_t stack[];
+} istate_t;
+
+static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	return istate->eip;
+}
+
+static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	return istate->ebp;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ia32/include/types.h
===================================================================
--- uspace/lib/libc/arch/ia32/include/types.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/ia32/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,4 +36,6 @@
 #define LIBC_ia32_TYPES_H_
 
+#define __32_BITS__
+
 typedef unsigned int sysarg_t;
 
Index: pace/lib/libc/arch/ia32/src/stacktrace.S
===================================================================
--- uspace/lib/libc/arch/ia32/src/stacktrace.S	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,57 +1,0 @@
-#
-# Copyright (c) 2009 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.
-#
-
-.text
-
-.global frame_pointer_get
-.global frame_pointer_prev
-.global frame_pointer_validate
-.global return_address_get
-.global program_counter_get
-
-frame_pointer_get:
-	movl %ebp, %eax
-	ret
-
-frame_pointer_prev:
-	movl 4(%esp), %eax
-	movl (%eax), %eax
-	ret
-
-frame_pointer_validate:
-	movl 4(%esp), %eax
-	ret
-
-return_address_get:
-	movl 4(%esp), %eax
-	movl 4(%eax), %eax
-	ret
-
-program_counter_get:
-	movl (%esp), %eax
-	ret
Index: uspace/lib/libc/arch/ia32/src/stacktrace.c
===================================================================
--- uspace/lib/libc/arch/ia32/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ia32/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 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 libcia32 ia32
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+
+#include <stacktrace.h>
+
+#define FRAME_OFFSET_FP_PREV	0
+#define FRAME_OFFSET_RA		4
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st;
+	return fp != 0;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV, prev);
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ia32/src/stacktrace_asm.S
===================================================================
--- uspace/lib/libc/arch/ia32/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ia32/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2009 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.
+#
+
+.text
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+	ret
+
+stacktrace_fp_get:
+	movl %ebp, %eax
+	ret
+
+stacktrace_pc_get:
+	movl (%esp), %eax
+	ret
Index: uspace/lib/libc/arch/ia64/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/ia64/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/ia64/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -37,5 +37,6 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/ddi.c \
-	arch/$(UARCH)/src/stacktrace.S
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
 
 GCC_CFLAGS += -fno-unwind-tables
Index: uspace/lib/libc/arch/ia64/include/fibril.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/fibril.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/ia64/include/fibril.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -52,8 +52,4 @@
 /* Stack is divided into two equal parts (for memory stack and register stack). */
 #define PSTHREAD_INITIAL_STACK_DIVISION 2  
-
-#ifdef context_set
-#undef context_set
-#endif
 
 #define context_set(c, _pc, stack, size, tls) 								\
Index: uspace/lib/libc/arch/ia64/include/inttypes.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ia64/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 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 libia64
+ * @{
+ */
+/** @file Macros for format specifiers.
+ *
+ * Macros for formatting stdint types as specified in section
+ * 7.8.1 Macros for format specifiers of the C99 draft specification
+ * (ISO/IEC 9899:201x). Only some macros from the specification are
+ * implemented.
+ */
+
+#ifndef LIBC_ia64_INTTYPES_H_
+#define LIBC_ia64_INTTYPES_H_
+
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "ld"
+#define PRIdPTR "ld"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "lo"
+#define PRIoPTR "lo"
+
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "lu"
+#define PRIuPTR "lu"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "lx"
+#define PRIxPTR "lx"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "lX"
+#define PRIXPTR "lX"
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ia64/include/istate.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ia64/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 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 libcsparc64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ia64_ISTATE_H_
+#define LIBC_ia64_ISTATE_H_
+
+#include <sys/types.h>
+
+/** Interrupt context.
+ *
+ * This is a copy of the kernel definition with which it must be kept in sync.
+ */
+typedef struct istate {
+	/* TODO */
+} istate_t;
+
+static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	/* TODO */
+	return 0;
+}
+
+static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	/* TODO */
+	return 0;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ia64/include/types.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/types.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/ia64/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,4 +36,6 @@
 #define LIBC_ia64_TYPES_H_
 
+#define __64_BITS__
+
 typedef unsigned long long sysarg_t;
 
Index: pace/lib/libc/arch/ia64/src/stacktrace.S
===================================================================
--- uspace/lib/libc/arch/ia64/src/stacktrace.S	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,43 +1,0 @@
-#
-# Copyright (c) 2009 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.
-#
-
-.text
-
-.global frame_pointer_get
-.global frame_pointer_prev
-.global frame_pointer_validate
-.global return_address_get
-.global program_counter_get
-
-frame_pointer_get:
-frame_pointer_prev:
-frame_pointer_validate:
-return_address_get:
-program_counter_get:
-	mov r8 = r0
-	br.ret.sptk.many b0
Index: uspace/lib/libc/arch/ia64/src/stacktrace.c
===================================================================
--- uspace/lib/libc/arch/ia64/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ia64/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 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 libcia64 ia64
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+#include <errno.h>
+
+#include <stacktrace.h>
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st; (void) fp;
+	return false;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	(void) st; (void) fp; (void) prev;
+	return ENOTSUP;
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	(void) st; (void) fp; (void) ra;
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ia64/src/stacktrace_asm.S
===================================================================
--- uspace/lib/libc/arch/ia64/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ia64/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2009 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.
+#
+
+.text
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+	br.ret.sptk.many b0
+
+stacktrace_fp_get:
+stacktrace_pc_get:
+	mov r8 = r0
+	br.ret.sptk.many b0
Index: uspace/lib/libc/arch/mips32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/mips32/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/mips32/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,5 +36,6 @@
 	arch/$(UARCH)/src/fibril.S \
 	arch/$(UARCH)/src/tls.c \
-	arch/$(UARCH)/src/stacktrace.S
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
 
 GCC_CFLAGS += -mips3
Index: uspace/lib/libc/arch/mips32/include/inttypes.h
===================================================================
--- uspace/lib/libc/arch/mips32/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/mips32/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 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 libcmips32
+ * @{
+ */
+/** @file Macros for format specifiers.
+ *
+ * Macros for formatting stdint types as specified in section
+ * 7.8.1 Macros for format specifiers of the C99 draft specification
+ * (ISO/IEC 9899:201x). Only some macros from the specification are
+ * implemented.
+ */
+
+#ifndef LIBC_mips32_INTTYPES_H_
+#define LIBC_mips32_INTTYPES_H_
+
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "lld"
+#define PRIdPTR "d"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "llo"
+#define PRIoPTR "o"
+
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "llu"
+#define PRIuPTR "u"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "llx"
+#define PRIxPTR "x"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "llX"
+#define PRIXPTR "x"
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/mips32/include/istate.h
===================================================================
--- uspace/lib/libc/arch/mips32/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/mips32/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2010 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 libcmips32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_mips32__ISTATE_H_
+#define LIBC_mips32__ISTATE_H_
+
+#include <sys/types.h>
+
+/** Interrupt context.
+ *
+ * This is a copy of the kernel definition with which it must be kept in sync.
+ */
+typedef struct istate {
+	uint32_t at;
+	uint32_t v0;
+	uint32_t v1;
+	uint32_t a0;
+	uint32_t a1;
+	uint32_t a2;
+	uint32_t a3;
+	uint32_t t0;
+	uint32_t t1;
+	uint32_t t2;
+	uint32_t t3;
+	uint32_t t4;
+	uint32_t t5;
+	uint32_t t6;
+	uint32_t t7;
+	uint32_t t8;
+	uint32_t t9;
+	uint32_t gp;
+	uint32_t sp;
+	uint32_t ra;
+
+	uint32_t lo;
+	uint32_t hi;
+
+	uint32_t status; /* cp0_status */
+	uint32_t epc; /* cp0_epc */
+	uint32_t k1; /* We use it as thread-local pointer */
+} istate_t;
+
+static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	return istate->epc;
+}
+
+static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	/* TODO */
+	return 0;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/mips32/include/types.h
===================================================================
--- uspace/lib/libc/arch/mips32/include/types.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/mips32/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -37,4 +37,6 @@
 #define LIBC_mips32_TYPES_H_
 
+#define __32_BITS__
+
 typedef unsigned int sysarg_t;
 
Index: pace/lib/libc/arch/mips32/src/stacktrace.S
===================================================================
--- uspace/lib/libc/arch/mips32/src/stacktrace.S	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,46 +1,0 @@
-#
-# Copyright (c) 2009 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.
-#
-
-.text
-
-.set noat
-.set noreorder
-
-.global frame_pointer_get
-.global frame_pointer_prev
-.global frame_pointer_validate
-.global return_address_get
-.global program_counter_get
-
-frame_pointer_get:
-frame_pointer_prev:
-frame_pointer_validate:
-return_address_get:
-program_counter_get:
-	j $ra
-	xor $v0, $v0
Index: uspace/lib/libc/arch/mips32/src/stacktrace.c
===================================================================
--- uspace/lib/libc/arch/mips32/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/mips32/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 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 libcmips32 mips32
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+#include <errno.h>
+
+#include <stacktrace.h>
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st; (void) fp;
+	return false;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	(void) st; (void) fp; (void) prev;
+	return ENOTSUP;
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	(void) st; (void) fp; (void) ra;
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/lib/libc/arch/mips32/src/stacktrace_asm.S
===================================================================
--- uspace/lib/libc/arch/mips32/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/mips32/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2009 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.
+#
+
+.text
+
+.set noat
+.set noreorder
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+stacktrace_fp_get:
+stacktrace_pc_get:
+	j $ra
+	xor $v0, $v0
Index: uspace/lib/libc/arch/mips32eb/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/mips32eb/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/mips32eb/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,5 +36,6 @@
 	arch/$(UARCH)/src/fibril.S \
 	arch/$(UARCH)/src/tls.c \
-	arch/$(UARCH)/src/stacktrace.S
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
 
 GCC_CFLAGS += -mips3
Index: uspace/lib/libc/arch/mips32eb/include/inttypes.h
===================================================================
--- uspace/lib/libc/arch/mips32eb/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/mips32eb/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,1 @@
+../../mips32/include/inttypes.h
Index: uspace/lib/libc/arch/mips32eb/include/istate.h
===================================================================
--- uspace/lib/libc/arch/mips32eb/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/mips32eb/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,1 @@
+../../mips32/include/istate.h
Index: uspace/lib/libc/arch/ppc32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/ppc32/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/ppc32/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,5 +36,6 @@
 	arch/$(UARCH)/src/fibril.S \
 	arch/$(UARCH)/src/tls.c \
-	arch/$(UARCH)/src/stacktrace.S
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
 
 GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
Index: uspace/lib/libc/arch/ppc32/include/inttypes.h
===================================================================
--- uspace/lib/libc/arch/ppc32/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ppc32/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 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 libcppc32
+ * @{
+ */
+/** @file Macros for format specifiers.
+ *
+ * Macros for formatting stdint types as specified in section
+ * 7.8.1 Macros for format specifiers of the C99 draft specification
+ * (ISO/IEC 9899:201x). Only some macros from the specification are
+ * implemented.
+ */
+
+#ifndef LIBC_ppc32_INTTYPES_H_
+#define LIBC_ppc32_INTTYPES_H_
+
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "lld"
+#define PRIdPTR "d"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "llo"
+#define PRIoPTR "o"
+
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "llu"
+#define PRIuPTR "u"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "llx"
+#define PRIxPTR "x"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "llX"
+#define PRIXPTR "X"
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ppc32/include/istate.h
===================================================================
--- uspace/lib/libc/arch/ppc32/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ppc32/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010 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 libcppc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ppc32_ISTATE_H_
+#define LIBC_ppc32_ISTATE_H_
+
+#include <sys/types.h>
+
+/** Interrupt context.
+ *
+ * This is a copy of the kernel definition with which it must be kept in sync.
+ */
+typedef struct istate {
+	uint32_t r0;
+	uint32_t r2;
+	uint32_t r3;
+	uint32_t r4;
+	uint32_t r5;
+	uint32_t r6;
+	uint32_t r7;
+	uint32_t r8;
+	uint32_t r9;
+	uint32_t r10;
+	uint32_t r11;
+	uint32_t r13;
+	uint32_t r14;
+	uint32_t r15;
+	uint32_t r16;
+	uint32_t r17;
+	uint32_t r18;
+	uint32_t r19;
+	uint32_t r20;
+	uint32_t r21;
+	uint32_t r22;
+	uint32_t r23;
+	uint32_t r24;
+	uint32_t r25;
+	uint32_t r26;
+	uint32_t r27;
+	uint32_t r28;
+	uint32_t r29;
+	uint32_t r30;
+	uint32_t r31;
+	uint32_t cr;
+	uint32_t pc;
+	uint32_t srr1;
+	uint32_t lr;
+	uint32_t ctr;
+	uint32_t xer;
+	uint32_t dar;
+	uint32_t r12;
+	uint32_t sp;
+} istate_t;
+
+static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	return istate->pc;
+}
+
+static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	return istate->sp;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ppc32/include/types.h
===================================================================
--- uspace/lib/libc/arch/ppc32/include/types.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/ppc32/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,4 +36,6 @@
 #define LIBC_ppc32_TYPES_H_
 
+#define __32_BITS__
+
 typedef unsigned int sysarg_t;
 
Index: pace/lib/libc/arch/ppc32/src/stacktrace.S
===================================================================
--- uspace/lib/libc/arch/ppc32/src/stacktrace.S	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,56 +1,0 @@
-#
-# Copyright (c) 2009 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.
-#
-
-.text
-
-#include <libarch/regname.h>
-
-.global frame_pointer_get
-.global frame_pointer_prev
-.global frame_pointer_validate
-.global return_address_get
-.global program_counter_get
-
-frame_pointer_get:
-	mr r3, sp
-	blr
-
-frame_pointer_prev:
-	lwz r3, 0(r3)
-	blr
-
-frame_pointer_validate:
-	blr
-
-return_address_get:
-	lwz r3, 4(r3)
-	blr
-
-program_counter_get:
-	mflr r3
-	blr
Index: uspace/lib/libc/arch/ppc32/src/stacktrace.c
===================================================================
--- uspace/lib/libc/arch/ppc32/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ppc32/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 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 libcppc32 ppc32
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+
+#include <stacktrace.h>
+
+#define FRAME_OFFSET_FP_PREV	0
+#define FRAME_OFFSET_RA		4
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st;
+	return fp != 0;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV, prev);
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ppc32/src/stacktrace_asm.S
===================================================================
--- uspace/lib/libc/arch/ppc32/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/ppc32/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2009 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.
+#
+
+.text
+
+#include <libarch/regname.h>
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+	blr
+
+stacktrace_fp_get:
+	mr r3, sp
+	blr
+
+stacktrace_pc_get:
+	mflr r3
+	blr
Index: uspace/lib/libc/arch/sparc64/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/sparc64/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/sparc64/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -35,5 +35,6 @@
 ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \
 	arch/$(UARCH)/src/tls.c \
-	arch/$(UARCH)/src/stacktrace.S
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
 
 GCC_CFLAGS += -mcpu=ultrasparc -m64
Index: uspace/lib/libc/arch/sparc64/include/fibril.h
===================================================================
--- uspace/lib/libc/arch/sparc64/include/fibril.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/sparc64/include/fibril.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -42,8 +42,4 @@
 #define SP_DELTA	(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
-#ifdef context_set
-#undef context_set
-#endif
-
 #define context_set(c, _pc, stack, size, ptls) \
 	do { \
Index: uspace/lib/libc/arch/sparc64/include/inttypes.h
===================================================================
--- uspace/lib/libc/arch/sparc64/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/sparc64/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 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 libcsparc64
+ * @{
+ */
+/** @file Macros for format specifiers.
+ *
+ * Macros for formatting stdint types as specified in section
+ * 7.8.1 Macros for format specifiers of the C99 draft specification
+ * (ISO/IEC 9899:201x). Only some macros from the specification are
+ * implemented.
+ */
+
+#ifndef LIBC_sparc64_INTTYPES_H_
+#define LIBC_sparc64_INTTYPES_H_
+
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "lld"
+#define PRIdPTR "lld"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "llo"
+#define PRIoPTR "llo"
+
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "llu"
+#define PRIuPTR "llu"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "llx"
+#define PRIxPTR "llx"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "llX"
+#define PRIXPTR "llX"
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/sparc64/include/istate.h
===================================================================
--- uspace/lib/libc/arch/sparc64/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/sparc64/include/istate.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 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 libcsparc64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc64_ISTATE_H_
+#define LIBC_sparc64_ISTATE_H_
+
+#include <sys/types.h>
+
+/** Interrupt context.
+ *
+ * This is a copy of the kernel definition with which it must be kept in sync.
+ */
+typedef struct istate {
+	/* TODO */
+} istate_t;
+
+static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	/* TODO */
+	return 0;
+}
+
+static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	/* TODO */
+	return 0;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/sparc64/include/types.h
===================================================================
--- uspace/lib/libc/arch/sparc64/include/types.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/arch/sparc64/include/types.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -36,4 +36,6 @@
 #define LIBC_sparc64_TYPES_H_
 
+#define __64_BITS__
+
 typedef unsigned long sysarg_t;
 
Index: pace/lib/libc/arch/sparc64/src/stacktrace.S
===================================================================
--- uspace/lib/libc/arch/sparc64/src/stacktrace.S	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,71 +1,0 @@
-#
-# Copyright (c) 2009 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 <libarch/stack.h>
-
-.text
-
-.global frame_pointer_get
-.global frame_pointer_prev
-.global frame_pointer_validate
-.global return_address_get
-.global program_counter_get
-
-frame_pointer_get:
-	# Add the stack bias to %sp to get the actual address.
-	retl
-	add %sp, STACK_BIAS, %o0
-
-frame_pointer_prev:
-	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE+STACK_ARG_SAVE_AREA_SIZE), %sp
-	# Flush all other windows to memory so that we can read their contents.
-	flushw
-	# Read the %fp from the window save area.
-	ldx [%i0 + 14 * 8], %i0
-	# Add the stack bias to the %fp read from the window save area.
-	add %i0, STACK_BIAS, %i0
-	ret
-	restore
-
-frame_pointer_validate:
-	retl
-	nop
-
-return_address_get:
-	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE+STACK_ARG_SAVE_AREA_SIZE), %sp
-	# Flush all other windows to memory so that we can read their contents.
-	flushw
-	# Read the %i7 from the window save area.
-	ldx [%i0 + 15 * 8], %i0
-	ret
-	restore
-
-program_counter_get:
-	retl
-	mov %o7, %o0
-
Index: uspace/lib/libc/arch/sparc64/src/stacktrace.c
===================================================================
--- uspace/lib/libc/arch/sparc64/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/sparc64/src/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 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 sparc64
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+#include <libarch/stack.h>
+#include <errno.h>
+
+#include <stacktrace.h>
+
+#define FRAME_OFFSET_FP_PREV	(14 * 8)
+#define FRAME_OFFSET_RA		(15 * 8)
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st;
+	return fp != 0;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	uintptr_t bprev;
+	int rc;
+
+	rc = (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV, &bprev);
+	if (rc == EOK)
+		*prev = bprev + STACK_BIAS;
+	return rc;
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/libc/arch/sparc64/src/stacktrace_asm.S
===================================================================
--- uspace/lib/libc/arch/sparc64/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/arch/sparc64/src/stacktrace_asm.S	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2009 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 <libarch/stack.h>
+
+.text
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE+STACK_ARG_SAVE_AREA_SIZE), %sp
+	# Flush all other windows to memory so that we can read their contents.
+	flushw
+	ret
+	restore
+
+stacktrace_fp_get:
+	# Add the stack bias to %sp to get the actual address.
+	retl
+	add %sp, STACK_BIAS, %o0
+
+stacktrace_pc_get:
+	retl
+	mov %o7, %o0
Index: uspace/lib/libc/generic/adt/hash_table.c
===================================================================
--- uspace/lib/libc/generic/adt/hash_table.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/generic/adt/hash_table.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -193,4 +193,24 @@
 }
 
+/** Apply fucntion to all items in hash table.
+ *
+ * @param h		Hash table.
+ * @param f		Function to be applied.
+ * @param arg		Argument to be passed to the function.
+ */
+void
+hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)
+{
+	hash_index_t bucket;
+	link_t *cur;
+
+	for (bucket = 0; bucket < h->entries; bucket++) {
+		for (cur = h->entry[bucket].next; cur != &h->entry[bucket];
+		    cur = cur->next) {
+			f(cur, arg);
+		}
+	}
+}
+
 /** @}
  */
Index: uspace/lib/libc/generic/async.c
===================================================================
--- uspace/lib/libc/generic/async.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/generic/async.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -1287,11 +1287,46 @@
 }
 
+/** Wrapper for forwarding any read request
+ *
+ *
+ */
+int async_data_read_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
+    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
+{
+	ipc_callid_t callid;
+	if (!async_data_read_receive(&callid, NULL)) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
+	    dataptr);
+	if (msg == 0) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
+	    IPC_FF_ROUTE_FROM_ME);
+	if (retval != EOK) {
+		async_wait_for(msg, NULL);
+		ipc_answer_0(callid, retval);
+		return retval;
+	}
+	
+	ipcarg_t rc;
+	async_wait_for(msg, &rc);
+	
+	return (int) rc;
+}
+
 /** 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.
+ * @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)
@@ -1308,10 +1343,11 @@
  * 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.
+ * @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)
@@ -1320,10 +1356,12 @@
 	
 	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;
 }
@@ -1334,9 +1372,10 @@
  * 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.
+ * @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)
@@ -1345,20 +1384,28 @@
 }
 
-/** Wrapper for receiving blobs via the async_data_write_*
+/** Wrapper for receiving binary data or strings
  *
  * This wrapper only makes it more comfortable to use async_data_write_*
- * functions to receive blobs.
- *
- * @param blob     Pointer to data pointer (which should be later disposed
- *                 by free()). If the operation fails, the pointer is not
- *                 touched.
- * @param max_size Maximum size (in bytes) of the blob to receive. 0 means
- *                 no limit.
- * @param received If not NULL, the size of the received data is stored here.
+ * functions to receive binary data or strings.
+ *
+ * @param data       Pointer to data pointer (which should be later disposed
+ *                   by free()). If the operation fails, the pointer is not
+ *                   touched.
+ * @param nullterm   If true then the received data is always zero terminated.
+ *                   This also causes to allocate one extra byte beyond the
+ *                   raw transmitted data.
+ * @param min_size   Minimum size (in bytes) of the data to receive.
+ * @param max_size   Maximum size (in bytes) of the data to receive. 0 means
+ *                   no limit.
+ * @param granulariy If non-zero then the size of the received data has to
+ *                   be divisible by this value.
+ * @param received   If not NULL, the size of the received data is stored here.
  *
  * @return Zero on success or a value from @ref errno.h on failure.
  *
  */
-int async_data_blob_receive(char **blob, const size_t max_size, size_t *received)
+int async_data_write_accept(void **data, const bool nullterm,
+    const size_t min_size, const size_t max_size, const size_t granularity,
+    size_t *received)
 {
 	ipc_callid_t callid;
@@ -1369,4 +1416,9 @@
 	}
 	
+	if (size < min_size) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
 	if ((max_size > 0) && (size > max_size)) {
 		ipc_answer_0(callid, EINVAL);
@@ -1374,17 +1426,31 @@
 	}
 	
-	char *data = (char *) malloc(size);
-	if (data == NULL) {
+	if ((granularity > 0) && ((size % granularity) != 0)) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	void *_data;
+	
+	if (nullterm)
+		_data = malloc(size + 1);
+	else
+		_data = malloc(size);
+	
+	if (_data == NULL) {
 		ipc_answer_0(callid, ENOMEM);
 		return ENOMEM;
 	}
 	
-	int rc = async_data_write_finalize(callid, data, size);
+	int rc = async_data_write_finalize(callid, _data, size);
 	if (rc != EOK) {
-		free(data);
+		free(_data);
 		return rc;
 	}
 	
-	*blob = data;
+	if (nullterm)
+		((char *) _data)[size] = 0;
+	
+	*data = _data;
 	if (received != NULL)
 		*received = size;
@@ -1393,47 +1459,50 @@
 }
 
-/** Wrapper for receiving strings via the async_data_write_*
- *
- * This wrapper only makes it more comfortable to use async_data_write_*
- * functions to receive strings.
- *
- * @param str      Pointer to string pointer (which should be later disposed
- *                 by free()). If the operation fails, the pointer is not
- *                 touched.
- * @param max_size Maximum size (in bytes) of the string to receive. 0 means
- *                 no limit.
- *
- * @return Zero on success or a value from @ref errno.h on failure.
- *
- */
-int async_data_string_receive(char **str, const size_t max_size)
+/** Wrapper for voiding any data that is about to be received
+ *
+ * This wrapper can be used to void any pending data
+ *
+ * @param retval Error value from @ref errno.h to be returned to the caller.
+ *
+ */
+void async_data_write_void(const int retval)
 {
 	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
+	async_data_write_receive(&callid, NULL);
+	ipc_answer_0(callid, retval);
+}
+
+/** Wrapper for forwarding any data that is about to be received
+ *
+ *
+ */
+int async_data_write_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
+    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
+{
+	ipc_callid_t callid;
+	if (!async_data_write_receive(&callid, NULL)) {
 		ipc_answer_0(callid, EINVAL);
 		return EINVAL;
 	}
 	
-	if ((max_size > 0) && (size > max_size)) {
+	aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
+	    dataptr);
+	if (msg == 0) {
 		ipc_answer_0(callid, EINVAL);
 		return EINVAL;
 	}
 	
-	char *data = (char *) malloc(size + 1);
-	if (data == NULL) {
-		ipc_answer_0(callid, ENOMEM);
-		return ENOMEM;
-	}
-	
-	int rc = async_data_write_finalize(callid, data, size);
-	if (rc != EOK) {
-		free(data);
-		return rc;
-	}
-	
-	data[size] = 0;
-	*str = data;
-	return EOK;
+	int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
+	    IPC_FF_ROUTE_FROM_ME);
+	if (retval != EOK) {
+		async_wait_for(msg, NULL);
+		ipc_answer_0(callid, retval);
+		return retval;
+	}
+	
+	ipcarg_t rc;
+	async_wait_for(msg, &rc);
+	
+	return (int) rc;
 }
 
Index: uspace/lib/libc/generic/clipboard.c
===================================================================
--- uspace/lib/libc/generic/clipboard.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/generic/clipboard.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -84,5 +84,5 @@
 		clip_connect();
 		
-		aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_BLOB, NULL);
+		aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL);
 		ipcarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
 		if (rc != EOK) {
@@ -139,5 +139,5 @@
 			*str = sbuf;
 			return EOK;
-		case CLIPBOARD_TAG_BLOB:
+		case CLIPBOARD_TAG_DATA:
 			sbuf = malloc(size + 1);
 			if (sbuf == NULL)
Index: uspace/lib/libc/generic/stacktrace.c
===================================================================
--- uspace/lib/libc/generic/stacktrace.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/generic/stacktrace.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2009 Jakub Jermar
+ * Copyright (c) 2010 Jiri Svoboda
  * All rights reserved.
  *
@@ -36,22 +37,40 @@
 #include <stdio.h>
 #include <sys/types.h>
+#include <errno.h>
 
-void stack_trace_fp_pc(uintptr_t fp, uintptr_t pc)
+static int stacktrace_read_uintptr(void *arg, uintptr_t addr, uintptr_t *data);
+
+void stacktrace_print_fp_pc(uintptr_t fp, uintptr_t pc)
 {
-	while (frame_pointer_validate(fp)) {
+	stacktrace_t st;
+	uintptr_t nfp;
+
+	st.op_arg = NULL;
+	st.read_uintptr = stacktrace_read_uintptr;
+
+	while (stacktrace_fp_valid(&st, fp)) {
 		printf("%p: %p()\n", fp, pc);
-		pc = return_address_get(fp);
-		fp = frame_pointer_prev(fp);
+		(void) stacktrace_ra_get(&st, fp, &pc);
+		(void) stacktrace_fp_prev(&st, fp, &nfp);
+		fp = nfp;
 	}
 }
 
-void stack_trace(void)
+void stacktrace_print(void)
 {
-	stack_trace_fp_pc(frame_pointer_get(), program_counter_get());
+	stacktrace_prepare();
+	stacktrace_print_fp_pc(stacktrace_fp_get(), stacktrace_pc_get());
 	/*
 	 * Prevent the tail call optimization of the previous call by
 	 * making it a non-tail call.
 	 */
-	(void) frame_pointer_get();
+	(void) stacktrace_fp_get();
+}
+
+static int stacktrace_read_uintptr(void *arg, uintptr_t addr, uintptr_t *data)
+{
+	(void) arg;
+	*data = *((uintptr_t *) addr);
+	return EOK;
 }
 
Index: uspace/lib/libc/generic/udebug.c
===================================================================
--- uspace/lib/libc/generic/udebug.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/generic/udebug.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -69,4 +69,34 @@
 }
 
+int udebug_name_read(int phoneid, void *buffer, size_t n,
+	size_t *copied, size_t *needed)
+{
+	ipcarg_t a_copied, a_needed;
+	int rc;
+
+	rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,
+		(sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
+
+	*copied = (size_t)a_copied;
+	*needed = (size_t)a_needed;
+
+	return rc;
+}
+
+int udebug_areas_read(int phoneid, void *buffer, size_t n,
+	size_t *copied, size_t *needed)
+{
+	ipcarg_t a_copied, a_needed;
+	int rc;
+
+	rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ,
+		(sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
+
+	*copied = (size_t)a_copied;
+	*needed = (size_t)a_needed;
+
+	return rc;
+}
+
 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
 {
@@ -78,4 +108,10 @@
 {
 	return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ,
+	    tid, (sysarg_t)buffer);
+}
+
+int udebug_regs_read(int phoneid, thash_t tid, void *buffer)
+{
+	return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ,
 	    tid, (sysarg_t)buffer);
 }
Index: uspace/lib/libc/generic/vfs/vfs.c
===================================================================
--- uspace/lib/libc/generic/vfs/vfs.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/generic/vfs/vfs.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -120,16 +120,128 @@
     const char *opts, unsigned int flags)
 {
-	int res;
+	int null_id = -1;
+	char null[DEVMAP_NAME_MAXLEN];
+	
+	if (str_cmp(fqdn, "") == 0) {
+		/* No device specified, create a fresh
+		   null/%d device instead */
+		null_id = devmap_null_create();
+		
+		if (null_id == -1)
+			return ENOMEM;
+		
+		snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);
+		fqdn = null;
+	}
+	
+	dev_handle_t dev_handle;
+	int res = devmap_device_get_handle(fqdn, &dev_handle, flags);
+	if (res != EOK) {
+		if (null_id != -1)
+			devmap_null_destroy(null_id);
+		
+		return res;
+	}
+	
+	size_t mpa_size;
+	char *mpa = absolutize(mp, &mpa_size);
+	if (!mpa) {
+		if (null_id != -1)
+			devmap_null_destroy(null_id);
+		
+		return ENOMEM;
+	}
+	
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	vfs_connect();
+	
+	ipcarg_t rc_orig;
+	aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
+	ipcarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
+	if (rc != EOK) {
+		async_wait_for(req, &rc_orig);
+		async_serialize_end();
+		futex_up(&vfs_phone_futex);
+		free(mpa);
+		
+		if (null_id != -1)
+			devmap_null_destroy(null_id);
+		
+		if (rc_orig == EOK)
+			return (int) rc;
+		else
+			return (int) rc_orig;
+	}
+	
+	rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
+	if (rc != EOK) {
+		async_wait_for(req, &rc_orig);
+		async_serialize_end();
+		futex_up(&vfs_phone_futex);
+		free(mpa);
+		
+		if (null_id != -1)
+			devmap_null_destroy(null_id);
+		
+		if (rc_orig == EOK)
+			return (int) rc;
+		else
+			return (int) rc_orig;
+	}
+	
+	rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
+	if (rc != EOK) {
+		async_wait_for(req, &rc_orig);
+		async_serialize_end();
+		futex_up(&vfs_phone_futex);
+		free(mpa);
+		
+		if (null_id != -1)
+			devmap_null_destroy(null_id);
+		
+		if (rc_orig == EOK)
+			return (int) rc;
+		else
+			return (int) rc_orig;
+	}
+	
+	/* Ask VFS whether it likes fs_name. */
+	rc = async_req_0_0(vfs_phone, IPC_M_PING);
+	if (rc != EOK) {
+		async_wait_for(req, &rc_orig);
+		async_serialize_end();
+		futex_up(&vfs_phone_futex);
+		free(mpa);
+		
+		if (null_id != -1)
+			devmap_null_destroy(null_id);
+		
+		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(mpa);
+	
+	if ((rc != EOK) && (null_id != -1))
+		devmap_null_destroy(null_id);
+	
+	return (int) rc;
+}
+
+int unmount(const char *mp)
+{
 	ipcarg_t rc;
 	ipcarg_t rc_orig;
 	aid_t req;
-	dev_handle_t dev_handle;
-	
-	res = devmap_device_get_handle(fqdn, &dev_handle, flags);
-	if (res != EOK)
-		return res;
-	
 	size_t mpa_size;
-	char *mpa = absolutize(mp, &mpa_size);
+	char *mpa;
+	
+	mpa = absolutize(mp, &mpa_size);
 	if (!mpa)
 		return ENOMEM;
@@ -139,5 +251,5 @@
 	vfs_connect();
 	
-	req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
+	req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
 	rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
 	if (rc != EOK) {
@@ -152,41 +264,5 @@
 	}
 	
-	rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
-	if (rc != EOK) {
-		async_wait_for(req, &rc_orig);
-		async_serialize_end();
-		futex_up(&vfs_phone_futex);
-		free(mpa);
-		if (rc_orig == EOK)
-			return (int) rc;
-		else
-			return (int) rc_orig;
-	}
-
-	rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
-	if (rc != EOK) {
-		async_wait_for(req, &rc_orig);
-		async_serialize_end();
-		futex_up(&vfs_phone_futex);
-		free(mpa);
-		if (rc_orig == EOK)
-			return (int) rc;
-		else
-			return (int) rc_orig;
-	}
-
-	/* Ask VFS whether it likes fs_name. */
-	rc = async_req_0_0(vfs_phone, IPC_M_PING);
-	if (rc != EOK) {
-		async_wait_for(req, &rc_orig);
-		async_serialize_end();
-		futex_up(&vfs_phone_futex);
-		free(mpa);
-		if (rc_orig == EOK)
-			return (int) rc;
-		else
-			return (int) rc_orig;
-	}
-	
+
 	async_wait_for(req, &rc);
 	async_serialize_end();
Index: uspace/lib/libc/include/adt/hash_table.h
===================================================================
--- uspace/lib/libc/include/adt/hash_table.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/adt/hash_table.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -88,4 +88,6 @@
 extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t);
 extern void hash_table_destroy(hash_table_t *);
+extern void hash_table_apply(hash_table_t *, void (*)(link_t *, void *),
+    void *);
 
 #endif
Index: uspace/lib/libc/include/async.h
===================================================================
--- uspace/lib/libc/include/async.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/async.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -277,13 +277,82 @@
 extern int async_share_out_receive(ipc_callid_t *, size_t *, int *);
 extern int async_share_out_finalize(ipc_callid_t, void *);
+
+/*
+ * User-friendly wrappers for async_data_read_forward_fast().
+ */
+#define async_data_read_forward_0_0(phoneid, method, answer) \
+	async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
+#define async_data_read_forward_0_1(phoneid, method, answer) \
+	async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
+#define async_data_read_forward_1_0(phoneid, method, arg1, answer) \
+	async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
+#define async_data_read_forward_1_1(phoneid, method, arg1, answer) \
+	async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer))
+#define async_data_read_forward_2_0(phoneid, method, arg1, arg2, answer) \
+	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL)
+#define async_data_read_forward_2_1(phoneid, method, arg1, arg2, answer) \
+	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
+	    (answer))
+#define async_data_read_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
+	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
+	    NULL)
+#define async_data_read_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
+	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
+	    (answer))
+#define async_data_read_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
+	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    (arg4), NULL)
+#define async_data_read_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
+	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    (arg4), (answer))
+
 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_read_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t,
+    ipcarg_t, ipcarg_t, ipc_call_t *);
+
+/*
+ * User-friendly wrappers for async_data_write_forward_fast().
+ */
+#define async_data_write_forward_0_0(phoneid, method, answer) \
+	async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
+#define async_data_write_forward_0_1(phoneid, method, answer) \
+	async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
+#define async_data_write_forward_1_0(phoneid, method, arg1, answer) \
+	async_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
+#define async_data_write_forward_1_1(phoneid, method, arg1, answer) \
+	async_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, \
+	    (answer))
+#define async_data_write_forward_2_0(phoneid, method, arg1, arg2, answer) \
+	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
+	    NULL)
+#define async_data_write_forward_2_1(phoneid, method, arg1, arg2, answer) \
+	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
+	    (answer))
+#define async_data_write_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
+	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    0, NULL)
+#define async_data_write_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
+	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    0, (answer))
+#define async_data_write_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
+	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    (arg4), NULL)
+#define async_data_write_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
+	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    (arg4), (answer))
+
 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);
 
-extern int async_data_blob_receive(char **, const size_t, size_t *);
-extern int async_data_string_receive(char **, const size_t);
+extern int async_data_write_accept(void **, const bool, const size_t,
+    const size_t, const size_t, size_t *);
+extern void async_data_write_void(const int);
+
+extern int async_data_write_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t,
+    ipcarg_t, ipcarg_t, ipc_call_t *);
 
 #endif
Index: uspace/lib/libc/include/fibril.h
===================================================================
--- uspace/lib/libc/include/fibril.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/fibril.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -40,13 +40,11 @@
 #include <libarch/tls.h>
 
-#ifndef context_set
-#define context_set(c, _pc, stack, size, ptls) \
+#define context_set_generic(c, _pc, stack, size, ptls) \
 	(c)->pc = (sysarg_t) (_pc); \
 	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
 	(c)->tls = (sysarg_t) (ptls);
-#endif /* context_set */
 
-#define FIBRIL_SERIALIZED	1
-#define FIBRIL_WRITER 		2
+#define FIBRIL_SERIALIZED  1
+#define FIBRIL_WRITER      2
 
 typedef enum {
@@ -59,5 +57,5 @@
 typedef sysarg_t fid_t;
 
-struct fibril {
+typedef struct fibril {
 	link_t link;
 	context_t ctx;
@@ -70,12 +68,11 @@
 	int retval;
 	int flags;
-};
-typedef struct fibril fibril_t;
+} fibril_t;
 
 /** Fibril-local variable specifier */
 #define fibril_local __thread
 
-extern int context_save(context_t *c) __attribute__ ((returns_twice));
-extern void context_restore(context_t *c) __attribute__ ((noreturn));
+extern int context_save(context_t *ctx) __attribute__((returns_twice));
+extern void context_restore(context_t *ctx) __attribute__((noreturn));
 
 extern fid_t fibril_create(int (*func)(void *), void *arg);
@@ -90,5 +87,6 @@
 extern void fibril_dec_sercount(void);
 
-static inline int fibril_yield(void) {
+static inline int fibril_yield(void)
+{
 	return fibril_switch(FIBRIL_PREEMPT);
 }
Index: uspace/lib/libc/include/inttypes.h
===================================================================
--- uspace/lib/libc/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/include/inttypes.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_INTTYPES_H_
+#define LIBC_INTTYPES_H_
+
+#include <libarch/inttypes.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/ipc/adb.h
===================================================================
--- uspace/lib/libc/include/ipc/adb.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/include/ipc/adb.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010 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 libcipc
+ * @{
+ */
+/** @file
+ * @brief ADB device interface.
+ */ 
+
+#ifndef LIBC_IPC_ADB_H_
+#define LIBC_IPC_ADB_H_
+
+#include <ipc/ipc.h>
+
+typedef enum {
+	ADB_REG_WRITE = IPC_FIRST_USER_METHOD
+} adb_request_t;
+
+
+typedef enum {
+	ADB_REG_NOTIF = IPC_FIRST_USER_METHOD
+} adb_notif_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/ipc/clipboard.h
===================================================================
--- uspace/lib/libc/include/ipc/clipboard.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/ipc/clipboard.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -46,5 +46,5 @@
 typedef enum {
 	CLIPBOARD_TAG_NONE,
-	CLIPBOARD_TAG_BLOB
+	CLIPBOARD_TAG_DATA
 } clipboard_tag_t;
 
Index: uspace/lib/libc/include/ipc/vfs.h
===================================================================
--- uspace/lib/libc/include/ipc/vfs.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/ipc/vfs.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -86,4 +86,5 @@
 	VFS_OUT_MOUNTED,
 	VFS_OUT_UNMOUNT,
+	VFS_OUT_UNMOUNTED,
 	VFS_OUT_SYNC,
 	VFS_OUT_STAT,
@@ -100,5 +101,5 @@
  * No lookup flags used.
  */
-#define L_NONE  0
+#define L_NONE			0
 
 /**
@@ -107,12 +108,25 @@
  * with L_DIRECTORY.
  */
-#define L_FILE  1
+#define L_FILE			1
 
 /**
- * Lookup wil succeed only if the object is a directory. If L_CREATE is
+ * Lookup will succeed only if the object is a directory. If L_CREATE is
  * specified, an empty directory will be created. This flag is mutually
  * exclusive with L_FILE.
  */
-#define L_DIRECTORY  2
+#define L_DIRECTORY		2
+
+/**
+ * Lookup will succeed only if the object is a root directory. The flag is
+ * mutually exclusive with L_FILE and L_MP.
+ */
+#define L_ROOT			4
+
+/**
+ * Lookup will succeed only if the object is a mount point. The flag is mutually
+ * exclusive with L_FILE and L_ROOT.
+ */
+#define L_MP			8
+
 
 /**
@@ -120,15 +134,15 @@
  * object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used.
  */
-#define L_EXCLUSIVE  4
+#define L_EXCLUSIVE 		16
 
 /**
  * L_CREATE is used for creating both regular files and directories.
  */
-#define L_CREATE  8
+#define L_CREATE		32
 
 /**
  * L_LINK is used for linking to an already existing nodes.
  */
-#define L_LINK  16
+#define L_LINK			64
 
 /**
@@ -137,13 +151,13 @@
  * VFS_UNLINK.
  */
-#define L_UNLINK  32
+#define L_UNLINK		128
 
 /**
- * L_OPEN is used to indicate that the lookup operation is a part of VFS_OPEN
+ * L_OPEN is used to indicate that the lookup operation is a part of VFS_IN_OPEN
  * call from the client. This means that the server might allocate some
  * resources for the opened file. This flag cannot be passed directly by the
  * client.
  */
-#define L_OPEN  64
+#define L_OPEN			256
 
 #endif
Index: uspace/lib/libc/include/stacktrace.h
===================================================================
--- uspace/lib/libc/include/stacktrace.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/stacktrace.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2009 Jakub Jermar
+ * Copyright (c) 2010 Jiri Svoboda
  * All rights reserved.
  *
@@ -39,15 +40,22 @@
 #include <bool.h>
 
-extern void stack_trace(void);
-extern void stack_trace_fp_pc(uintptr_t, uintptr_t);
+typedef struct {
+	void *op_arg;
+	int (*read_uintptr)(void *, uintptr_t, uintptr_t *);
+} stacktrace_t;
+
+extern void stacktrace_print(void);
+extern void stacktrace_print_fp_pc(uintptr_t, uintptr_t);
 
 /*
  * The following interface is to be implemented by each architecture.
  */
-extern bool frame_pointer_validate(uintptr_t);
-extern uintptr_t frame_pointer_get(void);
-extern uintptr_t frame_pointer_prev(uintptr_t);
-extern uintptr_t return_address_get(uintptr_t);
-extern uintptr_t program_counter_get();
+extern bool stacktrace_fp_valid(stacktrace_t *, uintptr_t);
+extern int stacktrace_fp_prev(stacktrace_t *, uintptr_t, uintptr_t *);
+extern int stacktrace_ra_get(stacktrace_t *, uintptr_t, uintptr_t *);
+
+extern void stacktrace_prepare(void);
+extern uintptr_t stacktrace_fp_get(void);
+extern uintptr_t stacktrace_pc_get();
 
 #endif
Index: uspace/lib/libc/include/stdlib.h
===================================================================
--- uspace/lib/libc/include/stdlib.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/stdlib.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -42,5 +42,5 @@
 #define abort() \
 	do { \
-		stack_trace(); \
+		stacktrace_print(); \
 		_exit(1); \
 	} while (0)
Index: uspace/lib/libc/include/sys/typefmt.h
===================================================================
--- uspace/lib/libc/include/sys/typefmt.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/lib/libc/include/sys/typefmt.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 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 libc
+ * @{
+ */
+/** @file Formatting macros for types from sys/types.h and some other
+ * system types.
+ */
+
+#ifndef LIBC_SYS_TYPEFMT_H_
+#define LIBC_SYS_TYPEFMT_H_
+
+#include <inttypes.h>
+
+/* off_t */
+#define PRIdOFF "ld"
+#define PRIuOFF "lu"
+#define PRIxOFF "lx"
+#define PRIXOFF "lX"
+
+/* bn_t */
+#define PRIdBN PRId64
+#define PRIuBN PRIu64
+#define PRIxBN PRIx64
+#define PRIXBN PRIX64
+
+/* (s)size_t */
+#define PRIdSIZE PRIdPTR
+#define PRIuSIZE PRIuPTR
+#define PRIxSIZE PRIxPTR
+#define PRIXSIZE PRIXPTR
+
+/* sysarg_t */
+#define PRIdSYSARG PRIdPTR
+#define PRIuSYSARG PRIuPTR
+#define PRIxSYSARG PRIxPTR
+#define PRIXSYSARG PRIxPTR
+
+/* ipcarg_t */
+#define PRIdIPCARG PRIdPTR
+#define PRIuIPCARG PRIuPTR
+#define PRIxIPCARG PRIxPTR
+#define PRIXIPCARG PRIXPTR
+
+/* taskid_t */
+#define PRIdTASKID PRId64
+#define PRIuTASKID PRIu64
+#define PRIxTASKID PRIx64
+#define PRIXTASKID PRIx64
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/udebug.h
===================================================================
--- uspace/lib/libc/include/udebug.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/udebug.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -47,6 +47,11 @@
 int udebug_thread_read(int phoneid, void *buffer, size_t n,
 	size_t *copied, size_t *needed);
+int udebug_name_read(int phoneid, void *buffer, size_t n,
+	size_t *copied, size_t *needed);
+int udebug_areas_read(int phoneid, void *buffer, size_t n,
+	size_t *copied, size_t *needed);
 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n);
 int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer);
+int udebug_regs_read(int phoneid, thash_t tid, void *buffer);
 int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type,
 	sysarg_t *val0, sysarg_t *val1);
Index: uspace/lib/libc/include/vfs/vfs.h
===================================================================
--- uspace/lib/libc/include/vfs/vfs.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libc/include/vfs/vfs.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -55,4 +55,5 @@
 extern int mount(const char *, const char *, const char *, const char *,
     unsigned int);
+extern int unmount(const char *);
 
 extern void __stdio_init(int filc, fdi_node_t *filv[]);
Index: uspace/lib/libfs/libfs.c
===================================================================
--- uspace/lib/libfs/libfs.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libfs/libfs.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -161,5 +161,5 @@
 	/* Accept the phone */
 	callid = async_get_call(&call);
-	int mountee_phone = (int)IPC_GET_ARG1(call);
+	int mountee_phone = (int) IPC_GET_ARG1(call);
 	if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
 	    (mountee_phone < 0)) {
@@ -172,17 +172,9 @@
 	ipc_answer_0(callid, EOK);
 	
-	res = async_data_write_receive(&callid, NULL);
-	if (!res) {
-		ipc_hangup(mountee_phone);
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
 	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, combine_rc(res, ENOENT));
+		async_data_write_void(combine_rc(res, ENOENT));
 		ipc_answer_0(rid, combine_rc(res, ENOENT));
 		return;
@@ -192,5 +184,5 @@
 		ipc_hangup(mountee_phone);
 		(void) ops->node_put(fn);
-		ipc_answer_0(callid, EBUSY);
+		async_data_write_void(EBUSY);
 		ipc_answer_0(rid, EBUSY);
 		return;
@@ -201,5 +193,5 @@
 		ipc_hangup(mountee_phone);
 		(void) ops->node_put(fn);
-		ipc_answer_0(callid, rc);
+		async_data_write_void(rc);
 		ipc_answer_0(rid, rc);
 		return;
@@ -207,8 +199,6 @@
 	
 	ipc_call_t answer;
-	aid_t msg = async_send_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle,
-	    &answer);
-	ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
-	async_wait_for(msg, &rc);
+	rc = async_data_write_forward_1_1(mountee_phone, VFS_OUT_MOUNTED,
+	    mr_dev_handle, &answer);
 	
 	if (rc == EOK) {
@@ -224,4 +214,49 @@
 	ipc_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
 	    IPC_GET_ARG3(answer));
+}
+
+void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
+{
+	dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
+	fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
+	fs_node_t *fn;
+	int res;
+
+	res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
+	if ((res != EOK) || (!fn)) {
+		ipc_answer_0(rid, combine_rc(res, ENOENT));
+		return;
+	}
+
+	/*
+	 * We are clearly expecting to find the mount point active.
+	 */
+	if (!fn->mp_data.mp_active) {
+		(void) ops->node_put(fn);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+
+	/*
+	 * Tell the mounted file system to unmount.
+	 */
+	res = async_req_1_0(fn->mp_data.phone, VFS_OUT_UNMOUNTED,
+	    fn->mp_data.dev_handle);
+
+	/*
+	 * If everything went well, perform the clean-up on our side.
+	 */
+	if (res == EOK) {
+		ipc_hangup(fn->mp_data.phone);
+		fn->mp_data.mp_active = false;
+		fn->mp_data.fs_handle = 0;
+		fn->mp_data.dev_handle = 0;
+		fn->mp_data.phone = 0;
+		/* Drop the reference created in libfs_mount(). */
+		(void) ops->node_put(fn);
+	}
+
+	(void) ops->node_put(fn);
+	ipc_answer_0(rid, res);
 }
 
@@ -304,5 +339,16 @@
 		on_error(rc, goto out_with_answer);
 		
-		if ((tmp) && (tmp->mp_data.mp_active)) {
+		/*
+		 * If the matching component is a mount point, there are two
+		 * legitimate semantics of the lookup operation. The first is
+		 * the commonly used one in which the lookup crosses each mount
+		 * point into the mounted file system. The second semantics is
+		 * used mostly during unmount() and differs from the first one
+		 * only in that the last mount point in the looked up path,
+		 * which is also its last component, is not crossed.
+		 */
+
+		if ((tmp) && (tmp->mp_data.mp_active) &&
+		    (!(lflag & L_MP) || (next <= last))) {
 			if (next > last)
 				next = last = first;
@@ -475,4 +521,9 @@
 		goto out;
 	}
+
+	if ((lflag & L_ROOT) && par) {
+		ipc_answer_0(rid, EINVAL);
+		goto out;
+	}
 	
 out_with_answer:
Index: uspace/lib/libfs/libfs.h
===================================================================
--- uspace/lib/libfs/libfs.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/lib/libfs/libfs.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -95,4 +95,5 @@
 
 extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
+extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
 extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
 extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -59,4 +59,5 @@
 #include <devmap.h>
 #include <sys/types.h>
+#include <inttypes.h>
 #include <errno.h>
 #include <bool.h>
@@ -112,5 +113,5 @@
 	printf(NAME ": ATA disk driver\n");
 
-	printf("I/O address 0x%p/0x%p\n", ctl_physical, cmd_physical);
+	printf("I/O address %p/%p\n", ctl_physical, cmd_physical);
 
 	if (ata_bd_init() != EOK)
@@ -180,9 +181,9 @@
 	}
 
-	printf(" %llu blocks", d->blocks, d->blocks / (2 * 1024));
+	printf(" %" PRIu64 " blocks", d->blocks, d->blocks / (2 * 1024));
 
 	mbytes = d->blocks / (2 * 1024);
 	if (mbytes > 0)
-		printf(" %llu MB.", mbytes);
+		printf(" %" PRIu64 " MB.", mbytes);
 
 	printf("\n");
Index: uspace/srv/bd/part/guid_part/guid_part.c
===================================================================
--- uspace/srv/bd/part/guid_part/guid_part.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/bd/part/guid_part/guid_part.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -54,4 +54,6 @@
 #include <devmap.h>
 #include <sys/types.h>
+#include <sys/typefmt.h>
+#include <inttypes.h>
 #include <libblock.h>
 #include <devmap.h>
@@ -196,6 +198,6 @@
 		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);
+		printf(NAME ": Registered device %s: %" PRIu64 " blocks "
+		    "%" PRIuBN " MB.\n", name, part->length, size_mb);
 
 		part->dev = dev;
Index: uspace/srv/bd/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/bd/part/mbr_part/mbr_part.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/bd/part/mbr_part/mbr_part.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -64,4 +64,6 @@
 #include <devmap.h>
 #include <sys/types.h>
+#include <sys/typefmt.h>
+#include <inttypes.h>
 #include <libblock.h>
 #include <devmap.h>
@@ -247,6 +249,6 @@
 		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);
+		printf(NAME ": Registered device %s: %" PRIuBN " blocks "
+		    "%" PRIu64 " MB.\n", name, part->length, size_mb);
 
 		part->dev = dev;
@@ -274,5 +276,5 @@
 	if (brb == NULL) {
 		printf(NAME ": Failed allocating memory.\n");
-		return ENOMEM;	
+		return ENOMEM;
 	}
 
@@ -289,5 +291,6 @@
 	sgn = uint16_t_le2host(brb->signature);
 	if (sgn != BR_SIGNATURE) {
-		printf(NAME ": Invalid boot record signature 0x%04X.\n", sgn);
+		printf(NAME ": Invalid boot record signature 0x%04" PRIX16
+		    ".\n", sgn);
 		return EINVAL;
 	}
@@ -333,5 +336,6 @@
 		rc = block_read_direct(indev_handle, ba, 1, brb);
 		if (rc != EOK) {
-			printf(NAME ": Failed reading EBR block at %u.\n", ba);
+			printf(NAME ": Failed reading EBR block at %"
+			    PRIu32 ".\n", ba);
 			return rc;
 		}
@@ -339,6 +343,6 @@
 		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);
+			printf(NAME ": Invalid boot record signature 0x%04"
+			    PRIX16 " in EBR at %" PRIu32 ".\n", sgn, ba);
 			return EINVAL;
 		}
Index: uspace/srv/clip/clip.c
===================================================================
--- uspace/srv/clip/clip.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/clip/clip.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -64,6 +64,6 @@
 		ipc_answer_0(rid, EOK);
 		break;
-	case CLIPBOARD_TAG_BLOB:
-		rc = async_data_blob_receive(&data, 0, &size);
+	case CLIPBOARD_TAG_DATA:
+		rc = async_data_write_accept((void **) &data, false, 0, 0, 0, &size);
 		if (rc != EOK) {
 			ipc_answer_0(rid, rc);
@@ -78,5 +78,5 @@
 		clip_data = data;
 		clip_size = size;
-		clip_tag = CLIPBOARD_TAG_BLOB;
+		clip_tag = CLIPBOARD_TAG_DATA;
 		
 		fibril_mutex_unlock(&clip_mtx);
@@ -97,5 +97,5 @@
 	/* Check for clipboard data tag compatibility */
 	switch (IPC_GET_ARG1(*request)) {
-	case CLIPBOARD_TAG_BLOB:
+	case CLIPBOARD_TAG_DATA:
 		if (!async_data_read_receive(&callid, &size)) {
 			ipc_answer_0(callid, EINVAL);
@@ -104,6 +104,6 @@
 		}
 		
-		if (clip_tag != CLIPBOARD_TAG_BLOB) {
-			/* So far we only understand BLOB */
+		if (clip_tag != CLIPBOARD_TAG_DATA) {
+			/* So far we only understand binary data */
 			ipc_answer_0(callid, EOVERFLOW);
 			ipc_answer_0(rid, EOVERFLOW);
Index: uspace/srv/devmap/devmap.c
===================================================================
--- uspace/srv/devmap/devmap.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/devmap/devmap.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -396,5 +396,6 @@
 	 * Get driver name
 	 */
-	int rc = async_data_string_receive(&driver->name, DEVMAP_NAME_MAXLEN);
+	int rc = async_data_write_accept((void **) &driver->name, true, 0,
+	    DEVMAP_NAME_MAXLEN, 0, NULL);
 	if (rc != EOK) {
 		free(driver);
@@ -510,5 +511,6 @@
 	/* Get fqdn */
 	char *fqdn;
-	int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);
+	int rc = async_data_write_accept((void **) &fqdn, true, 0,
+	    DEVMAP_NAME_MAXLEN, 0, NULL);
 	if (rc != EOK) {
 		free(device);
@@ -622,5 +624,6 @@
 	
 	/* Get fqdn */
-	int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);
+	int rc = async_data_write_accept((void **) &fqdn, true, 0,
+	    DEVMAP_NAME_MAXLEN, 0, NULL);
 	if (rc != EOK) {
 		ipc_answer_0(iid, rc);
@@ -683,5 +686,6 @@
 	
 	/* Get device name */
-	int rc = async_data_string_receive(&name, DEVMAP_NAME_MAXLEN);
+	int rc = async_data_write_accept((void **) &name, true, 0,
+	    DEVMAP_NAME_MAXLEN, 0, NULL);
 	if (rc != EOK) {
 		ipc_answer_0(iid, rc);
Index: uspace/srv/fs/devfs/devfs.c
===================================================================
--- uspace/srv/fs/devfs/devfs.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/devfs/devfs.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -75,4 +75,10 @@
 			devfs_mount(callid, &call);
 			break;
+		case VFS_OUT_UNMOUNTED:
+			devfs_unmounted(callid, &call);
+			break;
+		case VFS_OUT_UNMOUNT:
+			devfs_unmount(callid, &call);
+			break;
 		case VFS_OUT_LOOKUP:
 			devfs_lookup(callid, &call);
Index: uspace/srv/fs/devfs/devfs_ops.c
===================================================================
--- uspace/srv/fs/devfs/devfs_ops.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/devfs/devfs_ops.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -419,5 +419,6 @@
 	
 	/* Accept the mount options */
-	ipcarg_t retval = async_data_string_receive(&opts, 0);
+	ipcarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
+	    0, NULL);
 	if (retval != EOK) {
 		ipc_answer_0(rid, retval);
@@ -432,4 +433,14 @@
 {
 	libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
+}
+
+void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
+{
+	ipc_answer_0(rid, ENOTSUP);
+}
+
+void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_unmount(&devfs_libfs_ops, rid, request);
 }
 
Index: uspace/srv/fs/devfs/devfs_ops.h
===================================================================
--- uspace/srv/fs/devfs/devfs_ops.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/devfs/devfs_ops.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -41,4 +41,6 @@
 extern void devfs_mounted(ipc_callid_t, ipc_call_t *);
 extern void devfs_mount(ipc_callid_t, ipc_call_t *);
+extern void devfs_unmounted(ipc_callid_t, ipc_call_t *);
+extern void devfs_unmount(ipc_callid_t, ipc_call_t *);
 extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
 extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
Index: uspace/srv/fs/fat/fat.c
===================================================================
--- uspace/srv/fs/fat/fat.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/fat/fat.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -100,4 +100,10 @@
 			fat_mount(callid, &call);
 			break;
+		case VFS_OUT_UNMOUNTED:
+			fat_unmounted(callid, &call);
+			break;
+		case VFS_OUT_UNMOUNT:
+			fat_unmount(callid, &call);
+			break;
 		case VFS_OUT_LOOKUP:
 			fat_lookup(callid, &call);
Index: uspace/srv/fs/fat/fat.h
===================================================================
--- uspace/srv/fs/fat/fat.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/fat/fat.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -204,4 +204,6 @@
 extern void fat_mounted(ipc_callid_t, ipc_call_t *);
 extern void fat_mount(ipc_callid_t, ipc_call_t *);
+extern void fat_unmounted(ipc_callid_t, ipc_call_t *);
+extern void fat_unmount(ipc_callid_t, ipc_call_t *);
 extern void fat_lookup(ipc_callid_t, ipc_call_t *);
 extern void fat_read(ipc_callid_t, ipc_call_t *);
Index: uspace/srv/fs/fat/fat_fat.c
===================================================================
--- uspace/srv/fs/fat/fat_fat.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/fat/fat_fat.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -361,5 +361,5 @@
 	uint16_t rscnt;
 	uint16_t sf;
-	uint16_t ts;
+	uint32_t ts;
 	unsigned rde;
 	unsigned rds;
@@ -379,5 +379,7 @@
 	sf = uint16_t_le2host(bs->sec_per_fat);
 	rde = uint16_t_le2host(bs->root_ent_max);
-	ts = uint16_t_le2host(bs->totsec16);
+	ts = (uint32_t) uint16_t_le2host(bs->totsec16);
+	if (ts == 0)
+		ts = uint32_t_le2host(bs->totsec32);
 
 	rds = (sizeof(fat_dentry_t) * rde) / bps;
@@ -608,4 +610,74 @@
 }
 
+/** Perform basic sanity checks on the file system.
+ *
+ * Verify if values of boot sector fields are sane. Also verify media
+ * descriptor. This is used to rule out cases when a device obviously
+ * does not contain a fat file system.
+ */
+int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)
+{
+	fat_cluster_t e0, e1;
+	unsigned fat_no;
+	int rc;
+
+	/* Check number of FATs. */
+	if (bs->fatcnt == 0)
+		return ENOTSUP;
+
+	/* Check total number of sectors. */
+
+	if (bs->totsec16 == 0 && bs->totsec32 == 0)
+		return ENOTSUP;
+
+	if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
+	    bs->totsec16 != bs->totsec32) 
+		return ENOTSUP;
+
+	/* Check media descriptor. Must be between 0xf0 and 0xff. */
+	if ((bs->mdesc & 0xf0) != 0xf0)
+		return ENOTSUP;
+
+	/* Check number of sectors per FAT. */
+	if (bs->sec_per_fat == 0)
+		return ENOTSUP;
+
+	/*
+	 * Check that the root directory entries take up whole blocks.
+	 * This check is rather strict, but it allows us to treat the root
+	 * directory and non-root directories uniformly in some places.
+	 * It can be removed provided that functions such as fat_read() are
+	 * sanitized to support file systems with this property.
+	 */
+	if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %
+	    uint16_t_le2host(bs->bps) != 0)
+		return ENOTSUP;
+
+	/* Check signature of each FAT. */
+
+	for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
+		rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);
+		if (rc != EOK)
+			return EIO;
+
+		rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);
+		if (rc != EOK)
+			return EIO;
+
+		/* Check that first byte of FAT contains the media descriptor. */
+		if ((e0 & 0xff) != bs->mdesc)
+			return ENOTSUP;
+
+		/*
+		 * Check that remaining bits of the first two entries are
+		 * set to one.
+		 */
+		if ((e0 >> 8) != 0xff || e1 != 0xffff)
+			return ENOTSUP;
+	}
+
+	return EOK;
+}
+
 /**
  * @}
Index: uspace/srv/fs/fat/fat_fat.h
===================================================================
--- uspace/srv/fs/fat/fat_fat.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/fat/fat_fat.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -87,4 +87,5 @@
     off_t);
 extern int fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
+extern int fat_sanity_check(struct fat_bs *, dev_handle_t);
 
 #endif
Index: uspace/srv/fs/fat/fat_idx.c
===================================================================
--- uspace/srv/fs/fat/fat_idx.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/fat/fat_idx.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -149,10 +149,21 @@
 {
 	dev_handle_t dev_handle = (dev_handle_t)key[UPH_DH_KEY];
-	fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY];
-	unsigned pdi = (unsigned)key[UPH_PDI_KEY];
+	fat_cluster_t pfc;
+	unsigned pdi;
 	fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link);
 
-	return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) &&
-	    (pdi == fidx->pdi);
+	switch (keys) {
+	case 1:
+		return (dev_handle == fidx->dev_handle);
+	case 3:
+		pfc = (fat_cluster_t) key[UPH_PFC_KEY];
+		pdi = (unsigned) key[UPH_PDI_KEY];
+		return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) &&
+		    (pdi == fidx->pdi);
+	default:
+		assert((keys == 1) || (keys == 3));
+	}
+
+	return 0;
 }
 
@@ -197,13 +208,26 @@
 {
 	dev_handle_t dev_handle = (dev_handle_t)key[UIH_DH_KEY];
-	fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];
+	fs_index_t index;
 	fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link);
 
-	return (dev_handle == fidx->dev_handle) && (index == fidx->index);
+	switch (keys) {
+	case 1:
+		return (dev_handle == fidx->dev_handle);
+	case 2:
+		index = (fs_index_t) key[UIH_INDEX_KEY];
+		return (dev_handle == fidx->dev_handle) &&
+		    (index == fidx->index);
+	default:
+		assert((keys == 1) || (keys == 2));
+	}
+
+	return 0;
 }
 
 static void idx_remove_callback(link_t *item)
 {
-	/* nothing to do */
+	fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link);
+
+	free(fidx);
 }
 
@@ -486,4 +510,6 @@
 		[UIH_INDEX_KEY] = idx->index,
 	};
+	dev_handle_t dev_handle = idx->dev_handle;
+	fs_index_t index = idx->index;
 
 	assert(idx->pfc == FAT_CLST_RES0);
@@ -498,7 +524,6 @@
 	fibril_mutex_unlock(&used_lock);
 	/* Release the VFS index. */
-	fat_index_free(idx->dev_handle, idx->index);
-	/* Deallocate the structure. */
-	free(idx);
+	fat_index_free(dev_handle, index);
+	/* The index structure itself is freed in idx_remove_callback(). */
 }
 
@@ -531,8 +556,10 @@
 	unused_initialize(u, dev_handle);
 	fibril_mutex_lock(&unused_lock);
-	if (!unused_find(dev_handle, false))
+	if (!unused_find(dev_handle, false)) {
 		list_append(&u->link, &unused_head);
-	else
+	} else {
+		free(u);
 		rc = EEXIST;
+	}
 	fibril_mutex_unlock(&unused_lock);
 	return rc;
@@ -541,7 +568,25 @@
 void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle)
 {
-	unused_t *u;
-
-	u = unused_find(dev_handle, true);
+	unsigned long ikey[] = {
+		[UIH_DH_KEY] = dev_handle
+	};
+	unsigned long pkey[] = {
+		[UPH_DH_KEY] = dev_handle
+	};
+
+	/*
+	 * Remove this instance's index structure from up_hash and ui_hash.
+	 * Process up_hash first and ui_hash second because the index structure
+	 * is actually removed in idx_remove_callback(). 
+	 */
+	fibril_mutex_lock(&used_lock);
+	hash_table_remove(&up_hash, pkey, 1);
+	hash_table_remove(&ui_hash, ikey, 1);
+	fibril_mutex_unlock(&used_lock);
+
+	/*
+	 * Free the unused and freed structures for this instance.
+	 */
+	unused_t *u = unused_find(dev_handle, true);
 	assert(u);
 	list_remove(&u->link);
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/fat/fat_ops.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -139,4 +139,63 @@
 }
 
+static int fat_node_fini_by_dev_handle(dev_handle_t dev_handle)
+{
+	link_t *lnk;
+	fat_node_t *nodep;
+	int rc;
+
+	/*
+	 * We are called from fat_unmounted() and assume that there are already
+	 * no nodes belonging to this instance with non-zero refcount. Therefore
+	 * it is sufficient to clean up only the FAT free node list.
+	 */
+
+restart:
+	fibril_mutex_lock(&ffn_mutex);
+	for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {
+		nodep = list_get_instance(lnk, fat_node_t, ffn_link);
+		if (!fibril_mutex_trylock(&nodep->lock)) {
+			fibril_mutex_unlock(&ffn_mutex);
+			goto restart;
+		}
+		if (!fibril_mutex_trylock(&nodep->idx->lock)) {
+			fibril_mutex_unlock(&nodep->lock);
+			fibril_mutex_unlock(&ffn_mutex);
+			goto restart;
+		}
+		if (nodep->idx->dev_handle != dev_handle) {
+			fibril_mutex_unlock(&nodep->idx->lock);
+			fibril_mutex_unlock(&nodep->lock);
+			continue;
+		}
+
+		list_remove(&nodep->ffn_link);
+		fibril_mutex_unlock(&ffn_mutex);
+
+		/*
+		 * We can unlock the node and its index structure because we are
+		 * the last player on this playground and VFS is preventing new
+		 * players from entering.
+		 */
+		fibril_mutex_unlock(&nodep->idx->lock);
+		fibril_mutex_unlock(&nodep->lock);
+
+		if (nodep->dirty) {
+			rc = fat_node_sync(nodep);
+			if (rc != EOK)
+				return rc;
+		}
+		nodep->idx->nodep = NULL;
+		free(nodep->bp);
+		free(nodep);
+
+		/* Need to restart because we changed the ffn_head list. */
+		goto restart;
+	}
+	fibril_mutex_unlock(&ffn_mutex);
+
+	return EOK;
+}
+
 static int fat_node_get_new(fat_node_t **nodepp)
 {
@@ -290,74 +349,4 @@
 
 	*nodepp = nodep;
-	return EOK;
-}
-
-/** Perform basic sanity checks on the file system.
- *
- * Verify if values of boot sector fields are sane. Also verify media
- * descriptor. This is used to rule out cases when a device obviously
- * does not contain a fat file system.
- */
-static int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)
-{
-	fat_cluster_t e0, e1;
-	unsigned fat_no;
-	int rc;
-
-	/* Check number of FATs. */
-	if (bs->fatcnt == 0)
-		return ENOTSUP;
-
-	/* Check total number of sectors. */
-
-	if (bs->totsec16 == 0 && bs->totsec32 == 0)
-		return ENOTSUP;
-
-	if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
-	    bs->totsec16 != bs->totsec32) 
-		return ENOTSUP;
-
-	/* Check media descriptor. Must be between 0xf0 and 0xff. */
-	if ((bs->mdesc & 0xf0) != 0xf0)
-		return ENOTSUP;
-
-	/* Check number of sectors per FAT. */
-	if (bs->sec_per_fat == 0)
-		return ENOTSUP;
-
-	/*
-	 * Check that the root directory entries take up whole blocks.
-	 * This check is rather strict, but it allows us to treat the root
-	 * directory and non-root directories uniformly in some places.
-	 * It can be removed provided that functions such as fat_read() are
-	 * sanitized to support file systems with this property.
-	 */
-	if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %
-	    uint16_t_le2host(bs->bps) != 0)
-		return ENOTSUP;
-
-	/* Check signature of each FAT. */
-
-	for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
-		rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);
-		if (rc != EOK)
-			return EIO;
-
-		rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);
-		if (rc != EOK)
-			return EIO;
-
-		/* Check that first byte of FAT contains the media descriptor. */
-		if ((e0 & 0xff) != bs->mdesc)
-			return ENOTSUP;
-
-		/*
-		 * Check that remaining bits of the first two entries are
-		 * set to one.
-		 */
-		if ((e0 >> 8) != 0xff || e1 != 0xffff)
-			return ENOTSUP;
-	}
-
 	return EOK;
 }
@@ -985,27 +974,13 @@
 	uint16_t bps;
 	uint16_t rde;
-	int rc;
-
-	/* accept the mount options */
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *opts = malloc(size + 1);
-	if (!opts) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	ipcarg_t retval = async_data_write_finalize(callid, opts, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
-		free(opts);
-		return;
-	}
-	opts[size] = '\0';
+	
+	/* Accept the mount options */
+	char *opts;
+	int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
+	
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 
 	/* Check for option enabling write through. */
@@ -1015,4 +990,6 @@
 		cmode = CACHE_MODE_WB;
 
+	free(opts);
+
 	/* initialize libblock */
 	rc = block_init(dev_handle, BS_SIZE);
@@ -1054,4 +1031,5 @@
 	rc = fat_sanity_check(bs, dev_handle);
 	if (rc != EOK) {
+		(void) block_cache_fini(dev_handle);
 		block_fini(dev_handle);
 		ipc_answer_0(rid, rc);
@@ -1061,4 +1039,5 @@
 	rc = fat_idx_init_by_dev_handle(dev_handle);
 	if (rc != EOK) {
+		(void) block_cache_fini(dev_handle);
 		block_fini(dev_handle);
 		ipc_answer_0(rid, rc);
@@ -1069,4 +1048,5 @@
 	fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
 	if (!rfn) {
+		(void) block_cache_fini(dev_handle);
 		block_fini(dev_handle);
 		fat_idx_fini_by_dev_handle(dev_handle);
@@ -1078,4 +1058,5 @@
 	if (!rootp) {
 		free(rfn);
+		(void) block_cache_fini(dev_handle);
 		block_fini(dev_handle);
 		fat_idx_fini_by_dev_handle(dev_handle);
@@ -1089,4 +1070,5 @@
 		free(rfn);
 		free(rootp);
+		(void) block_cache_fini(dev_handle);
 		block_fini(dev_handle);
 		fat_idx_fini_by_dev_handle(dev_handle);
@@ -1115,4 +1097,52 @@
 {
 	libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
+}
+
+void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
+{
+	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
+	fs_node_t *fn;
+	fat_node_t *nodep;
+	int rc;
+
+	rc = fat_root_get(&fn, dev_handle);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	nodep = FAT_NODE(fn);
+
+	/*
+	 * We expect exactly two references on the root node. One for the
+	 * fat_root_get() above and one created in fat_mounted().
+	 */
+	if (nodep->refcnt != 2) {
+		(void) fat_node_put(fn);
+		ipc_answer_0(rid, EBUSY);
+		return;
+	}
+	
+	/*
+	 * Put the root node and force it to the FAT free node list.
+	 */
+	(void) fat_node_put(fn);
+	(void) fat_node_put(fn);
+
+	/*
+	 * Perform cleanup of the node structures, index structures and
+	 * associated data. Write back this file system's dirty blocks and
+	 * stop using libblock for this instance.
+	 */
+	(void) fat_node_fini_by_dev_handle(dev_handle);
+	fat_idx_fini_by_dev_handle(dev_handle);
+	(void) block_cache_fini(dev_handle);
+	block_fini(dev_handle);
+
+	ipc_answer_0(rid, EOK);
+}
+
+void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_unmount(&fat_libfs_ops, rid, request);
 }
 
Index: uspace/srv/fs/tmpfs/tmpfs.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/tmpfs/tmpfs.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -106,4 +106,10 @@
 			tmpfs_mount(callid, &call);
 			break;
+		case VFS_OUT_UNMOUNTED:
+			tmpfs_unmounted(callid, &call);
+			break;
+		case VFS_OUT_UNMOUNT:
+			tmpfs_unmount(callid, &call);
+			break;
 		case VFS_OUT_LOOKUP:
 			tmpfs_lookup(callid, &call);
Index: uspace/srv/fs/tmpfs/tmpfs.h
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/tmpfs/tmpfs.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -83,4 +83,6 @@
 extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
+extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);
+extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);
 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
 extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -147,6 +147,6 @@
 hash_table_t nodes;
 
-#define NODES_KEY_INDEX	0
-#define NODES_KEY_DEV	1
+#define NODES_KEY_DEV	0	
+#define NODES_KEY_INDEX	1
 
 /* Implementation of hash table interface for the nodes hash table. */
@@ -160,10 +160,38 @@
 	tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
 	    nh_link);
-	return (nodep->index == key[NODES_KEY_INDEX] &&
-	    nodep->dev_handle == key[NODES_KEY_DEV]);
+	
+	switch (keys) {
+	case 1:
+		return (nodep->dev_handle == key[NODES_KEY_DEV]);
+	case 2:	
+		return ((nodep->dev_handle == key[NODES_KEY_DEV]) &&
+		    (nodep->index == key[NODES_KEY_INDEX]));
+	default:
+		assert((keys == 1) || (keys == 2));
+	}
+
+	return 0;
 }
 
 static void nodes_remove_callback(link_t *item)
 {
+	tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
+	    nh_link);
+
+	while (!list_empty(&nodep->cs_head)) {
+		tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next,
+		    tmpfs_dentry_t, link);
+
+		assert(nodep->type == TMPFS_DIRECTORY);
+		list_remove(&dentryp->link);
+		free(dentryp);
+	}
+
+	if (nodep->data) {
+		assert(nodep->type == TMPFS_FILE);
+		free(nodep->data);
+	}
+	free(nodep->bp);
+	free(nodep);
 }
 
@@ -215,4 +243,19 @@
 }
 
+static void tmpfs_instance_done(dev_handle_t dev_handle)
+{
+	unsigned long key[] = {
+		[NODES_KEY_DEV] = dev_handle
+	};
+	/*
+	 * Here we are making use of one special feature of our hash table
+	 * implementation, which allows to remove more items based on a partial
+	 * key match. In the following, we are going to remove all nodes
+	 * matching our device handle. The nodes_remove_callback() function will
+	 * take care of resource deallocation.
+	 */
+	hash_table_remove(&nodes, key, 1);
+}
+
 int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
 {
@@ -237,6 +280,6 @@
 {
 	unsigned long key[] = {
-		[NODES_KEY_INDEX] = index,
-		[NODES_KEY_DEV] = dev_handle
+		[NODES_KEY_DEV] = dev_handle,
+		[NODES_KEY_INDEX] = index
 	};
 	link_t *lnk = hash_table_find(&nodes, key);
@@ -296,6 +339,6 @@
 	/* Insert the new node into the nodes hash table. */
 	unsigned long key[] = {
-		[NODES_KEY_INDEX] = nodep->index,
-		[NODES_KEY_DEV] = nodep->dev_handle
+		[NODES_KEY_DEV] = nodep->dev_handle,
+		[NODES_KEY_INDEX] = nodep->index
 	};
 	hash_table_insert(&nodes, key, &nodep->nh_link);
@@ -312,13 +355,13 @@
 
 	unsigned long key[] = {
-		[NODES_KEY_INDEX] = nodep->index,
-		[NODES_KEY_DEV] = nodep->dev_handle
+		[NODES_KEY_DEV] = nodep->dev_handle,
+		[NODES_KEY_INDEX] = nodep->index
 	};
 	hash_table_remove(&nodes, key, 2);
 
-	if (nodep->type == TMPFS_FILE)
-		free(nodep->data);
-	free(nodep->bp);
-	free(nodep);
+	/*
+	 * The nodes_remove_callback() function takes care of the actual
+	 * resource deallocation.
+	 */
 	return EOK;
 }
@@ -398,35 +441,31 @@
 {
 	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
+	fs_node_t *rootfn;
 	int rc;
-
-	/* accept the mount options */
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *opts = malloc(size + 1);
-	if (!opts) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	ipcarg_t retval = async_data_write_finalize(callid, opts, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
+	
+	/* Accept the mount options. */
+	char *opts;
+	rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+
+	/* Check if this device is not already mounted. */
+	rc = tmpfs_root_get(&rootfn, dev_handle);
+	if ((rc == EOK) && (rootfn)) {
+		(void) tmpfs_node_put(rootfn);
 		free(opts);
-		return;
-	}
-	opts[size] = '\0';
+		ipc_answer_0(rid, EEXIST);
+		return;
+	}
 
 	/* Initialize TMPFS instance. */
 	if (!tmpfs_instance_init(dev_handle)) {
+		free(opts);
 		ipc_answer_0(rid, ENOMEM);
 		return;
 	}
 
-	fs_node_t *rootfn;
 	rc = tmpfs_root_get(&rootfn, dev_handle);
 	assert(rc == EOK);
@@ -442,4 +481,5 @@
 		    rootp->lnkcnt);
 	}
+	free(opts);
 }
 
@@ -447,4 +487,17 @@
 {
 	libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
+}
+
+void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
+{
+	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
+
+	tmpfs_instance_done(dev_handle);
+	ipc_answer_0(rid, EOK);
+}
+
+void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_unmount(&tmpfs_libfs_ops, rid, request);
 }
 
@@ -465,6 +518,6 @@
 	link_t *hlp;
 	unsigned long key[] = {
-		[NODES_KEY_INDEX] = index,
 		[NODES_KEY_DEV] = dev_handle,
+		[NODES_KEY_INDEX] = index
 	};
 	hlp = hash_table_find(&nodes, key);
@@ -539,6 +592,6 @@
 	link_t *hlp;
 	unsigned long key[] = {
-		[NODES_KEY_INDEX] = index,
-		[NODES_KEY_DEV] = dev_handle
+		[NODES_KEY_DEV] = dev_handle,
+		[NODES_KEY_INDEX] = index
 	};
 	hlp = hash_table_find(&nodes, key);
@@ -603,6 +656,6 @@
 	link_t *hlp;
 	unsigned long key[] = {
-		[NODES_KEY_INDEX] = index,
-		[NODES_KEY_DEV] = dev_handle
+		[NODES_KEY_DEV] = dev_handle,
+		[NODES_KEY_INDEX] = index
 	};
 	hlp = hash_table_find(&nodes, key);
@@ -646,6 +699,6 @@
 	link_t *hlp;
 	unsigned long key[] = {
-		[NODES_KEY_INDEX] = index,
-		[NODES_KEY_DEV] = dev_handle
+		[NODES_KEY_DEV] = dev_handle,
+		[NODES_KEY_INDEX] = index
 	};
 	hlp = hash_table_find(&nodes, key);
Index: uspace/srv/hid/adb_mouse/Makefile
===================================================================
--- uspace/srv/hid/adb_mouse/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/adb_mouse/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2010 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBC_PREFIX)/libc.a
+EXTRA_CFLAGS = -Iinclude
+
+OUTPUT = adb_ms
+
+SOURCES = \
+	adb_mouse.c \
+	adb_dev.c
+
+include ../../Makefile.common
Index: uspace/srv/hid/adb_mouse/adb_dev.c
===================================================================
--- uspace/srv/hid/adb_mouse/adb_dev.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/adb_mouse/adb_dev.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010 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 mouse
+ * @{
+ */ 
+/** @file
+ * @brief
+ */
+
+#include <ipc/ipc.h>
+#include <ipc/adb.h>
+#include <async.h>
+#include <vfs/vfs.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "adb_mouse.h"
+#include "adb_dev.h"
+
+static void adb_dev_events(ipc_callid_t iid, ipc_call_t *icall);
+
+static int dev_phone;
+
+int adb_dev_init(void)
+{
+	char *input = "/dev/adb/mouse";
+	int input_fd;
+
+	printf(NAME ": open %s\n", input);
+
+	input_fd = open(input, O_RDONLY);
+	if (input_fd < 0) {
+		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
+		return false;
+	}
+
+	dev_phone = fd_phone(input_fd);
+	if (dev_phone < 0) {
+		printf(NAME ": Failed to connect to device\n");
+		return false;
+	}
+
+	/* NB: The callback connection is slotted for removal */
+	ipcarg_t phonehash;
+	if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
+		printf(NAME ": Failed to create callback from device\n");
+		return false;
+	}
+
+	async_new_connection(phonehash, 0, NULL, adb_dev_events);
+
+	return 0;
+}
+
+static void adb_dev_events(ipc_callid_t iid, ipc_call_t *icall)
+{
+	/* Ignore parameters, the connection is already opened */
+	while (true) {
+
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+
+		int retval;
+
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			/* TODO: Handle hangup */
+			return;
+		case IPC_FIRST_USER_METHOD:
+			mouse_handle_data(IPC_GET_ARG1(call));
+			break;
+		default:
+			retval = ENOENT;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/adb_mouse/adb_dev.h
===================================================================
--- uspace/srv/hid/adb_mouse/adb_dev.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/adb_mouse/adb_dev.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 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 mouse
+ * @brief
+ * @{
+ */
+/** @file
+ */
+
+#ifndef ADBDEV_H_
+#define ADBDEV_H_
+
+#include <sys/types.h>
+
+extern int adb_dev_init(void);
+
+#endif
+
+/**
+ * @}
+ */ 
+
Index: uspace/srv/hid/adb_mouse/adb_mouse.c
===================================================================
--- uspace/srv/hid/adb_mouse/adb_mouse.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/adb_mouse/adb_mouse.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2010 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 mouse
+ * @brief ADB Apple classic mouse driver.
+ *
+ * This driver handles a mouse connected to Apple Desktop Bus speaking
+ * the Apple classic protocol. It connects to an ADB driver.
+ *
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <ipc/mouse.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <async.h>
+#include <errno.h>
+#include <devmap.h>
+
+#include "adb_mouse.h"
+#include "adb_dev.h"
+
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void mouse_ev_btn(int button, int press);
+static void mouse_ev_move(int dx, int dy);
+
+static int client_phone = -1;
+static bool b1_pressed, b2_pressed;
+
+int main(int argc, char **argv)
+{
+	printf(NAME ": Chardev mouse driver\n");
+
+	/* Initialize device. */
+	if (adb_dev_init() != 0)
+		return -1;
+
+	b1_pressed = false;
+	b2_pressed = false; 
+
+	/* Register driver */
+	int rc = devmap_driver_register(NAME, client_connection);
+	if (rc < 0) {
+		printf(NAME ": Unable to register driver (%d)\n", rc);
+		return -1;
+	}
+
+	char dev_path[DEVMAP_NAME_MAXLEN + 1];
+	snprintf(dev_path, DEVMAP_NAME_MAXLEN, "%s/mouse", NAMESPACE);
+
+	dev_handle_t dev_handle;
+	if (devmap_device_register(dev_path, &dev_handle) != EOK) {
+		printf(NAME ": Unable to register device %s\n", dev_path);
+		return -1;
+	}
+
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
+	async_manager();
+
+	/* Not reached. */
+	return 0;
+}
+
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	int retval;
+
+	ipc_answer_0(iid, EOK);
+
+	while (1) {
+		callid = async_get_call(&call);
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			if (client_phone != -1) {
+				ipc_hangup(client_phone);
+				client_phone = -1;
+			}
+
+			ipc_answer_0(callid, EOK);
+			return;
+		case IPC_M_CONNECT_TO_ME:
+			if (client_phone != -1) {
+				retval = ELIMIT;
+				break;
+			}
+			client_phone = IPC_GET_ARG5(call);
+			retval = 0;
+			break;
+		default:
+			retval = EINVAL;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+void mouse_handle_data(uint16_t data)
+{
+	bool b1, b2;
+	uint16_t udx, udy;
+	int dx, dy;
+
+	/* Extract fields. */
+	b1 = ((data >> 15) & 1) == 0;
+	udy = (data >> 8) & 0x7f;
+	b2 = ((data >> 7) & 1) == 0;
+	udx = data & 0x7f;
+
+	/* Decode 7-bit two's complement signed values. */
+	dx = (udx & 0x40) ? (udx - 0x80) : udx;
+	dy = (udy & 0x40) ? (udy - 0x80) : udy;
+
+	if (b1 != b1_pressed) {
+		mouse_ev_btn(1, b1);
+		b1_pressed = b1;
+	}
+
+	if (b2 != b2_pressed) {
+		mouse_ev_btn(2, b2);
+		b1_pressed = b1;
+	}
+
+	if (dx != 0 || dy != 0)
+		mouse_ev_move(dx, dy);
+}
+
+static void mouse_ev_btn(int button, int press)
+{
+	if (client_phone != -1) {
+		async_msg_2(client_phone, MEVENT_BUTTON, button, press);
+	}
+}
+
+static void mouse_ev_move(int dx, int dy)
+{
+	if (client_phone != -1)
+		async_msg_2(client_phone, MEVENT_MOVE, dx, dy);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/adb_mouse/adb_mouse.h
===================================================================
--- uspace/srv/hid/adb_mouse/adb_mouse.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/adb_mouse/adb_mouse.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010 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 mouse
+ * @brief
+ * @{
+ */
+/** @file
+ */
+
+#ifndef ADB_MOUSE_H_
+#define ADB_MOUSE_H_
+
+#include <sys/types.h>
+
+#define NAME       "adb_ms"
+#define NAMESPACE  "hid_in"
+
+extern void mouse_handle_data(uint16_t);
+
+#endif
+
+/**
+ * @}
+ */
Index: pace/srv/hid/c_mouse/Makefile
===================================================================
--- uspace/srv/hid/c_mouse/Makefile	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,41 +1,0 @@
-#
-# 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.
-#
-
-USPACE_PREFIX = ../../..
-LIBS = $(LIBC_PREFIX)/libc.a
-EXTRA_CFLAGS = -Iinclude
-
-OUTPUT = c_mouse
-
-SOURCES = \
-	proto/ps2.c \
-	c_mouse.c \
-	chardev.c
-
-include ../../Makefile.common
Index: pace/srv/hid/c_mouse/c_mouse.c
===================================================================
--- uspace/srv/hid/c_mouse/c_mouse.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,152 +1,0 @@
-/*
- * 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 mouse
- * @brief Chardev mouse driver.
- *
- * This is a common driver for mice attached to simple character devices
- * (PS/2 mice, serial mice).
- *
- * @{
- */
-/** @file
- */
-
-#include <ipc/ipc.h>
-#include <ipc/mouse.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <async.h>
-#include <errno.h>
-#include <devmap.h>
-
-#include <c_mouse.h>
-#include <mouse_port.h>
-#include <mouse_proto.h>
-
-#define NAME       "mouse"
-#define NAMESPACE  "hid_in"
-
-int client_phone = -1;
-
-void mouse_handle_byte(int byte)
-{
-/*	printf("mouse byte: 0x%x\n", byte);*/
-	mouse_proto_parse_byte(byte);
-}
-
-void mouse_ev_btn(int button, int press)
-{
-/*	printf("ev_btn: button %d, press %d\n", button, press);*/
-	if (client_phone != -1) {
-		async_msg_2(client_phone, MEVENT_BUTTON, button, press);
-	}
-}
-
-void mouse_ev_move(int dx, int dy)
-{
-/*	printf("ev_move: dx %d, dy %d\n", dx, dy);*/
-	if (client_phone != -1)
-		async_msg_2(client_phone, MEVENT_MOVE, dx, dy);
-}
-
-static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	ipc_callid_t callid;
-	ipc_call_t call;
-	int retval;
-
-	ipc_answer_0(iid, EOK);
-
-	while (1) {
-		callid = async_get_call(&call);
-		switch (IPC_GET_METHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			if (client_phone != -1) {
-				ipc_hangup(client_phone);
-				client_phone = -1;
-			}
-
-			ipc_answer_0(callid, EOK);
-			return;
-		case IPC_M_CONNECT_TO_ME:
-			if (client_phone != -1) {
-				retval = ELIMIT;
-				break;
-			}
-			client_phone = IPC_GET_ARG5(call);
-			retval = 0;
-			break;
-		default:
-			retval = EINVAL;
-		}
-		ipc_answer_0(callid, retval);
-	}
-}
-
-
-int main(int argc, char **argv)
-{
-	printf(NAME ": Chardev mouse driver\n");
-
-	/* Initialize port. */
-	if (mouse_port_init() != 0)
-		return -1;
-
-	/* Initialize protocol driver. */
-	if (mouse_proto_init() != 0)
-		return -1;
-
-	/* Register driver */
-	int rc = devmap_driver_register(NAME, client_connection);
-	if (rc < 0) {
-		printf(NAME ": Unable to register driver (%d)\n", rc);
-		return -1;
-	}
-
-	char dev_path[DEVMAP_NAME_MAXLEN + 1];
-	snprintf(dev_path, DEVMAP_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
-
-	dev_handle_t dev_handle;
-	if (devmap_device_register(dev_path, &dev_handle) != EOK) {
-		printf(NAME ": Unable to register device %s\n", dev_path);
-		return -1;
-	}
-
-	printf(NAME ": Accepting connections\n");
-	task_retval(0);
-	async_manager();
-
-	/* Not reached. */
-	return 0;
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/c_mouse/chardev.c
===================================================================
--- uspace/srv/hid/c_mouse/chardev.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,122 +1,0 @@
-/*
- * 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 mouse
- * @{
- */ 
-/** @file
- * @brief
- */
-
-#include <ipc/ipc.h>
-#include <ipc/char.h>
-#include <async.h>
-#include <vfs/vfs.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <c_mouse.h>
-#include <mouse_port.h>
-
-static void chardev_events(ipc_callid_t iid, ipc_call_t *icall);
-
-static int dev_phone;
-
-#define NAME "kbd"
-
-int mouse_port_init(void)
-{
-	char *input = "/dev/char/ps2b";
-	int input_fd;
-
-	printf(NAME ": open %s\n", input);
-
-	input_fd = open(input, O_RDONLY);
-	if (input_fd < 0) {
-		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
-		return false;
-	}
-
-	dev_phone = fd_phone(input_fd);
-	if (dev_phone < 0) {
-		printf(NAME ": Failed to connect to device\n");
-		return false;
-	}
-
-	/* NB: The callback connection is slotted for removal */
-	ipcarg_t phonehash;
-	if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
-		printf(NAME ": Failed to create callback from device\n");
-		return false;
-	}
-
-	async_new_connection(phonehash, 0, NULL, chardev_events);
-
-	return 0;
-}
-
-void mouse_port_yield(void)
-{
-}
-
-void mouse_port_reclaim(void)
-{
-}
-
-void mouse_port_write(uint8_t data)
-{
-	async_msg_1(dev_phone, CHAR_WRITE_BYTE, data);
-}
-
-static void chardev_events(ipc_callid_t iid, ipc_call_t *icall)
-{
-	/* Ignore parameters, the connection is already opened */
-	while (true) {
-
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-
-		int retval;
-
-		switch (IPC_GET_METHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			/* TODO: Handle hangup */
-			return;
-		case IPC_FIRST_USER_METHOD:
-			mouse_handle_byte(IPC_GET_ARG1(call));
-			break;
-		default:
-			retval = ENOENT;
-		}
-		ipc_answer_0(callid, retval);
-	}
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/c_mouse/include/c_mouse.h
===================================================================
--- uspace/srv/hid/c_mouse/include/c_mouse.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,47 +1,0 @@
-/*
- * 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 mouse
- * @brief
- * @{
- */
-/** @file
- */
-
-#ifndef C_MOUSE_H_
-#define C_MOUSE_H_
-
-extern void mouse_handle_byte(int);
-extern void mouse_ev_btn(int button, int press);
-extern void mouse_ev_move(int dx, int dy);
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/c_mouse/include/mouse_port.h
===================================================================
--- uspace/srv/hid/c_mouse/include/mouse_port.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * 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 mouse
- * @brief
- * @{
- */
-/** @file
- */
-
-#ifndef MOUSE_PORT_H_
-#define MOUSE_PORT_H_
-
-#include <sys/types.h>
-
-extern int mouse_port_init(void);
-extern void mouse_port_yield(void);
-extern void mouse_port_reclaim(void);
-extern void mouse_port_write(uint8_t);
-
-#endif
-
-/**
- * @}
- */ 
-
Index: pace/srv/hid/c_mouse/include/mouse_proto.h
===================================================================
--- uspace/srv/hid/c_mouse/include/mouse_proto.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * 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 mouse
- * @brief
- * @{
- */
-/** @file
- */
-
-#ifndef MOUSE_PROTO_H_
-#define MOUSE_PROTO_H_
-
-extern void mouse_proto_parse_byte(int);
-extern int mouse_proto_init(void);
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/c_mouse/proto/ps2.c
===================================================================
--- uspace/srv/hid/c_mouse/proto/ps2.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ 	(revision )
@@ -1,125 +1,0 @@
-/*
- * 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 mouse
- * @{
- */
-/**
- * @file
- * @brief PS/2 mouse protocol driver.
- */
-
-#include <stdio.h>
-#include <mouse_proto.h>
-#include <c_mouse.h>
-
-#define BUFSIZE 3
-
-typedef struct {
-	union {
-		unsigned char data[BUFSIZE];
-		struct {
-			unsigned leftbtn : 1;
-			unsigned rightbtn : 1;
-			unsigned middlebtn : 1;
-			unsigned isone : 1; /* Always one */
-			unsigned xsign : 1;
-			unsigned ysign : 1;
-			unsigned xovfl : 1;
-			unsigned yovfl : 1;
-			unsigned char x;
-			unsigned char y;
-		} val;
-	} u;
-} ps2packet_t;
-
-static ps2packet_t buf;
-static int bufpos = 0;
-static int leftbtn = 0;
-static int rightbtn = 0;
-static int middlebtn = 0;
-
-int mouse_proto_init(void)
-{
-	return 0;
-}
-
-/** Convert 9-bit 2-complement signed number to integer */
-static int bit9toint(int sign, unsigned char data)
-{
-	int tmp;
-
-	if (!sign)
-		return data;
-
-	tmp = ((unsigned char)~data) + 1;
-	return -tmp;
-}
-
-/** Process mouse data */
-void mouse_proto_parse_byte(int data)
-{
-	int x, y;
-
-	/* Check that we have not lost synchronization */
-	if (bufpos == 0 && !(data & 0x8))
-		return; /* Synchro lost, ignore byte */
-
-	buf.u.data[bufpos++] = data;
-	if (bufpos == BUFSIZE) {
-		bufpos = 0;
-
-		if (buf.u.val.leftbtn ^ leftbtn) {
-			leftbtn = buf.u.val.leftbtn;
-			mouse_ev_btn(1, leftbtn);
-		}
-
-		if (buf.u.val.rightbtn ^ rightbtn) {
-			rightbtn = buf.u.val.rightbtn;
-			mouse_ev_btn(2, rightbtn);
-		}
-
-		if (buf.u.val.middlebtn ^ middlebtn) {
-			middlebtn = buf.u.val.middlebtn;
-			mouse_ev_btn(3, middlebtn);
-		}
-
-		x =   bit9toint(buf.u.val.xsign, buf.u.val.x);
-		y = - bit9toint(buf.u.val.ysign, buf.u.val.y);
-
-		if (x != 0 || y != 0) {
-			mouse_ev_move(x, y);
-		}
-	}
-
-	return;
-}
-
-/**
- * @}
- */
Index: uspace/srv/hid/char_mouse/Makefile
===================================================================
--- uspace/srv/hid/char_mouse/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/char_mouse/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBC_PREFIX)/libc.a
+EXTRA_CFLAGS = -Iinclude
+
+OUTPUT = char_ms
+
+SOURCES = \
+	proto/ps2.c \
+	char_mouse.c \
+	chardev.c
+
+include ../../Makefile.common
Index: uspace/srv/hid/char_mouse/char_mouse.c
===================================================================
--- uspace/srv/hid/char_mouse/char_mouse.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/char_mouse/char_mouse.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,152 @@
+/*
+ * 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 mouse
+ * @brief Chardev mouse driver.
+ *
+ * This is a common driver for mice attached to simple character devices
+ * (PS/2 mice, serial mice).
+ *
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <ipc/mouse.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <async.h>
+#include <errno.h>
+#include <devmap.h>
+
+#include <char_mouse.h>
+#include <mouse_port.h>
+#include <mouse_proto.h>
+
+#define NAME       "mouse"
+#define NAMESPACE  "hid_in"
+
+int client_phone = -1;
+
+void mouse_handle_byte(int byte)
+{
+/*	printf("mouse byte: 0x%x\n", byte);*/
+	mouse_proto_parse_byte(byte);
+}
+
+void mouse_ev_btn(int button, int press)
+{
+/*	printf("ev_btn: button %d, press %d\n", button, press);*/
+	if (client_phone != -1) {
+		async_msg_2(client_phone, MEVENT_BUTTON, button, press);
+	}
+}
+
+void mouse_ev_move(int dx, int dy)
+{
+/*	printf("ev_move: dx %d, dy %d\n", dx, dy);*/
+	if (client_phone != -1)
+		async_msg_2(client_phone, MEVENT_MOVE, dx, dy);
+}
+
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	int retval;
+
+	ipc_answer_0(iid, EOK);
+
+	while (1) {
+		callid = async_get_call(&call);
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			if (client_phone != -1) {
+				ipc_hangup(client_phone);
+				client_phone = -1;
+			}
+
+			ipc_answer_0(callid, EOK);
+			return;
+		case IPC_M_CONNECT_TO_ME:
+			if (client_phone != -1) {
+				retval = ELIMIT;
+				break;
+			}
+			client_phone = IPC_GET_ARG5(call);
+			retval = 0;
+			break;
+		default:
+			retval = EINVAL;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+
+int main(int argc, char **argv)
+{
+	printf(NAME ": Chardev mouse driver\n");
+
+	/* Initialize port. */
+	if (mouse_port_init() != 0)
+		return -1;
+
+	/* Initialize protocol driver. */
+	if (mouse_proto_init() != 0)
+		return -1;
+
+	/* Register driver */
+	int rc = devmap_driver_register(NAME, client_connection);
+	if (rc < 0) {
+		printf(NAME ": Unable to register driver (%d)\n", rc);
+		return -1;
+	}
+
+	char dev_path[DEVMAP_NAME_MAXLEN + 1];
+	snprintf(dev_path, DEVMAP_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
+
+	dev_handle_t dev_handle;
+	if (devmap_device_register(dev_path, &dev_handle) != EOK) {
+		printf(NAME ": Unable to register device %s\n", dev_path);
+		return -1;
+	}
+
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
+	async_manager();
+
+	/* Not reached. */
+	return 0;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/char_mouse/chardev.c
===================================================================
--- uspace/srv/hid/char_mouse/chardev.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/char_mouse/chardev.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,122 @@
+/*
+ * 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 mouse
+ * @{
+ */ 
+/** @file
+ * @brief
+ */
+
+#include <ipc/ipc.h>
+#include <ipc/char.h>
+#include <async.h>
+#include <vfs/vfs.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <char_mouse.h>
+#include <mouse_port.h>
+
+static void chardev_events(ipc_callid_t iid, ipc_call_t *icall);
+
+static int dev_phone;
+
+#define NAME "kbd"
+
+int mouse_port_init(void)
+{
+	char *input = "/dev/char/ps2b";
+	int input_fd;
+
+	printf(NAME ": open %s\n", input);
+
+	input_fd = open(input, O_RDONLY);
+	if (input_fd < 0) {
+		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
+		return false;
+	}
+
+	dev_phone = fd_phone(input_fd);
+	if (dev_phone < 0) {
+		printf(NAME ": Failed to connect to device\n");
+		return false;
+	}
+
+	/* NB: The callback connection is slotted for removal */
+	ipcarg_t phonehash;
+	if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
+		printf(NAME ": Failed to create callback from device\n");
+		return false;
+	}
+
+	async_new_connection(phonehash, 0, NULL, chardev_events);
+
+	return 0;
+}
+
+void mouse_port_yield(void)
+{
+}
+
+void mouse_port_reclaim(void)
+{
+}
+
+void mouse_port_write(uint8_t data)
+{
+	async_msg_1(dev_phone, CHAR_WRITE_BYTE, data);
+}
+
+static void chardev_events(ipc_callid_t iid, ipc_call_t *icall)
+{
+	/* Ignore parameters, the connection is already opened */
+	while (true) {
+
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+
+		int retval;
+
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			/* TODO: Handle hangup */
+			return;
+		case IPC_FIRST_USER_METHOD:
+			mouse_handle_byte(IPC_GET_ARG1(call));
+			break;
+		default:
+			retval = ENOENT;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/char_mouse/include/char_mouse.h
===================================================================
--- uspace/srv/hid/char_mouse/include/char_mouse.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/char_mouse/include/char_mouse.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,47 @@
+/*
+ * 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 mouse
+ * @brief
+ * @{
+ */
+/** @file
+ */
+
+#ifndef CHAR_MOUSE_H_
+#define CHAR_MOUSE_H_
+
+extern void mouse_handle_byte(int);
+extern void mouse_ev_btn(int button, int press);
+extern void mouse_ev_move(int dx, int dy);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/char_mouse/include/mouse_port.h
===================================================================
--- uspace/srv/hid/char_mouse/include/mouse_port.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/char_mouse/include/mouse_port.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,51 @@
+/*
+ * 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 mouse
+ * @brief
+ * @{
+ */
+/** @file
+ */
+
+#ifndef MOUSE_PORT_H_
+#define MOUSE_PORT_H_
+
+#include <sys/types.h>
+
+extern int mouse_port_init(void);
+extern void mouse_port_yield(void);
+extern void mouse_port_reclaim(void);
+extern void mouse_port_write(uint8_t);
+
+#endif
+
+/**
+ * @}
+ */ 
+
Index: uspace/srv/hid/char_mouse/include/mouse_proto.h
===================================================================
--- uspace/srv/hid/char_mouse/include/mouse_proto.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/char_mouse/include/mouse_proto.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,46 @@
+/*
+ * 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 mouse
+ * @brief
+ * @{
+ */
+/** @file
+ */
+
+#ifndef MOUSE_PROTO_H_
+#define MOUSE_PROTO_H_
+
+extern void mouse_proto_parse_byte(int);
+extern int mouse_proto_init(void);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/char_mouse/proto/ps2.c
===================================================================
--- uspace/srv/hid/char_mouse/proto/ps2.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/char_mouse/proto/ps2.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,125 @@
+/*
+ * 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 mouse
+ * @{
+ */
+/**
+ * @file
+ * @brief PS/2 mouse protocol driver.
+ */
+
+#include <stdio.h>
+#include <mouse_proto.h>
+#include <char_mouse.h>
+
+#define BUFSIZE 3
+
+typedef struct {
+	union {
+		unsigned char data[BUFSIZE];
+		struct {
+			unsigned leftbtn : 1;
+			unsigned rightbtn : 1;
+			unsigned middlebtn : 1;
+			unsigned isone : 1; /* Always one */
+			unsigned xsign : 1;
+			unsigned ysign : 1;
+			unsigned xovfl : 1;
+			unsigned yovfl : 1;
+			unsigned char x;
+			unsigned char y;
+		} val;
+	} u;
+} ps2packet_t;
+
+static ps2packet_t buf;
+static int bufpos = 0;
+static int leftbtn = 0;
+static int rightbtn = 0;
+static int middlebtn = 0;
+
+int mouse_proto_init(void)
+{
+	return 0;
+}
+
+/** Convert 9-bit 2-complement signed number to integer */
+static int bit9toint(int sign, unsigned char data)
+{
+	int tmp;
+
+	if (!sign)
+		return data;
+
+	tmp = ((unsigned char)~data) + 1;
+	return -tmp;
+}
+
+/** Process mouse data */
+void mouse_proto_parse_byte(int data)
+{
+	int x, y;
+
+	/* Check that we have not lost synchronization */
+	if (bufpos == 0 && !(data & 0x8))
+		return; /* Synchro lost, ignore byte */
+
+	buf.u.data[bufpos++] = data;
+	if (bufpos == BUFSIZE) {
+		bufpos = 0;
+
+		if (buf.u.val.leftbtn ^ leftbtn) {
+			leftbtn = buf.u.val.leftbtn;
+			mouse_ev_btn(1, leftbtn);
+		}
+
+		if (buf.u.val.rightbtn ^ rightbtn) {
+			rightbtn = buf.u.val.rightbtn;
+			mouse_ev_btn(2, rightbtn);
+		}
+
+		if (buf.u.val.middlebtn ^ middlebtn) {
+			middlebtn = buf.u.val.middlebtn;
+			mouse_ev_btn(3, middlebtn);
+		}
+
+		x =   bit9toint(buf.u.val.xsign, buf.u.val.x);
+		y = - bit9toint(buf.u.val.ysign, buf.u.val.y);
+
+		if (x != 0 || y != 0) {
+			mouse_ev_move(x, y);
+		}
+	}
+
+	return;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/hid/console/console.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -475,20 +475,12 @@
 static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
+	void *buf;
 	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
+	int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size);
+	
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
 		return;
 	}
-	
-	char *buf = (char *) malloc(size);
-	if (buf == NULL) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	(void) async_data_write_finalize(callid, buf, size);
 	
 	async_serialize_start();
Index: uspace/srv/hid/kbd/Makefile.build
===================================================================
--- uspace/srv/hid/kbd/Makefile.build	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/hid/kbd/Makefile.build	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -125,6 +125,6 @@
 ifeq ($(UARCH),ppc32)
 	SOURCES += \
-		port/dummy.c \
-		ctl/stty.c
+		port/adb.c \
+		ctl/apple.c
 endif
 
Index: uspace/srv/hid/kbd/ctl/apple.c
===================================================================
--- uspace/srv/hid/kbd/ctl/apple.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/kbd/ctl/apple.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2010 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 kbd_ctl
+ * @ingroup kbd
+ * @{
+ */
+/**
+ * @file
+ * @brief	Apple ADB keyboard controller driver.
+ */
+
+#include <kbd.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <kbd_ctl.h>
+
+#define KBD_KEY_RELEASE		0x80
+
+static int scanmap[];
+
+int kbd_ctl_init(void)
+{
+	return 0;
+}
+
+void kbd_ctl_parse_scancode(int scancode)
+{
+	console_ev_type_t type;
+	unsigned int key;
+
+	if (scancode < 0 || scancode >= 0x100)
+		return;
+
+	if (scancode & KBD_KEY_RELEASE) {
+		scancode &= ~KBD_KEY_RELEASE;
+		type = KEY_RELEASE;
+	} else {
+		type = KEY_PRESS;
+	}
+
+	key = scanmap[scancode];
+	if (key != 0)
+		kbd_push_ev(type, key);
+}
+
+void kbd_ctl_set_ind(unsigned mods)
+{
+	(void) mods;
+}
+
+static int scanmap[] = {
+	[0x00] = KC_A,
+	[0x01] = KC_S,
+	[0x02] = KC_D,
+	[0x03] = KC_F,
+	[0x04] = KC_H,
+	[0x05] = KC_G,
+	[0x06] = KC_Z,
+	[0x07] = KC_X,
+	[0x08] = KC_C,
+	[0x09] = KC_V,
+	[0x0a] = KC_BACKSLASH,
+	[0x0b] = KC_B,
+	[0x0c] = KC_Q,
+	[0x0d] = KC_W,
+	[0x0e] = KC_E,
+	[0x0f] = KC_R,
+	[0x10] = KC_Y,
+	[0x11] = KC_T,
+	[0x12] = KC_1,
+	[0x13] = KC_2,
+	[0x14] = KC_3,
+	[0x15] = KC_4,
+	[0x16] = KC_6,
+	[0x17] = KC_5,
+	[0x18] = KC_EQUALS,
+	[0x19] = KC_9,
+	[0x1a] = KC_7,
+	[0x1b] = KC_MINUS,
+	[0x1c] = KC_8,
+	[0x1d] = KC_0,
+	[0x1e] = KC_RBRACKET,
+	[0x1f] = KC_O,
+	[0x20] = KC_U,
+	[0x21] = KC_LBRACKET,
+	[0x22] = KC_I,
+	[0x23] = KC_P,
+	[0x24] = KC_ENTER,
+	[0x25] = KC_L,
+	[0x26] = KC_J,
+	[0x27] = KC_QUOTE,
+	[0x28] = KC_K,
+	[0x29] = KC_SEMICOLON,
+	[0x2a] = KC_BACKSLASH,
+	[0x2b] = KC_COMMA,
+	[0x2c] = KC_SLASH,
+	[0x2d] = KC_N,
+	[0x2e] = KC_M,
+	[0x2f] = KC_PERIOD,
+	[0x30] = KC_TAB,
+	[0x31] = KC_SPACE,
+	[0x32] = KC_BACKTICK,
+	[0x33] = KC_BACKSPACE,
+	[0x34] = 0,
+	[0x35] = KC_ESCAPE,
+	[0x36] = KC_LCTRL,
+	[0x37] = 0,
+	[0x38] = KC_LSHIFT,
+	[0x39] = KC_CAPS_LOCK,
+	[0x3a] = KC_LALT,
+	[0x3b] = KC_LEFT,
+	[0x3c] = KC_RIGHT,
+	[0x3d] = KC_DOWN,
+	[0x3e] = KC_UP,
+	[0x3f] = 0,
+	[0x40] = 0,
+	[0x41] = KC_NPERIOD,
+	[0x42] = 0,
+	[0x43] = KC_NTIMES,
+	[0x44] = 0,
+	[0x45] = KC_NPLUS,
+	[0x46] = 0,
+	[0x47] = KC_NUM_LOCK,
+	[0x48] = 0,
+	[0x49] = 0,
+	[0x4a] = 0,
+	[0x4b] = KC_NSLASH,
+	[0x4c] = KC_NENTER,
+	[0x4d] = 0,
+	[0x4e] = KC_NMINUS,
+	[0x4f] = 0,
+	[0x50] = 0,
+	[0x51] = 0,
+	[0x52] = KC_N0,
+	[0x53] = KC_N1,
+	[0x54] = KC_N2,
+	[0x55] = KC_N3,
+	[0x56] = KC_N4,
+	[0x57] = KC_N5,
+	[0x58] = KC_N6,
+	[0x59] = KC_N7,
+	[0x5a] = 0,
+	[0x5b] = KC_N8,
+	[0x5c] = KC_N9,
+	[0x5d] = 0,
+	[0x5e] = 0,
+	[0x5f] = 0,
+	[0x60] = KC_F5,
+	[0x61] = KC_F6,
+	[0x62] = KC_F7,
+	[0x63] = KC_F3,
+	[0x64] = KC_F8,
+	[0x65] = KC_F9,
+	[0x66] = 0,
+	[0x67] = KC_F11,
+	[0x68] = 0,
+	[0x69] = 0,
+	[0x6a] = 0,
+	[0x6b] = KC_SCROLL_LOCK,
+	[0x6c] = 0,
+	[0x6d] = KC_F10,
+	[0x6e] = 0,
+	[0x6f] = KC_F12,
+	[0x70] = 0,
+	[0x71] = 0,
+	[0x72] = KC_INSERT,
+	[0x73] = KC_HOME,
+	[0x74] = KC_PAGE_UP,
+	[0x75] = KC_DELETE,
+	[0x76] = KC_F4,
+	[0x77] = KC_END,
+	[0x78] = KC_F2,
+	[0x79] = KC_PAGE_DOWN,
+	[0x7a] = KC_F1,
+	[0x7b] = KC_RSHIFT,
+	[0x7c] = KC_RALT,
+	[0x7d] = KC_RCTRL,
+	[0x7e] = 0,
+	[0x7f] = 0
+};
+
+/** @}
+ */
Index: uspace/srv/hid/kbd/port/adb.c
===================================================================
--- uspace/srv/hid/kbd/port/adb.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hid/kbd/port/adb.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2010 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 kbd_port
+ * @ingroup kbd
+ * @{
+ */ 
+/** @file
+ * @brief ADB keyboard port driver.
+ */
+
+#include <ipc/ipc.h>
+#include <ipc/adb.h>
+#include <async.h>
+#include <kbd_port.h>
+#include <kbd.h>
+#include <vfs/vfs.h>
+#include <fcntl.h>
+#include <errno.h>
+
+static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall);
+static void adb_kbd_reg0_data(uint16_t data);
+
+static int dev_phone;
+
+#define NAME "kbd"
+
+int kbd_port_init(void)
+{
+	char *input = "/dev/adb/kbd";
+	int input_fd;
+
+	printf(NAME ": open %s\n", input);
+
+	input_fd = open(input, O_RDONLY);
+	if (input_fd < 0) {
+		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
+		return false;
+	}
+
+	dev_phone = fd_phone(input_fd);
+	if (dev_phone < 0) {
+		printf(NAME ": Failed to connect to device\n");
+		return false;
+	}
+
+	/* NB: The callback connection is slotted for removal */
+	ipcarg_t phonehash;
+	if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
+		printf(NAME ": Failed to create callback from device\n");
+		return false;
+	}
+
+	async_new_connection(phonehash, 0, NULL, kbd_port_events);
+
+	return 0;
+}
+
+void kbd_port_yield(void)
+{
+}
+
+void kbd_port_reclaim(void)
+{
+}
+
+void kbd_port_write(uint8_t data)
+{
+	/*async_msg_1(dev_phone, CHAR_WRITE_BYTE, data);*/
+}
+
+static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall)
+{
+	/* Ignore parameters, the connection is already opened */
+	while (true) {
+
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+
+		int retval;
+
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			/* TODO: Handle hangup */
+			return;
+		case ADB_REG_NOTIF:
+			adb_kbd_reg0_data(IPC_GET_ARG1(call));
+			break;
+		default:
+			retval = ENOENT;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+static void adb_kbd_reg0_data(uint16_t data)
+{
+	uint8_t b0, b1;
+
+	b0 = (data >> 8) & 0xff;
+	b1 = data & 0xff;
+
+	if (b0 != 0xff)
+		kbd_push_scancode(b0);
+	if (b1 != 0xff)
+		kbd_push_scancode(b1);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hw/bus/cuda_adb/Makefile
===================================================================
--- uspace/srv/hw/bus/cuda_adb/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hw/bus/cuda_adb/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2010 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.
+#
+
+USPACE_PREFIX = ../../../..
+LIBS = $(LIBC_PREFIX)/libc.a
+
+OUTPUT = cuda_adb
+
+SOURCES = \
+	cuda_adb.c
+
+include ../../../Makefile.common
+
Index: uspace/srv/hw/bus/cuda_adb/cuda_adb.c
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,517 @@
+/*
+ * Copyright (c) 2010 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 genarch
+ * @{
+ */
+/** @file VIA-CUDA Apple Desktop Bus driver
+ *
+ * Note: We should really do a full bus scan at the beginning and resolve
+ * address conflicts. Also we should consider the handler ID in r3. Instead
+ * we just assume a keyboard at address 2 or 8 and a mouse at address 9.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <bool.h>
+#include <ddi.h>
+#include <libarch/ddi.h>
+#include <devmap.h>
+#include <sysinfo.h>
+#include <errno.h>
+#include <ipc/adb.h>
+#include <async.h>
+#include <assert.h>
+#include "cuda_adb.h"
+
+#define NAME "cuda_adb"
+
+static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall);
+static int cuda_init(void);
+static int cuda_claim(void);
+static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+static void cuda_irq_listen(void);
+static void cuda_irq_receive(void);
+static void cuda_irq_rcv_end(void *buf, size_t *len);
+static void cuda_irq_send_start(void);
+static void cuda_irq_send(void);
+
+static void cuda_packet_handle(uint8_t *buf, size_t len);
+static void cuda_send_start(void);
+static void cuda_autopoll_set(bool enable);
+
+static void adb_packet_handle(uint8_t *data, size_t size, bool autopoll);
+
+
+/** B register fields */
+enum {
+	TREQ	= 0x08,
+	TACK	= 0x10,
+	TIP	= 0x20
+};
+
+/** IER register fields */
+enum {
+	IER_CLR	= 0x00,
+	IER_SET	= 0x80,
+
+	SR_INT	= 0x04,
+	ALL_INT	= 0x7f
+};
+
+/** ACR register fields */
+enum {
+	SR_OUT	= 0x10
+};
+
+/** Packet types */
+enum {
+	PT_ADB	= 0x00,
+	PT_CUDA	= 0x01
+};
+
+/** CUDA packet types */
+enum {
+	CPT_AUTOPOLL	= 0x01
+};
+
+enum {
+	ADB_MAX_ADDR	= 16
+};
+
+static irq_cmd_t cuda_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = NULL,	/* will be patched in run-time */
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_BTEST,
+		.value = SR_INT,
+		.srcarg = 1,
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_PREDICATE,
+		.value = 1,
+		.srcarg = 2
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+
+static irq_code_t cuda_irq_code = {
+	sizeof(cuda_cmds) / sizeof(irq_cmd_t),
+	cuda_cmds
+};
+
+static cuda_instance_t cinst;
+
+static cuda_instance_t *instance = &cinst;
+static cuda_t *dev;
+
+static adb_dev_t adb_dev[ADB_MAX_ADDR];
+
+int main(int argc, char *argv[])
+{
+	dev_handle_t dev_handle;
+	int rc;
+	int i;
+
+	printf(NAME ": VIA-CUDA Apple Desktop Bus driver\n");
+
+	for (i = 0; i < ADB_MAX_ADDR; ++i) {
+		adb_dev[i].client_phone = -1;
+		adb_dev[i].dev_handle = 0;
+	}
+
+	rc = devmap_driver_register(NAME, cuda_connection);
+	if (rc < 0) {
+		printf(NAME ": Unable to register driver.\n");
+		return rc;
+	}
+
+	rc = devmap_device_register("adb/kbd", &dev_handle);
+	if (rc != EOK) {
+		devmap_hangup_phone(DEVMAP_DRIVER);
+		printf(NAME ": Unable to register device %s.\n", "adb/kdb");
+		return rc;
+	}
+
+	adb_dev[2].dev_handle = dev_handle;
+	adb_dev[8].dev_handle = dev_handle;
+
+	rc = devmap_device_register("adb/mouse", &dev_handle);
+	if (rc != EOK) {
+		devmap_hangup_phone(DEVMAP_DRIVER);
+		printf(NAME ": Unable to register device %s.\n", "adb/mouse");
+		return rc;
+	}
+
+	adb_dev[9].dev_handle = dev_handle;
+
+	if (cuda_init() < 0) {
+		printf("cuda_init() failed\n");
+		return 1;
+	}
+
+	task_retval(0);
+	async_manager();
+
+	return 0;
+}
+
+/** Character device connection handler */
+static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	ipcarg_t method;
+	dev_handle_t dh;
+	int retval;
+	int dev_addr, i;
+
+	/* Get the device handle. */
+	dh = IPC_GET_ARG1(*icall);
+
+	/* Determine which disk device is the client connecting to. */
+	dev_addr = -1;
+	for (i = 0; i < ADB_MAX_ADDR; i++) {
+		if (adb_dev[i].dev_handle == dh)
+			dev_addr = i;
+	}
+
+	if (dev_addr < 0) {
+		ipc_answer_0(iid, EINVAL);
+		return;
+	}
+
+	/* Answer the IPC_M_CONNECT_ME_TO call. */
+	ipc_answer_0(iid, EOK);
+
+	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 IPC_M_CONNECT_TO_ME:
+			if (adb_dev[dev_addr].client_phone != -1) {
+				retval = ELIMIT;
+				break;
+			}
+			adb_dev[dev_addr].client_phone = IPC_GET_ARG5(call);
+			/*
+			 * A hack so that we send the data to the phone
+			 * regardless of which address the device is on.
+			 */
+			for (i = 0; i < ADB_MAX_ADDR; ++i) {
+				if (adb_dev[i].dev_handle == dh) {
+					adb_dev[i].client_phone = IPC_GET_ARG5(call);
+				}
+			}
+			retval = 0;
+			break;
+		default:
+			retval = EINVAL;
+			break;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+
+static int cuda_init(void)
+{
+	void *vaddr;
+
+	instance->cuda_physical = sysinfo_value("cuda.address.physical");
+	instance->cuda_kernel = sysinfo_value("cuda.address.kernel");
+
+	if (pio_enable((void *) instance->cuda_physical, sizeof(cuda_t), &vaddr) != 0)
+		return -1;
+	dev = vaddr;
+
+	instance->cuda = dev;
+	instance->xstate = cx_listen;
+	instance->bidx = 0;
+	instance->snd_bytes = 0;
+
+	fibril_mutex_initialize(&instance->dev_lock);
+
+	/* Disable all interrupts from CUDA. */
+	pio_write_8(&dev->ier, IER_CLR | ALL_INT);
+
+	cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_kernel)->ifr;
+	async_set_interrupt_received(cuda_irq_handler);
+	ipc_register_irq(10, device_assign_devno(), 0, &cuda_irq_code);
+
+	/* Enable SR interrupt. */
+	pio_write_8(&dev->ier, TIP | TREQ);
+	pio_write_8(&dev->ier, IER_SET | SR_INT);
+
+	/* Enable ADB autopolling. */
+	cuda_autopoll_set(true);
+
+	return 0;
+}
+
+static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	uint8_t rbuf[CUDA_RCV_BUF_SIZE];
+	size_t len;
+	bool handle;
+
+	handle = false;
+	len = 0;
+
+	fibril_mutex_lock(&instance->dev_lock);
+
+	/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
+	pio_write_8(&instance->cuda->ifr, SR_INT);
+
+	switch (instance->xstate) {
+	case cx_listen: cuda_irq_listen(); break;
+	case cx_receive: cuda_irq_receive(); break;
+	case cx_rcv_end: cuda_irq_rcv_end(rbuf, &len);
+	    handle = true; break;
+	case cx_send_start: cuda_irq_send_start(); break;
+	case cx_send: cuda_irq_send(); break;
+	}
+
+	fibril_mutex_unlock(&instance->dev_lock);
+
+	/* Handle an incoming packet. */
+	if (handle)
+		cuda_packet_handle(rbuf, len);
+}
+
+/** Interrupt in listen state.
+ *
+ * Start packet reception.
+ */
+static void cuda_irq_listen(void)
+{
+	uint8_t b;
+
+	b = pio_read_8(&dev->b);
+
+	if ((b & TREQ) != 0) {
+		printf("cuda_irq_listen: no TREQ?!\n");
+		return;
+	}
+
+	pio_read_8(&dev->sr);
+	pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
+	instance->xstate = cx_receive;
+}
+
+/** Interrupt in receive state.
+ *
+ * Receive next byte of packet.
+ */
+static void cuda_irq_receive(void)
+{
+	uint8_t b, data;
+
+	data = pio_read_8(&dev->sr);
+	if (instance->bidx < CUDA_RCV_BUF_SIZE)
+		instance->rcv_buf[instance->bidx++] = data;
+
+	b = pio_read_8(&dev->b);
+
+	if ((b & TREQ) == 0) {
+		pio_write_8(&dev->b, b ^ TACK);
+	} else {
+		pio_write_8(&dev->b, b | TACK | TIP);
+		instance->xstate = cx_rcv_end;
+	}
+}
+
+/** Interrupt in rcv_end state.
+ *
+ * Terminate packet reception. Either go back to listen state or start
+ * receiving another packet if CUDA has one for us.
+ */
+static void cuda_irq_rcv_end(void *buf, size_t *len)
+{
+	uint8_t data, b;
+
+	b = pio_read_8(&dev->b);
+	data = pio_read_8(&dev->sr);
+
+	if ((b & TREQ) == 0) {
+		instance->xstate = cx_receive;
+		pio_write_8(&dev->b, b & ~TIP);
+	} else {
+		instance->xstate = cx_listen;
+		cuda_send_start();
+	}
+
+        memcpy(buf, instance->rcv_buf, instance->bidx);
+        *len = instance->bidx;
+	instance->bidx = 0;
+}
+
+/** Interrupt in send_start state.
+ *
+ * Process result of sending first byte (and send second on success).
+ */
+static void cuda_irq_send_start(void)
+{
+	uint8_t b;
+
+	b = pio_read_8(&dev->b);
+
+	if ((b & TREQ) == 0) {
+		/* Collision */
+		pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
+		pio_read_8(&dev->sr);
+		pio_write_8(&dev->b, pio_read_8(&dev->b) | TIP | TACK);
+		instance->xstate = cx_listen;
+		return;
+	}
+
+	pio_write_8(&dev->sr, instance->snd_buf[1]);
+	pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
+	instance->bidx = 2;
+
+	instance->xstate = cx_send;
+}
+
+/** Interrupt in send state.
+ *
+ * Send next byte or terminate transmission.
+ */
+static void cuda_irq_send(void)
+{
+	if (instance->bidx < instance->snd_bytes) {
+		/* Send next byte. */
+		pio_write_8(&dev->sr, instance->snd_buf[instance->bidx++]);
+		pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
+		return;
+	}
+
+	/* End transfer. */
+	instance->snd_bytes = 0;
+	instance->bidx = 0;
+
+	pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
+	pio_read_8(&dev->sr);
+	pio_write_8(&dev->b, pio_read_8(&dev->b) | TACK | TIP);
+
+	instance->xstate = cx_listen;
+	/* TODO: Match reply with request. */
+}
+
+static void cuda_packet_handle(uint8_t *data, size_t len)
+{
+	if (data[0] != PT_ADB)
+		return;
+	if (len < 2)
+		return;
+
+	adb_packet_handle(data + 2, len - 2, (data[1] & 0x40) != 0);
+}
+
+static void adb_packet_handle(uint8_t *data, size_t size, bool autopoll)
+{
+	uint8_t dev_addr;
+	uint8_t reg_no;
+	uint16_t reg_val;
+	unsigned i;
+
+	dev_addr = data[0] >> 4;
+	reg_no = data[0] & 0x03;
+
+	if (size != 3) {
+		printf("unrecognized packet, size=%d\n", size);
+		for (i = 0; i < size; ++i) {
+			printf(" 0x%02x", data[i]);
+		}
+		putchar('\n');
+		return;
+	}
+
+	if (reg_no != 0) {
+		printf("unrecognized packet, size=%d\n", size);
+		for (i = 0; i < size; ++i) {
+			printf(" 0x%02x", data[i]);
+		}
+		putchar('\n');
+		return;
+	}
+
+	reg_val = ((uint16_t) data[1] << 8) | (uint16_t) data[2];
+
+	if (adb_dev[dev_addr].client_phone == -1)
+		return;
+
+	async_msg_1(adb_dev[dev_addr].client_phone, ADB_REG_NOTIF, reg_val);
+}
+
+static void cuda_autopoll_set(bool enable)
+{
+	instance->snd_buf[0] = PT_CUDA;
+	instance->snd_buf[1] = CPT_AUTOPOLL;
+	instance->snd_buf[2] = enable ? 0x01 : 0x00;
+	instance->snd_bytes = 3;
+	instance->bidx = 0;
+
+	cuda_send_start();
+}
+
+static void cuda_send_start(void)
+{
+	cuda_t *dev = instance->cuda;
+
+	assert(instance->xstate == cx_listen);
+
+	if (instance->snd_bytes == 0)
+		return;
+
+	/* Check for incoming data. */
+	if ((pio_read_8(&dev->b) & TREQ) == 0)
+		return;
+
+	pio_write_8(&dev->acr, pio_read_8(&dev->acr) | SR_OUT);
+	pio_write_8(&dev->sr, instance->snd_buf[0]);
+	pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
+
+	instance->xstate = cx_send_start;
+}
+
+
+/** @}
+ */
Index: uspace/srv/hw/bus/cuda_adb/cuda_adb.h
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/hw/bus/cuda_adb/cuda_adb.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * Copyright (c) 2010 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 genarch
+ * @{
+ */
+/** @file
+ */
+
+#ifndef CUDA_ADB_H_
+#define CUDA_ADB_H_
+
+#include <sys/types.h>
+#include <ipc/devmap.h>
+#include <fibril_synch.h>
+
+typedef struct {
+	uint8_t b;
+	uint8_t pad0[0x1ff];
+
+	uint8_t a;
+	uint8_t pad1[0x1ff];
+
+	uint8_t dirb;
+	uint8_t pad2[0x1ff];
+
+	uint8_t dira;
+	uint8_t pad3[0x1ff];
+
+	uint8_t t1cl;
+	uint8_t pad4[0x1ff];
+
+	uint8_t t1ch;
+	uint8_t pad5[0x1ff];
+
+	uint8_t t1ll;
+	uint8_t pad6[0x1ff];
+
+	uint8_t t1lh;
+	uint8_t pad7[0x1ff];
+
+	uint8_t t2cl;
+	uint8_t pad8[0x1ff];
+
+	uint8_t t2ch;
+	uint8_t pad9[0x1ff];
+
+	uint8_t sr;
+	uint8_t pad10[0x1ff];
+
+	uint8_t acr;
+	uint8_t pad11[0x1ff];
+
+	uint8_t pcr;
+	uint8_t pad12[0x1ff];
+
+	uint8_t ifr;
+	uint8_t pad13[0x1ff];
+
+	uint8_t ier;
+	uint8_t pad14[0x1ff];
+
+	uint8_t anh;
+	uint8_t pad15[0x1ff];
+} cuda_t;
+
+enum {
+	CUDA_RCV_BUF_SIZE = 5
+};
+
+enum cuda_xfer_state {
+	cx_listen,
+	cx_receive,
+	cx_rcv_end,
+	cx_send_start,
+	cx_send
+};
+
+typedef struct {
+	dev_handle_t dev_handle;
+	int client_phone;
+} adb_dev_t;
+
+typedef struct {
+	cuda_t *cuda;
+	uintptr_t cuda_physical;
+	uintptr_t cuda_kernel;
+
+	uint8_t rcv_buf[CUDA_RCV_BUF_SIZE];
+	uint8_t snd_buf[CUDA_RCV_BUF_SIZE];
+	size_t bidx;
+	size_t snd_bytes;
+	enum cuda_xfer_state xstate;
+	fibril_mutex_t dev_lock;
+} cuda_instance_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/loader/arch/amd64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/amd64/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/arch/amd64/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__64_BITS__
 ARCH_SOURCES := arch/$(UARCH)/amd64.s
Index: uspace/srv/loader/arch/arm32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/arm32/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/arch/arm32/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__32_BITS__
 ARCH_SOURCES := arch/$(UARCH)/arm32.s
Index: uspace/srv/loader/arch/ia32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ia32/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/arch/ia32/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__32_BITS__
 ARCH_SOURCES := arch/$(UARCH)/ia32.s
Index: uspace/srv/loader/arch/ia64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ia64/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/arch/ia64/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,5 +27,4 @@
 #
 
-EXTRA_CFLAGS = -D__64_BITS__
 ARCH_SOURCES := arch/$(UARCH)/ia64.s
 AFLAGS += -xexplicit
Index: uspace/srv/loader/arch/mips32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/mips32/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/arch/mips32/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__32_BITS__
 ARCH_SOURCES := arch/$(UARCH)/mips32.s
Index: uspace/srv/loader/arch/ppc32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ppc32/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/arch/ppc32/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__32_BITS__
 ARCH_SOURCES := arch/$(UARCH)/ppc32.s
Index: uspace/srv/loader/arch/sparc64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/sparc64/Makefile.inc	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/arch/sparc64/Makefile.inc	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__64_BITS__
 ARCH_SOURCES := arch/$(UARCH)/sparc64.s
Index: uspace/srv/loader/elf_load.c
===================================================================
--- uspace/srv/loader/elf_load.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/elf_load.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -342,6 +342,6 @@
 	seg_ptr = (void *) seg_addr;
 
-	DPRINTF("Load segment at addr 0x%x, size 0x%x\n", seg_addr,
-		entry->p_memsz);	
+	DPRINTF("Load segment at addr %p, size 0x%x\n", seg_addr,
+		entry->p_memsz);
 
 	if (entry->p_align > 1) {
@@ -370,5 +370,5 @@
 	mem_sz = entry->p_memsz + (entry->p_vaddr - base);
 
-	DPRINTF("Map to seg_addr=0x%x-0x%x.\n", seg_addr,
+	DPRINTF("Map to seg_addr=%p-%p.\n", seg_addr,
 	entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
 
@@ -384,5 +384,5 @@
 	}
 
-	DPRINTF("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
+	DPRINTF("as_area_create(%p, 0x%x, %d) -> 0x%lx\n",
 		base + bias, mem_sz, flags, (uintptr_t)a);
 
@@ -461,5 +461,5 @@
 		elf->info->dynamic =
 		    (void *)((uint8_t *)entry->sh_addr + elf->bias);
-		DPRINTF("Dynamic section found at 0x%x.\n",
+		DPRINTF("Dynamic section found at %p.\n",
 			(uintptr_t)elf->info->dynamic);
 		break;
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/loader/main.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -125,24 +125,15 @@
 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);
+	char *buf;
+	int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL);
+	
+	if (rc == EOK) {
+		if (cwd != NULL)
+			free(cwd);
+		
+		cwd = buf;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -154,31 +145,15 @@
 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	size_t len;
-	char *name_buf;
-	
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	name_buf = malloc(len + 1);
-	if (!name_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, name_buf, len);
-	ipc_answer_0(rid, EOK);
-	
-	if (pathname != NULL) {
-		free(pathname);
-		pathname = NULL;
-	}
-	
-	name_buf[len] = '\0';
-	pathname = name_buf;
+	char *buf;
+	int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL);
+	
+	if (rc == EOK) {
+		if (pathname != NULL)
+			free(pathname);
+		
+		pathname = buf;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -190,73 +165,60 @@
 static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	size_t buf_size, arg_size;
-	char *p;
-	int n;
-	
-	if (!async_data_write_receive(&callid, &buf_size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if (arg_buf != NULL) {
-		free(arg_buf);
-		arg_buf = NULL;
-	}
-	
-	if (argv != NULL) {
-		free(argv);
-		argv = NULL;
-	}
-	
-	arg_buf = malloc(buf_size + 1);
-	if (!arg_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, arg_buf, buf_size);
-	
-	arg_buf[buf_size] = '\0';
-	
-	/*
-	 * Count number of arguments
-	 */
-	p = arg_buf;
-	n = 0;
-	while (p < arg_buf + buf_size) {
-		arg_size = str_size(p);
-		p = p + arg_size + 1;
-		++n;
-	}
-	
-	/* Allocate argv */
-	argv = malloc((n + 1) * sizeof(char *));
-	
-	if (argv == NULL) {
-		free(arg_buf);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-
-	/*
-	 * Fill argv with argument pointers
-	 */
-	p = arg_buf;
-	n = 0;
-	while (p < arg_buf + buf_size) {
-		argv[n] = p;
-		
-		arg_size = str_size(p);
-		p = p + arg_size + 1;
-		++n;
-	}
-	
-	argc = n;
-	argv[n] = NULL;
-
-	ipc_answer_0(rid, EOK);
+	char *buf;
+	size_t buf_size;
+	int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, &buf_size);
+	
+	if (rc == EOK) {
+		/*
+		 * Count number of arguments
+		 */
+		char *cur = buf;
+		int count = 0;
+		
+		while (cur < buf + buf_size) {
+			size_t arg_size = str_size(cur);
+			cur += arg_size + 1;
+			count++;
+		}
+		
+		/*
+		 * Allocate new argv
+		 */
+		char **_argv = (char **) malloc((count + 1) * sizeof(char *));
+		if (_argv == NULL) {
+			free(buf);
+			ipc_answer_0(rid, ENOMEM);
+			return;
+		}
+		
+		/*
+		 * Fill the new argv with argument pointers
+		 */
+		cur = buf;
+		count = 0;
+		while (cur < buf + buf_size) {
+			_argv[count] = cur;
+			
+			size_t arg_size = str_size(cur);
+			cur += arg_size + 1;
+			count++;
+		}
+		_argv[count] = NULL;
+		
+		/*
+		 * Copy temporary data to global variables
+		 */
+		if (arg_buf != NULL)
+			free(arg_buf);
+		
+		if (argv != NULL)
+			free(argv);
+		
+		argc = count;
+		arg_buf = buf;
+		argv = _argv;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -268,57 +230,44 @@
 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
+	fdi_node_t *buf;
 	size_t buf_size;
-	if (!async_data_write_receive(&callid, &buf_size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if ((buf_size % sizeof(fdi_node_t)) != 0) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if (fil_buf != NULL) {
-		free(fil_buf);
-		fil_buf = NULL;
-	}
-	
-	if (filv != NULL) {
-		free(filv);
-		filv = NULL;
-	}
-	
-	fil_buf = malloc(buf_size);
-	if (!fil_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, fil_buf, buf_size);
-	
-	int count = buf_size / sizeof(fdi_node_t);
-	
-	/* Allocate filvv */
-	filv = malloc((count + 1) * sizeof(fdi_node_t *));
-	
-	if (filv == NULL) {
-		free(fil_buf);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	/*
-	 * Fill filv with argument pointers
-	 */
-	int i;
-	for (i = 0; i < count; i++)
-		filv[i] = &fil_buf[i];
-	
-	filc = count;
-	filv[count] = NULL;
+	int rc = async_data_write_accept((void **) &buf, false, 0, 0,
+	    sizeof(fdi_node_t), &buf_size);
+	
+	if (rc == EOK) {
+		int count = buf_size / sizeof(fdi_node_t);
+		
+		/*
+		 * Allocate new filv
+		 */
+		fdi_node_t **_filv = (fdi_node_t *) malloc((count + 1) * sizeof(fdi_node_t *));
+		if (_filv == NULL) {
+			free(buf);
+			ipc_answer_0(rid, ENOMEM);
+			return;
+		}
+		
+		/*
+		 * Fill the new filv with argument pointers
+		 */
+		int i;
+		for (i = 0; i < count; i++)
+			_filv[i] = &buf[i];
+		
+		_filv[count] = NULL;
+		
+		/*
+		 * Copy temporary data to global variables
+		 */
+		if (fil_buf != NULL)
+			free(fil_buf);
+		
+		if (filv != NULL)
+			free(filv);
+		
+		filc = count;
+		fil_buf = buf;
+		filv = _filv;
+	}
 	
 	ipc_answer_0(rid, EOK);
@@ -392,5 +341,5 @@
 		/* Dynamically linked program */
 		DPRINTF("Run ELF interpreter.\n");
-		DPRINTF("Entry point: 0x%lx\n", interp_info.entry);
+		DPRINTF("Entry point: %p\n", interp_info.entry);
 		
 		ipc_answer_0(rid, EOK);
Index: uspace/srv/taskmon/Makefile
===================================================================
--- uspace/srv/taskmon/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/taskmon/Makefile	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2010 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBC_PREFIX)/libc.a
+
+OUTPUT = taskmon
+
+SOURCES = \
+	taskmon.c
+
+include ../Makefile.common
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
+++ uspace/srv/taskmon/taskmon.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2010 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 taskmon
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <ipc/ipc.h>
+#include <async.h>
+#include <ipc/services.h>
+#include <sys/typefmt.h>
+#include <task.h>
+#include <event.h>
+#include <macros.h>
+#include <errno.h>
+
+#define NAME  "taskmon"
+
+static void fault_event(ipc_callid_t callid, ipc_call_t *call)
+{
+	char *argv[6];
+	char *fname;
+	char *dump_fname;
+	char *s_taskid;
+	char **s;
+
+	task_id_t taskid;
+	uintptr_t thread;
+
+	taskid = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
+	thread = IPC_GET_ARG3(*call);
+
+	if (asprintf(&s_taskid, "%" PRIuTASKID, taskid) < 0) {
+		printf("Memory allocation failed.\n");
+		return;
+	}
+
+	if (asprintf(&dump_fname, "/data/core%" PRIuTASKID, taskid) < 0) {
+		printf("Memory allocation failed.\n");
+		return;
+	}
+
+	printf(NAME ": Task %" PRIuTASKID " fault in thread %p.\n", taskid, thread);
+
+#ifdef CONFIG_WRITE_CORE_FILES
+	argv[0] = "/app/taskdump";
+	argv[1] = "-c";
+	argv[2] = dump_fname;
+	argv[3] = "-t";
+	argv[4] = s_taskid;
+	argv[5] = NULL;
+#else
+	argv[0] = "/app/taskdump";
+	argv[1] = "-t";
+	argv[2] = s_taskid;
+	argv[3] = NULL;
+#endif
+	fname = argv[0];
+
+	printf(NAME ": Executing");
+        s = argv;
+	while (*s != NULL) {
+		printf(" %s", *s);
+		++s;
+	}
+	putchar('\n');
+
+	if (!task_spawn(fname, argv))
+		printf(NAME ": Error spawning taskdump.\n", fname);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": Task Monitoring Service\n");
+
+	if (event_subscribe(EVENT_FAULT, 0) != EOK) {
+		printf(NAME ": Error registering fault notifications.\n");
+		return -1;
+	}
+
+	async_set_interrupt_received(fault_event);
+	async_manager();
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/vfs/vfs.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -87,4 +87,7 @@
 			vfs_mount(callid, &call);
 			break;
+		case VFS_IN_UNMOUNT:
+			vfs_unmount(callid, &call);
+			break;
 		case VFS_IN_OPEN:
 			vfs_open(callid, &call);
@@ -134,5 +137,5 @@
 	}
 	
-	/* TODO: cleanup after the client */
+	vfs_files_done();
 }
 
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/vfs/vfs.h	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -177,12 +177,17 @@
     vfs_pair_t *, ...);
 extern int vfs_open_node_internal(vfs_lookup_res_t *);
+extern int vfs_close_internal(vfs_file_t *);
 
 extern bool vfs_nodes_init(void);
 extern vfs_node_t *vfs_node_get(vfs_lookup_res_t *);
 extern void vfs_node_put(vfs_node_t *);
+extern void vfs_node_forget(vfs_node_t *);
+extern unsigned vfs_nodes_refcount_sum_get(fs_handle_t, dev_handle_t);
+
 
 #define MAX_OPEN_FILES	128
 
 extern bool vfs_files_init(void);
+extern void vfs_files_done(void);
 extern vfs_file_t *vfs_file_get(int);
 extern int vfs_fd_assign(vfs_file_t *file, int fd);
@@ -198,4 +203,5 @@
 extern void vfs_register(ipc_callid_t, ipc_call_t *);
 extern void vfs_mount(ipc_callid_t, ipc_call_t *);
+extern void vfs_unmount(ipc_callid_t, ipc_call_t *);
 extern void vfs_open(ipc_callid_t, ipc_call_t *);
 extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/vfs/vfs_file.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -72,4 +72,22 @@
 	}
 	return true;
+}
+
+/** Cleanup the table of open files. */
+void vfs_files_done(void)
+{
+	int i;
+
+	if (!files)
+		return;
+
+	for (i = 0; i < MAX_OPEN_FILES; i++) {
+		if (files[i]) {
+			(void) vfs_close_internal(files[i]);
+			(void) vfs_fd_free(i);
+		}
+	}
+	
+	free(files);
 }
 
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/vfs/vfs_node.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -137,4 +137,24 @@
 	if (free_vfs_node)
 		free(node);
+}
+
+/** Forget node.
+ *
+ * This function will remove the node from the node hash table and deallocate
+ * its memory, regardless of the node's reference count.
+ *
+ * @param node	Node to be forgotten.
+ */
+void vfs_node_forget(vfs_node_t *node)
+{
+	fibril_mutex_lock(&nodes_mutex);
+	unsigned long key[] = {
+		[KEY_FS_HANDLE] = node->fs_handle,
+		[KEY_DEV_HANDLE] = node->dev_handle,
+		[KEY_INDEX] = node->index
+	};
+	hash_table_remove(&nodes, key, 3);
+	fibril_mutex_unlock(&nodes_mutex);
+	free(node);
 }
 
@@ -231,4 +251,37 @@
 }
 
+struct refcnt_data {
+	/** Sum of all reference counts for this file system instance. */
+	unsigned refcnt;
+	fs_handle_t fs_handle;
+	dev_handle_t dev_handle;
+};
+
+static void refcnt_visitor(link_t *item, void *arg)
+{
+	vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);
+	struct refcnt_data *rd = (void *) arg;
+
+	if ((node->fs_handle == rd->fs_handle) &&
+	    (node->dev_handle == rd->dev_handle))
+		rd->refcnt += node->refcnt;
+}
+
+unsigned
+vfs_nodes_refcount_sum_get(fs_handle_t fs_handle, dev_handle_t dev_handle)
+{
+	struct refcnt_data rd = {
+		.refcnt = 0,
+		.fs_handle = fs_handle,
+		.dev_handle = dev_handle
+	};
+
+	fibril_mutex_lock(&nodes_mutex);
+	hash_table_apply(&nodes, refcnt_visitor, &rd);
+	fibril_mutex_unlock(&nodes_mutex);
+
+	return rd.refcnt;
+}
+
 /**
  * @}
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/vfs/vfs_ops.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -92,5 +92,5 @@
 		}
 		
-		rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
+		rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
 		if (rc != EOK) {
 			/* The lookup failed for some reason. */
@@ -266,118 +266,36 @@
 	
 	/* We want the client to send us the mount point. */
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	/* Check whether size is reasonable wrt. the mount point. */
-	if ((size < 1) || (size > MAX_PATH_LEN)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	/* Allocate buffer for the mount point data being received. */
-	char *mp = malloc(size + 1);
-	if (!mp) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	/* Deliver the mount point. */
-	ipcarg_t retval = async_data_write_finalize(callid, mp, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
+	char *mp;
+	int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
+	    0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	/* Now we expect to receive the mount options. */
+	char *opts;
+	rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN,
+	    0, NULL);
+	if (rc != EOK) {
 		free(mp);
-		return;
-	}
-	mp[size] = '\0';
-	
-	/* Now we expect to receive the mount options. */
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(mp);
-		return;
-	}
-
-	/* Check the offered options size. */
-	if (size > MAX_MNTOPTS_LEN) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(mp);
-		return;
-	}
-
-	/* Allocate buffer for the mount options. */
-	char *opts = (char *) malloc(size + 1);
-	if (!opts) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		free(mp);
-		return;
-	}
-
-	/* Deliver the mount options. */
-	retval = async_data_write_finalize(callid, opts, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	/*
+	 * Now, we expect the client to send us data with the name of the file
+	 * system.
+	 */
+	char *fs_name;
+	rc = async_data_write_accept((void **) &fs_name, true, 0, FS_NAME_MAXLEN,
+	    0, NULL);
+	if (rc != EOK) {
 		free(mp);
 		free(opts);
-		return;
-	}
-	opts[size] = '\0';
-	
-	/*
-	 * Now, we expect the client to send us data with the name of the file
-	 * system.
-	 */
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(mp);
-		free(opts);
-		return;
-	}
-	
-	/*
-	 * Don't receive more than is necessary for storing a full file system
-	 * name.
-	 */
-	if ((size < 1) || (size > FS_NAME_MAXLEN)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(mp);
-		free(opts);
-		return;
-	}
-	
-	/*
-	 * Allocate buffer for file system name.
-	 */
-	char *fs_name = (char *) malloc(size + 1);
-	if (fs_name == NULL) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		free(mp);
-		free(opts);
-		return;
-	}
-	
-	/* Deliver the file system name. */
-	retval = async_data_write_finalize(callid, fs_name, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
-		free(mp);
-		free(opts);
-		free(fs_name);
-		return;
-	}
-	fs_name[size] = '\0';
-
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
 	/*
 	 * Wait for IPC_M_PING so that we can return an error if we don't know
@@ -385,5 +303,5 @@
 	 */
 	ipc_call_t data;
-	callid = async_get_call(&data);
+	ipc_callid_t callid = async_get_call(&data);
 	if (IPC_GET_METHOD(data) != IPC_M_PING) {
 		ipc_answer_0(callid, ENOTSUP);
@@ -429,4 +347,142 @@
 }
 
+void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)
+{
+	int rc;
+	char *mp;
+	vfs_lookup_res_t mp_res;
+	vfs_lookup_res_t mr_res;
+	vfs_node_t *mp_node;
+	vfs_node_t *mr_node;
+	int phone;
+
+	/*
+	 * Receive the mount point path.
+	 */
+	rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
+	    0, NULL);
+	if (rc != EOK)
+		ipc_answer_0(rid, rc);
+
+	/*
+	 * Taking the namespace lock will do two things for us. First, it will
+	 * prevent races with other lookup operations. Second, it will stop new
+	 * references to already existing VFS nodes and creation of new VFS
+	 * nodes. This is because new references are added as a result of some
+	 * lookup operation or at least of some operation which is protected by
+	 * the namespace lock.
+	 */
+	fibril_rwlock_write_lock(&namespace_rwlock);
+	
+	/*
+	 * Lookup the mounted root and instantiate it.
+	 */
+	rc = vfs_lookup_internal(mp, L_ROOT, &mr_res, NULL);
+	if (rc != EOK) {
+		fibril_rwlock_write_unlock(&namespace_rwlock);
+		free(mp);
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	mr_node = vfs_node_get(&mr_res);
+	if (!mr_node) {
+		fibril_rwlock_write_unlock(&namespace_rwlock);
+		free(mp);
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+
+	/*
+	 * Count the total number of references for the mounted file system. We
+	 * are expecting at least two. One which we got above and one which we
+	 * got when the file system was mounted. If we find more, it means that
+	 * the file system cannot be gracefully unmounted at the moment because
+	 * someone is working with it.
+	 */
+	if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,
+	    mr_node->dev_handle) != 2) {
+		fibril_rwlock_write_unlock(&namespace_rwlock);
+		vfs_node_put(mr_node);
+		free(mp);
+		ipc_answer_0(rid, EBUSY);
+		return;
+	}
+
+	if (str_cmp(mp, "/") == 0) {
+
+		/*
+		 * Unmounting the root file system.
+		 *
+		 * In this case, there is no mount point node and we send
+		 * VFS_OUT_UNMOUNTED directly to the mounted file system.
+		 */
+
+		free(mp);
+		phone = vfs_grab_phone(mr_node->fs_handle);
+		rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,
+		    mr_node->dev_handle);
+		vfs_release_phone(phone);
+		if (rc != EOK) {
+			fibril_rwlock_write_unlock(&namespace_rwlock);
+			vfs_node_put(mr_node);
+			ipc_answer_0(rid, rc);
+			return;
+		}
+		rootfs.fs_handle = 0;
+		rootfs.dev_handle = 0;
+	} else {
+
+		/*
+		 * Unmounting a non-root file system.
+		 *
+		 * We have a regular mount point node representing the parent
+		 * file system, so we delegate the operation to it.
+		 */
+
+		rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
+		free(mp);
+		if (rc != EOK) {
+			fibril_rwlock_write_unlock(&namespace_rwlock);
+			vfs_node_put(mr_node);
+			ipc_answer_0(rid, rc);
+			return;
+		}
+		vfs_node_t *mp_node = vfs_node_get(&mp_res);
+		if (!mp_node) {
+			fibril_rwlock_write_unlock(&namespace_rwlock);
+			vfs_node_put(mr_node);
+			ipc_answer_0(rid, ENOMEM);
+			return;
+		}
+
+		phone = vfs_grab_phone(mp_node->fs_handle);
+		rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->dev_handle,
+		    mp_node->index);
+		vfs_release_phone(phone);
+		if (rc != EOK) {
+			fibril_rwlock_write_unlock(&namespace_rwlock);
+			vfs_node_put(mp_node);
+			vfs_node_put(mr_node);
+			ipc_answer_0(rid, rc);
+			return;
+		}
+
+		/* Drop the reference we got above. */
+		vfs_node_put(mp_node);
+		/* Drop the reference from when the file system was mounted. */
+		vfs_node_put(mp_node);
+	}
+
+
+	/*
+	 * All went well, the mounted file system was successfully unmounted.
+	 * The only thing left is to forget the unmounted root VFS node.
+	 */
+	vfs_node_forget(mr_node);
+
+	fibril_rwlock_write_unlock(&namespace_rwlock);
+	ipc_answer_0(rid, EOK);
+}
+
 void vfs_open(ipc_callid_t rid, ipc_call_t *request)
 {
@@ -454,9 +510,10 @@
 	/*
 	 * Make sure that we are called with exactly one of L_FILE and
-	 * L_DIRECTORY. Make sure that the user does not pass L_OPEN.
+	 * L_DIRECTORY. Make sure that the user does not pass L_OPEN,
+	 * L_ROOT or L_MP.
 	 */
 	if (((lflag & (L_FILE | L_DIRECTORY)) == 0) ||
 	    ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) ||
-	    ((lflag & L_OPEN) != 0)) {
+	    (lflag & (L_OPEN | L_ROOT | L_MP))) {
 		ipc_answer_0(rid, EINVAL);
 		return;
@@ -468,25 +525,10 @@
 		lflag |= L_EXCLUSIVE;
 	
-	ipc_callid_t callid;
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	char *path = malloc(len + 1);
-	if (!path) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	int rc;
-	if ((rc = async_data_write_finalize(callid, path, len))) {
-		ipc_answer_0(rid, rc);
-		free(path);
-		return;
-	}
-	path[len] = '\0';
+	char *path;
+	int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 	
 	/*
@@ -679,5 +721,5 @@
 }
 
-static int vfs_close_internal(vfs_file_t *file)
+int vfs_close_internal(vfs_file_t *file)
 {
 	/*
@@ -756,20 +798,4 @@
 	
 	/*
-	 * Now we need to receive a call with client's
-	 * IPC_M_DATA_READ/IPC_M_DATA_WRITE request.
-	 */
-	ipc_callid_t callid;
-	int res;
-	if (read)
-		res = async_data_read_receive(&callid, NULL);
-	else 
-		res = async_data_write_receive(&callid, NULL);
-	if (!res) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	/*
 	 * Lock the open file structure so that no other thread can manipulate
 	 * the same open file at a time.
@@ -795,30 +821,32 @@
 	}
 	
-	int fs_phone = vfs_grab_phone(file->node->fs_handle);	
-	
-	/* Make a VFS_READ/VFS_WRITE request at the destination FS server. */
-	aid_t msg;
-	ipc_call_t answer;
-	if (!read && file->append)
-		file->pos = file->node->size;
-	msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE,
-	    file->node->dev_handle, file->node->index, file->pos, &answer);
-	
-	/*
-	 * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
+	int fs_phone = vfs_grab_phone(file->node->fs_handle);
+	
+	/*
+	 * Make a VFS_READ/VFS_WRITE request at the destination FS server
+	 * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
 	 * destination FS server. The call will be routed as if sent by
 	 * ourselves. Note that call arguments are immutable in this case so we
 	 * don't have to bother.
 	 */
-	ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
-
-	/* Wait for reply from the FS server. */
 	ipcarg_t rc;
-	async_wait_for(msg, &rc);
+	ipc_call_t answer;
+	if (read) {
+		if (file->append)
+			file->pos = file->node->size;
+		
+		rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ,
+		    file->node->dev_handle, file->node->index, file->pos,
+		    &answer);
+	} else {
+		rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE,
+		    file->node->dev_handle, file->node->index, file->pos,
+		    &answer);
+	}
 	
 	vfs_release_phone(fs_phone);
 	
 	size_t bytes = IPC_GET_ARG1(answer);
-
+	
 	if (file->node->type == VFS_NODE_DIRECTORY)
 		fibril_rwlock_read_unlock(&namespace_rwlock);
@@ -982,26 +1010,12 @@
 void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
 {
-	size_t len;
+	char *path;
+	int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
 	ipc_callid_t callid;
-
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *path = malloc(len + 1);
-	if (!path) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	int rc;
-	if ((rc = async_data_write_finalize(callid, path, len))) {
-		ipc_answer_0(rid, rc);
-		free(path);
-		return;
-	}
-	path[len] = '\0';
-
 	if (!async_data_read_receive(&callid, NULL)) {
 		free(path);
@@ -1049,27 +1063,12 @@
 {
 	int mode = IPC_GET_ARG1(*request);
-
-	size_t len;
-	ipc_callid_t callid;
-
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *path = malloc(len + 1);
-	if (!path) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	int rc;
-	if ((rc = async_data_write_finalize(callid, path, len))) {
-		ipc_answer_0(rid, rc);
-		free(path);
-		return;
-	}
-	path[len] = '\0';
-
+	
+	char *path;
+	int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
 	/* Ignore mode for now. */
 	(void) mode;
@@ -1086,26 +1085,11 @@
 {
 	int lflag = IPC_GET_ARG1(*request);
-
-	size_t len;
-	ipc_callid_t callid;
-
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *path = malloc(len + 1);
-	if (!path) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	int rc;
-	if ((rc = async_data_write_finalize(callid, path, len))) {
-		ipc_answer_0(rid, rc);
-		free(path);
-		return;
-	}
-	path[len] = '\0';
+	
+	char *path;
+	int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 	
 	fibril_rwlock_write_lock(&namespace_rwlock);
@@ -1136,52 +1120,27 @@
 void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
 {
-	size_t olen, nlen;
-	ipc_callid_t callid;
-	int rc;
-
 	/* Retrieve the old path. */
-	if (!async_data_write_receive(&callid, &olen)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *old = malloc(olen + 1);
-	if (!old) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	if ((rc = async_data_write_finalize(callid, old, olen))) {
-		ipc_answer_0(rid, rc);
+	char *old;
+	int rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	/* Retrieve the new path. */
+	char *new;
+	rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
 		free(old);
-		return;
-	}
-	old[olen] = '\0';
-	
-	/* Retrieve the new path. */
-	if (!async_data_write_receive(&callid, &nlen)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(old);
-		return;
-	}
-	char *new = malloc(nlen + 1);
-	if (!new) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		free(old);
-		return;
-	}
-	if ((rc = async_data_write_finalize(callid, new, nlen))) {
-		ipc_answer_0(rid, rc);
-		free(old);
-		free(new);
-		return;
-	}
-	new[nlen] = '\0';
-
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	size_t olen;
+	size_t nlen;
 	char *oldc = canonify(old, &olen);
 	char *newc = canonify(new, &nlen);
-	if (!oldc || !newc) {
+	
+	if ((!oldc) || (!newc)) {
 		ipc_answer_0(rid, EINVAL);
 		free(old);
@@ -1189,6 +1148,8 @@
 		return;
 	}
+	
 	oldc[olen] = '\0';
 	newc[nlen] = '\0';
+	
 	if ((!str_lcmp(newc, oldc, str_length(oldc))) &&
 	    ((newc[str_length(oldc)] == '/') ||
@@ -1211,4 +1172,5 @@
 	vfs_lookup_res_t new_par_lr;
 	fibril_rwlock_write_lock(&namespace_rwlock);
+	
 	/* Lookup the node belonging to the old file name. */
 	rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL);
@@ -1220,4 +1182,5 @@
 		return;
 	}
+	
 	vfs_node_t *old_node = vfs_node_get(&old_lr);
 	if (!old_node) {
@@ -1228,4 +1191,5 @@
 		return;
 	}
+	
 	/* Determine the path to the parent of the node with the new name. */
 	char *parentc = str_dup(newc);
@@ -1237,4 +1201,5 @@
 		return;
 	}
+	
 	char *lastsl = str_rchr(parentc + 1, '/');
 	if (lastsl)
@@ -1242,4 +1207,5 @@
 	else
 		parentc[1] = '\0';
+	
 	/* Lookup parent of the new file name. */
 	rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL);
@@ -1252,4 +1218,5 @@
 		return;
 	}
+	
 	/* Check whether linking to the same file system instance. */
 	if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) ||
@@ -1261,7 +1228,9 @@
 		return;
 	}
+	
 	/* Destroy the old link for the new name. */
 	vfs_node_t *new_node = NULL;
 	rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL);
+	
 	switch (rc) {
 	case ENOENT:
@@ -1288,4 +1257,5 @@
 		return;
 	}
+	
 	/* Create the new link for the new name. */
 	rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index);
@@ -1299,7 +1269,9 @@
 		return;
 	}
+	
 	fibril_mutex_lock(&nodes_mutex);
 	old_node->lnkcnt++;
 	fibril_mutex_unlock(&nodes_mutex);
+	
 	/* Destroy the link for the old name. */
 	rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL);
@@ -1314,4 +1286,5 @@
 		return;
 	}
+	
 	fibril_mutex_lock(&nodes_mutex);
 	old_node->lnkcnt--;
@@ -1319,6 +1292,8 @@
 	fibril_rwlock_write_unlock(&namespace_rwlock);
 	vfs_node_put(old_node);
+	
 	if (new_node)
 		vfs_node_put(new_node);
+	
 	free(old);
 	free(new);
Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision 975e7e9657949fb3ec524791070ca75837c30ef9)
+++ uspace/srv/vfs/vfs_register.c	(revision e27cf669cb84d831da5b56f6fc99cd623239ba41)
@@ -110,78 +110,43 @@
 void vfs_register(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	ipc_call_t call;
-	int rc;
-	size_t size;
-
 	dprintf("Processing VFS_REGISTER request received from %p.\n",
 	    request->in_phone_hash);
-
-	/*
-	 * The first call has to be IPC_M_DATA_SEND in which we receive the
-	 * VFS info structure from the client FS.
-	 */
-	if (!async_data_write_receive(&callid, &size)) {
-		/*
-		 * The client doesn't obey the same protocol as we do.
-		 */
-		dprintf("Receiving of VFS info failed.\n");
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	dprintf("VFS info received, size = %d\n", size);
-	
-	/*
-	 * We know the size of the VFS info structure. See if the client
-	 * understands this easy concept too.
-	 */
-	if (size != sizeof(vfs_info_t)) {
-		/*
-		 * The client is sending us something, which cannot be
-		 * the info structure.
-		 */
-		dprintf("Received VFS info has bad size.\n");
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-
-	/*
-	 * Allocate and initialize a buffer for the fs_info structure.
-	 */
-	fs_info_t *fs_info;
-	fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));
-	if (!fs_info) {
-		dprintf("Could not allocate memory for FS info.\n");
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	link_initialize(&fs_info->fs_link);
-	fibril_mutex_initialize(&fs_info->phone_lock);
-		
-	rc = async_data_write_finalize(callid, &fs_info->vfs_info, size);
+	
+	vfs_info_t *vfs_info;
+	int rc = async_data_write_accept((void **) &vfs_info, false,
+	    sizeof(vfs_info_t), sizeof(vfs_info_t), 0, NULL);
+	
 	if (rc != EOK) {
 		dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n",
 		    rc);
-		free(fs_info);
-		ipc_answer_0(callid, rc);
 		ipc_answer_0(rid, rc);
 		return;
 	}
-
+	
+	/*
+	 * Allocate and initialize a buffer for the fs_info structure.
+	 */
+	fs_info_t *fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));
+	if (!fs_info) {
+		dprintf("Could not allocate memory for FS info.\n");
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+	
+	link_initialize(&fs_info->fs_link);
+	fibril_mutex_initialize(&fs_info->phone_lock);
+	fs_info->vfs_info = *vfs_info;
+	free(vfs_info);
+	
 	dprintf("VFS info delivered.\n");
-		
+	
 	if (!vfs_info_sane(&fs_info->vfs_info)) {
 		free(fs_info);
-		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
 		return;
 	}
-		
+	
 	fibril_mutex_lock(&fs_head_lock);
-
+	
 	/*
 	 * Check for duplicit registrations.
@@ -194,9 +159,8 @@
 		fibril_mutex_unlock(&fs_head_lock);
 		free(fs_info);
-		ipc_answer_0(callid, EEXISTS);
 		ipc_answer_0(rid, EEXISTS);
 		return;
 	}
-
+	
 	/*
 	 * Add fs_info to the list of registered FS's.
@@ -210,5 +174,6 @@
 	 * which to forward VFS requests to it.
 	 */
-	callid = async_get_call(&call);
+	ipc_call_t call;
+	ipc_callid_t callid = async_get_call(&call);
 	if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
 		dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
@@ -222,11 +187,12 @@
 	fs_info->phone = IPC_GET_ARG5(call);
 	ipc_answer_0(callid, EOK);
-
+	
 	dprintf("Callback connection to FS created.\n");
-
+	
 	/*
 	 * The client will want us to send him the address space area with PLB.
 	 */
-
+	
+	size_t size;
 	if (!async_share_in_receive(&callid, &size)) {
 		dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
@@ -253,5 +219,5 @@
 		return;
 	}
-
+	
 	/*
 	 * Commit to read-only sharing the PLB with the client.
@@ -259,7 +225,7 @@
 	(void) async_share_in_finalize(callid, plb,
 	    AS_AREA_READ | AS_AREA_CACHEABLE);
-
+	
 	dprintf("Sharing PLB.\n");
-
+	
 	/*
 	 * That was it. The FS has been registered.
