Index: .bzrignore
===================================================================
--- .bzrignore	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ .bzrignore	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,30 +1,55 @@
 *.disasm
+*.la
+*.lo
 *.map
 *.prev
-*.ag.probe.[cs]
-*.lo
-*.la
 *.so.*
-Makefile.depend
 Makefile.ag.depend
 Makefile.common
 Makefile.config
-cscope.out
+Makefile.depend
 autotool/
+boot/distroot/
+boot/initrd.img
 common.h
 config.h
+cscope.out
 hdisk.img
 image.iso
-boot/distroot/
-boot/initrd.img
+kernel/arch/amd64/_link.ld
+kernel/arch/amd64/include/arch/boot/memmap_struct.h
+kernel/arch/amd64/include/arch/common.h
+kernel/arch/amd64/include/arch/context_struct.h
+kernel/arch/amd64/include/arch/istate_struct.h
+kernel/arch/amd64/include/arch/kseg_struct.h
+kernel/arch/arm32/_link.ld
+kernel/arch/arm32/include/arch/context_struct.h
+kernel/arch/arm32/include/arch/istate_struct.h
+kernel/arch/ia32/_link.ld
+kernel/arch/ia32/include/arch/boot/memmap_struct.h
+kernel/arch/ia32/include/arch/context_struct.h
+kernel/arch/ia32/include/arch/istate_struct.h
+kernel/arch/ia64/include/arch/context_struct.h
+kernel/arch/ia64/include/arch/istate_struct.h
+kernel/arch/mips32/include/arch/context_struct.h
+kernel/arch/mips32/include/arch/fpu_context_struct.h
+kernel/arch/mips32/include/arch/istate_struct.h
+kernel/arch/ppc32/include/arch/context_struct.h
+kernel/arch/ppc32/include/arch/fpu_context_struct.h
+kernel/arch/ppc32/include/arch/istate_struct.h
+kernel/arch/sparc64/include/arch/context_struct.h
+kernel/arch/sparc64/include/arch/istate_struct.h
+kernel/genarch/include/genarch/multiboot/multiboot_info_struct.h
+kernel/genarch/include/genarch/multiboot/multiboot_memmap_struct.h
+kernel/generic/src/debug/real_map.bin
 kernel/kernel.bin
 kernel/kernel.dump
 kernel/kernel.raw
-kernel/arch/amd64/_link.ld
-kernel/arch/amd64/include/arch/common.h
-kernel/generic/src/debug/real_map.bin
 uspace/app/barber/barber
 uspace/app/barber/images.c
 uspace/app/barber/images.h
+uspace/app/barber/images.s
+uspace/app/barber/images.zip
+uspace/app/barber/images_desc.c
 uspace/app/bdsh/bdsh
 uspace/app/bdsh/test-bdsh
@@ -32,15 +57,18 @@
 uspace/app/blkdump/blkdump
 uspace/app/bnchmark/bnchmark
-uspace/drv/char/pl050/pl050
+uspace/app/corecfg/corecfg
 uspace/app/date/date
 uspace/app/devctl/devctl
+uspace/app/df/df
 uspace/app/dltest/dltest
 uspace/app/dltests/dltests
 uspace/app/dnscfg/dnscfg
 uspace/app/dnsres/dnsres
+uspace/app/download/download
 uspace/app/edit/edit
 uspace/app/fdisk/fdisk
 uspace/app/fontviewer/fontviewer
 uspace/app/getterm/getterm
+uspace/app/gunzip/gunzip
 uspace/app/inet/inet
 uspace/app/init/init
@@ -57,12 +85,13 @@
 uspace/app/modplay/modplay
 uspace/app/netecho/netecho
+uspace/app/netspeed/netspeed
 uspace/app/nettest1/nettest1
 uspace/app/nettest2/nettest2
 uspace/app/nettest3/nettest3
 uspace/app/nic/nic
-uspace/app/netecho/netecho
 uspace/app/nterm/nterm
 uspace/app/ping/ping
 uspace/app/ping6/ping6
+uspace/app/pkg/pkg
 uspace/app/rcubench/rcubench
 uspace/app/rcutest/rcutest
@@ -80,9 +109,14 @@
 uspace/app/top/top
 uspace/app/trace/trace
+uspace/app/untar/untar
 uspace/app/usbinfo/usbinfo
 uspace/app/vcalc/vcalc
 uspace/app/vdemo/vdemo
+uspace/app/viewer/viewer
 uspace/app/vlaunch/images.c
 uspace/app/vlaunch/images.h
+uspace/app/vlaunch/images.s
+uspace/app/vlaunch/images.zip
+uspace/app/vlaunch/images_desc.c
 uspace/app/vlaunch/vlaunch
 uspace/app/vterm/vterm
@@ -96,14 +130,18 @@
 uspace/dist/app/blkdump
 uspace/dist/app/bnchmark
+uspace/dist/app/corecfg
 uspace/dist/app/date
 uspace/dist/app/devctl
+uspace/dist/app/df
 uspace/dist/app/dltest
 uspace/dist/app/dltests
 uspace/dist/app/dnscfg
 uspace/dist/app/dnsres
+uspace/dist/app/download
 uspace/dist/app/edit
 uspace/dist/app/fdisk
 uspace/dist/app/fontviewer
 uspace/dist/app/getterm
+uspace/dist/app/gunzip
 uspace/dist/app/inet
 uspace/dist/app/kill
@@ -119,12 +157,13 @@
 uspace/dist/app/modplay
 uspace/dist/app/netecho
+uspace/dist/app/netspeed
 uspace/dist/app/nettest1
 uspace/dist/app/nettest2
 uspace/dist/app/nettest3
 uspace/dist/app/nic
-uspace/dist/app/netecho
 uspace/dist/app/nterm
 uspace/dist/app/ping
 uspace/dist/app/ping6
+uspace/dist/app/pkg
 uspace/dist/app/rcubench
 uspace/dist/app/rcutest
@@ -142,7 +181,9 @@
 uspace/dist/app/top
 uspace/dist/app/trace
+uspace/dist/app/untar
 uspace/dist/app/usbinfo
 uspace/dist/app/vcalc
 uspace/dist/app/vdemo
+uspace/dist/app/viewer
 uspace/dist/app/vlaunch
 uspace/dist/app/vterm
@@ -151,7 +192,11 @@
 uspace/dist/app/websrv
 uspace/dist/app/wifi_supplicant
+uspace/dist/demo.txt
+uspace/dist/demo.wav
+uspace/dist/demo.xm
 uspace/dist/drv/ahci/
 uspace/dist/drv/ar9271/
 uspace/dist/drv/ata_bd/
+uspace/dist/drv/atkbd/
 uspace/dist/drv/cmos-rtc/
 uspace/dist/drv/e1k/
@@ -159,4 +204,6 @@
 uspace/dist/drv/hdaudio/
 uspace/dist/drv/i8042/
+uspace/dist/drv/icp/
+uspace/dist/drv/icp-ic/
 uspace/dist/drv/isa/
 uspace/dist/drv/kfb/
@@ -166,8 +213,8 @@
 uspace/dist/drv/pc/
 uspace/dist/drv/pciintel/
+uspace/dist/drv/pl050/
 uspace/dist/drv/ps2mouse/
 uspace/dist/drv/root/
 uspace/dist/drv/rootpc/
-uspace/dist/drv/virt/
 uspace/dist/drv/rtl8139/
 uspace/dist/drv/rtl8169/
@@ -183,7 +230,10 @@
 uspace/dist/drv/usbmid/
 uspace/dist/drv/vhc/
+uspace/dist/drv/virt/
 uspace/dist/drv/xtkbd/
-uspace/dist/drv/atkbd/
 uspace/dist/drv/xhci/
+uspace/dist/inc/_link.ld
+uspace/dist/inc/c/
+uspace/dist/logo.tga
 uspace/dist/srv/apic
 uspace/dist/srv/cdfs
@@ -192,4 +242,5 @@
 uspace/dist/srv/console
 uspace/dist/srv/devman
+uspace/dist/srv/dhcp
 uspace/dist/srv/dnsrsrv
 uspace/dist/srv/ethip
@@ -203,9 +254,12 @@
 uspace/dist/srv/input
 uspace/dist/srv/isdv4_tablet
+uspace/dist/srv/klog
 uspace/dist/srv/locfs
 uspace/dist/srv/loopip
 uspace/dist/srv/mfs
+uspace/dist/srv/nconfsrv
 uspace/dist/srv/output
 uspace/dist/srv/remcons
+uspace/dist/srv/rfb
 uspace/dist/srv/sata_bd
 uspace/dist/srv/slip
@@ -223,4 +277,5 @@
 uspace/drv/block/ata_bd/ata_bd
 uspace/drv/block/ddisk/ddisk
+uspace/drv/bus/adb/cuda_adb/cuda_adb
 uspace/drv/bus/isa/isa
 uspace/drv/bus/pci/pciintel/pciintel
@@ -236,15 +291,13 @@
 uspace/drv/bus/usb/xhci/xhci
 uspace/drv/bus/usb/xhci/test-xhci
+uspace/drv/char/atkbd/atkbd
 uspace/drv/char/i8042/i8042
 uspace/drv/char/ns8250/ns8250
+uspace/drv/char/pl050/pl050
 uspace/drv/char/ps2mouse/ps2mouse
 uspace/drv/char/xtkbd/xtkbd
-uspace/drv/char/atkbd/atkbd
+uspace/drv/fb/amdm37x_dispc/amdm37x_dispc
 uspace/drv/fb/kfb/kfb
-uspace/drv/root/root/root
-uspace/drv/root/virt/virt
-uspace/drv/platform/icp/icp
-uspace/drv/platform/pc/pc
-uspace/drv/platform/rootpc/rootpc
+uspace/drv/intctl/icp-ic/icp-ic
 uspace/drv/nic/ar9271/ar9271
 uspace/drv/nic/e1k/e1k
@@ -252,4 +305,13 @@
 uspace/drv/nic/rtl8139/rtl8139
 uspace/drv/nic/rtl8169/rtl8169
+uspace/drv/platform/amdm37x/amdm37x
+uspace/drv/platform/icp/icp
+uspace/drv/platform/mac/mac
+uspace/drv/platform/malta/malta
+uspace/drv/platform/msim/msim
+uspace/drv/platform/pc/pc
+uspace/drv/platform/rootpc/rootpc
+uspace/drv/root/root/root
+uspace/drv/root/virt/virt
 uspace/drv/test/test1/test1
 uspace/drv/test/test2/test2
@@ -261,10 +323,37 @@
 uspace/lib/c/arch/amd64/_link.ld
 uspace/lib/c/arch/amd64/include/libarch/common.h
+uspace/lib/c/arch/amd64/include/libarch/fibril_context.h
+uspace/lib/c/arch/amd64/include/libarch/istate_struct.h
+uspace/lib/c/arch/arm32/_link-dlexe.ld
+uspace/lib/c/arch/arm32/_link-loader.ld
+uspace/lib/c/arch/arm32/_link-shlib.ld
+uspace/lib/c/arch/arm32/_link.ld
+uspace/lib/c/arch/arm32/include/libarch/fibril_context.h
+uspace/lib/c/arch/arm32/include/libarch/istate_struct.h
+uspace/lib/c/arch/ia32/_link-dlexe.ld
+uspace/lib/c/arch/ia32/_link-loader.ld
+uspace/lib/c/arch/ia32/_link-shlib.ld
+uspace/lib/c/arch/ia32/_link.ld
+uspace/lib/c/arch/ia32/include/libarch/fibril_context.h
+uspace/lib/c/arch/ia32/include/libarch/istate_struct.h
+uspace/lib/c/arch/ia64/include/libarch/fibril_context.h
+uspace/lib/c/arch/ia64/include/libarch/istate_struct.h
+uspace/lib/c/arch/mips32/include/libarch/fibril_context.h
+uspace/lib/c/arch/mips32/include/libarch/istate_struct.h
+uspace/lib/c/arch/mips32eb/include/libarch/fibril_context.h
+uspace/lib/c/arch/mips32eb/include/libarch/istate_struct.h
+uspace/lib/c/arch/ppc32/include/libarch/fibril_context.h
+uspace/lib/c/arch/ppc32/include/libarch/istate_struct.h
+uspace/lib/c/arch/sparc64/include/libarch/fibril_context.h
+uspace/lib/c/arch/sparc64/include/libarch/istate_struct.h
 uspace/lib/c/test-libc
+uspace/lib/label/test-liblabel
 uspace/lib/pcut/test-libpcut-*
 uspace/lib/posix/collisions.list
+uspace/lib/posix/include/libc
+uspace/lib/posix/redefs-hide-libc-symbols.list
 uspace/lib/posix/redefs-hide-libc.xargs
+uspace/lib/posix/redefs-show-posix-symbols.list
 uspace/lib/posix/redefs-show-posix.xargs
-uspace/lib/posix/include/libc
 uspace/lib/posix/test-libposix
 uspace/lib/uri/test-liburi
@@ -292,83 +381,27 @@
 uspace/srv/hid/output/output
 uspace/srv/hid/remcons/remcons
+uspace/srv/hid/rfb/rfb
 uspace/srv/hid/s3c24xx_ts/s3c24xx_ts
+uspace/srv/hw/bus/cuda_adb/cuda_adb
 uspace/srv/hw/char/s3c24xx_uart/s3c24ser
 uspace/srv/hw/irc/apic/apic
 uspace/srv/hw/irc/i8259/i8259
+uspace/srv/hw/irc/obio/obio
+uspace/srv/klog/klog
 uspace/srv/loader/loader
 uspace/srv/locsrv/locsrv
 uspace/srv/logger/logger
+uspace/srv/net/dhcp/dhcp
 uspace/srv/net/dnsrsrv/dnsrsrv
 uspace/srv/net/ethip/ethip
 uspace/srv/net/inetsrv/inetsrv
 uspace/srv/net/loopip/loopip
+uspace/srv/net/nconfsrv/nconfsrv
 uspace/srv/net/slip/slip
 uspace/srv/net/tcp/tcp
+uspace/srv/net/tcp/test-tcp
 uspace/srv/net/udp/udp
 uspace/srv/ns/ns
 uspace/srv/taskmon/taskmon
+uspace/srv/vfs/vfs
 uspace/srv/volsrv/volsrv
-uspace/srv/vfs/vfs
-kernel/arch/ia32/_link.ld
-uspace/lib/c/arch/ia32/_link-dlexe.ld
-uspace/lib/c/arch/ia32/_link-loader.ld
-uspace/lib/c/arch/ia32/_link-shlib.ld
-uspace/lib/c/arch/ia32/_link.ld
-kernel/arch/arm32/_link.ld
-uspace/app/corecfg/corecfg
-uspace/dist/app/corecfg
-uspace/dist/srv/rfb
-uspace/srv/hid/rfb/rfb
-uspace/dist/srv/dhcp
-uspace/srv/net/dhcp/dhcp
-uspace/dist/srv/nconfsrv
-uspace/srv/net/nconfsrv/nconfsrv
-uspace/app/netspeed/netspeed
-uspace/dist/app/netspeed
-uspace/app/df/df
-uspace/dist/app/df
-uspace/app/download/download
-uspace/dist/app/download
-uspace/app/viewer/viewer
-uspace/dist/app/viewer
-uspace/app/untar/untar
-uspace/dist/app/untar
-uspace/lib/posix/redefs-hide-libc-symbols.list
-uspace/lib/posix/redefs-show-posix-symbols.list
-uspace/srv/klog/klog
-uspace/dist/srv/klog
-kernel/arch/sparc64/include/arch/context_struct.h
-kernel/arch/sparc64/include/arch/istate_struct.h
-kernel/arch/amd64/include/arch/context_struct.h
-kernel/arch/amd64/include/arch/istate_struct.h
-kernel/arch/ia32/include/arch/context_struct.h
-kernel/arch/ia32/include/arch/istate_struct.h
-kernel/arch/ia32/include/arch/boot/memmap_struct.h
-kernel/arch/ppc32/include/arch/context_struct.h
-kernel/arch/ppc32/include/arch/fpu_context_struct.h
-kernel/arch/ppc32/include/arch/istate_struct.h
-kernel/arch/arm32/include/arch/context_struct.h
-kernel/arch/arm32/include/arch/istate_struct.h
-kernel/arch/mips32/include/arch/context_struct.h
-kernel/arch/mips32/include/arch/fpu_context_struct.h
-kernel/arch/mips32/include/arch/istate_struct.h
-kernel/arch/ia64/include/arch/context_struct.h
-kernel/arch/ia64/include/arch/istate_struct.h
-kernel/genarch/include/genarch/multiboot/multiboot_info_struct.h
-kernel/genarch/include/genarch/multiboot/multiboot_memmap_struct.h
-uspace/lib/c/arch/sparc64/include/libarch/fibril_context.h
-uspace/lib/c/arch/sparc64/include/libarch/istate_struct.h
-uspace/lib/c/arch/amd64/include/libarch/fibril_context.h
-uspace/lib/c/arch/amd64/include/libarch/istate_struct.h
-uspace/lib/c/arch/ia32/include/libarch/fibril_context.h
-uspace/lib/c/arch/ia32/include/libarch/istate_struct.h
-uspace/lib/c/arch/ppc32/include/libarch/fibril_context.h
-uspace/lib/c/arch/ppc32/include/libarch/istate_struct.h
-uspace/lib/c/arch/arm32/include/libarch/fibril_context.h
-uspace/lib/c/arch/arm32/include/libarch/istate_struct.h
-uspace/lib/c/arch/mips32eb/include/libarch/fibril_context.h
-uspace/lib/c/arch/mips32eb/include/libarch/istate_struct.h
-uspace/lib/c/arch/mips32/include/libarch/fibril_context.h
-uspace/lib/c/arch/mips32/include/libarch/istate_struct.h
-uspace/lib/c/arch/ia64/include/libarch/fibril_context.h
-uspace/lib/c/arch/ia64/include/libarch/istate_struct.h
Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ HelenOS.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -298,28 +298,12 @@
 @ "clang" Clang
 @ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
-@ "icc" Intel C Compiler
 @ "gcc_native" GNU C Compiler (native)
-! [PLATFORM=amd64|PLATFORM=ia32] COMPILER (choice)
-
-% Compiler
-@ "gcc_cross" GNU C Compiler (cross-compiler)
-@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
-@ "icc" Intel C Compiler
-@ "gcc_native" GNU C Compiler (native)
-! [PLATFORM=ia64] COMPILER (choice)
-
-% Compiler
-@ "gcc_cross" GNU C Compiler (cross-compiler)
-@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
-@ "gcc_native" GNU C Compiler (native)
-! [PLATFORM=riscv64] COMPILER (choice)
-
-% Compiler
-@ "gcc_cross" GNU C Compiler (cross-compiler)
-@ "clang" Clang
-@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
-@ "gcc_native" GNU C Compiler (native)
-! [PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=sparc64] COMPILER (choice)
-
+! COMPILER (choice)
+
+% Clang Integrated Assembler
+@ "default" Use architecture default.
+@ "yes" Use integrated assembler.
+@ "no" Use GNU Assembler.
+! [COMPILER=clang] INTEGRATED_AS (choice)
 
 ## Cross-compiler target for abstract architecture
@@ -347,5 +331,5 @@
 
 % IOMAP dummy support
-! [PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_IOMAP_DUMMY (y)
+! [PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=riscv64|PLATFORM=sparc64] CONFIG_IOMAP_DUMMY (y)
 
 % ACPI support
@@ -621,6 +605,13 @@
 ! CONFIG_STRIP_BINARIES (n/y)
 
-% Optimize for size
-! CONFIG_OPTIMIZE_FOR_SIZE (n/y)
+% Optimization level
+@ "3" Level 3 (recommended).
+@ "2" Level 2.
+@ "1" Level 1.
+@ "0" Disable optimizations.
+@ "s" Optimize for size.
+@ "g" Enable only optimizations that don't harm debugging.
+@ "fast" Level 3 + aggressive optimizations that can affect adherence to standards.
+! OPTIMIZATION (choice)
 
 % Barebone build with essential binaries only 
Index: abi/include/abi/ddi/arg.h
===================================================================
--- abi/include/abi/ddi/arg.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/ddi/arg.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define ABI_DDI_ARG_H_
 
+#include <stdint.h>
+
 #define DMAMEM_FLAGS_ANONYMOUS  0x01
 
Index: abi/include/abi/ddi/irq.h
===================================================================
--- abi/include/abi/ddi/irq.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/ddi/irq.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,6 @@
 #ifndef ABI_DDI_IRQ_H_
 #define ABI_DDI_IRQ_H_
+
+#include <stdint.h>
 
 typedef struct {
Index: abi/include/abi/elf.h
===================================================================
--- abi/include/abi/elf.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/elf.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,6 @@
 #ifndef ABI_ELF_H_
 #define ABI_ELF_H_
+
+#include <stdint.h>
 
 /**
Index: abi/include/abi/fourcc.h
===================================================================
--- abi/include/abi/fourcc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/fourcc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,12 +36,12 @@
 #define ABI_FOURCC_H_
 
-#include "../../../common.h"
+#include <stdint.h>
 
 #define FOURCC(a, b, c, d) \
-	(((UINT32_T) (a)) | (((UINT32_T) (b)) << 8) | \
-	    (((UINT32_T) (c)) << 16) | (((UINT32_T) (d)) << 24))
+	(((uint32_t) (a)) | (((uint32_t) (b)) << 8) | \
+	    (((uint32_t) (c)) << 16) | (((uint32_t) (d)) << 24))
 
 #define CC_COMPACT(a) \
-	((UINT32_T) (a) & 0x7f)
+	((uint32_t) (a) & 0x7f)
 
 #define FOURCC_COMPACT(a, b, c, d) \
Index: abi/include/abi/ipc/methods.h
===================================================================
--- abi/include/abi/ipc/methods.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/ipc/methods.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -58,26 +58,4 @@
 	 */
 	IPC_M_PHONE_HUNGUP = 0,
-
-	/** Clone connection.
-	 *
-	 * The calling task clones one of its phones for the callee.
-	 *
-	 * - ARG1 - The caller sets ARG1 to the phone of the cloned connection.
-	 *        - The callee gets the new phone from ARG1.
-	 *
-	 * - on answer, the callee acknowledges the new connection by sending EOK back
-	 *   or the kernel closes it
-	 */
-	IPC_M_CONNECTION_CLONE,
-
-	/** Protocol for establishing a cloned connection.
-	 *
-	 * Through this call, the recipient learns about the new cloned connection.
-	 *
-	 * - ARG5 - the kernel sets ARG5 to contain the hash of the used phone
-	 * - on answer, the callee acknowledges the new connection by sending EOK back
-	 *   or the kernel closes it
-	 */
-	IPC_M_CLONE_ESTABLISH,
 
 	/** Protocol for initializing callback connections.
Index: abi/include/abi/proc/task.h
===================================================================
--- abi/include/abi/proc/task.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/proc/task.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define ABI_PROC_TASK_H_
 
+#include <stdint.h>
+
 typedef uint64_t task_id_t;
 
Index: abi/include/abi/proc/thread.h
===================================================================
--- abi/include/abi/proc/thread.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/proc/thread.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define ABI_PROC_THREAD_H_
 
+#include <stdint.h>
+
 typedef uint64_t thread_id_t;
 
Index: abi/include/abi/proc/uarg.h
===================================================================
--- abi/include/abi/proc/uarg.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/proc/uarg.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define ABI_PROC_UARG_H_
 
+#include <stddef.h>
+
 /** Structure passed to uinit kernel thread as argument. */
 typedef struct uspace_arg {
Index: abi/include/abi/syscall.h
===================================================================
--- abi/include/abi/syscall.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/syscall.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -78,8 +78,7 @@
 	SYS_IPC_EVENT_UNMASK,
 	
-	SYS_CAP_GRANT,
-	SYS_CAP_REVOKE,
+	SYS_PERM_GRANT,
+	SYS_PERM_REVOKE,
 	
-	SYS_DEVICE_ASSIGN_DEVNO,
 	SYS_PHYSMEM_MAP,
 	SYS_PHYSMEM_UNMAP,
Index: abi/include/abi/sysinfo.h
===================================================================
--- abi/include/abi/sysinfo.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ abi/include/abi/sysinfo.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,6 +37,8 @@
 #define ABI_SYSINFO_H_
 
+#include <abi/bool.h>
 #include <abi/proc/task.h>
 #include <abi/proc/thread.h>
+#include <stdint.h>
 
 /** Number of load components */
Index: boot/Makefile
===================================================================
--- boot/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,9 +27,9 @@
 #
 
-.PHONY: all build_dist build_comps clean_dist clean
+.PHONY: all build_dist clean_dist clean
 
 include Makefile.common
 
-all: $(VERSION_DEF) $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) $(PREBUILD)
+all: $(VERSION_DEF) $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) $(PREBUILD) build_dist
 	$(MAKE) -r -f $(BUILD) PRECHECK=$(PRECHECK)
 ifneq ($(POSTBUILD),)
@@ -37,19 +37,13 @@
 endif
 
-build_comps: $(COMPONENTS) $(LINK).in
-	$(PACK) $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) arch/$(KARCH) $(COMPONENTS)
-
-$(INITRD).img: build_dist
-ifeq ($(RDFMT),tmpfs)
-	$(MKTMPFS) $(DIST_PATH) $@
-endif
-ifeq ($(RDFMT),fat)
-	$(MKFAT) 1048576 $(DIST_PATH) $@
-endif
-ifeq ($(RDFMT),ext4fs)
-	$(MKEXT4) 1048576 $(DIST_PATH) $@
-endif
-
 build_dist: clean_dist
+	mkdir -p "$(DIST_PATH)/app/"
+	mkdir -p "$(DIST_PATH)/cfg/net/"
+	mkdir -p "$(DIST_PATH)/lib/"
+	mkdir -p "$(DIST_PATH)/loc/"
+	mkdir -p "$(DIST_PATH)/log/"
+	mkdir -p "$(DIST_PATH)/srv/"
+	mkdir -p "$(DIST_PATH)/test/"
+	mkdir -p "$(DIST_PATH)/tmp/"
 	for file in $(RD_SRVS) ; do \
 		cp "$$file" "$(DIST_PATH)/srv/" ; \
@@ -59,5 +53,5 @@
 	done
 ifeq ($(CONFIG_DEVEL_FILES), y)
-	mkdir "$(DIST_PATH)/inc/c/"
+	mkdir -p "$(DIST_PATH)/inc/c/"
 	cp -r -L "$(USPACE_PATH)/lib/c/include/." "$(DIST_PATH)/inc/c/"
 	cp -r -L "$(ROOT_PATH)/abi/include/." "$(DIST_PATH)/inc/c/"
@@ -132,10 +126,9 @@
 	$(MAKE) -r -f $(POSTBUILD) clean PRECHECK=$(PRECHECK)
 endif
-	rm -fr $(SANDBOX)
 	rm -f $(POST_OUTPUT) $(BOOT_OUTPUT) $(DEPEND) $(DEPEND_PREV) arch/*/include/common.h
 	find generic/src/ arch/*/src/ genarch/src/ -name '*.o' -follow -exec rm \{\} \;
 
 clean_dist:
-	rm -f $(INITRD).img $(COMPS_H) $(COMPS_C) $(LINK) $(LINK).comp *.co
+	rm -f $(INITRD).img $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE) $(COMPS).o $(COMPS)_desc.o $(COMPS).zip $(LINK)
 	find $(USPACE_PATH)/dist -mindepth 1 -maxdepth 1 -type f -exec rm \{\} \;
 	rm -f $(USPACE_PATH)/dist/srv/*
Index: boot/Makefile.build
===================================================================
--- boot/Makefile.build	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/Makefile.build	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,63 +36,53 @@
 DEFS = -DBOOT -DRELEASE=$(RELEASE) "-DCOPYRIGHT=$(COPYRIGHT)" "-DNAME=$(NAME)" -D__$(BITS)_BITS__ -D__$(ENDIANESS)__
 
+AFLAGS =
 LFLAGS = --fatal-warnings
 
-GCC_CFLAGS = $(INCLUDES) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
+# FIXME: This condition is a workaround for issue #693.
+ifneq ($(BARCH),mips32)
+	AFLAGS += --fatal-warnings
+endif
+
+COMMON_CFLAGS = $(INCLUDES) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
+	-ffreestanding -fno-builtin -nostdlib -nostdinc \
+	-fexec-charset=UTF-8 -finput-charset=UTF-8
+
+GCC_CFLAGS = -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
 	-std=gnu99 -Werror-implicit-function-declaration -Wwrite-strings \
 	-pipe
 
-ICC_CFLAGS = $(INCLUDES) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
-	-ffreestanding -fno-builtin -nostdlib -nostdinc -Wall -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -wd170
-
-CLANG_CFLAGS = $(INCLUDES) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
+CLANG_CFLAGS = -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
 	-Werror-implicit-function-declaration -Wwrite-strings \
-	-pipe
+	-pipe  -fno-stack-protector -fno-PIC
 
 ifeq ($(CONFIG_DEBUG),y)
-	GCC_CFLAGS += -Werror
-	ICC_CFLAGS += -Werror
+	COMMON_CFLAGS += -Werror
 endif
 
 ifeq ($(CONFIG_LINE_DEBUG),y)
-	GCC_CFLAGS += -g
-	ICC_CFLAGS += -g
-	CLANG_CFLAGS += -g
+	COMMON_CFLAGS += -g
 endif
 
 ifeq ($(COMPILER),gcc_native)
-	CFLAGS = $(GCC_CFLAGS) $(EXTRA_CFLAGS)
+	CFLAGS = $(COMMON_CFLAGS) $(GCC_CFLAGS) $(EXTRA_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
 ifeq ($(COMPILER),gcc_cross)
-	CFLAGS = $(GCC_CFLAGS) $(EXTRA_CFLAGS)
+	CFLAGS = $(COMMON_CFLAGS) $(GCC_CFLAGS) $(EXTRA_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
 ifeq ($(COMPILER),gcc_helenos)
-	CFLAGS = $(GCC_CFLAGS) $(EXTRA_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-
-ifeq ($(COMPILER),icc)
-	CFLAGS = $(ICC_CFLAGS) $(EXTRA_CFLAGS)
+	CFLAGS = $(COMMON_CFLAGS) $(GCC_CFLAGS) $(EXTRA_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
 ifeq ($(COMPILER),clang)
-	CFLAGS = $(CLANG_CFLAGS) $(EXTRA_CFLAGS)
+	CFLAGS = $(COMMON_CFLAGS) $(CLANG_CFLAGS) $(EXTRA_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
 OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-COMPONENT_OBJECTS := $(addsuffix .co,$(basename $(MODULES)))
 
 all: $(VERSION_DEF) $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) $(BOOT_OUTPUT)
@@ -102,17 +92,21 @@
 	rm -f $(RAW) $(MAP) $(ARCH_INCLUDE) $(GENARCH_INCLUDE)
 
+ifneq ($(MAKECMDGOALS),clean)
 -include $(DEPEND)
+endif
+
+AS_CFLAGS := $(addprefix -Xassembler ,$(AFLAGS))
 
 $(BOOT_OUTPUT): $(RAW)
 	$(OBJCOPY) -O $(BFD_OUTPUT) $< $@
 
-$(RAW): $(OBJECTS) $(COMPONENT_OBJECTS) $(LINK)
-	$(LD) -n $(LFLAGS) -T $(LINK) -M -Map $(MAP) -o $@ $(COMPONENT_OBJECTS) $(OBJECTS)
+$(RAW): $(OBJECTS) $(LINK)
+	$(LD) -n $(LFLAGS) -T $(LINK) -M -Map $(MAP) -o $@ $(OBJECTS)
 
-$(LINK): $(LINK).comp $(DEPEND)
-	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $(LINK).comp | grep -v "^\#" > $(LINK)
+$(LINK): $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $(LINK).in | grep -v "^\#" > $(LINK)
 
 %.o: %.S $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
+	$(CC) $(DEFS) $(CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(CFLAGS) -D__ASM__
@@ -125,7 +119,30 @@
 endif
 
-$(DEPEND): $(ARCH_INCLUDE) $(GENARCH_INCLUDE) $(COMMON_HEADER_ARCH)
+%.o: %.s $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
+ifeq ($(PRECHECK),y)
+	$(JOBFILE) $(JOB) $< $@ as asm
+endif
+
+$(DEPEND): $(ARCH_INCLUDE) $(GENARCH_INCLUDE) $(COMMON_HEADER_ARCH) $(PRE_DEPEND)
 	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
 	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
+
+$(COMPS).s: $(COMPS).zip
+	unzip -p $< $@ > $@
+
+$(COMPS).h: $(COMPS).zip
+	unzip -p $< $@ > $@
+
+$(COMPS)_desc.c: $(COMPS).zip
+	unzip -p $< $@ > $@
+
+$(COMPONENTS_DEFLATE): $(COMPS).zip
+	unzip -p $< $@ > $@
+
+$(COMPS).zip: $(COMPONENTS)
+	$(MKARRAY) --deflate $(COMPS) $(COMP) "$(AS_PROLOG)" ".section .components, \"a\"" $^
+
+include Makefile.initrd
 
 $(ARCH_INCLUDE): arch/$(KARCH)/include/
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -52,6 +52,5 @@
 DRVS_PATH = drv
 
-SANDBOX = pack
-PACK = $(TOOLS_PATH)/pack.py
+MKARRAY = $(TOOLS_PATH)/mkarray.py
 MKTMPFS = $(TOOLS_PATH)/mktmpfs.py
 MKFAT = $(TOOLS_PATH)/mkfat.py
@@ -183,4 +182,5 @@
 	$(USPACE_PATH)/app/edit/edit \
 	$(USPACE_PATH)/app/fdisk/fdisk \
+	$(USPACE_PATH)/app/gunzip/gunzip \
 	$(USPACE_PATH)/app/inet/inet \
 	$(USPACE_PATH)/app/kill/kill \
@@ -208,4 +208,5 @@
 	$(USPACE_PATH)/app/nterm/nterm \
 	$(USPACE_PATH)/app/ping/ping \
+	$(USPACE_PATH)/app/pkg/pkg \
 	$(USPACE_PATH)/app/stats/stats \
 	$(USPACE_PATH)/app/sysinfo/sysinfo \
@@ -233,8 +234,10 @@
 RD_TESTS = \
 	$(USPACE_PATH)/lib/c/test-libc \
+	$(USPACE_PATH)/lib/label/test-liblabel \
 	$(USPACE_PATH)/lib/posix/test-libposix \
 	$(USPACE_PATH)/lib/uri/test-liburi \
 	$(USPACE_PATH)/drv/bus/usb/xhci/test-xhci \
-	$(USPACE_PATH)/app/bdsh/test-bdsh
+	$(USPACE_PATH)/app/bdsh/test-bdsh \
+	$(USPACE_PATH)/srv/net/tcp/test-tcp
 
 RD_DATA_ESSENTIAL = \
@@ -251,22 +254,24 @@
 	$(INITRD).img
 
+COMPONENTS_DEFLATE := $(addsuffix .deflate,$(notdir $(COMPONENTS)))
+
 LINK = arch/$(BARCH)/_link.ld
-COMPS_H = arch/$(BARCH)/include/_components.h
-COMPS_C = arch/$(BARCH)/src/_components.c
+COMP = component
+COMPS = $(COMP)s
 
 -include arch/$(BARCH)/Makefile.inc
 
 ifeq ($(CONFIG_BAREBONE),y)
-RD_SRVS = $(RD_SRVS_ESSENTIAL)
-RD_APPS = $(RD_APPS_ESSENTIAL)
-RD_DRVS = $(RD_DRVS_ESSENTIAL)
-RD_DRVS_FW = $(RD_DRVS_FW_ESSENTIAL)
-RD_DATA = $(RD_DATA_ESSENTIAL)
+	RD_SRVS = $(RD_SRVS_ESSENTIAL)
+	RD_APPS = $(RD_APPS_ESSENTIAL)
+	RD_DRVS = $(RD_DRVS_ESSENTIAL)
+	RD_DRVS_FW = $(RD_DRVS_FW_ESSENTIAL)
+	RD_DATA = $(RD_DATA_ESSENTIAL)
 else
-RD_SRVS = $(RD_SRVS_ESSENTIAL) $(RD_SRVS_NON_ESSENTIAL)
-RD_APPS = $(RD_APPS_ESSENTIAL) $(RD_APPS_NON_ESSENTIAL)
-RD_DRVS = $(RD_DRVS_ESSENTIAL) $(RD_DRVS_NON_ESSENTIAL)
-RD_DRVS_FW = $(RD_DRVS_FW_ESSENTIAL) $(RD_DRVS_FW_NON_ESSENTIAL)
-RD_DATA = $(RD_DATA_ESSENTIAL) $(RD_DATA_NON_ESSENTIAL)
+	RD_SRVS = $(RD_SRVS_ESSENTIAL) $(RD_SRVS_NON_ESSENTIAL)
+	RD_APPS = $(RD_APPS_ESSENTIAL) $(RD_APPS_NON_ESSENTIAL)
+	RD_DRVS = $(RD_DRVS_ESSENTIAL) $(RD_DRVS_NON_ESSENTIAL)
+	RD_DRVS_FW = $(RD_DRVS_FW_ESSENTIAL) $(RD_DRVS_FW_NON_ESSENTIAL)
+	RD_DATA = $(RD_DATA_ESSENTIAL) $(RD_DATA_NON_ESSENTIAL)
 endif
 
@@ -277,4 +282,3 @@
 JOB ?= image.job
 MAP ?= image.map
-PREBUILD ?= build_comps
 BUILD ?= Makefile.build
Index: boot/Makefile.grub
===================================================================
--- boot/Makefile.grub	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/Makefile.grub	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -57,5 +57,5 @@
 endif
 
-build_dist: clean
+build_dist: clean $(COMPONENTS)
 	mkdir -p $(BOOT)
 	cp -r -L $(GRUB) $(BOOT)/grub
@@ -95,2 +95,4 @@
 clean:
 	rm -fr $(DISTROOT)
+
+include Makefile.initrd
Index: boot/Makefile.initrd
===================================================================
--- boot/Makefile.initrd	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ boot/Makefile.initrd	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2006 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+$(INITRD).img:
+ifeq ($(RDFMT),tmpfs)
+	$(MKTMPFS) $(DIST_PATH) $@
+endif
+ifeq ($(RDFMT),fat)
+	$(MKFAT) 1048576 $(DIST_PATH) $@
+endif
+ifeq ($(RDFMT),ext4fs)
+	$(MKEXT4) 1048576 $(DIST_PATH) $@
+endif
Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/amd64/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -71,4 +71,3 @@
 
 BOOT_OUTPUT = $(ROOT_PATH)/image.iso
-PREBUILD = $(INITRD).img
 BUILD = Makefile.grub
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/arm32/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,8 +45,8 @@
 ifeq ($(MACHINE), raspberrypi)
 	BOOT_OUTPUT = image.boot
-	POST_OUTPUT = $(ROOT_PATH)/uImage.bin	
+	POST_OUTPUT = $(ROOT_PATH)/uImage.bin
 	LADDR = 0x00008000
 	SADDR = 0x00008000
-	POSTBUILD = Makefile.uboot	     
+	POSTBUILD = Makefile.uboot
 endif
 
@@ -76,7 +76,6 @@
 		char/atkbd \
 		char/ps2mouse \
+		intctl/icp-ic \
 		platform/icp
-	RD_SRVS_ESSENTIAL += \
-		$(USPACE_PATH)/srv/hw/irc/icp-ic/icp-ic
 endif
 
@@ -96,5 +95,6 @@
 	arch/$(BARCH)/src/mm.c \
 	arch/$(BARCH)/src/putchar.c \
-	$(COMPS_C) \
+	$(COMPS).s \
+	$(COMPS)_desc.c \
 	genarch/src/division.c \
 	generic/src/memstr.c \
@@ -105,2 +105,4 @@
 	generic/src/version.c \
 	generic/src/inflate.c
+
+PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
Index: boot/arch/arm32/_link.ld.in
===================================================================
--- boot/arch/arm32/_link.ld.in	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/arm32/_link.ld.in	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -23,5 +23,5 @@
 		*(.bss);        /* uninitialized static variables */
 		*(COMMON);      /* global variables */
-[[COMPONENTS]]
+		*(.components);
 	}
 	bdata_end = .;
Index: boot/arch/arm32/include/mm.h
===================================================================
--- boot/arch/arm32/include/mm.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/arm32/include/mm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,6 +42,4 @@
 #ifndef BOOT_arm32__MM_H
 #define BOOT_arm32__MM_H
-
-#include <typedefs.h>
 
 /** Describe "section" page table entry (one-level paging with 1 MB sized pages). */
Index: boot/arch/arm32/include/types.h
===================================================================
--- boot/arch/arm32/include/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/arm32/include/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,6 @@
 #define BOOT_arm32_TYPES_H
 
+#include <arch/common.h>
+
 #define TASKMAP_MAX_RECORDS        32
 #define BOOTINFO_TASK_NAME_BUFLEN  32
Index: boot/arch/arm32/src/main.c
===================================================================
--- boot/arch/arm32/src/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/arm32/src/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,4 @@
 #include <arch/asm.h>
 #include <arch/mm.h>
-#include <arch/_components.h>
 #include <halt.h>
 #include <printf.h>
@@ -44,8 +43,10 @@
 #include <macros.h>
 #include <align.h>
+#include <stdbool.h>
 #include <str.h>
 #include <errno.h>
 #include <inflate.h>
 #include <arch/cp15.h>
+#include "../../components.h"
 
 #define TOP2ADDR(top)  (((void *) PA2KA(BOOT_OFFSET)) + (top))
@@ -98,6 +99,6 @@
 	
 	for (size_t i = 0; i < COMPONENTS; i++) {
-		printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start,
-		    components[i].start, components[i].name, components[i].inflated,
+		printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].addr,
+		    components[i].addr, components[i].name, components[i].inflated,
 		    components[i].size);
 	}
@@ -128,5 +129,5 @@
 	
 	for (size_t i = cnt; i > 0; i--) {
-		void *tail = components[i - 1].start + components[i - 1].size;
+		void *tail = components[i - 1].addr + components[i - 1].size;
 		if (tail >= dest[i - 1]) {
 			printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
@@ -137,5 +138,5 @@
 		printf("%s ", components[i - 1].name);
 		
-		int err = inflate(components[i - 1].start, components[i - 1].size,
+		int err = inflate(components[i - 1].addr, components[i - 1].size,
 		    dest[i - 1], components[i - 1].inflated);
 		if (err != EOK) {
Index: boot/arch/arm32/src/mm.c
===================================================================
--- boot/arch/arm32/src/mm.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/arm32/src/mm.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
  */
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <arch/asm.h>
 #include <arch/mm.h>
Index: boot/arch/arm32/src/putchar.c
===================================================================
--- boot/arch/arm32/src/putchar.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/arm32/src/putchar.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,8 @@
  */
 
-#include <typedefs.h>
 #include <arch/main.h>
 #include <putchar.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <str.h>
 
Index: boot/arch/ia64/Makefile.inc
===================================================================
--- boot/arch/ia64/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ia64/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,5 +48,6 @@
 	arch/$(BARCH)/src/pal_asm.S \
 	arch/$(BARCH)/src/putchar.c \
-	$(COMPS_C) \
+	$(COMPS).s \
+	$(COMPS)_desc.c \
 	genarch/src/efi.c \
 	genarch/src/division.c \
@@ -88,2 +89,3 @@
 	bus/isa
 
+PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
Index: boot/arch/ia64/_link.ld.in
===================================================================
--- boot/arch/ia64/_link.ld.in	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ia64/_link.ld.in	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -16,7 +16,7 @@
 		*(.bss);                /* uninitialized static variables */
 		*(COMMON);
-[[COMPONENTS]]
+		*(.components);
 	}
-
+	
 	/DISCARD/ : {
 		*(.*);
Index: boot/arch/ia64/include/pal.h
===================================================================
--- boot/arch/ia64/include/pal.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ia64/include/pal.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,6 @@
 
 #include <arch/types.h>
-#include <typedefs.h>
+#include <stddef.h>
+#include <stdint.h>
 
 /*
Index: boot/arch/ia64/include/sal.h
===================================================================
--- boot/arch/ia64/include/sal.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ia64/include/sal.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,6 @@
 
 #include <arch/types.h>
-#include <typedefs.h>
+#include <stddef.h>
+#include <stdint.h>
 
 /*
Index: boot/arch/ia64/include/ski.h
===================================================================
--- boot/arch/ia64/include/ski.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ia64/include/ski.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,4 +30,5 @@
 #define BOOT_ia64_SKI_H_
 
+#include <stddef.h>
 #include <str.h>
 
Index: boot/arch/ia64/src/main.c
===================================================================
--- boot/arch/ia64/src/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ia64/src/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,4 @@
 #include <arch/arch.h>
 #include <arch/asm.h>
-#include <arch/_components.h>
 #include <genarch/efi.h>
 #include <arch/sal.h>
@@ -46,4 +45,5 @@
 #include <errno.h>
 #include <inflate.h>
+#include "../../components.h"
 
 #define DEFAULT_MEMORY_BASE		0x4000000ULL
@@ -78,5 +78,5 @@
 		memmap[items].size = DEFAULT_LEGACY_IO_SIZE;
 		memmap[items].type = MEMMAP_IO_PORTS;
-		items++;		 
+		items++;
 	} else {
 		char *cur, *mm_base = (char *) bootpar->efi_memmap;
@@ -159,6 +159,6 @@
 	size_t i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
-		    components[i].start, components[i].name,
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].addr,
+		    components[i].addr, components[i].name,
 		    components[i].inflated, components[i].size);
 	
@@ -202,5 +202,5 @@
 		 * overlap with the destination for inflate().
 		 */
-		memmove((void *) top, components[i - 1].start, components[i - 1].size);
+		memmove((void *) top, components[i - 1].addr, components[i - 1].size);
 		
 		int err = inflate((void *) top, components[i - 1].size,
Index: boot/arch/ia64/src/putchar.c
===================================================================
--- boot/arch/ia64/src/putchar.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ia64/src/putchar.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,7 +27,7 @@
  */
 
-#include <typedefs.h>
 #include <arch/arch.h>
 #include <putchar.h>
+#include <stddef.h>
 #include <str.h>
 #include <arch/ski.h>
Index: boot/arch/ia64/src/ski.c
===================================================================
--- boot/arch/ia64/src/ski.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ia64/src/ski.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,5 +28,6 @@
 
 #include <arch/ski.h>
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
 
 #define SKI_INIT_CONSOLE	20
Index: boot/arch/mips32/Makefile.inc
===================================================================
--- boot/arch/mips32/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/mips32/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,4 +30,5 @@
 BITS = 32
 EXTRA_CFLAGS = -msoft-float -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mabi=32
+AS_PROLOG = .module softfloat;
 
 ifeq ($(MACHINE),msim)
@@ -74,5 +75,6 @@
 	arch/$(BARCH)/src/main.c \
 	arch/$(BARCH)/src/putchar.c \
-	$(COMPS_C) \
+	$(COMPS).s \
+	$(COMPS)_desc.c \
 	genarch/src/division.c \
 	genarch/src/multiplication.c \
@@ -84,2 +86,4 @@
 	generic/src/version.c \
 	generic/src/inflate.c
+
+PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
Index: boot/arch/mips32/_link.ld.in
===================================================================
--- boot/arch/mips32/_link.ld.in	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/mips32/_link.ld.in	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -21,5 +21,5 @@
 		*(.bss);        /* uninitialized static variables */
 		*(COMMON);      /* global variables */
-[[COMPONENTS]]
+		*(.components);
 	}
 	
Index: boot/arch/mips32/include/types.h
===================================================================
--- boot/arch/mips32/include/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/mips32/include/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,4 +30,6 @@
 #define BOOT_mips32_TYPES_H_
 
+#include <arch/common.h>
+
 #define TASKMAP_MAX_RECORDS        32
 #define CPUMAP_MAX_RECORDS         32
Index: boot/arch/mips32/src/main.c
===================================================================
--- boot/arch/mips32/src/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/mips32/src/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,4 @@
 #include <arch/arch.h>
 #include <arch/asm.h>
-#include <arch/_components.h>
 #include <halt.h>
 #include <printf.h>
@@ -40,4 +39,5 @@
 #include <errno.h>
 #include <inflate.h>
+#include "../../components.h"
 
 #define TOP2ADDR(top)  (((void *) PA2KA(BOOT_OFFSET)) + (top))
@@ -64,8 +64,8 @@
 	size_t i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
-		    (uintptr_t) components[i].start >= PA2KSEG(0) ?
-		    (void *) KSEG2PA(components[i].start) :
-		    (void *) KA2PA(components[i].start),
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].addr,
+		    (uintptr_t) components[i].addr >= PA2KSEG(0) ?
+		    (void *) KSEG2PA(components[i].addr) :
+		    (void *) KA2PA(components[i].addr),
 		    components[i].name, components[i].inflated,
 		    components[i].size);
@@ -107,5 +107,5 @@
 		printf("%s ", components[i - 1].name);
 		
-		int err = inflate(components[i - 1].start, components[i - 1].size,
+		int err = inflate(components[i - 1].addr, components[i - 1].size,
 		    dest[i - 1], components[i - 1].inflated);
 		
Index: boot/arch/mips32/src/putchar.c
===================================================================
--- boot/arch/mips32/src/putchar.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/mips32/src/putchar.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,5 +27,6 @@
  */
 
-#include <typedefs.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <arch/arch.h>
 #include <putchar.h>
Index: boot/arch/ppc32/Makefile.inc
===================================================================
--- boot/arch/ppc32/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ppc32/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,4 +44,5 @@
 RD_DRVS_ESSENTIAL += \
 	platform/mac \
+	bus/adb/cuda_adb \
 	bus/pci/pciintel \
 	bus/usb/ohci \
@@ -57,5 +58,6 @@
 	arch/$(BARCH)/src/main.c \
 	arch/$(BARCH)/src/ofw.c \
-	$(COMPS_C) \
+	$(COMPS).s \
+	$(COMPS)_desc.c \
 	genarch/src/ofw.c \
 	genarch/src/ofw_tree.c \
@@ -70,2 +72,4 @@
 	generic/src/version.c \
 	generic/src/inflate.c
+
+PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
Index: boot/arch/ppc32/_link.ld.in
===================================================================
--- boot/arch/ppc32/_link.ld.in	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ppc32/_link.ld.in	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -18,5 +18,5 @@
 		*(.bss);        /* uninitialized static variables */
 		*(COMMON);      /* global variables */
-[[COMPONENTS]]
+		*(.components);
 	}
 	
Index: boot/arch/ppc32/include/asm.h
===================================================================
--- boot/arch/ppc32/include/asm.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ppc32/include/asm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #define BOOT_ppc32_ASM_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <arch/main.h>
 
Index: boot/arch/ppc32/include/main.h
===================================================================
--- boot/arch/ppc32/include/main.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ppc32/include/main.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #define BOOT_ppc32_MAIN_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <balloc.h>
 #include <genarch/ofw_tree.h>
Index: boot/arch/ppc32/include/types.h
===================================================================
--- boot/arch/ppc32/include/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ppc32/include/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,4 +30,6 @@
 #define BOOT_ppc32_TYPES_H_
 
+#include <arch/common.h>
+
 #define TASKMAP_MAX_RECORDS        32
 #define BOOTINFO_TASK_NAME_BUFLEN  32
Index: boot/arch/ppc32/src/main.c
===================================================================
--- boot/arch/ppc32/src/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ppc32/src/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,4 @@
 #include <arch/arch.h>
 #include <arch/asm.h>
-#include <arch/_components.h>
 #include <genarch/ofw.h>
 #include <genarch/ofw_tree.h>
@@ -42,4 +41,5 @@
 #include <errno.h>
 #include <inflate.h>
+#include "../../components.h"
 
 #define BALLOC_MAX_SIZE  131072
@@ -75,6 +75,6 @@
 	size_t i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
-		    ofw_translate(components[i].start), components[i].name,
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].addr,
+		    ofw_translate(components[i].addr), components[i].name,
 		    components[i].inflated, components[i].size);
 	
@@ -139,5 +139,5 @@
 		printf("%s ", components[i - 1].name);
 		
-		int err = inflate(components[i - 1].start, components[i - 1].size,
+		int err = inflate(components[i - 1].addr, components[i - 1].size,
 		    inflate_base + dest[i - 1], components[i - 1].inflated);
 		
Index: boot/arch/ppc32/src/ofw.c
===================================================================
--- boot/arch/ppc32/src/ofw.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/ppc32/src/ofw.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,5 +28,5 @@
 
 #include <genarch/ofw.h>
-#include <typedefs.h>
+#include <stddef.h>
 #include <putchar.h>
 #include <str.h>
Index: boot/arch/riscv64/Makefile.inc
===================================================================
--- boot/arch/riscv64/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 BITS = 64
 ENDIANESS = LE
+EXTRA_CFLAGS = -mcmodel=medany
 
 SOURCES = \
@@ -40,5 +41,6 @@
 	arch/$(BARCH)/src/ucb.c \
 	arch/$(BARCH)/src/putchar.c \
-	$(COMPS_C) \
+	$(COMPS).s \
+	$(COMPS)_desc.c \
 	generic/src/memstr.c \
 	generic/src/printf_core.c \
@@ -48,2 +50,4 @@
 	generic/src/version.c \
 	generic/src/inflate.c
+
+PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
Index: boot/arch/riscv64/_link.ld.in
===================================================================
--- boot/arch/riscv64/_link.ld.in	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/_link.ld.in	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,9 +1,27 @@
+#include <arch/arch.h>
+
 ENTRY(start)
 
 SECTIONS {
+	. = PHYSMEM_START;
+	
 	.text : {
 		*(BOOTSTRAP);
 		*(.text);
 	}
+	
+	. = ALIGN(0x1000);
+	.htif : {
+		htif_page = .;
+		*(.htif)
+	}
+	. = ALIGN(0x1000);
+	
+	. = ALIGN(0x1000);
+	.pt : {
+		pt_page = .;
+		*(.pt)
+	}
+	. = ALIGN(0x1000);
 	
 	.data : {
@@ -17,5 +35,5 @@
 		*(.bss);        /* uninitialized static variables */
 		*(COMMON);      /* global variables */
-[[COMPONENTS]]
+		*(.components);
 	}
 	
Index: boot/arch/riscv64/include/arch.h
===================================================================
--- boot/arch/riscv64/include/arch.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/include/arch.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,8 @@
 #define BOOT_STACK_SIZE  PAGE_SIZE
 
+#define PHYSMEM_START  0x40000000
+#define PHYSMEM_SIZE   1073741824
+#define BOOT_OFFSET    0x48000000
+
 #define DEFAULT_MTVEC      0x00000100
 #define TRAP_VECTOR_RESET  0x0100
Index: boot/arch/riscv64/include/asm.h
===================================================================
--- boot/arch/riscv64/include/asm.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/include/asm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,7 +30,10 @@
 #define BOOT_riscv64_ASM_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 
-extern void jump_to_kernel(void *, uintptr_t)
+extern char htif_page[];
+extern char pt_page[];
+
+extern void jump_to_kernel(uintptr_t)
     __attribute__((noreturn));
 
Index: boot/arch/riscv64/include/mm.h
===================================================================
--- boot/arch/riscv64/include/mm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ boot/arch/riscv64/include/mm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+/** @file
+ */
+
+#ifndef BOOT_riscv64_MM_H_
+#define BOOT_riscv64_MM_H_
+
+#ifndef __ASM__
+	#define KA2PA(x)  (((uintptr_t) (x)) - UINT64_C(0xffff800000000000))
+	#define PA2KA(x)  (((uintptr_t) (x)) + UINT64_C(0xffff800000000000))
+#else
+	#define KA2PA(x)  ((x) - 0xffff800000000000)
+	#define PA2KA(x)  ((x) + 0xffff800000000000)
+#endif
+
+#define PTL_DIRTY       (1 << 7)
+#define PTL_ACCESSED    (1 << 6)
+#define PTL_GLOBAL      (1 << 5)
+#define PTL_USER        (1 << 4)
+#define PTL_EXECUTABLE  (1 << 3)
+#define PTL_WRITABLE    (1 << 2)
+#define PTL_READABLE    (1 << 1)
+#define PTL_VALID       1
+
+#endif
+
+/** @}
+ */
Index: boot/arch/riscv64/include/types.h
===================================================================
--- boot/arch/riscv64/include/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/include/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,4 +30,6 @@
 #define BOOT_riscv64_TYPES_H_
 
+#include <arch/common.h>
+
 #define MEMMAP_MAX_RECORDS         32
 #define TASKMAP_MAX_RECORDS        32
@@ -38,4 +40,9 @@
 
 typedef int64_t ptrdiff_t;
+
+typedef struct {
+	volatile uint64_t *tohost;
+	volatile uint64_t *fromhost;
+} ucbinfo_t;
 
 typedef struct {
@@ -65,4 +72,8 @@
 
 typedef struct {
+	ucbinfo_t ucbinfo;
+	uintptr_t physmem_start;
+	uintptr_t htif_frame;
+	uintptr_t pt_frame;
 	memmap_t memmap;
 	taskmap_t taskmap;
Index: boot/arch/riscv64/include/ucb.h
===================================================================
--- boot/arch/riscv64/include/ucb.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/include/ucb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,8 +36,8 @@
  */
 
-#include <typedefs.h>
+#include <stddef.h>
 
-#define CSR_MTOHOST    0x780
-#define CSR_MFROMHOST  0x781
+extern volatile uint64_t tohost;
+extern volatile uint64_t fromhost;
 
 #define HTIF_DEVICE_CONSOLE  1
Index: boot/arch/riscv64/src/asm.S
===================================================================
--- boot/arch/riscv64/src/asm.S	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/src/asm.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -29,4 +29,23 @@
 #include <abi/asmtool.h>
 #include <arch/arch.h>
+#include <arch/mm.h>
+
+#define MCOUNTEREN_CY_MASK  0x00000001
+#define MCOUNTEREN_TM_MASK  0x00000002
+#define MCOUNTEREN_IR_MASK  0x00000004
+
+#define MSTATUS_MPP_MASK        0x00001800
+#define MSTATUS_MPP_USER        0x00000000
+#define MSTATUS_MPP_SUPERVISOR  0x00000800
+#define MSTATUS_MPP_MACHINE     0x00001800
+
+#define MSTATUS_SUM_MASK        0x00040000
+
+#define SATP_PFN_MASK  0x00000fffffffffff
+
+#define SATP_MODE_MASK  0xf000000000000000
+#define SATP_MODE_BARE  0x0000000000000000
+#define SATP_MODE_SV39  0x8000000000000000
+#define SATP_MODE_SV48  0x9000000000000000
 
 .section BOOTSTRAP
@@ -76,5 +95,38 @@
 
 FUNCTION_BEGIN(jump_to_kernel)
-	j halt
+	/* Enable performance counters access in supervisor mode */
+	csrsi mcounteren, MCOUNTEREN_CY_MASK | MCOUNTEREN_TM_MASK | MCOUNTEREN_IR_MASK
+	
+	/* Setup SV48 paging for supervisor mode */
+	la t0, ptl_0
+	srli t0, t0, 12
+	
+	li t1, SATP_PFN_MASK
+	and t0, t0, t1
+	
+	li t1, SATP_MODE_SV48
+	or t0, t0, t1
+	
+	csrw sptbr, t0
+	
+	/* Jump to supervisor mode */
+	csrr t0, mstatus
+	
+	li t1, ~MSTATUS_MPP_MASK
+	and t0, t0, t1
+	
+	/*
+	 * TODO: Enable running with Supervisor User Mode
+	 * access disabled.
+	 */
+	li t1, MSTATUS_MPP_SUPERVISOR | MSTATUS_SUM_MASK
+	or t0, t0, t1
+	
+	csrw mstatus, t0
+	
+	li ra, PA2KA(BOOT_OFFSET)
+	csrw mepc, ra
+	
+	mret
 FUNCTION_END(jump_to_kernel)
 
@@ -88,2 +140,11 @@
 SYMBOL(boot_stack)
 	.space BOOT_STACK_SIZE
+
+.section .pt, "aw", @progbits
+
+.align PAGE_WIDTH
+SYMBOL(ptl_0)
+	.fill 256, 8, 0
+	/* Identity mapping for [0; 512G) */
+	.quad 0 + (PTL_DIRTY | PTL_ACCESSED | PTL_EXECUTABLE | PTL_WRITABLE | PTL_READABLE | PTL_VALID)
+	.fill 255, 8, 0
Index: boot/arch/riscv64/src/main.c
===================================================================
--- boot/arch/riscv64/src/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/src/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,6 +30,8 @@
 #include <arch/arch.h>
 #include <arch/asm.h>
+#include <arch/ucb.h>
+#include <arch/mm.h>
 #include <version.h>
-#include <typedefs.h>
+#include <stddef.h>
 #include <printf.h>
 #include <macros.h>
@@ -39,8 +41,5 @@
 #include <halt.h>
 #include <inflate.h>
-#include <arch/_components.h>
-
-#define KA2PA(x)  (((uintptr_t) (x)) - UINT64_C(0xffff800000000000))
-#define PA2KA(x)  (((uintptr_t) (x)) + UINT64_C(0xffff800000000000))
+#include "../../components.h"
 
 static bootinfo_t bootinfo;
@@ -50,25 +49,39 @@
 	version_print();
 	
+	bootinfo.htif_frame = ((uintptr_t) &htif_page) >> PAGE_WIDTH;
+	bootinfo.pt_frame = ((uintptr_t) &pt_page) >> PAGE_WIDTH;
+	
+	bootinfo.ucbinfo.tohost =
+	    (volatile uint64_t *) PA2KA((uintptr_t) &tohost);
+	bootinfo.ucbinfo.fromhost =
+	    (volatile uint64_t *) PA2KA((uintptr_t) &fromhost);
+	
 	// FIXME TODO: read from device tree
-	bootinfo.memmap.total = 1024 * 1024 * 1024;
-	bootinfo.memmap.cnt = 0;
+	bootinfo.physmem_start = PHYSMEM_START;
+	bootinfo.memmap.total = PHYSMEM_SIZE;
+	bootinfo.memmap.cnt = 1;
+	bootinfo.memmap.zones[0].start = (void *) PHYSMEM_START;
+	bootinfo.memmap.zones[0].size = PHYSMEM_SIZE;
 	
-	printf("\nMemory statistics (total %lu MB)\n\n", bootinfo.memmap.total >> 20);
+	printf("\nMemory statistics (total %lu MB, starting at %p)\n\n",
+	    bootinfo.memmap.total >> 20, (void *) bootinfo.physmem_start);
 	printf(" %p: boot info structure\n", &bootinfo);
 	
-	uintptr_t top = 0;
+	uintptr_t top = BOOT_OFFSET;
 	
 	for (size_t i = 0; i < COMPONENTS; i++) {
-		printf(" %p: %s image (%zu/%zu bytes)\n", components[i].start,
+		printf(" %p: %s image (%zu/%zu bytes)\n", components[i].addr,
 		    components[i].name, components[i].inflated,
 		    components[i].size);
 		
-		uintptr_t tail = (uintptr_t) components[i].start +
+		uintptr_t tail = (uintptr_t) components[i].addr +
 		    components[i].size;
-		if (tail > top)
-			top = tail;
+		if (tail > top) {
+			printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
+			    components[i].name, (void *) tail, (void *) top);
+			halt();
+		}
 	}
 	
-	top = ALIGN_UP(top, PAGE_SIZE);
 	printf(" %p: inflate area\n", (void *) top);
 	
@@ -92,5 +105,5 @@
 			bootinfo.taskmap.cnt++;
 		} else
-			kernel_entry = (void *) top;
+			kernel_entry = (void *) PA2KA(top);
 		
 		dest[i] = (void *) top;
@@ -101,5 +114,5 @@
 	printf(" %p: kernel entry point\n", kernel_entry);
 	
-	if (top >= bootinfo.memmap.total) {
+	if (top >= bootinfo.physmem_start + bootinfo.memmap.total) {
 		printf("Not enough physical memory available.\n");
 		printf("The boot image is too large. Halting.\n");
@@ -112,5 +125,5 @@
 		printf("%s ", components[i - 1].name);
 		
-		int err = inflate(components[i - 1].start, components[i - 1].size,
+		int err = inflate(components[i - 1].addr, components[i - 1].size,
 		    dest[i - 1], components[i - 1].inflated);
 		
@@ -125,4 +138,4 @@
 	
 	printf("Booting the kernel...\n");
-	jump_to_kernel(kernel_entry, PA2KA(&bootinfo));
+	jump_to_kernel(PA2KA(&bootinfo));
 }
Index: boot/arch/riscv64/src/putchar.c
===================================================================
--- boot/arch/riscv64/src/putchar.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/src/putchar.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,5 +27,5 @@
  */
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <arch/arch.h>
 #include <putchar.h>
Index: boot/arch/riscv64/src/ucb.c
===================================================================
--- boot/arch/riscv64/src/ucb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/riscv64/src/ucb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,4 +31,16 @@
 #include <macros.h>
 
+volatile uint64_t tohost __attribute__((section(".htif")));
+volatile uint64_t fromhost __attribute__((section(".htif")));
+
+static void poll_fromhost()
+{
+	uint64_t val = fromhost;
+	if (!val)
+		return;
+	
+	fromhost = 0;
+}
+
 void htif_cmd(uint8_t device, uint8_t cmd, uint64_t payload)
 {
@@ -36,12 +48,8 @@
 	    (((uint64_t) cmd) << 48) |
 	    (payload & UINT64_C(0xffffffffffff));
-	uint64_t retval;
 	
-	do {
-		asm volatile (
-			"csrrw %[retval], " STRING(CSR_MTOHOST) ", %[val]\n"
-			: [retval] "=r" (retval)
-			: [val] "r" (val)
-		);
-	} while (retval != 0);
+	while (tohost)
+		poll_fromhost();
+	
+	tohost = val;
 }
Index: boot/arch/sparc64/Makefile.inc
===================================================================
--- boot/arch/sparc64/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/sparc64/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -57,5 +57,6 @@
 	arch/$(BARCH)/src/main.c \
 	arch/$(BARCH)/src/ofw.c \
-	$(COMPS_C) \
+	$(COMPS).s \
+	$(COMPS)_desc.c \
 	genarch/src/ofw.c \
 	genarch/src/ofw_tree.c \
@@ -68,2 +69,4 @@
 	generic/src/version.c \
 	generic/src/inflate.c
+
+PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
Index: boot/arch/sparc64/_link.ld.in
===================================================================
--- boot/arch/sparc64/_link.ld.in	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/sparc64/_link.ld.in	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -15,5 +15,5 @@
 		*(.bss);        /* uninitialized static variables */
 		*(COMMON);      /* global variables */
-[[COMPONENTS]]
+		*(.components);
 	}
 	
Index: boot/arch/sparc64/include/asm.h
===================================================================
--- boot/arch/sparc64/include/asm.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/sparc64/include/asm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,5 @@
 #define BOOT_sparc64_ASM_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 extern void jump_to_kernel(uintptr_t physmem_start, bootinfo_t *bootinfo,
Index: boot/arch/sparc64/include/main.h
===================================================================
--- boot/arch/sparc64/include/main.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/sparc64/include/main.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #define BOOT_sparc64_MAIN_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <balloc.h>
 #include <genarch/ofw_tree.h>
Index: boot/arch/sparc64/include/ofw.h
===================================================================
--- boot/arch/sparc64/include/ofw.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/sparc64/include/ofw.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #define BOOT_sparc64_OFW_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #define OFW_ADDRESS_CELLS  2
Index: boot/arch/sparc64/include/types.h
===================================================================
--- boot/arch/sparc64/include/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/sparc64/include/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,4 +30,6 @@
 #define BOOT_sparc64_TYPES_H_
 
+#include <arch/common.h>
+
 #define TASKMAP_MAX_RECORDS        32
 #define BOOTINFO_TASK_NAME_BUFLEN  32
Index: boot/arch/sparc64/src/main.c
===================================================================
--- boot/arch/sparc64/src/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/sparc64/src/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -32,5 +32,4 @@
 #include <arch/asm.h>
 #include <arch/ofw.h>
-#include <arch/_components.h>
 #include <genarch/ofw.h>
 #include <genarch/ofw_tree.h>
@@ -44,4 +43,5 @@
 #include <errno.h>
 #include <inflate.h>
+#include "../../components.h"
 
 /* The lowest ID (read from the VER register) of some US3 CPU model */
@@ -220,6 +220,6 @@
 	size_t i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
-		    ofw_translate(components[i].start), components[i].name,
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].addr,
+		    ofw_translate(components[i].addr), components[i].name,
 		    components[i].inflated, components[i].size);
 	
@@ -267,5 +267,5 @@
 		    ALIGN_UP(components[i - 1].inflated, PAGE_SIZE), -1);
 		
-		int err = inflate(components[i - 1].start, components[i - 1].size,
+		int err = inflate(components[i - 1].addr, components[i - 1].size,
 		    dest[i - 1], components[i - 1].inflated);
 		
Index: boot/arch/sparc64/src/ofw.c
===================================================================
--- boot/arch/sparc64/src/ofw.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/arch/sparc64/src/ofw.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,6 @@
 #include <arch/ofw.h>
 #include <genarch/ofw.h>
-#include <typedefs.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <printf.h>
 #include <halt.h>
Index: boot/genarch/include/ofw.h
===================================================================
--- boot/genarch/include/ofw.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/genarch/include/ofw.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #define BOOT_OFW_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <stdarg.h>
 
Index: boot/genarch/include/ofw_tree.h
===================================================================
--- boot/genarch/include/ofw_tree.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/genarch/include/ofw_tree.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #define BOOT_OFW_TREE_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <genarch/ofw.h>
 
Index: boot/genarch/src/efi.c
===================================================================
--- boot/genarch/src/efi.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/genarch/src/efi.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -29,5 +29,5 @@
 #include <genarch/efi.h>
 #include <arch/types.h>
-#include <typedefs.h>
+#include <stddef.h>
 
 void *efi_vendor_table_find(efi_system_table_t *st, efi_guid_t guid)
Index: boot/genarch/src/multiplication.c
===================================================================
--- boot/genarch/src/multiplication.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/genarch/src/multiplication.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
 
 #include <genarch/multiplication.h>
-#include <typedefs.h>
+#include <stdint.h>
 
 /** Set 1 to return INT64_MAX or INT64_MIN on overflow */
Index: boot/genarch/src/ofw.c
===================================================================
--- boot/genarch/src/ofw.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/genarch/src/ofw.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,5 @@
 #include <genarch/ofw.h>
 #include <printf.h>
-#include <typedefs.h>
+#include <stddef.h>
 #include <str.h>
 #include <align.h>
Index: boot/genarch/src/ofw_tree.c
===================================================================
--- boot/genarch/src/ofw_tree.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/genarch/src/ofw_tree.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #include <genarch/ofw.h>
 #include <arch/ofw.h>
-#include <typedefs.h>
+#include <stddef.h>
 #include <str.h>
 #include <balloc.h>
Index: boot/generic/include/balloc.h
===================================================================
--- boot/generic/include/balloc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/balloc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #define BOOT_BALLOC_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 
 typedef struct {
Index: boot/generic/include/errno.h
===================================================================
--- boot/generic/include/errno.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/errno.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,5 @@
 
 #ifndef BOOT_ERRNO_H_
-#define BOTT_ERRNO_H_
+#define BOOT_ERRNO_H_
 
 #define EOK        0    /* No error. */
Index: boot/generic/include/inflate.h
===================================================================
--- boot/generic/include/inflate.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/inflate.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
 #define BOOT_INFLATE_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 
 extern int inflate(void *, size_t, void *, size_t);
Index: boot/generic/include/memstr.h
===================================================================
--- boot/generic/include/memstr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/memstr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
 #define BOOT_MEMSTR_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 
 extern void *memcpy(void *, const void *, size_t)
Index: boot/generic/include/printf.h
===================================================================
--- boot/generic/include/printf.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/printf.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
 #define BOOT_PRINT_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <stdarg.h>
 #include <printf_verify.h>
Index: boot/generic/include/printf_core.h
===================================================================
--- boot/generic/include/printf_core.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/printf_core.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
 #define BOOT_PRINTF_CORE_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <stdarg.h>
 
Index: boot/generic/include/putchar.h
===================================================================
--- boot/generic/include/putchar.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/putchar.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define BOOT_PUTCHAR_H_
 
+#include <stddef.h>
+
 extern void putchar(const wchar_t);
 
Index: boot/generic/include/stdbool.h
===================================================================
--- boot/generic/include/stdbool.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ boot/generic/include/stdbool.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ */
+
+#ifndef BOOT_STDBOOL_H_
+#define BOOT_STDBOOL_H_
+
+#define false  0
+#define true   1
+
+#define bool _Bool
+
+#endif
+
+/** @}
+ */
Index: boot/generic/include/stddef.h
===================================================================
--- boot/generic/include/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ boot/generic/include/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ */
+
+#ifndef BOOT_STDDEF_H_
+#define BOOT_STDDEF_H_
+
+#include <arch/common.h>
+#include <arch/types.h>
+
+#define NULL  ((void *) 0)
+
+#endif
+
+/** @}
+ */
Index: boot/generic/include/stdint.h
===================================================================
--- boot/generic/include/stdint.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/stdint.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,4 +33,7 @@
 #define BOOT_STDINT_H_
 
+#include <arch/common.h>
+#include <arch/types.h>
+
 #define INT8_MIN  INT8_C(0x80)
 #define INT8_MAX  INT8_C(0x7F)
Index: boot/generic/include/str.h
===================================================================
--- boot/generic/include/str.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/include/str.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,6 @@
 #define BOOT_STR_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
 
 /**< Common Unicode characters */
Index: ot/generic/include/typedefs.h
===================================================================
--- boot/generic/include/typedefs.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2006 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @file
- */
-
-#ifndef BOOT_TYPEDEFS_H_
-#define BOOT_TYPEDEFS_H_
-
-#include <stdint.h>
-#include <arch/common.h>
-#include <arch/types.h>
-
-#define NULL  ((void *) 0)
-
-#define false  0
-#define true   1
-
-typedef uint8_t bool;
-
-#endif
-
-/** @}
- */
Index: boot/generic/src/balloc.c
===================================================================
--- boot/generic/src/balloc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/src/balloc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,5 +28,5 @@
 
 #include <balloc.h>
-#include <typedefs.h>
+#include <stddef.h>
 #include <align.h>
 
Index: boot/generic/src/inflate.c
===================================================================
--- boot/generic/src/inflate.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/src/inflate.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -65,5 +65,6 @@
  */
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
 #include <errno.h>
 #include <memstr.h>
Index: boot/generic/src/memstr.c
===================================================================
--- boot/generic/src/memstr.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/src/memstr.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,5 +28,5 @@
 
 #include <memstr.h>
-#include <typedefs.h>
+#include <stddef.h>
 
 /** Move memory block without overlapping.
Index: boot/generic/src/printf_core.c
===================================================================
--- boot/generic/src/printf_core.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/src/printf_core.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,6 @@
 #include <printf.h>
 #include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
 #include <macros.h>
 #include <str.h>
Index: boot/generic/src/str.c
===================================================================
--- boot/generic/src/str.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/src/str.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -98,6 +98,8 @@
  */
 
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
 #include <str.h>
-#include <errno.h>
 
 /** Check the condition if wchar_t is signed */
Index: boot/generic/src/vprintf.c
===================================================================
--- boot/generic/src/vprintf.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ boot/generic/src/vprintf.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,5 @@
  */
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <printf.h>
 #include <printf_core.h>
Index: contrib/qemu/build-from-scratch.sh
===================================================================
--- contrib/qemu/build-from-scratch.sh	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ contrib/qemu/build-from-scratch.sh	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -29,5 +29,5 @@
 #
 
-VERSION=2.9.0
+VERSION=2.10.0
 BASENAME=qemu-${VERSION}
 BASENAME_MASTER=qemu-master
@@ -36,5 +36,5 @@
 URL=http://wiki.qemu-project.org/download/${TARBALL}
 REPO=git://git.qemu.org/qemu.git
-MD5="02781eb15b364aedef79da7a5113f5b7"
+MD5="ca73441de73a9b52c6c49c97190d2185"
 
 OPENSPARC_TARBALL="OpenSPARCT1_Arch.1.5.tar.bz2"
Index: contrib/tools/random_check.sh
===================================================================
--- contrib/tools/random_check.sh	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ contrib/tools/random_check.sh	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -52,5 +52,4 @@
 		echo "COMPILER=gcc_native" >>"$PRUNE_CONFIG_FILE"
 		echo "COMPILER=gcc_helenos" >>"$PRUNE_CONFIG_FILE"
-		echo "COMPILER=icc" >>"$PRUNE_CONFIG_FILE"
 		;;
 	*|h)
Index: defaults/amd64/Makefile.config
===================================================================
--- defaults/amd64/Makefile.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ defaults/amd64/Makefile.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -10,4 +10,7 @@
 # Compiler
 COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
 
 # Debug build
@@ -65,4 +68,7 @@
 CONFIG_BFB_BPP = 16
 
+# Include development files (headers, libraries)
+CONFIG_DEVEL_FILES = y
+
 # OHCI root hub power switch, ganged is enough
 OHCI_POWER_SWITCH = ganged
@@ -70,2 +76,5 @@
 # GRUB boot loader architecture
 GRUB_ARCH = pc
+
+# Optimization level
+OPTIMIZATION = 3
Index: defaults/arm32/Makefile.config
===================================================================
--- defaults/arm32/Makefile.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ defaults/arm32/Makefile.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -7,4 +7,7 @@
 # Compiler
 COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
 
 # Debug build
@@ -37,2 +40,5 @@
 # What is your output device?
 CONFIG_HID_OUT = generic
+
+# Optimization level
+OPTIMIZATION = 3
Index: defaults/ia32/Makefile.config
===================================================================
--- defaults/ia32/Makefile.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ defaults/ia32/Makefile.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -10,4 +10,7 @@
 # Compiler
 COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
 
 # Debug build
@@ -77,4 +80,7 @@
 CONFIG_USE_SHARED_LIBS = y
 
+# Include development files (headers, libraries)
+CONFIG_DEVEL_FILES = y
+
 # OHCI root hub power switch, ganged is enough
 OHCI_POWER_SWITCH = ganged
@@ -82,2 +88,5 @@
 # GRUB boot loader architecture
 GRUB_ARCH = pc
+
+# Optimization level
+OPTIMIZATION = 3
Index: defaults/ia64/Makefile.config
===================================================================
--- defaults/ia64/Makefile.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ defaults/ia64/Makefile.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -7,4 +7,7 @@
 # Compiler
 COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
 
 # Debug build
@@ -49,2 +52,5 @@
 # Output device class
 CONFIG_HID_OUT = generic
+
+# Optimization level
+OPTIMIZATION = 3
Index: defaults/mips32/Makefile.config
===================================================================
--- defaults/mips32/Makefile.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ defaults/mips32/Makefile.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -7,4 +7,7 @@
 # Compiler
 COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
 
 # Debug build
@@ -46,2 +49,5 @@
 # Barebone build with essential binaries only
 CONFIG_BAREBONE = y
+
+# Optimization level
+OPTIMIZATION = 3
Index: defaults/ppc32/Makefile.config
===================================================================
--- defaults/ppc32/Makefile.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ defaults/ppc32/Makefile.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -7,4 +7,7 @@
 # Compiler
 COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
 
 # Lazy FPU context switching
@@ -46,2 +49,5 @@
 # OHCI root hub power switch, ganged is enough
 OHCI_POWER_SWITCH = ganged
+
+# Optimization level
+OPTIMIZATION = 3
Index: defaults/sparc64/Makefile.config
===================================================================
--- defaults/sparc64/Makefile.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ defaults/sparc64/Makefile.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -7,4 +7,7 @@
 # Compiler
 COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
 
 # Support for SMP
@@ -55,2 +58,5 @@
 # Start AP processors by the loader
 CONFIG_AP = y
+
+# Optimization level
+OPTIMIZATION = 3
Index: defaults/special/Makefile.config
===================================================================
--- defaults/special/Makefile.config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ defaults/special/Makefile.config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -4,4 +4,7 @@
 # Compiler
 COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
 
 # Support for SMP
@@ -32,2 +35,4 @@
 RCU = PREEMPT_A
 
+# Optimization level
+OPTIMIZATION = 3
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -82,45 +82,29 @@
 INCLUDES_FLAGS = $(addprefix -I,$(INCLUDES))
 
-ifeq ($(CONFIG_OPTIMIZE_FOR_SIZE),y)
-	OPTIMIZATION = s
-else
-	OPTIMIZATION = 3
-endif
-
 DEFS = -DKERNEL -DRELEASE=$(RELEASE) "-DCOPYRIGHT=$(COPYRIGHT)" "-DNAME=$(NAME)" -D__$(BITS)_BITS__ -D__$(ENDIANESS)__
 
-GCC_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-std=gnu99 -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -Wwrite-strings \
-	-pipe
-
-ICC_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
-	-ffreestanding -fno-builtin -nostdlib -nostdinc -Wall -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -wd170
-
-# clang does not support following options but I am not sure whether
-# something won't break because of that:
-# -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) -finput-charset=UTF-8
-CLANG_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
+COMMON_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
 	-ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-std=gnu99 -Wall -Werror -Wextra -Wno-unused-parameter -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -Wwrite-strings \
-	-integrated-as -pipe -target $(CLANG_TARGET)
+	-fexec-charset=UTF-8 -finput-charset=UTF-8
+
+GCC_CFLAGS = -std=gnu99 -Wall -Wextra -Wno-unused-parameter \
+	-Wmissing-prototypes -Werror-implicit-function-declaration \
+	-Wwrite-strings -pipe
+
+CLANG_CFLAGS = -std=gnu99 -Wall -Wextra -Wno-unused-parameter \
+	-Wno-missing-field-initializers -Wno-unused-command-line-argument \
+	-Wmissing-prototypes -Werror-implicit-function-declaration \
+	-Wwrite-strings -pipe -fno-stack-protector -fno-PIC
 
 ifeq ($(CONFIG_DEBUG),y)
-	GCC_CFLAGS += -Werror
-	ICC_CFLAGS += -Werror
+	COMMON_CFLAGS += -Werror
 endif
 
 ifeq ($(CONFIG_LTO),y)
-	GCC_CFLAGS += -flto
+	COMMON_CFLAGS += -flto
 endif
 
 ifeq ($(CONFIG_LINE_DEBUG),y)
-	GCC_CFLAGS += -g
-	ICC_CFLAGS += -g
-	CLANG_CFLAGS += -g
+	COMMON_CFLAGS += -g
 endif
 
@@ -129,6 +113,13 @@
 # AFLAGS and LFLAGS must be initialized before the inclusion.
 #
-AFLAGS = --fatal-warnings
+AFLAGS =
 LFLAGS = -n -T $(LINK) -M --fatal-warnings
+
+# FIXME: This condition is a workaround for issues #693 and #694.
+ifneq ($(KARCH),sparc64)
+ifneq ($(KARCH),mips32)
+	AFLAGS += --fatal-warnings
+endif
+endif
 
 #
@@ -162,5 +153,5 @@
 
 ifeq ($(COMPILER),gcc_native)
-	CFLAGS = $(GCC_CFLAGS)
+	CFLAGS = $(COMMON_CFLAGS) $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 	INSTRUMENTATION = -finstrument-functions
@@ -168,5 +159,5 @@
 
 ifeq ($(COMPILER),gcc_cross)
-	CFLAGS = $(GCC_CFLAGS)
+	CFLAGS = $(COMMON_CFLAGS) $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 	INSTRUMENTATION = -finstrument-functions
@@ -174,19 +165,13 @@
 
 ifeq ($(COMPILER),gcc_helenos)
-	CFLAGS = $(GCC_CFLAGS)
+	CFLAGS = $(COMMON_CFLAGS) $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 	INSTRUMENTATION = -finstrument-functions
 endif
 
-ifeq ($(COMPILER),icc)
-	CFLAGS = $(ICC_CFLAGS)
+ifeq ($(COMPILER),clang)
+	CFLAGS = $(COMMON_CFLAGS) $(CLANG_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-	INSTRUMENTATION =
-endif
-
-ifeq ($(COMPILER),clang)
-	CFLAGS = $(CLANG_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-	INSTRUMENTATION =
+	INSTRUMENTATION = -finstrument-functions
 endif
 
@@ -209,5 +194,4 @@
 	generic/src/ddi/ddi.c \
 	generic/src/ddi/irq.c \
-	generic/src/ddi/device.c \
 	generic/src/debug/symtab.c \
 	generic/src/debug/stacktrace.c \
@@ -240,7 +224,7 @@
 	generic/src/mm/slab.c \
 	generic/src/lib/func.c \
-	generic/src/lib/memstr.c \
+	generic/src/lib/mem.c \
 	generic/src/lib/memfnc.c \
-	generic/src/lib/sort.c \
+	generic/src/lib/gsort.c \
 	generic/src/lib/str.c \
 	generic/src/lib/elf.c \
@@ -272,8 +256,6 @@
 	generic/src/ipc/sysipc.c \
 	generic/src/ipc/sysipc_ops.c \
-	generic/src/ipc/ops/clnestab.c \
 	generic/src/ipc/ops/conctmeto.c \
 	generic/src/ipc/ops/concttome.c \
-	generic/src/ipc/ops/connclone.c \
 	generic/src/ipc/ops/dataread.c \
 	generic/src/ipc/ops/datawrite.c \
@@ -286,5 +268,6 @@
 	generic/src/ipc/irq.c \
 	generic/src/ipc/event.c \
-	generic/src/security/cap.c \
+	generic/src/cap/cap.c \
+	generic/src/security/perm.c \
 	generic/src/sysinfo/sysinfo.c \
 	generic/src/sysinfo/stats.c
@@ -392,5 +375,10 @@
 AUTOGENS_AG := $(ARCH_AUTOGENS_AG) $(GENARCH_AUTOGENS_AG)
 
-LFLAGS_LTO := $(addprefix -Xlinker ,$(LFLAGS))
+AS_CFLAGS := $(addprefix -Xassembler ,$(AFLAGS))
+LD_CFLAGS := $(addprefix -Xlinker ,$(LFLAGS))
+
+ifeq ($(COMPILER),clang)
+	AS_CFLAGS += -mllvm -asm-macro-max-nesting-depth=1000
+endif
 
 ifeq ($(CONFIG_SYMTAB),y)
@@ -412,5 +400,5 @@
 $(RAW): $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(SYMTAB_OBJECTS)
 ifeq ($(CONFIG_LTO),y)
-	$(GCC) $(LFLAGS_LTO) -Xlinker -Map -Xlinker $(MAP) $(DEFS) $(GCC_CFLAGS) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS)
+	$(CC) $(DEFS) $(CFLAGS) $(LD_CFLAGS) -Xlinker -Map -Xlinker $(MAP) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS)
 else
 	$(LD) $(LFLAGS) -Map $(MAP) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS)
@@ -425,15 +413,15 @@
 %.h: %.ag
 	$(AUTOGEN) probe $< >$<.probe.c
-	$(CC) $(DEFS) $(CFLAGS) -S -o $<.probe.s $<.probe.c
+	$(CC_AUTOGEN) $(DEFS) $(CFLAGS) -S -o $<.probe.s $<.probe.c
 	$(AUTOGEN) generate $< <$<.probe.s >$@   
 
 %.o: %.S $(DEPEND)
-	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -c -o $@ $<
+	$(CC) $(DEFS) $(CFLAGS) $(AS_CFLAGS) -D__ASM__ -c -o $@ $<
 ifeq ($(PRECHECK),y)
-	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(GCC_CFLAGS) -D__ASM__
+	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(CFLAGS) -D__ASM__
 endif
 
 %.o: %.s $(DEPEND)
-	$(AS) $(AFLAGS) -o $@ $<
+	$(CC) $(DEFS) $(CFLAGS) $(AS_CFLAGS) -D__ASM__ -c -o $@ $<
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm $(DEFS) $(CFLAGS) $(EXTRA_FLAGS)
@@ -447,10 +435,10 @@
 
 $(REAL_MAP).o: $(REAL_MAP).bin
-	echo "$(AS_PROLOG)""$(SYMTAB_SECTION)"" .incbin \"$<\"" | $(AS) $(AFLAGS) -o $@
+	echo "$(AS_PROLOG)""$(SYMTAB_SECTION)"" .incbin \"$<\"" | $(CC) $(CFLAGS) $(AS_CFLAGS) -x assembler -c -o $@ -
 
 $(REAL_MAP).bin: $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
-	echo "$(AS_PROLOG)""$(SYMTAB_SECTION)" | $(AS) $(AFLAGS) -o $(EMPTY_MAP)
+	echo "$(AS_PROLOG)""$(SYMTAB_SECTION)" | $(CC) $(CFLAGS) $(AS_CFLAGS) -x assembler -c -o $(EMPTY_MAP) -
 ifeq ($(CONFIG_LTO),y)
-	$(GCC) $(LFLAGS_LTO) -Xlinker -Map -Xlinker $(MAP_PREV) $(DEFS) $(GCC_CFLAGS) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(EMPTY_MAP)
+	$(CC) $(DEFS) $(CFLAGS) $(LD_CFLAGS) -Xlinker -Map -Xlinker $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(EMPTY_MAP)
 else
 	$(LD) $(LFLAGS) -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(EMPTY_MAP)
@@ -462,7 +450,7 @@
 	# on architectures that have bss after symtab
 	
-	echo "$(AS_PROLOG)""$(SYMTAB_SECTION)"" .incbin \"$@\"" | $(AS) $(AFLAGS) -o $(SIZEOK_MAP)
+	echo "$(AS_PROLOG)""$(SYMTAB_SECTION)"" .incbin \"$@\"" | $(CC) $(CFLAGS) $(AS_CFLAGS) -x assembler -c -o $(SIZEOK_MAP) -
 ifeq ($(CONFIG_LTO),y)
-	$(GCC) $(LFLAGS_LTO) -Xlinker -Map -Xlinker $(MAP_PREV) $(DEFS) $(GCC_CFLAGS) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SIZEOK_MAP)
+	$(CC) $(DEFS) $(CFLAGS) $(LD_CFLAGS) -Xlinker -Map -Xlinker $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SIZEOK_MAP)
 else
 	$(LD) $(LFLAGS) -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SIZEOK_MAP)
Index: kernel/arch/abs32le/Makefile.inc
===================================================================
--- kernel/arch/abs32le/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,5 +35,5 @@
 	
 	ifeq ($(CROSS_TARGET),mips32)
-		GCC_CFLAGS += -mno-abicalls
+		COMMON_CFLAGS += -mno-abicalls
 	endif
 endif
Index: kernel/arch/abs32le/include/arch/fpu_context.h
===================================================================
--- kernel/arch/abs32le/include/arch/fpu_context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/fpu_context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,4 @@
 #define KERN_abs32le_FPU_CONTEXT_H_
 
-#include <typedefs.h>
-
 #define FPU_CONTEXT_ALIGN  16
 
Index: kernel/arch/abs32le/include/arch/interrupt.h
===================================================================
--- kernel/arch/abs32le/include/arch/interrupt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/interrupt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_abs32le_INTERRUPT_H_
 
-#include <typedefs.h>
 #include <arch/istate.h>
 
Index: kernel/arch/abs32le/include/arch/istate.h
===================================================================
--- kernel/arch/abs32le/include/arch/istate.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/istate.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,7 +40,10 @@
 #ifdef KERNEL
 
+#include <typedefs.h>
 #include <verify.h>
 
 #else /* KERNEL */
+
+#include <stdint.h>
 
 #define REQUIRES_EXTENT_MUTABLE(arg)
Index: kernel/arch/abs32le/include/arch/mm/asid.h
===================================================================
--- kernel/arch/abs32le/include/arch/mm/asid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/mm/asid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 #define KERN_abs32le_ASID_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 typedef uint32_t asid_t;
Index: kernel/arch/abs32le/include/arch/mm/frame.h
===================================================================
--- kernel/arch/abs32le/include/arch/mm/frame.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/mm/frame.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,6 +41,4 @@
 #define FRAME_LOWPRIO  0
 
-#include <typedefs.h>
-
 extern void frame_low_arch_init(void);
 extern void frame_high_arch_init(void);
Index: kernel/arch/abs32le/include/arch/mm/km.h
===================================================================
--- kernel/arch/abs32le/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_abs32le_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/abs32le/include/arch/mm/page.h
===================================================================
--- kernel/arch/abs32le/include/arch/mm/page.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/mm/page.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
 
 #include <arch/mm/frame.h>
+#include <stdbool.h>
 #include <trace.h>
 
Index: kernel/arch/abs32le/include/arch/proc/task.h
===================================================================
--- kernel/arch/abs32le/include/arch/proc/task.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/proc/task.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_abs32le_TASK_H_
 
-#include <typedefs.h>
 #include <adt/bitmap.h>
 
Index: kernel/arch/abs32le/include/arch/proc/thread.h
===================================================================
--- kernel/arch/abs32le/include/arch/proc/thread.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/proc/thread.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,4 @@
 #define KERN_abs32le_THREAD_H_
 
-#include <typedefs.h>
-
 typedef struct {
 } thread_arch_t;
Index: kernel/arch/abs32le/include/arch/types.h
===================================================================
--- kernel/arch/abs32le/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_abs32le_TYPES_H_
 
+#include <arch/common.h>
+
 #define ATOMIC_COUNT_MIN  UINT32_MIN
 #define ATOMIC_COUNT_MAX  UINT32_MAX
@@ -54,7 +56,4 @@
 } fncptr_t;
 
-#define INTN_C(c)   INT32_C(c)
-#define UINTN_C(c)  UINT32_C(c)
-
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: kernel/arch/abs32le/src/abs32le.c
===================================================================
--- kernel/arch/abs32le/src/abs32le.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/src/abs32le.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,14 +40,12 @@
 #include <func.h>
 #include <config.h>
+#include <console/console.h>
 #include <errno.h>
 #include <context.h>
 #include <fpu_context.h>
 #include <interrupt.h>
+#include <ddi/irq.h>
 #include <syscall/copy.h>
-#include <ddi/irq.h>
-#include <proc/thread.h>
 #include <syscall/syscall.h>
-#include <console/console.h>
-#include <memstr.h>
 
 static void abs32le_post_mm_init(void);
Index: kernel/arch/abs32le/src/cpu/cpu.c
===================================================================
--- kernel/arch/abs32le/src/cpu/cpu.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/src/cpu/cpu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #include <cpu.h>
 #include <arch.h>
-#include <typedefs.h>
 #include <print.h>
 #include <fpu_context.h>
@@ -57,5 +56,5 @@
 }
 
-void cpu_print_report(cpu_t* cpu)
+void cpu_print_report(cpu_t *cpu)
 {
 }
Index: kernel/arch/abs32le/src/debug/stacktrace.c
===================================================================
--- kernel/arch/abs32le/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,6 +34,6 @@
 
 #include <stacktrace.h>
+#include <stdbool.h>
 #include <syscall/copy.h>
-#include <typedefs.h>
 
 bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
Index: kernel/arch/abs32le/src/mm/frame.c
===================================================================
--- kernel/arch/abs32le/src/mm/frame.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/src/mm/frame.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -49,5 +49,4 @@
 }
 
-
 void frame_low_arch_init(void)
 {
Index: kernel/arch/abs32le/src/mm/page.c
===================================================================
--- kernel/arch/abs32le/src/mm/page.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/src/mm/page.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,4 @@
 #include <mm/page.h>
 #include <mm/as.h>
-#include <typedefs.h>
 #include <align.h>
 #include <config.h>
@@ -46,5 +45,4 @@
 #include <arch/asm.h>
 #include <debug.h>
-#include <memstr.h>
 #include <print.h>
 #include <interrupt.h>
Index: kernel/arch/abs32le/src/userspace.c
===================================================================
--- kernel/arch/abs32le/src/userspace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/abs32le/src/userspace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #include <userspace.h>
-#include <typedefs.h>
+#include <stdbool.h>
 #include <arch.h>
 #include <abi/proc/uarg.h>
Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -32,8 +32,5 @@
 
 FPU_NO_CFLAGS = -mno-sse -mno-sse2
-CMN1 = -m64 -mcmodel=$(MEMORY_MODEL) -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer
-GCC_CFLAGS += $(CMN1)
-ICC_CFLAGS += $(CMN1)
-CLANG_CFLAGS += $(CMN1)
+COMMON_CFLAGS += -m64 -mcmodel=$(MEMORY_MODEL) -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer
 
 BITS = 64
@@ -44,7 +41,5 @@
 
 ifeq ($(PROCESSOR),opteron)
-	CMN2 := -march=opteron
-	GCC_CFLAGS += $(CMN2)
-	ICC_CFLAGS += $(CMN2)
+	COMMON_CFLAGS += -march=opteron
 endif
 
Index: kernel/arch/amd64/include/arch/atomic.h
===================================================================
--- kernel/arch/amd64/include/arch/atomic.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/atomic.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,4 @@
 #define KERN_amd64_ATOMIC_H_
 
-#include <typedefs.h>
 #include <arch/barrier.h>
 #include <preemption.h>
Index: kernel/arch/amd64/include/arch/cpuid.h
===================================================================
--- kernel/arch/amd64/include/arch/cpuid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/cpuid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,5 +48,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 typedef struct {
Index: kernel/arch/amd64/include/arch/interrupt.h
===================================================================
--- kernel/arch/amd64/include/arch/interrupt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/interrupt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,7 @@
 #define KERN_amd64_INTERRUPT_H_
 
-#include <typedefs.h>
 #include <arch/istate.h>
 #include <arch/pm.h>
+#include <stdint.h>
 
 #define IVT_ITEMS  IDT_ITEMS
Index: kernel/arch/amd64/include/arch/mm/frame.h
===================================================================
--- kernel/arch/amd64/include/arch/mm/frame.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/mm/frame.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,6 +43,4 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
-
 extern void frame_low_arch_init(void);
 extern void frame_high_arch_init(void);
Index: kernel/arch/amd64/include/arch/mm/km.h
===================================================================
--- kernel/arch/amd64/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_amd64_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/amd64/include/arch/proc/task.h
===================================================================
--- kernel/arch/amd64/include/arch/proc/task.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/proc/task.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,6 @@
 #define KERN_amd64_TASK_H_
 
-#include <typedefs.h>
 #include <adt/bitmap.h>
+#include <stddef.h>
 
 typedef struct {
Index: kernel/arch/amd64/include/arch/proc/thread.h
===================================================================
--- kernel/arch/amd64/include/arch/proc/thread.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/proc/thread.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_amd64_THREAD_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 typedef struct {
Index: kernel/arch/amd64/include/arch/types.h
===================================================================
--- kernel/arch/amd64/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_amd64_TYPES_H_
 
+#include <arch/common.h>
+
 typedef uint64_t size_t;
 typedef int64_t ssize_t;
@@ -51,7 +53,4 @@
 } fncptr_t;
 
-#define INTN_C(c)   INT64_C(c)
-#define UINTN_C(c)  UINT64_C(c)
-
 #define PRIdn  PRId64  /**< Format for native_t. */
 #define PRIun  PRIu64  /**< Format for sysarg_t. */
Index: kernel/arch/amd64/include/arch/vreg.h
===================================================================
--- kernel/arch/amd64/include/arch/vreg.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/include/arch/vreg.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 extern uint64_t *vreg_ptr;
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/amd64.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,7 +35,7 @@
 #include <arch.h>
 #include <arch/arch.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <errno.h>
-#include <memstr.h>
+#include <mem.h>
 #include <interrupt.h>
 #include <console/console.h>
Index: kernel/arch/amd64/src/boot/multiboot2.S
===================================================================
--- kernel/arch/amd64/src/boot/multiboot2.S	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/boot/multiboot2.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -54,4 +54,5 @@
 		.word MULTIBOOT2_FLAGS_REQUIRED
 		.long tag_info_req_end - tag_info_req_start
+		.long MULTIBOOT2_TAG_CMDLINE
 		.long MULTIBOOT2_TAG_MODULE
 		.long MULTIBOOT2_TAG_MEMMAP
Index: kernel/arch/amd64/src/cpu/cpu.c
===================================================================
--- kernel/arch/amd64/src/cpu/cpu.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/cpu/cpu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,4 @@
 
 #include <arch.h>
-#include <typedefs.h>
 #include <print.h>
 #include <fpu_context.h>
Index: kernel/arch/amd64/src/ddi/ddi.c
===================================================================
--- kernel/arch/amd64/src/ddi/ddi.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/ddi/ddi.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,6 +35,6 @@
 #include <ddi/ddi.h>
 #include <arch/ddi/ddi.h>
+#include <assert.h>
 #include <proc/task.h>
-#include <typedefs.h>
 #include <adt/bitmap.h>
 #include <mm/slab.h>
@@ -45,4 +45,5 @@
 #include <arch.h>
 #include <align.h>
+#include <stdbool.h>
 
 /** Install I/O Permission bitmap.
@@ -63,5 +64,5 @@
 	
 	if (elements > 0) {
-		ASSERT(TASK->arch.iomap.bits);
+		assert(TASK->arch.iomap.bits);
 		
 		bitmap_t iomap;
Index: kernel/arch/amd64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/amd64/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 
 #include <stacktrace.h>
+#include <stdbool.h>
 #include <syscall/copy.h>
 #include <typedefs.h>
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,7 +34,7 @@
 
 #include <arch/interrupt.h>
+#include <assert.h>
 #include <print.h>
 #include <log.h>
-#include <debug.h>
 #include <panic.h>
 #include <arch/drivers/i8259.h>
@@ -175,10 +175,10 @@
 static void irq_interrupt(unsigned int n, istate_t *istate)
 {
-	ASSERT(n >= IVT_IRQBASE);
+	assert(n >= IVT_IRQBASE);
 	
 	unsigned int inum = n - IVT_IRQBASE;
 	bool ack = false;
-	ASSERT(inum < IRQ_COUNT);
-	ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
+	assert(inum < IRQ_COUNT);
+	assert((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
 	
 	irq_t *irq = irq_dispatch_and_lock(inum);
Index: kernel/arch/amd64/src/kseg.c
===================================================================
--- kernel/arch/amd64/src/kseg.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/kseg.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,4 @@
 
 #include <arch/kseg.h>
-#include <typedefs.h>
 #include <arch/asm.h>
 #include <panic.h>
Index: kernel/arch/amd64/src/mm/km.c
===================================================================
--- kernel/arch/amd64/src/mm/km.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/mm/km.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,6 +34,6 @@
 #include <mm/km.h>
 #include <config.h>
-#include <typedefs.h>
 #include <macros.h>
+#include <stdbool.h>
 
 void km_identity_arch_init(void)
Index: kernel/arch/amd64/src/mm/page.c
===================================================================
--- kernel/arch/amd64/src/mm/page.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/mm/page.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,4 @@
 #include <arch/asm.h>
 #include <config.h>
-#include <memstr.h>
 #include <interrupt.h>
 #include <print.h>
Index: kernel/arch/amd64/src/pm.c
===================================================================
--- kernel/arch/amd64/src/pm.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/pm.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #include <mm/as.h>
 #include <mm/frame.h>
-#include <memstr.h>
+#include <mem.h>
 #include <mm/slab.h>
 
Index: kernel/arch/amd64/src/proc/task.c
===================================================================
--- kernel/arch/amd64/src/proc/task.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/proc/task.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #include <proc/task.h>
-#include <typedefs.h>
+#include <stddef.h>
 #include <adt/bitmap.h>
 #include <mm/slab.h>
Index: kernel/arch/amd64/src/userspace.c
===================================================================
--- kernel/arch/amd64/src/userspace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/amd64/src/userspace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #include <arch/cpu.h>
 #include <arch/pm.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <arch.h>
 #include <abi/proc/uarg.h>
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
 ATSIGN = %
 
-GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access -mfpu=vfpv3
+COMMON_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access -mfpu=vfpv3
 
 ifeq ($(CONFIG_FPU),y)
Index: kernel/arch/arm32/include/arch/arch.h
===================================================================
--- kernel/arch/arm32/include/arch/arch.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/arch.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,5 +42,5 @@
 #define BOOTINFO_TASK_NAME_BUFLEN 32
 
-#include <typedefs.h>
+#include <stddef.h>
 
 typedef struct {
Index: kernel/arch/arm32/include/arch/cp15.h
===================================================================
--- kernel/arch/arm32/include/arch/cp15.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/cp15.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,9 +37,5 @@
 #define KERN_arm32_CP15_H_
 
-#if defined(KERNEL) || defined(BOOT)
-#include <typedefs.h>
-#else
 #include <stdint.h>
-#endif
 
 /** See ARM Architecture reference manual ch. B3.17.1 page B3-1456
Index: kernel/arch/arm32/include/arch/cpu.h
===================================================================
--- kernel/arch/arm32/include/arch/cpu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/cpu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,6 +37,6 @@
 #define KERN_arm32_CPU_H_
 
-#include <typedefs.h>
 #include <arch/asm.h>
+#include <stdint.h>
 
 enum {
Index: kernel/arch/arm32/include/arch/fpu_context.h
===================================================================
--- kernel/arch/arm32/include/arch/fpu_context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/fpu_context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,6 @@
 #define KERN_arm32_FPU_CONTEXT_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stdint.h>
 
 #define FPU_CONTEXT_ALIGN    8
Index: kernel/arch/arm32/include/arch/interrupt.h
===================================================================
--- kernel/arch/arm32/include/arch/interrupt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/interrupt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 #define KERN_arm32_INTERRUPT_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
 #include <arch/exception.h>
 
Index: kernel/arch/arm32/include/arch/mm/asid.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/asid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/mm/asid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #define KERN_arm32_ASID_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #define ASID_MAX_ARCH		3	/* minimal required number */
Index: kernel/arch/arm32/include/arch/mm/frame.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/frame.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/mm/frame.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,6 +44,4 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
-
 #define BOOT_PAGE_TABLE_SIZE     0x4000
 
Index: kernel/arch/arm32/include/arch/mm/km.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_arm32_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/arm32/include/arch/mm/page_fault.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/page_fault.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/mm/page_fault.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 #define KERN_arm32_PAGE_FAULT_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 
Index: kernel/arch/arm32/include/arch/types.h
===================================================================
--- kernel/arch/arm32/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,6 @@
 #define KERN_arm32_TYPES_H_
 
+#include <arch/common.h>
+
 #ifndef DOXYGEN
 	#define ATTRIBUTE_PACKED __attribute__((packed))
@@ -58,7 +60,4 @@
 } fncptr_t;
 
-#define INTN_C(c)   INT32_C(c)
-#define UINTN_C(c)  UINT32_C(c)
-
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: kernel/arch/arm32/src/interrupt.c
===================================================================
--- kernel/arch/arm32/src/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/src/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,4 @@
 #include <arch/machine_func.h>
 #include <ddi/irq.h>
-#include <ddi/device.h>
 #include <interrupt.h>
 
Index: kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c
===================================================================
--- kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
 #include <arch/exception.h>
 #include <arch/mach/beagleboardxm/beagleboardxm.h>
+#include <assert.h>
 #include <genarch/drivers/amdm37x/uart.h>
 #include <genarch/drivers/amdm37x/irc.h>
@@ -43,5 +44,4 @@
 #include <mm/km.h>
 #include <ddi/ddi.h>
-#include <ddi/device.h>
 
 static void bbxm_init(void);
@@ -102,5 +102,5 @@
 	    (void *) km_map(AMDM37x_IRC_BASE_ADDRESS, AMDM37x_IRC_SIZE,
 	    PAGE_NOT_CACHEABLE);
-	ASSERT(beagleboard.irc_addr);
+	assert(beagleboard.irc_addr);
 	omap_irc_init(beagleboard.irc_addr);
 
@@ -116,5 +116,4 @@
 	static irq_t timer_irq;
 	irq_initialize(&timer_irq);
-	timer_irq.devno = device_assign_devno();
 	timer_irq.inr = AMDM37x_GPT1_IRQ;
 	timer_irq.claim = bb_timer_irq_claim;
Index: kernel/arch/arm32/src/mach/beaglebone/beaglebone.c
===================================================================
--- kernel/arch/arm32/src/mach/beaglebone/beaglebone.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/src/mach/beaglebone/beaglebone.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #include <arch/exception.h>
 #include <arch/mach/beaglebone/beaglebone.h>
+#include <assert.h>
 #include <genarch/drivers/am335x/irc.h>
 #include <genarch/drivers/am335x/uart.h>
@@ -45,5 +46,4 @@
 #include <interrupt.h>
 #include <ddi/ddi.h>
-#include <ddi/device.h>
 #include <mm/km.h>
 
@@ -98,8 +98,8 @@
 	    AM335x_CTRL_MODULE_SIZE, PAGE_NOT_CACHEABLE);
 
-	ASSERT(bbone.irc_addr != NULL);
-	ASSERT(bbone.cm_per_addr != NULL);
-	ASSERT(bbone.cm_dpll_addr != NULL);
-	ASSERT(bbone.ctrl_module != NULL);
+	assert(bbone.irc_addr != NULL);
+	assert(bbone.cm_per_addr != NULL);
+	assert(bbone.cm_dpll_addr != NULL);
+	assert(bbone.ctrl_module != NULL);
 
 	/* Initialize the interrupt controller */
@@ -128,5 +128,4 @@
 	static irq_t timer_irq;
 	irq_initialize(&timer_irq);
-	timer_irq.devno = device_assign_devno();
 	timer_irq.inr = AM335x_DMTIMER2_IRQ;
 	timer_irq.claim = bbone_timer_irq_claim;
Index: kernel/arch/arm32/src/mach/gta02/gta02.c
===================================================================
--- kernel/arch/arm32/src/mach/gta02/gta02.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/src/mach/gta02/gta02.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,5 +48,4 @@
 #include <interrupt.h>
 #include <ddi/ddi.h>
-#include <ddi/device.h>
 #include <log.h>
 
@@ -241,5 +240,4 @@
 {
 	irq_initialize(&gta02_timer_irq);
-	gta02_timer_irq.devno = device_assign_devno();
 	gta02_timer_irq.inr = GTA02_TIMER_IRQ;
 	gta02_timer_irq.claim = gta02_timer_irq_claim;
Index: kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
===================================================================
--- kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,4 @@
 #include <console/console.h>
 #include <sysinfo/sysinfo.h>
-#include <ddi/device.h>
 #include <mm/page.h>
 #include <mm/frame.h>
@@ -207,5 +206,4 @@
 {
 	irq_initialize(&icp.timer_irq);
-	icp.timer_irq.devno = device_assign_devno();
 	icp.timer_irq.inr = ICP_TIMER_IRQ;
 	icp.timer_irq.claim = icp_timer_claim;
Index: kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c
===================================================================
--- kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #include <arch/exception.h>
 #include <arch/mach/raspberrypi/raspberrypi.h>
+#include <assert.h>
 #include <genarch/drivers/pl011/pl011.h>
 #include <genarch/drivers/bcm2835/irc.h>
@@ -49,5 +50,4 @@
 #include <interrupt.h>
 #include <ddi/ddi.h>
-#include <ddi/device.h>
 
 #define RPI_DEFAULT_MEMORY_START	0
@@ -103,5 +103,5 @@
 	raspi.irc = (void *) km_map(BCM2835_IRC_ADDR, sizeof(bcm2835_irc_t),
 				    PAGE_NOT_CACHEABLE);
-	ASSERT(raspi.irc);
+	assert(raspi.irc);
 	bcm2835_irc_init(raspi.irc);
 
@@ -117,5 +117,4 @@
 	static irq_t timer_irq;
 	irq_initialize(&timer_irq);
-	timer_irq.devno = device_assign_devno();
 	timer_irq.inr = BCM2835_TIMER1_IRQ;
 	timer_irq.claim = raspberrypi_timer_irq_claim;
Index: kernel/arch/arm32/src/mm/km.c
===================================================================
--- kernel/arch/arm32/src/mm/km.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/src/mm/km.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 #include <mm/km.h>
 #include <config.h>
+#include <stdbool.h>
 #include <typedefs.h>
 #include <macros.h>
Index: kernel/arch/arm32/src/ras.c
===================================================================
--- kernel/arch/arm32/src/ras.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/arm32/src/ras.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,5 @@
 #include <arch/exception.h>
 #include <arch.h>
-#include <memstr.h>
+#include <mem.h>
 #include <typedefs.h>
 
Index: kernel/arch/ia32/Makefile.inc
===================================================================
--- kernel/arch/ia32/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,8 +34,5 @@
 ENDIANESS = LE
 
-CMN1 = -m32 -fno-omit-frame-pointer
-GCC_CFLAGS += $(CMN1)
-ICC_CFLAGS += $(CMN1)
-CLANG_CFLAGS += $(CMN1)
+COMMON_CFLAGS += -m32 -fno-omit-frame-pointer
 
 ## Accepted CPUs
@@ -43,31 +40,28 @@
 
 ifeq ($(PROCESSOR),i486)
-	CMN2 = -march=i486
+	COMMON_CFLAGS += -march=i486
 endif
 
 ifeq ($(PROCESSOR),athlon_xp)
-	CMN2 = -march=athlon-xp
+	COMMON_CFLAGS += -march=athlon-xp
 endif
 
 ifeq ($(PROCESSOR),athlon_mp)
-	CMN2 = -march=athlon-mp
+	COMMON_CFLAGS += -march=athlon-mp
 endif
 
 ifeq ($(PROCESSOR),pentium3)
-	CMN2 = -march=pentium3
+	COMMON_CFLAGS += -march=pentium3
 endif
 
 ifeq ($(PROCESSOR),pentium4)
-	CMN2 = -march=pentium4
+	COMMON_CFLAGS += -march=pentium4
 endif
 
 ifeq ($(PROCESSOR),core)
-	CMN2 = -march=prescott
+	COMMON_CFLAGS += -march=prescott
 endif
 
 FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
-GCC_CFLAGS += $(CMN2)
-ICC_CFLAGS += $(CMN2)
-CLANG_CFLAGS += $(CMN2)
 
 ARCH_SOURCES = \
Index: kernel/arch/ia32/include/arch/arch.h
===================================================================
--- kernel/arch/ia32/include/arch/arch.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/arch.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_ia32_ARCH_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 extern void ia32_pre_main(uint32_t, void *);
Index: kernel/arch/ia32/include/arch/boot/memmap.h
===================================================================
--- kernel/arch/ia32/include/arch/boot/memmap.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/boot/memmap.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -63,5 +63,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 extern e820memmap_t e820table[MEMMAP_E820_MAX_RECORDS];
Index: kernel/arch/ia32/include/arch/cpuid.h
===================================================================
--- kernel/arch/ia32/include/arch/cpuid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/cpuid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,6 +43,6 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
 #include <arch/cpu.h>
+#include <stdint.h>
 
 typedef struct {
Index: kernel/arch/ia32/include/arch/fpu_context.h
===================================================================
--- kernel/arch/ia32/include/arch/fpu_context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/fpu_context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_ia32_FPU_CONTEXT_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #define FPU_CONTEXT_ALIGN  16
Index: kernel/arch/ia32/include/arch/interrupt.h
===================================================================
--- kernel/arch/ia32/include/arch/interrupt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/interrupt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,7 @@
 #define KERN_ia32_INTERRUPT_H_
 
-#include <typedefs.h>
 #include <arch/istate.h>
 #include <arch/pm.h>
+#include <stdint.h>
 
 #define IVT_ITEMS  IDT_ITEMS
Index: kernel/arch/ia32/include/arch/mm/asid.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/asid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/mm/asid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,5 @@
 #define KERN_ia32_ASID_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 typedef int32_t asid_t;
Index: kernel/arch/ia32/include/arch/mm/frame.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/frame.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/mm/frame.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,6 +43,4 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
-
 extern void frame_low_arch_init(void);
 extern void frame_high_arch_init(void);
Index: kernel/arch/ia32/include/arch/mm/km.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_ia32_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/ia32/include/arch/mm/page.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/page.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/mm/page.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
 
 #include <arch/mm/frame.h>
+#include <stdbool.h>
 #include <trace.h>
 
@@ -145,5 +146,5 @@
 #include <mm/mm.h>
 #include <arch/interrupt.h>
-#include <typedefs.h>
+#include <stddef.h>
 
 /* Page fault error codes. */
Index: kernel/arch/ia32/include/arch/proc/task.h
===================================================================
--- kernel/arch/ia32/include/arch/proc/task.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/proc/task.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_ia32_TASK_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <adt/bitmap.h>
 
Index: kernel/arch/ia32/include/arch/proc/thread.h
===================================================================
--- kernel/arch/ia32/include/arch/proc/thread.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/proc/thread.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,4 @@
 #define KERN_ia32_THREAD_H_
 
-#include <typedefs.h>
-
 typedef struct {
 } thread_arch_t;
Index: kernel/arch/ia32/include/arch/smp/apic.h
===================================================================
--- kernel/arch/ia32/include/arch/smp/apic.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/smp/apic.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,6 +41,6 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
 #include <cpu.h>
+#include <stdint.h>
 
 #define FIXED  (0 << 0)
Index: kernel/arch/ia32/include/arch/smp/mps.h
===================================================================
--- kernel/arch/ia32/include/arch/smp/mps.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/smp/mps.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_ia32_MPS_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <synch/waitq.h>
 #include <config.h>
Index: kernel/arch/ia32/include/arch/smp/smp.h
===================================================================
--- kernel/arch/ia32/include/arch/smp/smp.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/smp/smp.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,6 @@
 #define KERN_ia32_SMP_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
 
 /** SMP config opertaions interface. */
Index: kernel/arch/ia32/include/arch/types.h
===================================================================
--- kernel/arch/ia32/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_ia32_TYPES_H_
 
+#include <arch/common.h>
+
 typedef uint32_t size_t;
 typedef int32_t ssize_t;
@@ -51,7 +53,4 @@
 } fncptr_t;
 
-#define INTN_C(c)   INT32_C(c)
-#define UINTN_C(c)  UINT32_C(c)
-
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: kernel/arch/ia32/include/arch/vreg.h
===================================================================
--- kernel/arch/ia32/include/arch/vreg.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/include/arch/vreg.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 extern uint32_t *vreg_ptr;
Index: kernel/arch/ia32/src/boot/multiboot.S
===================================================================
--- kernel/arch/ia32/src/boot/multiboot.S	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/boot/multiboot.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -165,5 +165,4 @@
  */
 FUNCTION_BEGIN(map_kernel_pse)
-map_kernel_pse:
 	/* Paging features */
 	movl %cr4, %ecx
Index: kernel/arch/ia32/src/boot/multiboot2.S
===================================================================
--- kernel/arch/ia32/src/boot/multiboot2.S	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/boot/multiboot2.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -52,4 +52,5 @@
 		.word MULTIBOOT2_FLAGS_REQUIRED
 		.long tag_info_req_end - tag_info_req_start
+		.long MULTIBOOT2_TAG_CMDLINE
 		.long MULTIBOOT2_TAG_MODULE
 		.long MULTIBOOT2_TAG_MEMMAP
Index: kernel/arch/ia32/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia32/src/cpu/cpu.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/cpu/cpu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 
 #include <arch.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <print.h>
 #include <fpu_context.h>
Index: kernel/arch/ia32/src/ddi/ddi.c
===================================================================
--- kernel/arch/ia32/src/ddi/ddi.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/ddi/ddi.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,6 +35,7 @@
 #include <ddi/ddi.h>
 #include <arch/ddi/ddi.h>
+#include <assert.h>
 #include <proc/task.h>
-#include <typedefs.h>
+#include <stddef.h>
 #include <adt/bitmap.h>
 #include <mm/slab.h>
@@ -63,5 +64,5 @@
 	
 	if (elements > 0) {
-		ASSERT(TASK->arch.iomap.bits);
+		assert(TASK->arch.iomap.bits);
 		
 		bitmap_t iomap;
Index: kernel/arch/ia32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia32/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,6 +34,7 @@
 
 #include <stacktrace.h>
+#include <stdbool.h>
+#include <stdint.h>
 #include <syscall/copy.h>
-#include <typedefs.h>
 
 #define FRAME_OFFSET_FP_PREV  0
Index: kernel/arch/ia32/src/drivers/i8254.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8254.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/drivers/i8254.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
  */
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <time/clock.h>
 #include <time/delay.h>
@@ -51,5 +51,4 @@
 #include <arch.h>
 #include <ddi/irq.h>
-#include <ddi/device.h>
 
 #define CLK_PORT1  ((ioport8_t *) 0x40U)
@@ -86,5 +85,4 @@
 	irq_initialize(&i8254_irq);
 	i8254_irq.preack = true;
-	i8254_irq.devno = device_assign_devno();
 	i8254_irq.inr = IRQ_CLK;
 	i8254_irq.claim = i8254_claim;
Index: kernel/arch/ia32/src/drivers/i8259.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8259.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/drivers/i8259.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #include <arch/drivers/i8259.h>
 #include <cpu.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <arch/asm.h>
 #include <arch.h>
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/ia32.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,7 +37,7 @@
 #include <arch.h>
 #include <arch/arch.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <errno.h>
-#include <memstr.h>
+#include <mem.h>
 #include <interrupt.h>
 #include <console/console.h>
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 
 #include <arch/interrupt.h>
+#include <assert.h>
 #include <syscall/syscall.h>
 #include <print.h>
@@ -84,5 +85,5 @@
 	
 	printf("esi=%0#10" PRIx32 "\tedi=%0#10" PRIx32 "\t"
-	    "ebp=%0#10" PRIx32 "\tesp=%0#10" PRIx32 "\n",
+	    "ebp=%0#10" PRIx32 "\tesp=%0#10" PRIxn "\n",
 	    istate->esi, istate->edi, istate->ebp,
 	    istate_from_uspace(istate) ? istate->esp :
@@ -183,10 +184,10 @@
 static void irq_interrupt(unsigned int n, istate_t *istate __attribute__((unused)))
 {
-	ASSERT(n >= IVT_IRQBASE);
+	assert(n >= IVT_IRQBASE);
 	
 	unsigned int inum = n - IVT_IRQBASE;
 	bool ack = false;
-	ASSERT(inum < IRQ_COUNT);
-	ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
+	assert(inum < IRQ_COUNT);
+	assert((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
 	
 	irq_t *irq = irq_dispatch_and_lock(inum);
Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/mm/frame.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -147,5 +147,4 @@
 }
 
-
 void frame_low_arch_init(void)
 {
Index: kernel/arch/ia32/src/mm/page.c
===================================================================
--- kernel/arch/ia32/src/mm/page.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/mm/page.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -46,5 +46,4 @@
 #include <arch/asm.h>
 #include <debug.h>
-#include <memstr.h>
 #include <print.h>
 #include <interrupt.h>
Index: kernel/arch/ia32/src/pm.c
===================================================================
--- kernel/arch/ia32/src/pm.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/pm.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,5 @@
 #include <mm/frame.h>
 #include <mm/slab.h>
-#include <memstr.h>
+#include <mem.h>
 #include <arch/boot/boot.h>
 #include <interrupt.h>
Index: kernel/arch/ia32/src/proc/task.c
===================================================================
--- kernel/arch/ia32/src/proc/task.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/proc/task.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #include <proc/task.h>
-#include <typedefs.h>
+#include <stddef.h>
 #include <adt/bitmap.h>
 #include <mm/slab.h>
Index: kernel/arch/ia32/src/smp/apic.c
===================================================================
--- kernel/arch/ia32/src/smp/apic.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/smp/apic.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <arch/smp/mps.h>
 #include <arch/boot/boot.h>
+#include <assert.h>
 #include <mm/page.h>
 #include <time/delay.h>
@@ -46,5 +47,4 @@
 #include <arch.h>
 #include <ddi/irq.h>
-#include <ddi/device.h>
 
 #ifdef CONFIG_SMP
@@ -189,5 +189,4 @@
 	irq_initialize(&l_apic_timer_irq);
 	l_apic_timer_irq.preack = true;
-	l_apic_timer_irq.devno = device_assign_devno();
 	l_apic_timer_irq.inr = IRQ_CLK;
 	l_apic_timer_irq.claim = l_apic_timer_claim;
@@ -492,5 +491,5 @@
 	
 	/* Program Logical Destination Register. */
-	ASSERT(CPU->id < 8);
+	assert(CPU->id < 8);
 	ldr_t ldr;
 	
Index: kernel/arch/ia32/src/smp/mps.c
===================================================================
--- kernel/arch/ia32/src/smp/mps.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/smp/mps.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,8 +37,8 @@
 #include <config.h>
 #include <log.h>
-#include <debug.h>
 #include <arch/smp/mps.h>
 #include <arch/smp/apic.h>
 #include <arch/smp/smp.h>
+#include <assert.h>
 #include <func.h>
 #include <typedefs.h>
@@ -74,5 +74,5 @@
 static uint8_t mps_cpu_apic_id(size_t i)
 {
-	ASSERT(i < processor_entry_cnt);
+	assert(i < processor_entry_cnt);
 	
 	return processor_entries[i].l_apic_id;
@@ -81,5 +81,5 @@
 static bool mps_cpu_enabled(size_t i)
 {
-	ASSERT(i < processor_entry_cnt);
+	assert(i < processor_entry_cnt);
 	
 	/*
@@ -96,5 +96,5 @@
 static bool mps_cpu_bootstrap(size_t i)
 {
-	ASSERT(i < processor_entry_cnt);
+	assert(i < processor_entry_cnt);
 	
 	return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02);
Index: kernel/arch/ia32/src/smp/smp.c
===================================================================
--- kernel/arch/ia32/src/smp/smp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/smp/smp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <arch/smp/ap.h>
 #include <arch/boot/boot.h>
+#include <assert.h>
 #include <genarch/acpi/acpi.h>
 #include <genarch/acpi/madt.h>
@@ -45,5 +46,4 @@
 #include <func.h>
 #include <panic.h>
-#include <debug.h>
 #include <arch/asm.h>
 #include <mm/page.h>
@@ -53,5 +53,5 @@
 #include <mm/as.h>
 #include <log.h>
-#include <memstr.h>
+#include <mem.h>
 #include <arch/drivers/i8259.h>
 #include <cpu.h>
@@ -83,6 +83,6 @@
 static void cpu_arch_id_init(void)
 {
-	ASSERT(ops != NULL);
-	ASSERT(cpus != NULL);
+	assert(ops != NULL);
+	assert(cpus != NULL);
 	
 	for (unsigned int i = 0; i < config.cpu_count; ++i) {
@@ -102,5 +102,5 @@
 	unsigned int i;
 	
-	ASSERT(ops != NULL);
+	assert(ops != NULL);
 
 	/*
@@ -191,5 +191,5 @@
 int smp_irq_to_pin(unsigned int irq)
 {
-	ASSERT(ops != NULL);
+	assert(ops != NULL);
 	return ops->irq_to_pin(irq);
 }
Index: kernel/arch/ia32/src/syscall.c
===================================================================
--- kernel/arch/ia32/src/syscall.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/syscall.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,6 @@
 #include <arch/cpu.h>
 #include <arch/asm.h>
-#include <typedefs.h>
 #include <arch/pm.h>
+#include <stdint.h>
 
 #ifndef PROCESSOR_i486
Index: kernel/arch/ia32/src/userspace.c
===================================================================
--- kernel/arch/ia32/src/userspace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia32/src/userspace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,5 +35,5 @@
 #include <userspace.h>
 #include <arch/pm.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <arch.h>
 #include <abi/proc/uarg.h>
Index: kernel/arch/ia64/Makefile.inc
===================================================================
--- kernel/arch/ia64/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,7 +30,5 @@
 BFD_ARCH = ia64-elf64
 
-CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127
-GCC_CFLAGS += $(CMN1)
-ICC_CFLAGS += $(CMN1)
+COMMON_CFLAGS += -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127
 
 AFLAGS += -mconstant-gp
Index: kernel/arch/ia64/include/arch/cpu.h
===================================================================
--- kernel/arch/ia64/include/arch/cpu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/include/arch/cpu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,8 +36,8 @@
 #define KERN_ia64_CPU_H_
 
-#include <typedefs.h>
 #include <arch/register.h>
 #include <arch/asm.h>
 #include <arch/bootinfo.h>
+#include <stdint.h>
 #include <trace.h>
 
Index: kernel/arch/ia64/include/arch/fpu_context.h
===================================================================
--- kernel/arch/ia64/include/arch/fpu_context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/include/arch/fpu_context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #define FPU_CONTEXT_ALIGN 16
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #define FRS 96
Index: kernel/arch/ia64/include/arch/interrupt.h
===================================================================
--- kernel/arch/ia64/include/arch/interrupt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/include/arch/interrupt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,6 +37,6 @@
 
 #ifndef __ASM__
-#include <typedefs.h>
 #include <arch/istate.h>
+#include <stdint.h>
 #endif
 
Index: kernel/arch/ia64/include/arch/mm/asid.h
===================================================================
--- kernel/arch/ia64/include/arch/mm/asid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/include/arch/mm/asid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 typedef uint16_t asid_t;
Index: kernel/arch/ia64/include/arch/mm/km.h
===================================================================
--- kernel/arch/ia64/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_ia64_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/ia64/include/arch/mm/page.h
===================================================================
--- kernel/arch/ia64/include/arch/mm/page.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/include/arch/mm/page.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,8 @@
 
 #include <arch/mm/frame.h>
+
+#ifndef __ASM__
+#include <assert.h>
+#endif
 
 #define PAGE_SIZE   FRAME_SIZE
@@ -232,5 +236,5 @@
 	uint64_t ret;
 	
-	ASSERT(i < REGION_REGISTERS);
+	assert(i < REGION_REGISTERS);
 	
 	asm volatile (
@@ -250,5 +254,5 @@
 NO_TRACE static inline void rr_write(size_t i, uint64_t v)
 {
-	ASSERT(i < REGION_REGISTERS);
+	assert(i < REGION_REGISTERS);
 	
 	asm volatile (
Index: kernel/arch/ia64/include/arch/types.h
===================================================================
--- kernel/arch/ia64/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_ia64_TYPES_H_
 
+#include <arch/common.h>
+
 typedef uint64_t size_t;
 typedef int64_t ssize_t;
@@ -53,7 +55,4 @@
 } __attribute__((may_alias)) fncptr_t;
 
-#define INTN_C(c)   INT64_C(c)
-#define UINTN_C(c)  UINT64_C(c)
-
 #define PRIdn  PRId64  /**< Format for native_t. */
 #define PRIun  PRIu64  /**< Format for sysarg_t. */
Index: kernel/arch/ia64/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia64/src/cpu/cpu.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/cpu/cpu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 #include <arch/register.h>
 #include <print.h>
-#include <memstr.h>
+#include <mem.h>
 
 void cpu_arch_init(void)
Index: kernel/arch/ia64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia64/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 
 #include <stacktrace.h>
+#include <stdbool.h>
 #include <syscall/copy.h>
 #include <typedefs.h>
Index: kernel/arch/ia64/src/drivers/it.c
===================================================================
--- kernel/arch/ia64/src/drivers/it.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/drivers/it.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,5 +42,4 @@
 #include <time/clock.h>
 #include <ddi/irq.h>
-#include <ddi/device.h>
 #include <arch.h>
 
@@ -66,5 +65,4 @@
 		irq_initialize(&it_irq);
 		it_irq.inr = INTERRUPT_TIMER;
-		it_irq.devno = device_assign_devno();
 		it_irq.claim = it_claim;
 		it_irq.handler = it_interrupt;
Index: kernel/arch/ia64/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,8 +34,9 @@
 
 #include <arch/drivers/ski.h>
+#include <assert.h>
 #include <console/console.h>
 #include <console/chardev.h>
 #include <sysinfo/sysinfo.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <proc/thread.h>
 #include <synch/spinlock.h>
@@ -238,6 +239,6 @@
 void skiin_wire(ski_instance_t *instance, indev_t *srlnin)
 {
-	ASSERT(instance);
-	ASSERT(srlnin);
+	assert(instance);
+	assert(srlnin);
 	
 	instance->srlnin = srlnin;
Index: kernel/arch/ia64/src/interrupt.c
===================================================================
--- kernel/arch/ia64/src/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,9 +35,9 @@
 
 #include <arch/interrupt.h>
+#include <assert.h>
 #include <interrupt.h>
 #include <ddi/irq.h>
 #include <panic.h>
 #include <print.h>
-#include <debug.h>
 #include <console/console.h>
 #include <typedefs.h>
@@ -123,5 +123,5 @@
 static const char *vector_to_string(unsigned int n)
 {
-	ASSERT(n <= VECTOR_MAX);
+	assert(n <= VECTOR_MAX);
 	
 	if (n >= VECTORS_16_BUNDLE_START)
Index: kernel/arch/ia64/src/mm/as.c
===================================================================
--- kernel/arch/ia64/src/mm/as.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/mm/as.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #include <arch/mm/asid.h>
 #include <arch/mm/page.h>
+#include <assert.h>
 #include <genarch/mm/as_ht.h>
 #include <genarch/mm/page_ht.h>
@@ -58,5 +59,5 @@
 	int i;
 	
-	ASSERT(as->asid != ASID_INVALID);
+	assert(as->asid != ASID_INVALID);
 	
 	/*
Index: kernel/arch/ia64/src/mm/page.c
===================================================================
--- kernel/arch/ia64/src/mm/page.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/mm/page.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
 
 #include <arch/mm/page.h>
+#include <assert.h>
 #include <genarch/mm/page_ht.h>
 #include <mm/asid.h>
@@ -47,5 +48,4 @@
 #include <arch/asm.h>
 #include <arch/barrier.h>
-#include <memstr.h>
 #include <align.h>
 
@@ -167,5 +167,5 @@
 	bool match;
 
-	ASSERT(v);
+	assert(v);
 
 	vrn = page >> VRN_SHIFT;
@@ -214,5 +214,5 @@
 	uint64_t tag;
 
-	ASSERT(v);
+	assert(v);
 
 	vrn = page >> VRN_SHIFT;
Index: kernel/arch/ia64/src/mm/tlb.c
===================================================================
--- kernel/arch/ia64/src/mm/tlb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/mm/tlb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,4 +48,5 @@
 #include <arch/pal/pal.h>
 #include <arch/asm.h>
+#include <assert.h>
 #include <panic.h>
 #include <print.h>
@@ -449,5 +450,5 @@
 	entry.word[1] = 0;
 	
-	ASSERT(t->x);
+	assert(t->x);
 	
 	entry.p = t->p;
@@ -488,9 +489,9 @@
 	va = istate->cr_ifa; /* faulting address */
 	
-	ASSERT(!is_kernel_fault(va));
+	assert(!is_kernel_fault(va));
 
 	bool found = page_mapping_find(AS, va, true, &t);
 	if (found) {
-		ASSERT(t.p);
+		assert(t.p);
 
 		/*
@@ -605,5 +606,5 @@
 	bool found = page_mapping_find(as, va, true, &t);
 	if (found) {
-		ASSERT(t.p);
+		assert(t.p);
 
 		/*
@@ -634,5 +635,5 @@
 void data_nested_tlb_fault(unsigned int n, istate_t *istate)
 {
-	ASSERT(false);
+	assert(false);
 }
 
@@ -656,6 +657,6 @@
 	bool found = page_mapping_find(as, va, true, &t);
 
-	ASSERT(found);
-	ASSERT(t.p);
+	assert(found);
+	assert(t.p);
 
 	if (found && t.p && t.w) {
@@ -685,10 +686,10 @@
 	va = istate->cr_ifa;  /* faulting address */
 
-	ASSERT(!is_kernel_fault(va));
+	assert(!is_kernel_fault(va));
 	
 	bool found = page_mapping_find(AS, va, true, &t);
 
-	ASSERT(found);
-	ASSERT(t.p);
+	assert(found);
+	assert(t.p);
 
 	if (found && t.p && t.x) {
@@ -724,6 +725,6 @@
 	bool found = page_mapping_find(as, va, true, &t);
 
-	ASSERT(found);
-	ASSERT(t.p);
+	assert(found);
+	assert(t.p);
 
 	if (found && t.p) {
@@ -757,5 +758,5 @@
 	va = istate->cr_ifa;  /* faulting address */
 
-	ASSERT(!is_kernel_fault(va));
+	assert(!is_kernel_fault(va));
 	
 	/*
@@ -764,7 +765,7 @@
 	bool found = page_mapping_find(AS, va, true, &t);
 
-	ASSERT(found);
-	ASSERT(t.p);
-	ASSERT(!t.w);
+	assert(found);
+	assert(t.p);
+	assert(!t.w);
 
 	as_page_fault(va, PF_ACCESS_WRITE, istate);
@@ -784,9 +785,9 @@
 	va = istate->cr_ifa;  /* faulting address */
 	
-	ASSERT(!is_kernel_fault(va));
+	assert(!is_kernel_fault(va));
 
 	bool found = page_mapping_find(AS, va, true, &t);
 
-	ASSERT(found);
+	assert(found);
 	
 	if (t.p) {
Index: kernel/arch/ia64/src/mm/vhpt.c
===================================================================
--- kernel/arch/ia64/src/mm/vhpt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ia64/src/mm/vhpt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
 */
 
-#include <memstr.h>
+#include <mem.h>
 #include <arch/mm/vhpt.h>
 #include <mm/frame.h>
Index: kernel/arch/mips32/Makefile.inc
===================================================================
--- kernel/arch/mips32/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -29,5 +29,5 @@
 BFD_ARCH = mips
 BFD = binary
-GCC_CFLAGS += -msoft-float -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mabi=32
+COMMON_CFLAGS += -msoft-float -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mabi=32
 AS_PROLOG = .module softfloat;
 
@@ -40,15 +40,15 @@
 	BFD_NAME = elf32-tradlittlemips
 	ENDIANESS = LE
-	GCC_CFLAGS += -march=r4000
+	COMMON_CFLAGS += -march=r4000
 endif
 ifeq ($(MACHINE),bmalta)
 	BFD_NAME = elf32-tradbigmips
 	ENDIANESS = BE
-	GCC_CFLAGS += -D__BE__ -march=4kc
+	COMMON_CFLAGS += -D__BE__ -march=4kc
 endif
 ifeq ($(MACHINE),lmalta)
 	BFD_NAME = elf32-tradlittlemips
 	ENDIANESS = LE
-	GCC_CFLAGS += -march=4kc
+	COMMON_CFLAGS += -march=4kc
 endif
 
Index: kernel/arch/mips32/include/arch/arch.h
===================================================================
--- kernel/arch/mips32/include/arch/arch.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/arch.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,6 @@
 #define KERN_mips32_ARCH_H_
 
-#include <typedefs.h>
+#include <stddef.h>
+#include <stdint.h>
 
 #define TASKMAP_MAX_RECORDS        32
Index: kernel/arch/mips32/include/arch/context.h
===================================================================
--- kernel/arch/mips32/include/arch/context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,4 @@
 #include <arch/stack.h>
 #include <arch/context_struct.h>
-#include <typedefs.h>
 
 /*
Index: kernel/arch/mips32/include/arch/cp0.h
===================================================================
--- kernel/arch/mips32/include/arch/cp0.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/cp0.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,6 @@
 #ifndef KERN_mips32_CP0_H_
 #define KERN_mips32_CP0_H_
+
+#include <stdint.h>
 
 #define cp0_status_ie_enabled_bit     (1 << 0)
Index: kernel/arch/mips32/include/arch/cpu.h
===================================================================
--- kernel/arch/mips32/include/arch/cpu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/cpu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,6 @@
 #define KERN_mips32_CPU_H_
 
-#include <typedefs.h>
 #include <arch/asm.h>
+#include <stdint.h>
 
 typedef struct {
Index: kernel/arch/mips32/include/arch/debugger.h
===================================================================
--- kernel/arch/mips32/include/arch/debugger.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/debugger.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <arch/exception.h>
 #include <typedefs.h>
+#include <stdbool.h>
 
 #define BKPOINTS_MAX 10
Index: kernel/arch/mips32/include/arch/exception.h
===================================================================
--- kernel/arch/mips32/include/arch/exception.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/exception.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_mips32_EXCEPTION_H_
 
-#include <typedefs.h>
 #include <arch/istate.h>
 
Index: kernel/arch/mips32/include/arch/interrupt.h
===================================================================
--- kernel/arch/mips32/include/arch/interrupt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/interrupt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_mips32_INTERRUPT_H_
 
-#include <typedefs.h>
 #include <arch/exception.h>
 
Index: kernel/arch/mips32/include/arch/mm/asid.h
===================================================================
--- kernel/arch/mips32/include/arch/mm/asid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/mm/asid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_mips32_ASID_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #define ASID_MAX_ARCH  255    /* 2^8 - 1 */
Index: kernel/arch/mips32/include/arch/mm/km.h
===================================================================
--- kernel/arch/mips32/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_mips32_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/mips32/include/arch/mm/tlb.h
===================================================================
--- kernel/arch/mips32/include/arch/mm/tlb.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/mm/tlb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,8 +36,9 @@
 #define KERN_mips32_TLB_H_
 
-#include <typedefs.h>
 #include <arch/mm/asid.h>
 #include <arch/exception.h>
+#include <stdbool.h>
 #include <trace.h>
+#include <typedefs.h>
 
 #if defined(PROCESSOR_R4000)
Index: kernel/arch/mips32/include/arch/smp/dorder.h
===================================================================
--- kernel/arch/mips32/include/arch/smp/dorder.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/smp/dorder.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_mips32_DORDER_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 extern uint32_t dorder_cpuid(void);
Index: kernel/arch/mips32/include/arch/types.h
===================================================================
--- kernel/arch/mips32/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_mips32_TYPES_H_
 
+#include <arch/common.h>
+
 typedef uint32_t size_t;
 typedef int32_t ssize_t;
@@ -51,7 +53,4 @@
 } fncptr_t;
 
-#define INTN_C(c)   INT32_C(c)
-#define UINTN_C(c)  UINT32_C(c)
-
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: kernel/arch/mips32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/mips32/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -62,4 +62,5 @@
 
 #include <stacktrace.h>
+#include <stddef.h>
 #include <syscall/copy.h>
 #include <typedefs.h>
Index: kernel/arch/mips32/src/debugger.c
===================================================================
--- kernel/arch/mips32/src/debugger.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/src/debugger.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,5 +35,4 @@
 #include <arch/debugger.h>
 #include <arch/barrier.h>
-#include <memstr.h>
 #include <console/kconsole.h>
 #include <console/cmd.h>
Index: kernel/arch/mips32/src/exception.c
===================================================================
--- kernel/arch/mips32/src/exception.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/src/exception.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,7 +38,6 @@
 #include <panic.h>
 #include <arch/cp0.h>
-#include <typedefs.h>
 #include <arch.h>
-#include <debug.h>
+#include <assert.h>
 #include <proc/thread.h>
 #include <print.h>
@@ -121,5 +120,5 @@
 {
 	if (*((uint32_t *) istate->epc) == 0x7c03e83b) {
-		ASSERT(THREAD);
+		assert(THREAD);
 		istate->epc += 4;
 		istate->v1 = istate->kt1;
Index: kernel/arch/mips32/src/interrupt.c
===================================================================
--- kernel/arch/mips32/src/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/src/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,4 @@
 #include <time/clock.h>
 #include <ipc/sysipc.h>
-#include <ddi/device.h>
 
 #define IRQ_COUNT   8
@@ -175,5 +174,4 @@
 	
 	irq_initialize(&timer_irq);
-	timer_irq.devno = device_assign_devno();
 	timer_irq.inr = TIMER_IRQ;
 	timer_irq.claim = timer_claim;
@@ -186,5 +184,4 @@
 #ifdef MACHINE_msim
 	irq_initialize(&dorder_irq);
-	dorder_irq.devno = device_assign_devno();
 	dorder_irq.inr = DORDER_IRQ;
 	dorder_irq.claim = dorder_claim;
Index: kernel/arch/mips32/src/machine_func.c
===================================================================
--- kernel/arch/mips32/src/machine_func.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/src/machine_func.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
  */
 
+#include <stddef.h>
 #include <arch/machine_func.h>
 #if defined(MACHINE_msim)
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/src/mips32.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,5 @@
 #include <macros.h>
 #include <str.h>
-#include <memstr.h>
+#include <mem.h>
 #include <userspace.h>
 #include <syscall/syscall.h>
Index: kernel/arch/mips32/src/mm/tlb.c
===================================================================
--- kernel/arch/mips32/src/mm/tlb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/src/mm/tlb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,5 @@
 #include <print.h>
 #include <log.h>
-#include <debug.h>
+#include <assert.h>
 #include <align.h>
 #include <interrupt.h>
@@ -160,5 +160,5 @@
 #endif
 
-	ASSERT(!index.p);
+	assert(!index.p);
 
 	badvaddr = cp0_badvaddr_read();
@@ -323,5 +323,5 @@
 	int i;
 
-	ASSERT(interrupts_disabled());
+	assert(interrupts_disabled());
 
 	hi_save.value = cp0_entry_hi_read();
@@ -356,6 +356,6 @@
 	int i;
 
-	ASSERT(interrupts_disabled());
-	ASSERT(asid != ASID_INVALID);
+	assert(interrupts_disabled());
+	assert(asid != ASID_INVALID);
 
 	hi_save.value = cp0_entry_hi_read();
@@ -398,5 +398,5 @@
 	tlb_index_t index;
 
-	ASSERT(interrupts_disabled());
+	assert(interrupts_disabled());
 	
 	if (asid == ASID_INVALID)
Index: kernel/arch/mips32/src/smp/dorder.c
===================================================================
--- kernel/arch/mips32/src/smp/dorder.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/mips32/src/smp/dorder.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
  */
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <smp/ipi.h>
 #include <arch/smp/dorder.h>
Index: kernel/arch/ppc32/Makefile.inc
===================================================================
--- kernel/arch/ppc32/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,5 @@
 BFD = binary
 
-GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
+COMMON_CFLAGS += -mcpu=powerpc -msoft-float -m32
 AFLAGS += -a32
 LFLAGS += -no-check-sections
Index: kernel/arch/ppc32/include/arch/boot/boot.h
===================================================================
--- kernel/arch/ppc32/include/arch/boot/boot.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/include/arch/boot/boot.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,7 +44,7 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
 #include <config.h>
 #include <genarch/ofw/ofw_tree.h>
+#include <stddef.h>
 
 typedef struct {
Index: kernel/arch/ppc32/include/arch/cpu.h
===================================================================
--- kernel/arch/ppc32/include/arch/cpu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/include/arch/cpu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_ppc32_CPU_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <trace.h>
 
Index: kernel/arch/ppc32/include/arch/mm/asid.h
===================================================================
--- kernel/arch/ppc32/include/arch/mm/asid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/include/arch/mm/asid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_ppc32_ASID_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #define ASID_MAX_ARCH  4096
Index: kernel/arch/ppc32/include/arch/mm/frame.h
===================================================================
--- kernel/arch/ppc32/include/arch/mm/frame.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/include/arch/mm/frame.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <trace.h>
 
Index: kernel/arch/ppc32/include/arch/mm/km.h
===================================================================
--- kernel/arch/ppc32/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_ppc32_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/ppc32/include/arch/types.h
===================================================================
--- kernel/arch/ppc32/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_ppc32_TYPES_H_
 
+#include <arch/common.h>
+
 typedef uint32_t size_t;
 typedef int32_t ssize_t;
@@ -51,7 +53,4 @@
 } fncptr_t;
 
-#define INTN_C(c)   INT32_C(c)
-#define UINTN_C(c)  UINT32_C(c)
-
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: kernel/arch/ppc32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ppc32/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 
 #include <stacktrace.h>
+#include <stdbool.h>
 #include <syscall/copy.h>
 #include <typedefs.h>
Index: kernel/arch/ppc32/src/interrupt.c
===================================================================
--- kernel/arch/ppc32/src/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/src/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 #include <arch/interrupt.h>
 #include <arch/istate.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <arch.h>
 #include <ipc/sysipc.h>
Index: kernel/arch/ppc32/src/mm/pht.c
===================================================================
--- kernel/arch/ppc32/src/mm/pht.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/ppc32/src/mm/pht.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
 #include <arch/mm/pht.h>
 #include <arch/mm/tlb.h>
+#include <assert.h>
 #include <interrupt.h>
 #include <mm/as.h>
@@ -79,6 +80,6 @@
 		found = page_mapping_find(as, badvaddr, true, pte);
 
-		ASSERT(found);
-		ASSERT(pte->present);
+		assert(found);
+		assert(pte->present);
 
 		return found;
Index: kernel/arch/riscv64/Makefile.inc
===================================================================
--- kernel/arch/riscv64/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,10 +31,15 @@
 BFD = binary
 
+COMMON_CFLAGS += -mcmodel=medany
+
 BITS = 64
 ENDIANESS = LE
 
 ARCH_SOURCES = \
+	arch/$(KARCH)/src/boot/boot.S \
 	arch/$(KARCH)/src/asm.S \
+	arch/$(KARCH)/src/context.S \
 	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/drivers/ucb.c \
 	arch/$(KARCH)/src/proc/scheduler.c \
 	arch/$(KARCH)/src/proc/task.c \
Index: kernel/arch/riscv64/_link.ld.in
===================================================================
--- kernel/arch/riscv64/_link.ld.in	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/_link.ld.in	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -14,17 +14,7 @@
 
 SECTIONS {
-	.unmapped BOOT_OFFSET: AT (0) {
-		unmapped_ktext_start = .;
+	.image (PA2KA(BOOT_OFFSET)) : AT (0) {
+		ktext_start = .;
 		*(K_TEXT_START);
-		unmapped_ktext_end = .;
-		
-		unmapped_kdata_start = .;
-		*(K_DATA_START);
-		*(K_INI_PTLS);
-		unmapped_kdata_end = .;
-	}
-	
-	.mapped (BOOT_OFFSET + SIZEOF(.unmapped)) : AT (SIZEOF(.unmapped)) {
-		ktext_start = .;
 		*(.text);
 		ktext_end = .;
@@ -36,11 +26,7 @@
 		QUAD(PA2KA(BOOT_OFFSET));
 		hardcoded_ktext_size = .;
-		QUAD(ktext_end - ktext_start + (unmapped_ktext_end - unmapped_ktext_start));
+		QUAD(ktext_end - ktext_start);
 		hardcoded_kdata_size = .;
-		QUAD(kdata_end - kdata_start + (unmapped_kdata_end - unmapped_kdata_start));
-		hardcoded_unmapped_ktext_size = .;
-		QUAD(unmapped_ktext_end - unmapped_ktext_start);
-		hardcoded_unmapped_kdata_size = .;
-		QUAD(unmapped_kdata_end - unmapped_kdata_start);
+		QUAD(kdata_end - kdata_start);
 		*(.sdata);
 		*(.reginfo);
Index: kernel/arch/riscv64/include/arch/arch.h
===================================================================
--- kernel/arch/riscv64/include/arch/arch.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/arch.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,6 @@
 #include <arch/boot/boot.h>
 
+extern void riscv64_pre_main(bootinfo_t *);
+
 #endif
 
Index: kernel/arch/riscv64/include/arch/asm.h
===================================================================
--- kernel/arch/riscv64/include/arch/asm.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/asm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_riscv64_ASM_H_
 
+#include <arch/cpu.h>
 #include <typedefs.h>
 #include <config.h>
@@ -43,35 +44,62 @@
 NO_TRACE static inline ipl_t interrupts_enable(void)
 {
-	// FIXME
-	return 0;
+	ipl_t ipl;
+	
+	asm volatile (
+		"csrrsi %[ipl], sstatus, " STRING(SSTATUS_SIE_MASK) "\n"
+		: [ipl] "=r" (ipl)
+	);
+	
+	return ipl;
 }
 
 NO_TRACE static inline ipl_t interrupts_disable(void)
 {
-	// FIXME
-	return 0;
+	ipl_t ipl;
+	
+	asm volatile (
+		"csrrci %[ipl], sstatus, " STRING(SSTATUS_SIE_MASK) "\n"
+		: [ipl] "=r" (ipl)
+	);
+	
+	return ipl;
 }
 
 NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
-	// FIXME
+	if ((ipl & SSTATUS_SIE_MASK) == SSTATUS_SIE_MASK)
+		interrupts_enable();
+	else
+		interrupts_disable();
 }
 
 NO_TRACE static inline ipl_t interrupts_read(void)
 {
-	// FIXME
-	return 0;
+	ipl_t ipl;
+	
+	asm volatile (
+		"csrr %[ipl], sstatus\n"
+		: [ipl] "=r" (ipl)
+	);
+	
+	return ipl;
 }
 
 NO_TRACE static inline bool interrupts_disabled(void)
 {
-	// FIXME
-	return 0;
+	return ((interrupts_read() & SSTATUS_SIE_MASK) == 0);
 }
 
 NO_TRACE static inline uintptr_t get_stack_base(void)
 {
-	// FIXME
-	return 0;
+	uintptr_t base;
+	
+	asm volatile (
+		"and %[base], sp, %[mask]\n"
+		: [base] "=r" (base)
+		: [mask] "r" (~(STACK_SIZE - 1))
+	);
+	
+	return base;
 }
 
Index: kernel/arch/riscv64/include/arch/atomic.h
===================================================================
--- kernel/arch/riscv64/include/arch/atomic.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/atomic.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,34 +40,70 @@
 NO_TRACE static inline void atomic_inc(atomic_t *val)
 {
-	// FIXME
+	asm volatile (
+		"amoadd.d zero, %[inc], %[addr]\n"
+		: [addr] "+A" (val->count)
+		: [inc] "r" (1)
+	);
 }
 
 NO_TRACE static inline void atomic_dec(atomic_t *val)
 {
-	// FIXME
+	asm volatile (
+		"amoadd.d zero, %[inc], %[addr]\n"
+		: [addr] "+A" (val->count)
+		: [inc] "r" (-1)
+	);
 }
 
 NO_TRACE static inline atomic_count_t atomic_postinc(atomic_t *val)
 {
-	atomic_inc(val);
-	return val->count - 1;
+	atomic_count_t orig;
+	
+	asm volatile (
+		"amoadd.d %[orig], %[inc], %[addr]\n"
+		: [orig] "=r" (orig), [addr] "+A" (val->count)
+		: [inc] "r" (1)
+	);
+	
+	return orig;
 }
 
 NO_TRACE static inline atomic_count_t atomic_postdec(atomic_t *val)
 {
-	atomic_dec(val);
-	return val->count + 1;
+	atomic_count_t orig;
+	
+	asm volatile (
+		"amoadd.d %[orig], %[inc], %[addr]\n"
+		: [orig] "=r" (orig), [addr] "+A" (val->count)
+		: [inc] "r" (-1)
+	);
+	
+	return orig;
 }
 
 NO_TRACE static inline atomic_count_t atomic_preinc(atomic_t *val)
 {
-	atomic_inc(val);
-	return val->count;
+	atomic_count_t orig;
+	
+	asm volatile (
+		"amoadd.d %[orig], %[inc], %[addr]\n"
+		: [orig] "=r" (orig), [addr] "+A" (val->count)
+		: [inc] "r" (1)
+	);
+	
+	return orig - 1;
 }
 
 NO_TRACE static inline atomic_count_t atomic_predec(atomic_t *val)
 {
-	atomic_dec(val);
-	return val->count;
+	atomic_count_t orig;
+	
+	asm volatile (
+		"amoadd.d %[orig], %[inc], %[addr]\n"
+		: [orig] "=r" (orig), [addr] "+A" (val->count)
+		: [inc] "r" (-1)
+	);
+	
+	return orig + 1;
 }
 
Index: kernel/arch/riscv64/include/arch/boot/boot.h
===================================================================
--- kernel/arch/riscv64/include/arch/boot/boot.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/boot/boot.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_riscv64_BOOT_H_
 
-#define BOOT_OFFSET  0x200000
+#define BOOT_OFFSET  0x48000000
 
 #define TASKMAP_MAX_RECORDS        32
@@ -42,8 +42,28 @@
 #define BOOTINFO_TASK_NAME_BUFLEN  32
 
+/* Temporary stack size for boot process */
+#define TEMP_STACK_SIZE  0x1000
+
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <config.h>
+
+typedef struct {
+	volatile uint64_t *tohost;
+	volatile uint64_t *fromhost;
+} ucbinfo_t;
+
+typedef struct {
+	void *start;
+	size_t size;
+} memzone_t;
+
+typedef struct {
+	uint64_t total;
+	size_t cnt;
+	memzone_t zones[MEMMAP_MAX_RECORDS];
+} memmap_t;
 
 typedef struct {
@@ -59,21 +79,11 @@
 
 typedef struct {
-	void *start;
-	size_t size;
-} memzone_t;
-
-typedef struct {
-	uint64_t total;
-	size_t cnt;
-	memzone_t zones[MEMMAP_MAX_RECORDS];
-} memmap_t;
-
-typedef struct {
+	ucbinfo_t ucbinfo;
+	uintptr_t physmem_start;
+	uintptr_t htif_frame;
+	uintptr_t pt_frame;
 	memmap_t memmap;
 	taskmap_t taskmap;
-	ballocs_t ballocs;
 } bootinfo_t;
-
-extern memmap_t memmap;
 
 #endif
Index: kernel/arch/riscv64/include/arch/context.h
===================================================================
--- kernel/arch/riscv64/include/arch/context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,6 +40,4 @@
 #define SP_DELTA  16
 
-// FIXME
-
 #define context_set(context, pc, stack, size) \
 	context_set_generic(context, pc, stack, size)
Index: kernel/arch/riscv64/include/arch/context_struct.ag
===================================================================
--- kernel/arch/riscv64/include/arch/context_struct.ag	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/context_struct.ag	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,6 +38,6 @@
         members : [
                 #
-                # There is a room for optimization (we can store just those
-                # registers that must be preserved during ABI function call).
+                # Only save registers that must be preserved across function
+                # calls.
                 #
 
@@ -52,126 +52,57 @@
 
                 {
-                        name : zero,
+                        name : gp,
                         type : uint64_t
                 },
                 {
-                        name : ra,
-                        type : uint64_t
-                },
-
-                {
-                        name : x3,
+                        name : tp,
                         type : uint64_t
                 },
                 {
-                        name : x4,
+                        name : s0,
                         type : uint64_t
                 },
                 {
-                        name : x5,
+                        name : s1,
                         type : uint64_t
                 },
                 {
-                        name : x6,
+                        name : s2,
                         type : uint64_t
                 },
                 {
-                        name : x7,
+                        name : s3,
                         type : uint64_t
                 },
                 {
-                        name : x8,
+                        name : s4,
                         type : uint64_t
                 },
                 {
-                        name : x9,
+                        name : s5,
                         type : uint64_t
                 },
                 {
-                        name : x10,
+                        name : s6,
                         type : uint64_t
                 },
                 {
-                        name : x11,
+                        name : s7,
                         type : uint64_t
                 },
                 {
-                        name : x12,
+                        name : s8,
                         type : uint64_t
                 },
                 {
-                        name : x13,
+                        name : s9,
                         type : uint64_t
                 },
                 {
-                        name : x14,
+                        name : s10,
                         type : uint64_t
                 },
                 {
-                        name : x15,
-                        type : uint64_t
-                },
-                {
-                        name : x16,
-                        type : uint64_t
-                },
-                {
-                        name : x17,
-                        type : uint64_t
-                },
-                {
-                        name : x18,
-                        type : uint64_t
-                },
-                {
-                        name : x19,
-                        type : uint64_t
-                },
-                {
-                        name : x20,
-                        type : uint64_t
-                },
-                {
-                        name : x21,
-                        type : uint64_t
-                },
-                {
-                        name : x22,
-                        type : uint64_t
-                },
-                {
-                        name : x23,
-                        type : uint64_t
-                },
-                {
-                        name : x24,
-                        type : uint64_t
-                },
-                {
-                        name : x25,
-                        type : uint64_t
-                },
-                {
-                        name : x26,
-                        type : uint64_t
-                },
-                {
-                        name : x27,
-                        type : uint64_t
-                },
-                {
-                        name : x28,
-                        type : uint64_t
-                },
-                {
-                        name : x29,
-                        type : uint64_t
-                },
-                {
-                        name : x30,
-                        type : uint64_t
-                },
-                {
-                        name : x31,
+                        name : s11,
                         type : uint64_t
                 },
Index: kernel/arch/riscv64/include/arch/cpu.h
===================================================================
--- kernel/arch/riscv64/include/arch/cpu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/cpu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,13 @@
 #define KERN_riscv64_CPU_H_
 
+#define SSTATUS_SIE_MASK  0x00000002
+
+#define SATP_PFN_MASK  UINT64_C(0x00000fffffffffff)
+
+#define SATP_MODE_MASK  UINT64_C(0xf000000000000000)
+#define SATP_MODE_BARE  UINT64_C(0x0000000000000000)
+#define SATP_MODE_SV39  UINT64_C(0x8000000000000000)
+#define SATP_MODE_SV48  UINT64_C(0x9000000000000000)
+
 #ifndef __ASM__
 
Index: kernel/arch/riscv64/include/arch/cycle.h
===================================================================
--- kernel/arch/riscv64/include/arch/cycle.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/cycle.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,12 @@
 NO_TRACE static inline uint64_t get_cycle(void)
 {
-	return 0;
+	uint64_t cycle;
+	
+	asm volatile (
+		"rdcycle %[cycle]\n"
+		: [cycle] "=r" (cycle)
+	);
+	
+	return cycle;
 }
 
Index: kernel/arch/riscv64/include/arch/drivers/ucb.h
===================================================================
--- kernel/arch/riscv64/include/arch/drivers/ucb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/arch/riscv64/include/arch/drivers/ucb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 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 riscv64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_riscv64_DRIVERS_UCB_H_
+#define KERN_riscv64_DRIVERS_UCB_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <console/chardev.h>
+
+extern void htif_init(volatile uint64_t *, volatile uint64_t *);
+extern outdev_t *htifout_init(void);
+extern void htif_putchar(outdev_t *, const wchar_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/riscv64/include/arch/fpu_context.h
===================================================================
--- kernel/arch/riscv64/include/arch/fpu_context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/fpu_context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_riscv64_FPU_CONTEXT_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 typedef struct {
Index: kernel/arch/riscv64/include/arch/istate_struct.ag
===================================================================
--- kernel/arch/riscv64/include/arch/istate_struct.ag	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/istate_struct.ag	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,9 @@
                 },
                 {
-                        negative-guard: KERNEL,
+                        negative-guard : KERNEL,
+                        include : <stddef.h>
+                },
+                {
+                        negative-guard : KERNEL,
                         include : <stdint.h>
                 }
Index: kernel/arch/riscv64/include/arch/mm/asid.h
===================================================================
--- kernel/arch/riscv64/include/arch/mm/asid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/mm/asid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_riscv64_ASID_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #define ASID_MAX_ARCH  4096
@@ -42,4 +42,7 @@
 typedef uint32_t asid_t;
 
+#define asid_get()  (ASID_START + 1)
+#define asid_put(asid)
+
 #endif
 
Index: kernel/arch/riscv64/include/arch/mm/frame.h
===================================================================
--- kernel/arch/riscv64/include/arch/mm/frame.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/mm/frame.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,10 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <arch/boot/boot.h>
+
+extern uintptr_t physmem_start;
+extern uintptr_t htif_frame;
+extern uintptr_t pt_frame;
+extern memmap_t memmap;
 
 extern void frame_low_arch_init(void);
Index: kernel/arch/riscv64/include/arch/mm/km.h
===================================================================
--- kernel/arch/riscv64/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,12 @@
 #define KERN_riscv64_KM_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#define KM_RISCV64_IDENTITY_START      UINT64_C(0xffff800000000000)
+#define KM_RISCV64_IDENTITY_SIZE       UINT64_C(0x0000400000000000)
+
+#define KM_RISCV64_NON_IDENTITY_START  UINT64_C(0xffffc00000000000)
+#define KM_RISCV64_NON_IDENTITY_SIZE   UINT64_C(0x0000400000000000)
 
 extern void km_identity_arch_init(void);
Index: kernel/arch/riscv64/include/arch/mm/page.h
===================================================================
--- kernel/arch/riscv64/include/arch/mm/page.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/mm/page.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -50,48 +50,4 @@
 
 /*
- * Page table entry types.
- *
- * - PTE_TYPE_PTR:         pointer to next level PTE
- * - PTE_TYPE_PTR_GLOBAL:  pointer to next level PTE (global mapping)
- *
- * - PTE_TYPE_SRURX:       kernel read, user read execute
- * - PTE_TYPE_SRWURWX:     kernel read write, user read write execute
- * - PTE_TYPE_SRUR:        kernel read, user read
- * - PTE_TYPE_SRWURW:      kernel read write, user read write
- * - PTE_TYPE_SRXURX:      kernel read execute, user read execute
- * - PTE_TYPE_SRWXURWX:    kernel read write execute, user read write execute
- *
- * - PTE_TYPE_SR:          kernel read
- * - PTE_TYPE_SRW:         kernel read write
- * - PTE_TYPE_SRX:         kernel read execute
- * - PTE_TYPE_SRWX:        kernel read write execute
- *
- * - PTE_TYPE_SR_GLOBAL:   kernel read (global mapping)
- * - PTE_TYPE_SRW_GLOBAL:  kernel read write (global mapping)
- * - PTE_TYPE_SRX_GLOBAL:  kernel read execute (global mapping)
- * - PTE_TYPE_SRWX_GLOBAL: kernel read write execute (global mapping)
- */
-
-#define PTE_TYPE_PTR          0
-#define PTE_TYPE_PTR_GLOBAL   1
-
-#define PTE_TYPE_SRURX        2
-#define PTE_TYPE_SRWURWX      3
-#define PTE_TYPE_SRUR         4
-#define PTE_TYPE_SRWURW       5
-#define PTE_TYPE_SRXURX       6
-#define PTE_TYPE_SRWXURWX     7
-
-#define PTE_TYPE_SR           8
-#define PTE_TYPE_SRW          9
-#define PTE_TYPE_SRX          10
-#define PTE_TYPE_SRWX         11
-
-#define PTE_TYPE_SR_GLOBAL    12
-#define PTE_TYPE_SRW_GLOBAL   13
-#define PTE_TYPE_SRX_GLOBAL   14
-#define PTE_TYPE_SRWX_GLOBAL  15
-
-/*
  * Implementation of 4-level page table interface.
  *
@@ -125,4 +81,7 @@
 #define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x1ff)
 
+/* Flags mask for non-leaf page table entries */
+#define NON_LEAF_MASK  (~(PAGE_READ | PAGE_WRITE | PAGE_EXEC))
+
 /* Get PTE address accessors for each level. */
 #define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
@@ -139,5 +98,6 @@
 
 /* Set PTE address accessors for each level. */
-#define SET_PTL0_ADDRESS_ARCH(ptl0)
+#define SET_PTL0_ADDRESS_ARCH(ptl0) \
+	(write_satp((uintptr_t) (ptl0)))
 
 #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
@@ -167,15 +127,15 @@
 
 /* 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) \
-	set_pt_flags((pte_t *) (ptl1), (size_t) (i), (x))
-
-#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) \
-	set_pt_flags((pte_t *) (ptl2), (size_t) (i), (x))
-
-#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
-	set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, flags) \
+	set_pt_flags((pte_t *) (ptl0), (size_t) (i), ((flags) & NON_LEAF_MASK))
+
+#define SET_PTL2_FLAGS_ARCH(ptl1, i, flags) \
+	set_pt_flags((pte_t *) (ptl1), (size_t) (i), ((flags) & NON_LEAF_MASK))
+
+#define SET_PTL3_FLAGS_ARCH(ptl2, i, flags) \
+	set_pt_flags((pte_t *) (ptl2), (size_t) (i), ((flags) & NON_LEAF_MASK))
+
+#define SET_FRAME_FLAGS_ARCH(ptl3, i, flags) \
+	set_pt_flags((pte_t *) (ptl3), (size_t) (i), (flags))
 
 /* Set PTE present accessors for each level. */
@@ -196,15 +156,6 @@
 #define PTE_PRESENT_ARCH(pte)     ((pte)->valid != 0)
 #define PTE_GET_FRAME_ARCH(pte)   ((uintptr_t) (pte)->pfn << 12)
-
-#define PTE_WRITABLE_ARCH(pte) \
-	(((pte)->type == PTE_TYPE_SRWURWX) || \
-	((pte)->type == PTE_TYPE_SRWURW) || \
-	((pte)->type == PTE_TYPE_SRWXURWX))
-
-#define PTE_EXECUTABLE_ARCH(pte) \
-	(((pte)->type == PTE_TYPE_SRURX) || \
-	((pte)->type == PTE_TYPE_SRWURWX) || \
-	((pte)->type == PTE_TYPE_SRXURX) || \
-	((pte)->type == PTE_TYPE_SRWXURWX))
+#define PTE_WRITABLE_ARCH(pte)    ((pte)->writable != 0)
+#define PTE_EXECUTABLE_ARCH(pte)  ((pte)->executable != 0)
 
 #ifndef __ASM__
@@ -212,13 +163,17 @@
 #include <mm/mm.h>
 #include <arch/interrupt.h>
-#include <typedefs.h>
+#include <stdint.h>
 
 /** Page Table Entry. */
 typedef struct {
 	unsigned long valid : 1;       /**< Valid bit. */
-	unsigned long type : 4;        /**< Entry type. */
-	unsigned long referenced : 1;  /**< Refenced bit. */
+	unsigned long readable : 1;    /**< Readable bit. */
+	unsigned long writable : 1;    /**< Writable bit. */
+	unsigned long executable : 1;  /**< Executable bit. */
+	unsigned long user : 1;        /**< User mode accessible bit. */
+	unsigned long global : 1;      /**< Global mapping bit. */
+	unsigned long accessed : 1;    /**< Accessed bit. */
 	unsigned long dirty : 1;       /**< Dirty bit. */
-	unsigned long reserved : 3;    /**< Reserved bits. */
+	unsigned long reserved : 2;    /**< Reserved bits. */
 	unsigned long pfn : 54;        /**< Physical frame number. */
 } pte_t;
@@ -229,9 +184,9 @@
 	
 	return (((!entry->valid) << PAGE_PRESENT_SHIFT) |
-	    ((entry->type < PTE_TYPE_SR) << PAGE_USER_SHIFT) |
-	    PAGE_READ |
-	    (PTE_WRITABLE_ARCH(entry) << PAGE_WRITE_SHIFT) |
-	    (PTE_EXECUTABLE_ARCH(entry) << PAGE_EXEC_SHIFT) |
-	    ((entry->type >= PTE_TYPE_SR_GLOBAL) << PAGE_GLOBAL_SHIFT));
+	    (entry->user << PAGE_USER_SHIFT) |
+	    (entry->readable << PAGE_READ_SHIFT) |
+	    (entry->writable << PAGE_WRITE_SHIFT) |
+	    (entry->executable << PAGE_EXEC_SHIFT) |
+	    (entry->global << PAGE_GLOBAL_SHIFT));
 }
 
@@ -241,16 +196,11 @@
 	
 	entry->valid = !(flags & PAGE_NOT_PRESENT);
-	
-	if ((flags & PAGE_WRITE) != 0) {
-		if ((flags & PAGE_EXEC) != 0)
-			entry->type = PTE_TYPE_SRWXURWX;
-		else
-			entry->type = PTE_TYPE_SRWURW;
-	} else {
-		if ((flags & PAGE_EXEC) != 0)
-			entry->type = PTE_TYPE_SRXURX;
-		else
-			entry->type = PTE_TYPE_SRUR;
-	}
+	entry->readable = (flags & PAGE_READ) != 0;
+	entry->writable = (flags & PAGE_WRITE) != 0;
+	entry->executable = (flags & PAGE_EXEC) != 0;
+	entry->user = (flags & PAGE_USER) != 0;
+	entry->global = (flags & PAGE_GLOBAL) != 0;
+	entry->accessed = 1;
+	entry->dirty = 1;
 }
 
@@ -264,4 +214,5 @@
 extern void page_arch_init(void);
 extern void page_fault(unsigned int, istate_t *);
+extern void write_satp(uintptr_t);
 
 #endif /* __ASM__ */
Index: kernel/arch/riscv64/include/arch/proc/task.h
===================================================================
--- kernel/arch/riscv64/include/arch/proc/task.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/proc/task.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_riscv64_TASK_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 
 typedef struct {
Index: kernel/arch/riscv64/include/arch/types.h
===================================================================
--- kernel/arch/riscv64/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_riscv64_TYPES_H_
 
+#include <arch/common.h>
+
 typedef uint64_t size_t;
 typedef int64_t ssize_t;
@@ -51,7 +53,4 @@
 } fncptr_t;
 
-#define INTN_C(c)   INT64_C(c)
-#define UINTN_C(c)  UINT64_C(c)
-
 #define PRIdn  PRId64  /**< Format for native_t. */
 #define PRIun  PRIu64  /**< Format for sysarg_t. */
Index: kernel/arch/riscv64/src/asm.S
===================================================================
--- kernel/arch/riscv64/src/asm.S	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/asm.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,13 @@
 .text
 
-SYMBOL(kernel_image_start)
-	// FIXME
-	nop
+FUNCTION_BEGIN(asm_delay_loop)
+	ret
+FUNCTION_END(asm_delay_loop)
+
+FUNCTION_BEGIN(early_putchar)
+	ret
+FUNCTION_END(early_putchar)
+
+FUNCTION_BEGIN(cpu_halt)
+	j cpu_halt
+FUNCTION_END(cpu_halt)
Index: kernel/arch/riscv64/src/boot/boot.S
===================================================================
--- kernel/arch/riscv64/src/boot/boot.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/arch/riscv64/src/boot/boot.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <abi/asmtool.h>
+#include <arch/boot/boot.h>
+#include <arch/cpu.h>
+
+.section K_TEXT_START, "ax"
+
+SYMBOL(kernel_image_start)
+	/* Setup temporary stack */
+	la sp, temp_stack
+	
+	/* Create the first stack frame */
+	addi sp, sp, -16
+	
+	/* Call riscv64_pre_main() */
+	jal riscv64_pre_main
+	
+	/* Call main_bsp() */
+	jal main_bsp
+	
+	/* Not reached */
+	csrci sstatus, SSTATUS_SIE_MASK
+	hlt0:
+		wfi
+		j hlt0
+
+.data
+
+.align 16
+.space TEMP_STACK_SIZE
+temp_stack:
Index: kernel/arch/riscv64/src/context.S
===================================================================
--- kernel/arch/riscv64/src/context.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/arch/riscv64/src/context.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2003-2004 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#include <abi/asmtool.h>
+#include <arch/context_struct.h>
+
+.text
+
+FUNCTION_BEGIN(context_save_arch)
+	sd gp, CONTEXT_OFFSET_GP(a0)
+	sd tp, CONTEXT_OFFSET_TP(a0)
+	sd s0, CONTEXT_OFFSET_S0(a0)
+	sd s1, CONTEXT_OFFSET_S1(a0)
+	sd s2, CONTEXT_OFFSET_S2(a0)
+	sd s3, CONTEXT_OFFSET_S3(a0)
+	sd s4, CONTEXT_OFFSET_S4(a0)
+	sd s5, CONTEXT_OFFSET_S5(a0)
+	sd s6, CONTEXT_OFFSET_S6(a0)
+	sd s7, CONTEXT_OFFSET_S7(a0)
+	sd s8, CONTEXT_OFFSET_S8(a0)
+	sd s9, CONTEXT_OFFSET_S9(a0)
+	sd s10, CONTEXT_OFFSET_S10(a0)
+	sd s11, CONTEXT_OFFSET_S11(a0)
+	
+	sd ra, CONTEXT_OFFSET_PC(a0)
+	sd sp, CONTEXT_OFFSET_SP(a0)
+	
+	# context_save returns 1
+	li a0, 1
+	ret
+FUNCTION_END(context_save_arch)
+
+FUNCTION_BEGIN(context_restore_arch)
+	ld gp, CONTEXT_OFFSET_GP(a0)
+	ld tp, CONTEXT_OFFSET_TP(a0)
+	ld s0, CONTEXT_OFFSET_S0(a0)
+	ld s1, CONTEXT_OFFSET_S1(a0)
+	ld s2, CONTEXT_OFFSET_S2(a0)
+	ld s3, CONTEXT_OFFSET_S3(a0)
+	ld s4, CONTEXT_OFFSET_S4(a0)
+	ld s5, CONTEXT_OFFSET_S5(a0)
+	ld s6, CONTEXT_OFFSET_S6(a0)
+	ld s7, CONTEXT_OFFSET_S7(a0)
+	ld s8, CONTEXT_OFFSET_S8(a0)
+	ld s9, CONTEXT_OFFSET_S9(a0)
+	ld s10, CONTEXT_OFFSET_S10(a0)
+	ld s11, CONTEXT_OFFSET_S11(a0)
+	
+	ld ra, CONTEXT_OFFSET_PC(a0)
+	ld sp, CONTEXT_OFFSET_SP(a0)
+	
+	# context_restore returns 0
+	li a0, 0
+	ret
+FUNCTION_END(context_restore_arch)
Index: kernel/arch/riscv64/src/cpu/cpu.c
===================================================================
--- kernel/arch/riscv64/src/cpu/cpu.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/cpu/cpu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #include <cpu.h>
 #include <arch.h>
-#include <typedefs.h>
 #include <print.h>
 #include <fpu_context.h>
@@ -57,5 +56,5 @@
 }
 
-void cpu_print_report(cpu_t* cpu)
+void cpu_print_report(cpu_t *cpu)
 {
 }
Index: kernel/arch/riscv64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/riscv64/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 
 #include <stacktrace.h>
+#include <stdbool.h>
 #include <syscall/copy.h>
 #include <typedefs.h>
Index: kernel/arch/riscv64/src/drivers/ucb.c
===================================================================
--- kernel/arch/riscv64/src/drivers/ucb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/arch/riscv64/src/drivers/ucb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch/drivers/ucb.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <console/chardev.h>
+#include <str.h>
+#include <mm/slab.h>
+
+#define HTIF_DEVICE_CONSOLE  1
+
+#define HTIF_CONSOLE_PUTC  1
+
+static volatile uint64_t *tohost;
+static volatile uint64_t *fromhost;
+
+static outdev_operations_t htifdev_ops = {
+	.write = htif_putchar,
+	.redraw = NULL,
+	.scroll_up = NULL,
+	.scroll_down = NULL
+};
+
+static void poll_fromhost()
+{
+	uint64_t val = *fromhost;
+	if (!val)
+		return;
+	
+	*fromhost = 0;
+}
+
+void htif_init(volatile uint64_t *tohost_addr, volatile uint64_t *fromhost_addr)
+{
+	tohost = tohost_addr;
+	fromhost = fromhost_addr;
+}
+
+outdev_t *htifout_init(void)
+{
+	outdev_t *htifdev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!htifdev)
+		return NULL;
+	
+	outdev_initialize("htifdev", htifdev, &htifdev_ops);
+	return htifdev;
+}
+
+static void htif_cmd(uint8_t device, uint8_t cmd, uint64_t payload)
+{
+	uint64_t val = (((uint64_t) device) << 56) |
+	    (((uint64_t) cmd) << 48) |
+	    (payload & UINT64_C(0xffffffffffff));
+	
+	while (*tohost)
+		poll_fromhost();
+	
+	*tohost = val;
+}
+
+void htif_putchar(outdev_t *dev, const wchar_t ch)
+{
+	if (ascii_check(ch))
+		htif_cmd(HTIF_DEVICE_CONSOLE, HTIF_CONSOLE_PUTC, ch);
+	else
+		htif_cmd(HTIF_DEVICE_CONSOLE, HTIF_CONSOLE_PUTC, U_SPECIAL);
+}
Index: kernel/arch/riscv64/src/mm/as.c
===================================================================
--- kernel/arch/riscv64/src/mm/as.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/mm/as.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,4 +40,15 @@
 }
 
+/** Install address space.
+ *
+ * Install ASID.
+ *
+ * @param as Address space structure.
+ */
+void as_install_arch(as_t *as)
+{
+	// FIXME
+}
+
 /** @}
  */
Index: kernel/arch/riscv64/src/mm/frame.c
===================================================================
--- kernel/arch/riscv64/src/mm/frame.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/mm/frame.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -32,5 +32,7 @@
 
 #include <mm/frame.h>
+#include <arch/boot/boot.h>
 #include <arch/mm/frame.h>
+#include <arch/drivers/ucb.h>
 #include <mm/as.h>
 #include <config.h>
@@ -39,9 +41,10 @@
 #include <align.h>
 #include <macros.h>
-
 #include <print.h>
 
-size_t hardcoded_unmapped_ktext_size = 0;
-size_t hardcoded_unmapped_kdata_size = 0;
+uintptr_t physmem_start;
+uintptr_t htif_frame;
+uintptr_t pt_frame;
+memmap_t memmap;
 
 void physmem_print(void)
@@ -49,11 +52,51 @@
 }
 
+static void frame_common_arch_init(bool low)
+{
+	pfn_t minconf =
+	    max3(ADDR2PFN(physmem_start), htif_frame + 1, pt_frame + 1);
+	
+	for (size_t i = 0; i < memmap.cnt; i++) {
+		/* To be safe, make the available zone possibly smaller */
+		uintptr_t base = ALIGN_UP((uintptr_t) memmap.zones[i].start,
+		    FRAME_SIZE);
+		size_t size = ALIGN_DOWN(memmap.zones[i].size -
+		    (base - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
+		
+		if (!frame_adjust_zone_bounds(low, &base, &size))
+			return;
+		
+		pfn_t pfn = ADDR2PFN(base);
+		size_t count = SIZE2FRAMES(size);
+		pfn_t conf;
+		
+		if (low) {
+			if ((minconf < pfn) || (minconf >= pfn + count))
+				conf = pfn;
+			else
+				conf = minconf;
+			
+			zone_create(pfn, count, conf,
+			    ZONE_AVAILABLE | ZONE_LOWMEM);
+		} else {
+			conf = zone_external_conf_alloc(count);
+			if (conf != 0)
+				zone_create(pfn, count, conf,
+				    ZONE_AVAILABLE | ZONE_HIGHMEM);
+		}
+	}
+}
 
 void frame_low_arch_init(void)
 {
+	frame_common_arch_init(true);
+	
+	frame_mark_unavailable(htif_frame, 1);
+	frame_mark_unavailable(pt_frame, 1);
 }
 
 void frame_high_arch_init(void)
 {
+	frame_common_arch_init(false);
 }
 
Index: kernel/arch/riscv64/src/mm/km.c
===================================================================
--- kernel/arch/riscv64/src/mm/km.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/mm/km.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -32,17 +32,25 @@
 
 #include <arch/mm/km.h>
+#include <mm/km.h>
+#include <stdbool.h>
 #include <typedefs.h>
+#include <macros.h>
 
 void km_identity_arch_init(void)
 {
+	config.identity_base = KM_RISCV64_IDENTITY_START;
+	config.identity_size = KM_RISCV64_IDENTITY_SIZE;
 }
 
 void km_non_identity_arch_init(void)
 {
+	km_non_identity_span_add(KM_RISCV64_NON_IDENTITY_START,
+	    KM_RISCV64_NON_IDENTITY_SIZE);
 }
 
 bool km_is_non_identity_arch(uintptr_t addr)
 {
-	return false;
+	return iswithin(KM_RISCV64_NON_IDENTITY_START,
+	    KM_RISCV64_NON_IDENTITY_SIZE, addr, 1);
 }
 
Index: kernel/arch/riscv64/src/mm/page.c
===================================================================
--- kernel/arch/riscv64/src/mm/page.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/mm/page.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,8 +36,8 @@
 #include <genarch/mm/page_pt.h>
 #include <arch/mm/frame.h>
+#include <arch/cpu.h>
 #include <mm/frame.h>
 #include <mm/page.h>
 #include <mm/as.h>
-#include <typedefs.h>
 #include <align.h>
 #include <config.h>
@@ -46,5 +46,4 @@
 #include <arch/asm.h>
 #include <debug.h>
-#include <memstr.h>
 #include <print.h>
 #include <interrupt.h>
@@ -52,6 +51,27 @@
 void page_arch_init(void)
 {
-	if (config.cpu_active == 1)
+	if (config.cpu_active == 1) {
 		page_mapping_operations = &pt_mapping_operations;
+		
+		page_table_lock(AS_KERNEL, true);
+		
+		/*
+		 * PA2KA(identity) mapping for all low-memory frames.
+		 */
+		for (uintptr_t cur = 0;
+		    cur < min(config.identity_size, config.physmem_end);
+		    cur += FRAME_SIZE)
+			page_mapping_insert(AS_KERNEL, PA2KA(cur), cur,
+			    PAGE_GLOBAL | PAGE_CACHEABLE | PAGE_EXEC | PAGE_WRITE | PAGE_READ);
+		
+		page_table_unlock(AS_KERNEL, true);
+		
+		// FIXME: register page fault extension handler
+		
+		write_satp((uintptr_t) AS_KERNEL->genarch.page_table);
+		
+		/* The boot page table is no longer needed. */
+		// FIXME: frame_mark_available(pt_frame, 1);
+	}
 }
 
@@ -60,4 +80,15 @@
 }
 
+void write_satp(uintptr_t ptl0)
+{
+	uint64_t satp = ((ptl0 >> FRAME_WIDTH) & SATP_PFN_MASK) |
+	    SATP_MODE_SV48;
+	
+	asm volatile (
+		"csrw sptbr, %[satp]\n"
+		:: [satp] "r" (satp)
+	);
+}
+
 /** @}
  */
Index: kernel/arch/riscv64/src/riscv64.c
===================================================================
--- kernel/arch/riscv64/src/riscv64.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/riscv64.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,7 +34,9 @@
 
 #include <arch.h>
-#include <typedefs.h>
+#include <stddef.h>
+#include <arch/arch.h>
 #include <arch/interrupt.h>
 #include <arch/asm.h>
+#include <arch/drivers/ucb.h>
 
 #include <func.h>
@@ -48,13 +50,52 @@
 #include <proc/thread.h>
 #include <console/console.h>
-#include <memstr.h>
+#include <mem.h>
+#include <str.h>
 
 char memcpy_from_uspace_failover_address;
 char memcpy_to_uspace_failover_address;
 
+static void riscv64_post_mm_init(void);
+
 arch_ops_t riscv64_ops = {
+	.post_mm_init = riscv64_post_mm_init
 };
 
 arch_ops_t *arch_ops = &riscv64_ops;
+
+void riscv64_pre_main(bootinfo_t *bootinfo)
+{
+	physmem_start = bootinfo->physmem_start;
+	htif_frame = bootinfo->htif_frame;
+	pt_frame = bootinfo->pt_frame;
+	
+	htif_init(bootinfo->ucbinfo.tohost, bootinfo->ucbinfo.fromhost);
+	
+	/* Copy tasks map. */
+	init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS,
+	    CONFIG_INIT_TASKS);
+	
+	for (size_t i = 0; i < init.cnt; i++) {
+		init.tasks[i].paddr = KA2PA(bootinfo->taskmap.tasks[i].addr);
+		init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo->taskmap.tasks[i].name);
+	}
+	
+	/* Copy physical memory map. */
+	memmap.total = bootinfo->memmap.total;
+	memmap.cnt = min(bootinfo->memmap.cnt, MEMMAP_MAX_RECORDS);
+	for (size_t i = 0; i < memmap.cnt; i++) {
+		memmap.zones[i].start = bootinfo->memmap.zones[i].start;
+		memmap.zones[i].size = bootinfo->memmap.zones[i].size;
+	}
+}
+
+void riscv64_post_mm_init(void)
+{
+	outdev_t *htifout = htifout_init();
+	if (htifout)
+		stdout_wire(htifout);
+}
 
 void calibrate_delay_loop(void)
@@ -90,14 +131,4 @@
 }
 
-int context_save_arch(context_t *ctx)
-{
-	return 1;
-}
-
-void context_restore_arch(context_t *ctx)
-{
-	while (true);
-}
-
 void fpu_init(void)
 {
@@ -122,8 +153,4 @@
 }
 
-void early_putchar(wchar_t ch)
-{
-}
-
 /** @}
  */
Index: kernel/arch/riscv64/src/userspace.c
===================================================================
--- kernel/arch/riscv64/src/userspace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/riscv64/src/userspace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,9 +33,6 @@
  */
 
+#include <abi/proc/uarg.h>
 #include <userspace.h>
-#include <typedefs.h>
-#include <arch.h>
-#include <abi/proc/uarg.h>
-#include <mm/as.h>
 
 void userspace(uspace_arg_t *kernel_uarg)
Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,5 @@
 BFD = binary
 
-GCC_CFLAGS += -m64 -mcpu=ultrasparc -mcmodel=medlow -mno-fpu
+COMMON_CFLAGS += -m64 -mcpu=ultrasparc -mcmodel=medlow -mno-fpu
 
 LFLAGS += -no-check-sections
Index: kernel/arch/sparc64/include/arch/cpu.h
===================================================================
--- kernel/arch/sparc64/include/arch/cpu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/cpu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -54,5 +54,4 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
 #include <arch/register.h>
 #include <arch/regdef.h>
Index: kernel/arch/sparc64/include/arch/drivers/kbd.h
===================================================================
--- kernel/arch/sparc64/include/arch/drivers/kbd.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/drivers/kbd.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_sparc64_KBD_H_
 
-#include <typedefs.h>
 #include <genarch/ofw/ofw_tree.h>
 
Index: kernel/arch/sparc64/include/arch/drivers/pci.h
===================================================================
--- kernel/arch/sparc64/include/arch/drivers/pci.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/drivers/pci.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_sparc64_PCI_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <genarch/ofw/ofw_tree.h>
 #include <arch/arch.h>
Index: kernel/arch/sparc64/include/arch/drivers/scr.h
===================================================================
--- kernel/arch/sparc64/include/arch/drivers/scr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/drivers/scr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_sparc64_SCR_H_
 
-#include <typedefs.h>
 #include <genarch/ofw/ofw_tree.h>
 
Index: kernel/arch/sparc64/include/arch/fpu_context.h
===================================================================
--- kernel/arch/sparc64/include/arch/fpu_context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/fpu_context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_sparc64_FPU_CONTEXT_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #define FPU_CONTEXT_ALIGN	8
Index: kernel/arch/sparc64/include/arch/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/arch/interrupt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/interrupt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,4 @@
 #define KERN_sparc64_INTERRUPT_H_
 
-#include <typedefs.h>
 #include <arch/istate.h>
 
Index: kernel/arch/sparc64/include/arch/mm/asid.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/asid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/mm/asid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_sparc64_ASID_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 /*
Index: kernel/arch/sparc64/include/arch/mm/km.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/mm/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm
  * @{
  */
Index: kernel/arch/sparc64/include/arch/mm/sun4u/km.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4u/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/mm/sun4u/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_sparc64_sun4u_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/sparc64/include/arch/mm/sun4u/mmu.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4u/mmu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/mm/sun4u/mmu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -91,5 +91,5 @@
 #include <arch/asm.h>
 #include <arch/barrier.h>
-#include <typedefs.h>
+#include <stdint.h>
 
 #if defined(US)
Index: kernel/arch/sparc64/include/arch/mm/sun4u/tte.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4u/tte.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/mm/sun4u/tte.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -49,5 +49,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 /* TTE tag's VA_tag field contains bits <63:VA_TAG_PAGE_SHIFT> of the VA */
Index: kernel/arch/sparc64/include/arch/mm/sun4v/km.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4v/km.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/mm/sun4v/km.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_sparc64_sun4v_KM_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/arch/sparc64/include/arch/mm/sun4v/tsb.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4v/tsb.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/mm/sun4v/tsb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -51,4 +51,5 @@
 #ifndef __ASM__
 
+#include <stdbool.h>
 #include <typedefs.h>
 #include <arch/mm/tte.h>
Index: kernel/arch/sparc64/include/arch/mm/sun4v/tte.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4v/tte.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/mm/sun4v/tte.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -50,5 +50,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 /** Translation Table Entry - Data. */
Index: kernel/arch/sparc64/include/arch/proc/thread.h
===================================================================
--- kernel/arch/sparc64/include/arch/proc/thread.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/proc/thread.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,7 @@
 #define KERN_sparc64_THREAD_H_
 
-#include <typedefs.h>
 #include <arch/arch.h>
 #include <mm/slab.h>
+#include <stdint.h>
 
 extern slab_cache_t *uwb_cache;
Index: kernel/arch/sparc64/include/arch/register.h
===================================================================
--- kernel/arch/sparc64/include/arch/register.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/register.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 
 #include <arch/regdef.h>
-#include <typedefs.h>
+#include <stdint.h>
 
 /** Version Register. */
Index: kernel/arch/sparc64/include/arch/smp/sun4v/smp.h
===================================================================
--- kernel/arch/sparc64/include/arch/smp/sun4v/smp.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/smp/sun4v/smp.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,6 +38,6 @@
 #define KERN_sparc64_sun4v_SMP_H_
 
-#include <typedefs.h>
 #include <arch/sun4v/cpu.h>
+#include <stdint.h>
 
 extern bool calculate_optimal_nrdy(exec_unit_t *);
Index: kernel/arch/sparc64/include/arch/sun4u/cpu.h
===================================================================
--- kernel/arch/sparc64/include/arch/sun4u/cpu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/sun4u/cpu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -54,9 +54,9 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
 #include <arch/register.h>
 #include <arch/regdef.h>
 #include <arch/asm.h>
 #include <arch/arch.h>
+#include <stdint.h>
 #include <trace.h>
 
Index: kernel/arch/sparc64/include/arch/sun4v/hypercall.h
===================================================================
--- kernel/arch/sparc64/include/arch/sun4v/hypercall.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/sun4v/hypercall.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -119,5 +119,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 /*
Index: kernel/arch/sparc64/include/arch/sun4v/ipi.h
===================================================================
--- kernel/arch/sparc64/include/arch/sun4v/ipi.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/sun4v/ipi.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #define KERN_sparc64_sun4v_IPI_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 extern uint64_t ipi_brodcast_to(void (*)(void), uint16_t cpu_list[], uint64_t);
Index: kernel/arch/sparc64/include/arch/sun4v/md.h
===================================================================
--- kernel/arch/sparc64/include/arch/sun4v/md.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/sun4v/md.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_sparc64_sun4v_MD_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
 
 /**
Index: kernel/arch/sparc64/include/arch/sun4v/register.h
===================================================================
--- kernel/arch/sparc64/include/arch/sun4v/register.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/sun4v/register.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 
 #include <arch/regdef.h>
-#include <typedefs.h>
+#include <stdint.h>
 
 /** Processor State Register. */
Index: kernel/arch/sparc64/include/arch/trap/trap_table.h
===================================================================
--- kernel/arch/sparc64/include/arch/trap/trap_table.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/trap/trap_table.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,5 +45,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 
 struct trap_table_entry {
Index: kernel/arch/sparc64/include/arch/types.h
===================================================================
--- kernel/arch/sparc64/include/arch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/include/arch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_sparc64_TYPES_H_
 
+#include <arch/common.h>
+
 typedef uint64_t size_t;
 typedef int64_t ssize_t;
@@ -53,7 +55,4 @@
 typedef uint8_t asi_t;
 
-#define INTN_C(c)   INT64_C(c)
-#define UINTN_C(c)  UINT64_C(c)
-
 #define PRIdn  PRId64  /**< Format for native_t. */
 #define PRIun  PRIu64  /**< Format for sysarg_t. */
Index: kernel/arch/sparc64/src/console.c
===================================================================
--- kernel/arch/sparc64/src/console.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/console.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,4 @@
 
 #include <arch/console.h>
-#include <typedefs.h>
 
 #include <arch/drivers/scr.h>
Index: kernel/arch/sparc64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/sparc64/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,6 +34,7 @@
 
 #include <stacktrace.h>
+#include <stdbool.h>
+#include <stdint.h>
 #include <syscall/copy.h>
-#include <typedefs.h>
 #include <proc/thread.h>
 
Index: kernel/arch/sparc64/src/drivers/niagara.c
===================================================================
--- kernel/arch/sparc64/src/drivers/niagara.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/drivers/niagara.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,4 @@
 #include <console/console.h>
 #include <ddi/ddi.h>
-#include <ddi/device.h>
 #include <arch/asm.h>
 #include <arch.h>
Index: kernel/arch/sparc64/src/drivers/pci.c
===================================================================
--- kernel/arch/sparc64/src/drivers/pci.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/drivers/pci.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,5 +42,5 @@
 #include <mm/slab.h>
 #include <typedefs.h>
-#include <debug.h>
+#include <assert.h>
 #include <log.h>
 #include <str.h>
@@ -175,5 +175,5 @@
 	 * First, verify this is a PCI node.
 	 */
-	ASSERT(str_cmp(ofw_tree_node_name(node), "pci") == 0);
+	assert(str_cmp(ofw_tree_node_name(node), "pci") == 0);
 
 	/*
@@ -210,5 +210,5 @@
 void pci_enable_interrupt(pci_t *pci, int inr)
 {
-	ASSERT(pci->op && pci->op->enable_interrupt);
+	assert(pci->op && pci->op->enable_interrupt);
 	pci->op->enable_interrupt(pci, inr);
 }
@@ -218,5 +218,5 @@
 	pci_t *pci = (pci_t *)pcip;
 
-	ASSERT(pci->op && pci->op->clear_interrupt);
+	assert(pci->op && pci->op->clear_interrupt);
 	pci->op->clear_interrupt(pci, inr);
 }
Index: kernel/arch/sparc64/src/drivers/scr.c
===================================================================
--- kernel/arch/sparc64/src/drivers/scr.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/drivers/scr.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,5 +42,5 @@
 #include <console/chardev.h>
 #include <console/console.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <str.h>
 #include <align.h>
Index: kernel/arch/sparc64/src/drivers/tick.c
===================================================================
--- kernel/arch/sparc64/src/drivers/tick.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/drivers/tick.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,5 @@
 #include <time/clock.h>
 #include <arch.h>
-#include <debug.h>
+#include <assert.h>
 
 /** Initialize tick and stick interrupt. */
@@ -93,10 +93,10 @@
 	 * Make sure we are servicing interrupt_level_14
 	 */
-	ASSERT(n == TT_INTERRUPT_LEVEL_14);
+	assert(n == TT_INTERRUPT_LEVEL_14);
 	
 	/*
 	 * Make sure we are servicing TICK_INT.
 	 */
-	ASSERT(softint.tick_int);
+	assert(softint.tick_int);
 
 	/*
Index: kernel/arch/sparc64/src/mm/sun4u/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/as.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/mm/sun4u/as.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,8 +35,8 @@
 #include <arch/mm/as.h>
 #include <arch/mm/tlb.h>
+#include <assert.h>
+#include <config.h>
 #include <genarch/mm/page_ht.h>
 #include <genarch/mm/asid_fifo.h>
-#include <debug.h>
-#include <config.h>
 
 #ifdef CONFIG_TSB
@@ -47,5 +47,5 @@
 #include <bitops.h>
 #include <macros.h>
-#include <memstr.h>
+#include <mem.h>
 
 #endif /* CONFIG_TSB */
@@ -130,6 +130,6 @@
 	uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 	
-	ASSERT(as->arch.itsb);
-	ASSERT(as->arch.dtsb);
+	assert(as->arch.itsb);
+	assert(as->arch.dtsb);
 	
 	uintptr_t tsb = (uintptr_t) as->arch.itsb;
@@ -202,6 +202,6 @@
 	uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 	
-	ASSERT(as->arch.itsb);
-	ASSERT(as->arch.dtsb);
+	assert(as->arch.itsb);
+	assert(as->arch.dtsb);
 	
 	uintptr_t tsb = (uintptr_t) as->arch.itsb;
Index: kernel/arch/sparc64/src/mm/sun4u/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,4 +41,5 @@
 #include <arch/mm/mmu.h>
 #include <arch/interrupt.h>
+#include <assert.h>
 #include <interrupt.h>
 #include <arch.h>
@@ -201,5 +202,5 @@
 	bool found = page_mapping_find(AS, istate->tpc, true, &t);
 	if (found && PTE_EXECUTABLE(&t)) {
-		ASSERT(t.p);
+		assert(t.p);
 
 		/*
@@ -258,5 +259,5 @@
 	bool found = page_mapping_find(as, page_16k, true, &t);
 	if (found) {
-		ASSERT(t.p);
+		assert(t.p);
 
 		/*
@@ -301,5 +302,5 @@
 	bool found = page_mapping_find(as, page_16k, true, &t);
 	if (found && PTE_WRITABLE(&t)) {
-		ASSERT(t.p);
+		assert(t.p);
 
 		/*
Index: kernel/arch/sparc64/src/mm/sun4u/tsb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/tsb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/mm/sun4u/tsb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm
  * @{
  */
@@ -37,8 +37,8 @@
 #include <arch/mm/page.h>
 #include <arch/barrier.h>
+#include <assert.h>
 #include <mm/as.h>
 #include <typedefs.h>
 #include <macros.h>
-#include <debug.h>
 
 /** Invalidate portion of TSB.
@@ -58,6 +58,6 @@
 	size_t cnt;
 	
-	ASSERT(as->arch.itsb);
-	ASSERT(as->arch.dtsb);
+	assert(as->arch.itsb);
+	assert(as->arch.dtsb);
 	
 	i0 = (page >> MMU_PAGE_WIDTH) & ITSB_ENTRY_MASK;
@@ -85,5 +85,5 @@
 	size_t entry;
 
-	ASSERT(index <= 1);
+	assert(index <= 1);
 	
 	as = t->as;
@@ -130,5 +130,5 @@
 	size_t entry;
 	
-	ASSERT(index <= 1);
+	assert(index <= 1);
 
 	as = t->as;
Index: kernel/arch/sparc64/src/mm/sun4v/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/as.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/mm/sun4v/as.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,7 +37,7 @@
 #include <arch/mm/pagesize.h>
 #include <arch/mm/tlb.h>
+#include <assert.h>
 #include <genarch/mm/page_ht.h>
 #include <genarch/mm/asid_fifo.h>
-#include <debug.h>
 #include <config.h>
 #include <arch/sun4v/hypercall.h>
@@ -50,5 +50,5 @@
 #include <bitops.h>
 #include <macros.h>
-#include <memstr.h>
+#include <mem.h>
 
 #endif /* CONFIG_TSB */
@@ -121,5 +121,5 @@
 	uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 	
-	ASSERT(as->arch.tsb_description.tsb_base);
+	assert(as->arch.tsb_description.tsb_base);
 	uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base);
 	
@@ -160,5 +160,5 @@
 	uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 	
-	ASSERT(as->arch.tsb_description.tsb_base);
+	assert(as->arch.tsb_description.tsb_base);
 	
 	uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base);
Index: kernel/arch/sparc64/src/mm/sun4v/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,4 +43,5 @@
 #include <arch/mm/tlb.h>
 #include <arch/interrupt.h>
+#include <assert.h>
 #include <interrupt.h>
 #include <arch.h>
@@ -215,5 +216,5 @@
 	bool found = page_mapping_find(AS, va, true, &t);
 	if (found && PTE_EXECUTABLE(&t)) {
-		ASSERT(t.p);
+		assert(t.p);
 
 		/*
@@ -265,5 +266,5 @@
 	bool found = page_mapping_find(as, va, true, &t);
 	if (found) {
-		ASSERT(t.p);
+		assert(t.p);
 
 		/*
@@ -303,5 +304,5 @@
 	bool found = page_mapping_find(as, va, true, &t);
 	if (found && PTE_WRITABLE(&t)) {
-		ASSERT(t.p);
+		assert(t.p);
 
 		/*
@@ -345,5 +346,5 @@
 	__hypercall_fast_ret1(0, 0, 0, 0, 0, CPU_MYID, &myid);
 
-	ASSERT(mmu_fsas[myid].dft < 16);
+	assert(mmu_fsas[myid].dft < 16);
 
 	printf("condition which caused the fault: %s\n",
Index: kernel/arch/sparc64/src/mm/sun4v/tsb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/tsb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/mm/sun4v/tsb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,8 +39,8 @@
 #include <arch/mm/page.h>
 #include <arch/barrier.h>
+#include <assert.h>
 #include <mm/as.h>
 #include <typedefs.h>
 #include <macros.h>
-#include <debug.h>
 
 /** Invalidate portion of TSB.
@@ -60,5 +60,5 @@
 	size_t cnt;
 	
-	ASSERT(as->arch.tsb_description.tsb_base);
+	assert(as->arch.tsb_description.tsb_base);
 	
 	i0 = (page >> MMU_PAGE_WIDTH) & TSB_ENTRY_MASK;
Index: kernel/arch/sparc64/src/smp/sun4u/ipi.c
===================================================================
--- kernel/arch/sparc64/src/smp/sun4u/ipi.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/smp/sun4u/ipi.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
 #include <smp/ipi.h>
 #include <arch/smp/sun4u/ipi.h>
+#include <assert.h>
 #include <cpu.h>
 #include <arch.h>
@@ -103,5 +104,5 @@
 		panic("Interrupt Dispatch Status busy bit set\n");
 	
-	ASSERT(!(pstate_read() & PSTATE_IE_BIT));
+	assert(!(pstate_read() & PSTATE_IE_BIT));
 	
 	do {
@@ -185,5 +186,5 @@
 void ipi_unicast_arch(unsigned int cpu_id, int ipi)
 {
-	ASSERT(&cpus[cpu_id] != CPU);
+	assert(&cpus[cpu_id] != CPU);
 	
 	if (ipi == IPI_SMP_CALL) {
Index: kernel/arch/sparc64/src/smp/sun4u/smp.c
===================================================================
--- kernel/arch/sparc64/src/smp/sun4u/smp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/smp/sun4u/smp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,5 @@
 #include <config.h>
 #include <macros.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <synch/waitq.h>
 #include <log.h>
Index: kernel/arch/sparc64/src/smp/sun4v/smp.c
===================================================================
--- kernel/arch/sparc64/src/smp/sun4v/smp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/smp/sun4v/smp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,7 @@
 #include <macros.h>
 #include <func.h>
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <synch/waitq.h>
 #include <print.h>
Index: kernel/arch/sparc64/src/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sparc64.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/sparc64.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -70,5 +70,5 @@
 
 	if (config.cpu_active == 1) {
-		STATIC_ASSERT(UWB_SIZE <= UWB_ALIGNMENT);
+		static_assert(UWB_SIZE <= UWB_ALIGNMENT, "");
 		/* Create slab cache for the userspace window buffers */
 		uwb_cache = slab_cache_create("uwb_cache", UWB_SIZE,
Index: kernel/arch/sparc64/src/trap/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/trap/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,5 @@
 #include <interrupt.h>
 #include <ddi/irq.h>
-#include <typedefs.h>
+#include <stdbool.h>
 #include <debug.h>
 #include <arch/asm.h>
Index: kernel/arch/sparc64/src/trap/sun4u/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4u/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/trap/sun4u/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #include <interrupt.h>
 #include <ddi/irq.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <debug.h>
 #include <arch/asm.h>
Index: kernel/arch/sparc64/src/trap/sun4v/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #include <interrupt.h>
 #include <ddi/irq.h>
-#include <typedefs.h>
+#include <stdint.h>
 #include <debug.h>
 #include <arch/asm.h>
Index: kernel/arch/sparc64/src/trap/trap.c
===================================================================
--- kernel/arch/sparc64/src/trap/trap.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/arch/sparc64/src/trap/trap.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,14 +35,4 @@
 
 #include <arch/trap/trap.h>
-#include <arch/trap/trap_table.h>
-#include <arch/trap/regwin.h>
-#include <arch/trap/exception.h>
-#include <arch/trap/interrupt.h>
-#include <arch/trap/mmu.h>
-#include <arch/asm.h>
-#include <memstr.h>
-#include <debug.h>
-#include <typedefs.h>
-#include <arch/drivers/tick.h>
 
 /** Initialize trap table. */
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/Makefile.inc	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -169,4 +169,5 @@
 ifeq ($(CONFIG_MULTIBOOT), y)
 GENARCH_SOURCES += \
+	genarch/src/multiboot/common.c \
 	genarch/src/multiboot/multiboot.c \
 	genarch/src/multiboot/multiboot2.c
Index: kernel/genarch/include/genarch/drivers/amdm37x/gpt.h
===================================================================
--- kernel/genarch/include/genarch/drivers/amdm37x/gpt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/drivers/amdm37x/gpt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
 #define KERN_AMDM37x_GPT_H_
 
+#include <assert.h>
 #include <typedefs.h>
 #include <mm/km.h>
@@ -211,5 +212,5 @@
 	km_unmap((uintptr_t)clksel, 4);
 
-	ASSERT(timer);
+	assert(timer);
 	/* Map control register */
 	timer->regs = (void*) km_map(ioregs, iosize, PAGE_NOT_CACHEABLE);
@@ -247,6 +248,6 @@
 static inline void amdm37x_gpt_timer_ticks_start(amdm37x_gpt_t* timer)
 {
-	ASSERT(timer);
-	ASSERT(timer->regs);
+	assert(timer);
+	assert(timer->regs);
 	/* Enable overflow interrupt */
 	timer->regs->tier |= AMDM37x_GPT_TIER_OVF_IRQ_FLAG;
@@ -257,6 +258,6 @@
 static inline bool amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)
 {
-	ASSERT(timer);
-	ASSERT(timer->regs);
+	assert(timer);
+	assert(timer->regs);
 	/* Clear all pending interrupts */
 	const uint32_t tisr = timer->regs->tisr;
Index: kernel/genarch/include/genarch/drivers/bcm2835/irc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #define KERN_BCM2835_IRQC_H_
 
+#include <assert.h>
 #include <typedefs.h>
 
@@ -158,5 +159,5 @@
 static inline void bcm2835_irc_enable(bcm2835_irc_t *regs, unsigned inum)
 {
-	ASSERT(inum < BCM2835_IRQ_COUNT);
+	assert(inum < BCM2835_IRQ_COUNT);
 	regs->irq_enable[IRQ_TO_BANK(inum)] |= (1 << IRQ_TO_NUM(inum));
 }
@@ -164,5 +165,5 @@
 static inline void bcm2835_irc_disable(bcm2835_irc_t *regs, unsigned inum)
 {
-	ASSERT(inum < BCM2835_IRQ_COUNT);
+	assert(inum < BCM2835_IRQ_COUNT);
 	regs->irq_disable[IRQ_TO_BANK(inum)] |= (1 << IRQ_TO_NUM(inum));
 }
Index: kernel/genarch/include/genarch/drivers/bcm2835/timer.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/timer.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/drivers/bcm2835/timer.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #ifndef KERN_BCM2835_TIMER_H_
 
+#include <assert.h>
 #include <typedefs.h>
 #include <mm/km.h>
@@ -66,5 +67,5 @@
 static inline void bcm2835_timer_start(bcm2835_timer_t* timer)
 {
-	ASSERT(timer);
+	assert(timer);
 	/* Clear pending interrupt on channel 1 */
 	timer->cs |= BCM2835_TIMER_CS_M1;
@@ -75,5 +76,5 @@
 static inline void bcm2835_timer_irq_ack(bcm2835_timer_t* timer)
 {
-	ASSERT(timer);
+	assert(timer);
 	/* Clear pending interrupt on channel 1 */
 	timer->cs |= BCM2835_TIMER_CS_M1;
Index: kernel/genarch/include/genarch/drivers/omap/irc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/omap/irc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/drivers/omap/irc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 #define KERN_OMAP_IRQC_H_
 
+#include <assert.h>
 #include <typedefs.h>
 
@@ -230,5 +231,5 @@
 static inline void omap_irc_enable(omap_irc_regs_t *regs, unsigned inum)
 {
-	ASSERT(inum < OMAP_IRC_IRQ_COUNT);
+	assert(inum < OMAP_IRC_IRQ_COUNT);
 	const unsigned set = inum / 32;
 	const unsigned pos = inum % 32;
@@ -243,5 +244,5 @@
 static inline void omap_irc_disable(omap_irc_regs_t *regs, unsigned inum)
 {
-	ASSERT(inum < OMAP_IRC_IRQ_COUNT);
+	assert(inum < OMAP_IRC_IRQ_COUNT);
 	const unsigned set = inum / 32;
 	const unsigned pos = inum % 32;
Index: kernel/genarch/include/genarch/drivers/pl050/pl050.h
===================================================================
--- kernel/genarch/include/genarch/drivers/pl050/pl050.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/drivers/pl050/pl050.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup genarch		
+/** @addtogroup genarch
  * @{
  */
Index: kernel/genarch/include/genarch/fb/bfb.h
===================================================================
--- kernel/genarch/include/genarch/fb/bfb.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/fb/bfb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_BFB_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/genarch/include/genarch/mm/as_ht.h
===================================================================
--- kernel/genarch/include/genarch/mm/as_ht.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/mm/as_ht.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 
 #include <mm/mm.h>
-#include <adt/list.h>
+#include <adt/hash_table.h>
 #include <typedefs.h>
 
@@ -46,5 +46,5 @@
 
 typedef struct pte {
-	link_t link;		/**< Page hash table link. */
+	ht_link_t link;		/**< Page hash table link. */
 	struct as *as;		/**< Address space. */
 	uintptr_t page;		/**< Virtual memory page. */
Index: kernel/genarch/include/genarch/mm/page_ht.h
===================================================================
--- kernel/genarch/include/genarch/mm/page_ht.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/mm/page_ht.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -46,10 +46,6 @@
 #include <adt/hash_table.h>
 
-#define PAGE_HT_KEYS  2
 #define KEY_AS        0
 #define KEY_PAGE      1
-
-#define PAGE_HT_ENTRIES_BITS  13
-#define PAGE_HT_ENTRIES       (1 << PAGE_HT_ENTRIES_BITS)
 
 /* Macros for querying page hash table PTEs. */
@@ -66,5 +62,5 @@
 extern slab_cache_t *pte_cache;
 extern hash_table_t page_ht;
-extern hash_table_operations_t ht_operations;
+extern hash_table_ops_t ht_ops;
 
 #endif
Index: kernel/genarch/include/genarch/multiboot/multiboot.h
===================================================================
--- kernel/genarch/include/genarch/multiboot/multiboot.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/multiboot/multiboot.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -71,4 +71,6 @@
 } __attribute__((packed)) multiboot_module_t;
 
+extern void multiboot_cmdline(const char *);
+
 extern void multiboot_extract_command(char *, size_t, const char *);
 extern void multiboot_extract_argument(char *, size_t, const char *);
Index: kernel/genarch/include/genarch/multiboot/multiboot2.h
===================================================================
--- kernel/genarch/include/genarch/multiboot/multiboot2.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/multiboot/multiboot2.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -52,4 +52,5 @@
 #define MULTIBOOT2_TAG_MODULE_ALIGN   6
 
+#define MULTIBOOT2_TAG_CMDLINE 1
 #define MULTIBOOT2_TAG_MODULE  3
 #define MULTIBOOT2_TAG_MEMMAP  6
@@ -73,4 +74,9 @@
 	uint32_t reserved;
 } __attribute__((packed)) multiboot2_info_t;
+
+/** Multiboot2 cmdline structure */
+typedef struct {
+	char string[0];
+} __attribute__((packed)) multiboot2_cmdline_t;
 
 /** Multiboot2 modules structure */
@@ -138,4 +144,5 @@
 	uint32_t size;
 	union {
+		multiboot2_cmdline_t cmdline;
 		multiboot2_module_t module;
 		multiboot2_memmap_t memmap;
Index: kernel/genarch/include/genarch/ofw/ofw_tree.h
===================================================================
--- kernel/genarch/include/genarch/ofw/ofw_tree.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/include/genarch/ofw/ofw_tree.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,4 +30,5 @@
 #define KERN_OFW_TREE_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/genarch/src/acpi/acpi.c
===================================================================
--- kernel/genarch/src/acpi/acpi.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/acpi/acpi.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 #include <genarch/acpi/madt.h>
 #include <arch/bios/bios.h>
+#include <debug.h>
 #include <mm/page.h>
 #include <mm/km.h>
Index: kernel/genarch/src/acpi/madt.c
===================================================================
--- kernel/genarch/src/acpi/madt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/acpi/madt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <typedefs.h>
 #include <genarch/acpi/acpi.h>
@@ -41,10 +42,8 @@
 #include <arch/smp/smp.h>
 #include <panic.h>
-#include <debug.h>
 #include <config.h>
 #include <log.h>
 #include <mm/slab.h>
-#include <memstr.h>
-#include <sort.h>
+#include <gsort.h>
 
 struct acpi_madt *acpi_madt = NULL;
@@ -83,5 +82,5 @@
 static uint8_t madt_cpu_apic_id(size_t i)
 {
-	ASSERT(i < madt_l_apic_entry_cnt);
+	assert(i < madt_l_apic_entry_cnt);
 	
 	return ((struct madt_l_apic *)
@@ -91,5 +90,5 @@
 static bool madt_cpu_enabled(size_t i)
 {
-	ASSERT(i < madt_l_apic_entry_cnt);
+	assert(i < madt_l_apic_entry_cnt);
 	
 	/*
@@ -107,5 +106,5 @@
 static bool madt_cpu_bootstrap(size_t i)
 {
-	ASSERT(i < madt_l_apic_entry_cnt);
+	assert(i < madt_l_apic_entry_cnt);
 	
 	return ((struct madt_l_apic *)
@@ -177,5 +176,5 @@
     size_t i)
 {
-	ASSERT(override->source < sizeof(isa_irq_map) / sizeof(int));
+	assert(override->source < sizeof(isa_irq_map) / sizeof(int));
 	
 	isa_irq_map[override->source] = override->global_int;
Index: kernel/genarch/src/drivers/am335x/timer.c
===================================================================
--- kernel/genarch/src/drivers/am335x/timer.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/am335x/timer.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
  */
 
+#include <assert.h>
 #include <genarch/drivers/am335x/timer.h>
 #include <mm/km.h>
@@ -90,6 +91,6 @@
 	size_t size;
 
-	ASSERT(id < TIMERS_MAX);
-	ASSERT(timer != NULL);
+	assert(id < TIMERS_MAX);
+	assert(timer != NULL);
 
 	if (id == DMTIMER1_1MS)
@@ -100,5 +101,5 @@
 
 	timer->regs = (void *) km_map(base_addr, size, PAGE_NOT_CACHEABLE);
-	ASSERT(timer->regs != NULL);
+	assert(timer->regs != NULL);
 
 	timer->id = id;
Index: kernel/genarch/src/drivers/dsrln/dsrlnin.c
===================================================================
--- kernel/genarch/src/drivers/dsrln/dsrlnin.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/dsrln/dsrlnin.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,9 +35,9 @@
  */
 
+#include <assert.h>
 #include <genarch/drivers/dsrln/dsrlnin.h>
 #include <console/chardev.h>
 #include <mm/slab.h>
 #include <arch/asm.h>
-#include <ddi/device.h>
 
 static irq_ownership_t dsrlnin_claim(irq_t *irq)
@@ -63,5 +63,4 @@
 		
 		irq_initialize(&instance->irq);
-		instance->irq.devno = device_assign_devno();
 		instance->irq.inr = inr;
 		instance->irq.claim = dsrlnin_claim;
@@ -75,6 +74,6 @@
 void dsrlnin_wire(dsrlnin_instance_t *instance, indev_t *srlnin)
 {
-	ASSERT(instance);
-	ASSERT(srlnin);
+	assert(instance);
+	assert(srlnin);
 	
 	instance->srlnin = srlnin;
Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <debug.h>
 #include <genarch/drivers/ega/ega.h>
 #include <putchar.h>
@@ -42,5 +43,5 @@
 #include <typedefs.h>
 #include <arch/asm.h>
-#include <memstr.h>
+#include <mem.h>
 #include <str.h>
 #include <console/chardev.h>
Index: kernel/genarch/src/drivers/i8042/i8042.c
===================================================================
--- kernel/genarch/src/drivers/i8042/i8042.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/i8042/i8042.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
  */
 
+#include <assert.h>
 #include <genarch/drivers/i8042/i8042.h>
 #include <genarch/drivers/legacy/ia32/io.h>
@@ -43,5 +44,4 @@
 #include <console/chardev.h>
 #include <mm/slab.h>
-#include <ddi/device.h>
 #include <time/delay.h>
 
@@ -112,5 +112,4 @@
 		
 		irq_initialize(&instance->irq);
-		instance->irq.devno = device_assign_devno();
 		instance->irq.inr = inr;
 		instance->irq.claim = i8042_claim;
@@ -124,6 +123,6 @@
 void i8042_wire(i8042_instance_t *instance, indev_t *kbrdin)
 {
-	ASSERT(instance);
-	ASSERT(kbrdin);
+	assert(instance);
+	assert(kbrdin);
 	
 	i8042_clear_buffer(instance->i8042);
Index: kernel/genarch/src/drivers/ns16550/ns16550.c
===================================================================
--- kernel/genarch/src/drivers/ns16550/ns16550.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/ns16550/ns16550.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <genarch/drivers/ns16550/ns16550.h>
 #include <ddi/irq.h>
@@ -40,5 +41,4 @@
 #include <console/chardev.h>
 #include <mm/slab.h>
-#include <ddi/device.h>
 #include <str.h>
 
@@ -137,5 +137,4 @@
 		
 		irq_initialize(&instance->irq);
-		instance->irq.devno = device_assign_devno();
 		instance->irq.inr = inr;
 		instance->irq.claim = ns16550_claim;
@@ -157,6 +156,6 @@
 void ns16550_wire(ns16550_instance_t *instance, indev_t *input)
 {
-	ASSERT(instance);
-	ASSERT(input);
+	assert(instance);
+	assert(input);
 	
 	instance->input = input;
Index: kernel/genarch/src/drivers/omap/uart.c
===================================================================
--- kernel/genarch/src/drivers/omap/uart.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/omap/uart.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,6 +35,6 @@
  */
 
+#include <assert.h>
 #include <genarch/drivers/omap/uart.h>
-#include <ddi/device.h>
 #include <str.h>
 #include <mm/km.h>
@@ -86,8 +86,8 @@
     omap_uart_t *uart, inr_t interrupt, uintptr_t addr, size_t size)
 {
-	ASSERT(uart);
+	assert(uart);
 	uart->regs = (void *)km_map(addr, size, PAGE_NOT_CACHEABLE);
 
-	ASSERT(uart->regs);
+	assert(uart->regs);
 
 	/* Soft reset the port */
@@ -160,5 +160,4 @@
 	/* Initialize IRQ */
 	irq_initialize(&uart->irq);
-	uart->irq.devno = device_assign_devno();
 	uart->irq.inr = interrupt;
 	uart->irq.claim = omap_uart_claim;
@@ -171,5 +170,5 @@
 void omap_uart_input_wire(omap_uart_t *uart, indev_t *indev)
 {
-	ASSERT(uart);
+	assert(uart);
 	/* Set indev */
 	uart->indev = indev;
Index: kernel/genarch/src/drivers/pl011/pl011.c
===================================================================
--- kernel/genarch/src/drivers/pl011/pl011.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/pl011/pl011.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,8 +35,8 @@
  */
 
+#include <assert.h>
 #include <genarch/drivers/pl011/pl011.h>
 #include <console/chardev.h>
 #include <console/console.h>
-#include <ddi/device.h>
 #include <arch/asm.h>
 #include <mm/slab.h>
@@ -98,8 +98,8 @@
 bool pl011_uart_init(pl011_uart_t *uart, inr_t interrupt, uintptr_t addr)
 {
-	ASSERT(uart);
+	assert(uart);
 	uart->regs = (void*)km_map(addr, sizeof(pl011_uart_regs_t),
 				   PAGE_NOT_CACHEABLE);
-	ASSERT(uart->regs);
+	assert(uart->regs);
 
 	/* Disable UART */
@@ -126,5 +126,4 @@
 	/* Initialize IRQ */
 	irq_initialize(&uart->irq);
-	uart->irq.devno = device_assign_devno();
 	uart->irq.inr = interrupt;
 	uart->irq.claim = pl011_uart_claim;
@@ -137,6 +136,6 @@
 void pl011_uart_input_wire(pl011_uart_t *uart, indev_t *indev)
 {
-	ASSERT(uart);
-	ASSERT(indev);
+	assert(uart);
+	assert(indev);
 
 	uart->indev = indev;
Index: kernel/genarch/src/drivers/pl050/pl050.c
===================================================================
--- kernel/genarch/src/drivers/pl050/pl050.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/pl050/pl050.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,4 @@
 #include <console/chardev.h>
 #include <mm/slab.h>
-#include <ddi/device.h>
 
 #define PL050_KEY_RELEASE 0xF0
@@ -87,5 +86,4 @@
 
 		irq_initialize(&instance->irq);
-		instance->irq.devno = device_assign_devno();
 		instance->irq.inr = inr;
 		instance->irq.claim = pl050_claim;
Index: kernel/genarch/src/drivers/s3c24xx/uart.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx/uart.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/s3c24xx/uart.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,8 +38,8 @@
  */
 
+#include <assert.h>
 #include <genarch/drivers/s3c24xx/uart.h>
 #include <console/chardev.h>
 #include <console/console.h>
-#include <ddi/device.h>
 #include <arch/asm.h>
 #include <mm/slab.h>
@@ -122,5 +122,4 @@
 	/* Initialize IRQ structure. */
 	irq_initialize(&uart->irq);
-	uart->irq.devno = device_assign_devno();
 	uart->irq.inr = inr;
 	uart->irq.claim = s3c24xx_uart_claim;
@@ -161,6 +160,6 @@
 void s3c24xx_uart_input_wire(s3c24xx_uart_t *uart, indev_t *indev)
 {
-	ASSERT(uart);
-	ASSERT(indev);
+	assert(uart);
+	assert(indev);
 
 	uart->indev = indev;
Index: kernel/genarch/src/drivers/via-cuda/cuda.c
===================================================================
--- kernel/genarch/src/drivers/via-cuda/cuda.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/drivers/via-cuda/cuda.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
  */
 
+#include <assert.h>
 #include <genarch/drivers/via-cuda/cuda.h>
 #include <console/chardev.h>
@@ -39,7 +40,6 @@
 #include <arch/asm.h>
 #include <mm/slab.h>
-#include <ddi/device.h>
 #include <synch/spinlock.h>
-#include <memstr.h>
+#include <mem.h>
 
 static irq_ownership_t cuda_claim(irq_t *irq);
@@ -105,5 +105,4 @@
 
 		irq_initialize(&instance->irq);
-		instance->irq.devno = device_assign_devno();
 		instance->irq.inr = inr;
 		instance->irq.claim = cuda_claim;
@@ -123,6 +122,6 @@
 	cuda_t *dev = instance->cuda;
 
-	ASSERT(instance);
-	ASSERT(kbrdin);
+	assert(instance);
+	assert(kbrdin);
 
 	instance->kbrdin = kbrdin;
@@ -341,5 +340,5 @@
 	cuda_t *dev = instance->cuda;
 
-	ASSERT(instance->xstate == cx_listen);
+	assert(instance->xstate == cx_listen);
 
 	if (instance->snd_bytes == 0)
Index: kernel/genarch/src/fb/bfb.c
===================================================================
--- kernel/genarch/src/fb/bfb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/fb/bfb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <debug.h>
 #include <typedefs.h>
 #include <genarch/fb/fb.h>
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/fb/fb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,6 @@
  */
 
+#include <assert.h>
+#include <debug.h>
 #include <genarch/fb/font-8x16.h>
 #include <genarch/fb/fb.h>
@@ -43,5 +45,5 @@
 #include <align.h>
 #include <panic.h>
-#include <memstr.h>
+#include <mem.h>
 #include <config.h>
 #include <bitops.h>
@@ -511,8 +513,8 @@
 outdev_t *fb_init(fb_properties_t *props)
 {
-	ASSERT(props);
-	ASSERT(props->x > 0);
-	ASSERT(props->y > 0);
-	ASSERT(props->scan > 0);
+	assert(props);
+	assert(props->x > 0);
+	assert(props->y > 0);
+	assert(props->scan > 0);
 	
 	rgb_conv_t rgb_conv;
Index: kernel/genarch/src/kbrd/kbrd.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/kbrd/kbrd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <genarch/kbrd/kbrd.h>
 #include <genarch/kbrd/scanc.h>
@@ -194,6 +195,6 @@
 indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
 {
-	ASSERT(instance);
-	ASSERT(sink);
+	assert(instance);
+	assert(sink);
 	
 	instance->sink = sink;
Index: kernel/genarch/src/kbrd/kbrd_at.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd_at.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/kbrd/kbrd_at.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <genarch/kbrd/kbrd.h>
 #include <genarch/kbrd/scanc.h>
@@ -192,6 +193,6 @@
 indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
 {
-	ASSERT(instance);
-	ASSERT(sink);
+	assert(instance);
+	assert(sink);
 	
 	instance->sink = sink;
Index: kernel/genarch/src/mm/as_ht.c
===================================================================
--- kernel/genarch/src/mm/as_ht.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/mm/as_ht.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,4 @@
 #include <mm/slab.h>
 #include <typedefs.h>
-#include <memstr.h>
 #include <adt/hash_table.h>
 #include <synch/mutex.h>
@@ -76,5 +75,5 @@
 {
 	if (flags & FLAG_AS_KERNEL) {
-		hash_table_create(&page_ht, PAGE_HT_ENTRIES, 2, &ht_operations);
+		hash_table_create(&page_ht, 0, 0, &ht_ops);
 		pte_cache = slab_cache_create("pte_t", sizeof(pte_t), 0,
 		    NULL, NULL, SLAB_CACHE_MAGDEFERRED);
Index: kernel/genarch/src/mm/as_pt.c
===================================================================
--- kernel/genarch/src/mm/as_pt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/mm/as_pt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,5 @@
 #include <arch/mm/as.h>
 #include <typedefs.h>
-#include <memstr.h>
+#include <mem.h>
 #include <arch.h>
 
Index: kernel/genarch/src/mm/asid.c
===================================================================
--- kernel/genarch/src/mm/asid.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/mm/asid.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -57,4 +57,5 @@
  */
 
+#include <assert.h>
 #include <mm/asid.h>
 #include <mm/as.h>
@@ -64,5 +65,4 @@
 #include <synch/mutex.h>
 #include <adt/list.h>
-#include <debug.h>
 
 static size_t asids_allocated = 0;
@@ -78,6 +78,6 @@
 	as_t *as;
 
-	ASSERT(interrupts_disabled());
-	ASSERT(spinlock_locked(&asidlock));
+	assert(interrupts_disabled());
+	assert(spinlock_locked(&asidlock));
 
 	/*
@@ -98,5 +98,5 @@
 		 */
 		tmp = list_first(&inactive_as_with_asid_list);
-		ASSERT(tmp != NULL);
+		assert(tmp != NULL);
 		list_remove(tmp);
 		
@@ -108,5 +108,5 @@
 		 */
 		asid = as->asid;
-		ASSERT(asid != ASID_INVALID);
+		assert(asid != ASID_INVALID);
 
 		/*
Index: kernel/genarch/src/mm/page_ht.c
===================================================================
--- kernel/genarch/src/mm/page_ht.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/mm/page_ht.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,12 +48,13 @@
 #include <synch/spinlock.h>
 #include <arch.h>
-#include <debug.h>
-#include <memstr.h>
+#include <assert.h>
+#include <adt/hash.h>
 #include <adt/hash_table.h>
 #include <align.h>
 
-static size_t hash(sysarg_t[]);
-static bool compare(sysarg_t[], size_t, link_t *);
-static void remove_callback(link_t *);
+static size_t ht_hash(const ht_link_t *);
+static size_t ht_key_hash(void *);
+static bool ht_key_equal(void *, const ht_link_t *);
+static void ht_remove_callback(ht_link_t *);
 
 static void ht_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
@@ -81,8 +82,9 @@
 
 /** Hash table operations for page hash table. */
-hash_table_operations_t ht_operations = {
-	.hash = hash,
-	.compare = compare,
-	.remove_callback = remove_callback
+hash_table_ops_t ht_ops = {
+	.hash = ht_hash,
+	.key_hash = ht_key_hash,
+	.key_equal = ht_key_equal,
+	.remove_callback = ht_remove_callback
 };
 
@@ -96,61 +98,31 @@
 };
 
-/** Compute page hash table index.
- *
- * @param key Array of two keys (i.e. page and address space).
- *
- * @return Index into page hash table.
- *
- */
-size_t hash(sysarg_t key[])
-{
-	as_t *as = (as_t *) key[KEY_AS];
-	uintptr_t page = (uintptr_t) key[KEY_PAGE];
-	
-	/*
-	 * Virtual page addresses have roughly the same probability
-	 * of occurring. Least significant bits of VPN compose the
-	 * hash index.
-	 *
-	 */
-	size_t index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES - 1));
-	
-	/*
-	 * Address space structures are likely to be allocated from
-	 * similar addresses. Least significant bits compose the
-	 * hash index.
-	 *
-	 */
-	index |= ((sysarg_t) as) & (PAGE_HT_ENTRIES - 1);
-	
-	return index;
-}
-
-/** Compare page hash table item with page and/or address space.
- *
- * @param key  Array of one or two keys (i.e. page and/or address space).
- * @param keys Number of keys passed.
- * @param item Item to compare the keys with.
- *
- * @return true on match, false otherwise.
- *
- */
-bool compare(sysarg_t key[], size_t keys, link_t *item)
-{
-	ASSERT(item);
-	ASSERT(keys > 0);
-	ASSERT(keys <= PAGE_HT_KEYS);
-	
-	/*
-	 * Convert item to PTE.
-	 *
-	 */
-	pte_t *pte = hash_table_get_instance(item, pte_t, link);
-	
-	if (keys == PAGE_HT_KEYS)
-		return (key[KEY_AS] == (uintptr_t) pte->as) &&
-		    (key[KEY_PAGE] == pte->page);
-	
-	return (key[KEY_AS] == (uintptr_t) pte->as);
+/** Return the hash of the key stored in the item */
+size_t ht_hash(const ht_link_t *item)
+{
+	pte_t *pte = hash_table_get_inst(item, pte_t, link);
+	size_t hash = 0;
+	hash = hash_combine(hash, (uintptr_t) pte->as);
+	hash = hash_combine(hash, pte->page >> PAGE_WIDTH);
+	return hash;
+}
+
+/** Return the hash of the key. */
+size_t ht_key_hash(void *arg)
+{
+	uintptr_t *key = (uintptr_t *) arg;
+	size_t hash = 0;
+	hash = hash_combine(hash, key[KEY_AS]);
+	hash = hash_combine(hash, key[KEY_PAGE] >> PAGE_WIDTH);
+	return hash;
+}
+
+/** Return true if the key is equal to the item's lookup key. */
+bool ht_key_equal(void *arg, const ht_link_t *item)
+{
+	uintptr_t *key = (uintptr_t *) arg;
+	pte_t *pte = hash_table_get_inst(item, pte_t, link);
+	return (key[KEY_AS] == (uintptr_t) pte->as) &&
+	    (key[KEY_PAGE] == pte->page);
 }
 
@@ -160,14 +132,9 @@
  *
  */
-void remove_callback(link_t *item)
-{
-	ASSERT(item);
-	
-	/*
-	 * Convert item to PTE.
-	 *
-	 */
-	pte_t *pte = hash_table_get_instance(item, pte_t, link);
-	
+void ht_remove_callback(ht_link_t *item)
+{
+	assert(item);
+	
+	pte_t *pte = hash_table_get_inst(item, pte_t, link);
 	slab_free(pte_cache, pte);
 }
@@ -187,10 +154,10 @@
     unsigned int flags)
 {
-	sysarg_t key[2] = {
-		(uintptr_t) as,
-		page = ALIGN_DOWN(page, PAGE_SIZE)
+	uintptr_t key[2] = {
+		[KEY_AS] = (uintptr_t) as,
+		[KEY_PAGE] = ALIGN_DOWN(page, PAGE_SIZE)
 	};
 
-	ASSERT(page_table_locked(as));
+	assert(page_table_locked(as));
 
 	irq_spinlock_lock(&page_ht_lock, true);
@@ -198,5 +165,5 @@
 	if (!hash_table_find(&page_ht, key)) {
 		pte_t *pte = slab_alloc(pte_cache, FRAME_LOWMEM | FRAME_ATOMIC);
-		ASSERT(pte != NULL);
+		assert(pte != NULL);
 		
 		pte->g = (flags & PAGE_GLOBAL) != 0;
@@ -219,5 +186,5 @@
 		write_barrier();
 		
-		hash_table_insert(&page_ht, key, &pte->link);
+		hash_table_insert(&page_ht, &pte->link);
 	}
 
@@ -237,10 +204,10 @@
 void ht_mapping_remove(as_t *as, uintptr_t page)
 {
-	sysarg_t key[2] = {
-		(uintptr_t) as,
-		page = ALIGN_DOWN(page, PAGE_SIZE)
+	uintptr_t key[2] = {
+		[KEY_AS] = (uintptr_t) as,
+		[KEY_PAGE] = ALIGN_DOWN(page, PAGE_SIZE)
 	};
 
-	ASSERT(page_table_locked(as));
+	assert(page_table_locked(as));
 	
 	irq_spinlock_lock(&page_ht_lock, true);
@@ -250,21 +217,22 @@
 	 * by remove_callback().
 	 */
-	hash_table_remove(&page_ht, key, 2);
+	hash_table_remove(&page_ht, key);
 
 	irq_spinlock_unlock(&page_ht_lock, true);
 }
 
-static pte_t *ht_mapping_find_internal(as_t *as, uintptr_t page, bool nolock)
-{
-	sysarg_t key[2] = {
-		(uintptr_t) as,
-		page = ALIGN_DOWN(page, PAGE_SIZE)
+static pte_t *
+ht_mapping_find_internal(as_t *as, uintptr_t page, bool nolock)
+{
+	uintptr_t key[2] = {
+		[KEY_AS] = (uintptr_t) as,
+		[KEY_PAGE] = ALIGN_DOWN(page, PAGE_SIZE)
 	};
 
-	ASSERT(nolock || page_table_locked(as));
-
-	link_t *cur = hash_table_find(&page_ht, key);
+	assert(nolock || page_table_locked(as));
+
+	ht_link_t *cur = hash_table_find(&page_ht, key);
 	if (cur)
-		return hash_table_get_instance(cur, pte_t, link);
+		return hash_table_get_inst(cur, pte_t, link);
 	
 	return NULL;
@@ -308,13 +276,13 @@
 		panic("Updating non-existent PTE");
 	
-	ASSERT(pte->as == t->as);
-	ASSERT(pte->page == t->page);
-	ASSERT(pte->frame == t->frame);
-	ASSERT(pte->g == t->g);
-	ASSERT(pte->x == t->x);
-	ASSERT(pte->w == t->w);
-	ASSERT(pte->k == t->k);
-	ASSERT(pte->c == t->c);
-	ASSERT(pte->p == t->p);
+	assert(pte->as == t->as);
+	assert(pte->page == t->page);
+	assert(pte->frame == t->frame);
+	assert(pte->g == t->g);
+	assert(pte->x == t->x);
+	assert(pte->w == t->w);
+	assert(pte->k == t->k);
+	assert(pte->c == t->c);
+	assert(pte->p == t->p);
 
 	t->a = pte->a;
Index: kernel/genarch/src/mm/page_pt.c
===================================================================
--- kernel/genarch/src/mm/page_pt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/mm/page_pt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
  */
 
+#include <assert.h>
 #include <genarch/mm/page_pt.h>
 #include <mm/page.h>
@@ -46,5 +47,5 @@
 #include <typedefs.h>
 #include <arch/asm.h>
-#include <memstr.h>
+#include <mem.h>
 #include <align.h>
 #include <macros.h>
@@ -81,5 +82,5 @@
 	pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
 
-	ASSERT(page_table_locked(as));
+	assert(page_table_locked(as));
 	
 	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
@@ -159,5 +160,5 @@
 void pt_mapping_remove(as_t *as, uintptr_t page)
 {
-	ASSERT(page_table_locked(as));
+	assert(page_table_locked(as));
 
 	/*
@@ -293,5 +294,5 @@
 static pte_t *pt_mapping_find_internal(as_t *as, uintptr_t page, bool nolock)
 {
-	ASSERT(nolock || page_table_locked(as));
+	assert(nolock || page_table_locked(as));
 
 	pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
@@ -358,9 +359,9 @@
 		panic("Updating non-existent PTE");	
 
-	ASSERT(PTE_VALID(t) == PTE_VALID(pte));
-	ASSERT(PTE_PRESENT(t) == PTE_PRESENT(pte));
-	ASSERT(PTE_GET_FRAME(t) == PTE_GET_FRAME(pte));
-	ASSERT(PTE_WRITABLE(t) == PTE_WRITABLE(pte));
-	ASSERT(PTE_EXECUTABLE(t) == PTE_EXECUTABLE(pte));
+	assert(PTE_VALID(t) == PTE_VALID(pte));
+	assert(PTE_PRESENT(t) == PTE_PRESENT(pte));
+	assert(PTE_GET_FRAME(t) == PTE_GET_FRAME(pte));
+	assert(PTE_WRITABLE(t) == PTE_WRITABLE(pte));
+	assert(PTE_EXECUTABLE(t) == PTE_EXECUTABLE(pte));
 
 	*t = *pte;
@@ -398,5 +399,5 @@
 void pt_mapping_make_global(uintptr_t base, size_t size)
 {
-	ASSERT(size > 0);
+	assert(size > 0);
 	
 	uintptr_t ptl0 = PA2KA((uintptr_t) AS_KERNEL->genarch.page_table);
@@ -416,5 +417,5 @@
 	    addr += ptl0_step) {
 		if (GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr)) != 0) {
-			ASSERT(overlaps(addr, ptl0_step,
+			assert(overlaps(addr, ptl0_step,
 			    config.identity_base, config.identity_size));
 
Index: kernel/genarch/src/multiboot/common.c
===================================================================
--- kernel/genarch/src/multiboot/common.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/genarch/src/multiboot/common.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 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 genarch
+ * @{
+ */
+/** @file
+ */
+
+#include <genarch/multiboot/multiboot.h>
+#include <config.h>
+#include <stddef.h>
+
+void multiboot_cmdline(const char *cmdline)
+{
+	/*
+	 * GRUB passes the command line in an escaped form.
+	 */
+	for (size_t i = 0, j = 0;
+	    cmdline[i] && j < CONFIG_BOOT_ARGUMENTS_BUFLEN;
+	    i++, j++) {
+		if (cmdline[i] == '\\') {
+			switch (cmdline[i + 1]) {
+			case '\\':
+			case '\'':
+			case '\"':
+				i++;
+				break;
+			}
+		}
+		bargs[j] = cmdline[i];
+	}
+}
+
+/** @}
+ */
Index: kernel/genarch/src/multiboot/multiboot.c
===================================================================
--- kernel/genarch/src/multiboot/multiboot.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/multiboot/multiboot.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #include <genarch/multiboot/multiboot.h>
 #include <config.h>
+#include <stddef.h>
 #include <str.h>
 
@@ -98,25 +99,4 @@
 
 	str_ncpy(buf, size, start, (size_t) (end - start));
-}
-
-static void multiboot_cmdline(char *cmdline)
-{
-	/*
-	 * GRUB passes the command line in an escaped form.
-	 */
-	for (size_t i = 0, j = 0;
-	    cmdline[i] && j < CONFIG_BOOT_ARGUMENTS_BUFLEN;
-	    i++, j++) {
-		if (cmdline[i] == '\\') {
-			switch (cmdline[i + 1]) {
-			case '\\':
-			case '\'':
-			case '\"':
-				i++;
-				break;
-			}
-		}
-		bargs[j] = cmdline[i];
-	} 
 }
 
Index: kernel/genarch/src/multiboot/multiboot2.c
===================================================================
--- kernel/genarch/src/multiboot/multiboot2.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/multiboot/multiboot2.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,4 +41,9 @@
 
 #define MULTIBOOT2_TAG_ALIGN  8
+
+static void multiboot2_cmdline(const multiboot2_cmdline_t *module)
+{
+	multiboot_cmdline(module->string);
+}
 
 static void multiboot2_module(const multiboot2_module_t *module)
@@ -117,4 +122,7 @@
 	while (tag->type != MULTIBOOT2_TAG_TERMINATOR) {
 		switch (tag->type) {
+		case MULTIBOOT2_TAG_CMDLINE:
+			multiboot2_cmdline(&tag->cmdline);
+			break;
 		case MULTIBOOT2_TAG_MODULE:
 			multiboot2_module(&tag->module);
Index: kernel/genarch/src/ofw/ebus.c
===================================================================
--- kernel/genarch/src/ofw/ebus.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/ofw/ebus.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
  */
 
+#include <assert.h>
 #include <genarch/ofw/ofw_tree.h>
 #include <genarch/ofw/ebus.h>
@@ -41,5 +42,4 @@
 #include <str.h>
 #include <panic.h>
-#include <debug.h>
 #include <macros.h>
 
@@ -94,5 +94,5 @@
 	size_t count = prop->size / sizeof(ofw_ebus_intr_map_t);
 	
-	ASSERT(count);
+	assert(count);
 	
 	prop = ofw_tree_getprop(node, "interrupt-map-mask");
@@ -102,5 +102,5 @@
 	ofw_ebus_intr_mask_t *intr_mask = prop->value;
 	
-	ASSERT(prop->size == sizeof(ofw_ebus_intr_mask_t));
+	assert(prop->size == sizeof(ofw_ebus_intr_mask_t));
 	
 	uint32_t space = reg->space & intr_mask->space_mask;
Index: kernel/genarch/src/ofw/ofw_tree.c
===================================================================
--- kernel/genarch/src/ofw/ofw_tree.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #include <mm/slab.h>
 #include <sysinfo/sysinfo.h>
-#include <memstr.h>
+#include <mem.h>
 #include <str.h>
 #include <panic.h>
Index: kernel/genarch/src/srln/srln.c
===================================================================
--- kernel/genarch/src/srln/srln.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/genarch/src/srln/srln.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <genarch/srln/srln.h>
 #include <console/chardev.h>
@@ -148,6 +149,6 @@
 indev_t *srln_wire(srln_instance_t *instance, indev_t *sink)
 {
-	ASSERT(instance);
-	ASSERT(sink);
+	assert(instance);
+	assert(sink);
 	
 	instance->sink = sink;
Index: kernel/generic/include/adt/avl.h
===================================================================
--- kernel/generic/include/adt/avl.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/adt/avl.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,7 @@
 #define KERN_AVLTREE_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <trace.h>
 
Index: kernel/generic/include/adt/bitmap.h
===================================================================
--- kernel/generic/include/adt/bitmap.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/adt/bitmap.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_BITMAP_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 
 #define BITMAP_ELEMENT   8
Index: kernel/generic/include/adt/btree.h
===================================================================
--- kernel/generic/include/adt/btree.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/adt/btree.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,6 @@
 #define KERN_BTREE_H_
 
-#include <typedefs.h>
 #include <adt/list.h>
+#include <stddef.h>
 
 #define BTREE_M		5
@@ -81,5 +81,5 @@
 	link_t leaf_link;
 
-	/* Variables needed by btree_print(). */	
+	/* Variables needed by btree_print(). */
 	link_t bfs_link;
 	int depth;
Index: kernel/generic/include/adt/hash.h
===================================================================
--- kernel/generic/include/adt/hash.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/adt/hash.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,11 +45,11 @@
 	 * Public domain.
 	 */
-	hash = ~hash + (hash << 15); 
+	hash = ~hash + (hash << 15);
 	hash = hash ^ (hash >> 12);
 	hash = hash + (hash << 2);
 	hash = hash ^ (hash >> 4);
-	hash = hash * 2057; 
+	hash = hash * 2057;
 	hash = hash ^ (hash >> 16);
-	return hash;	
+	return hash;
 }
 
@@ -65,6 +65,6 @@
 	hash = hash ^ (hash >> 4);
 	hash = hash * 0x27d4eb2d;
-	hash = hash ^ (hash >> 15);	
-	/* 
+	hash = hash ^ (hash >> 15);
+	/*
 	 * Lower order bits are mixed more thoroughly. Swap them with
 	 * the higher order bits and make the resulting higher order bits
@@ -105,7 +105,7 @@
 	 * http://burtleburtle.net/bob/c/lookup3.c
 	 */
-	seed ^= hash + 0x9e3779b9 
+	seed ^= hash + 0x9e3779b9
 		+ ((seed << 5) | (seed >> (sizeof(size_t) * 8 - 5)));
-	return seed;	
+	return seed;
 }
 
Index: kernel/generic/include/adt/hash_table.h
===================================================================
--- kernel/generic/include/adt/hash_table.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/adt/hash_table.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,4 +1,6 @@
 /*
  * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2012 Adam Hraska
+ * 
  * All rights reserved.
  *
@@ -27,5 +29,5 @@
  */
 
-/** @addtogroup genericadt
+/** @addtogroup libc
  * @{
  */
@@ -33,53 +35,70 @@
  */
 
-#ifndef KERN_HASH_TABLE_H_
-#define KERN_HASH_TABLE_H_
+#ifndef LIBC_HASH_TABLE_H_
+#define LIBC_HASH_TABLE_H_
 
 #include <adt/list.h>
-#include <typedefs.h>
+#include <stdbool.h>
+#include <macros.h>
+
+/** Opaque hash table link type. */
+typedef struct ht_link {
+	link_t link;
+} ht_link_t;
 
 /** Set of operations for hash table. */
 typedef struct {
-	/** Hash function.
-	 *
-	 * @param key 	Array of keys needed to compute hash index. All keys must
-	 * 		be passed.
-	 *
-	 * @return Index into hash table.
-	 */
-	size_t (* hash)(sysarg_t key[]);
+	/** Returns the hash of the key stored in the item (ie its lookup key). */
+	size_t (*hash)(const ht_link_t *item);
 	
-	/** Hash table item comparison function.
-	 *
-	 * @param key 	Array of keys that will be compared with item. It is not
-	 *		necessary to pass all keys.
-	 *
-	 * @return true if the keys match, false otherwise.
-	 */
-	bool (*compare)(sysarg_t key[], size_t keys, link_t *item);
+	/** Returns the hash of the key. */
+	size_t (*key_hash)(void *key);
+	
+	/** True if the items are equal (have the same lookup keys). */
+	bool (*equal)(const ht_link_t *item1, const ht_link_t *item2);
+
+	/** Returns true if the key is equal to the item's lookup key. */
+	bool (*key_equal)(void *key, const ht_link_t *item);
 
 	/** Hash table item removal callback.
+	 * 
+	 * Must not invoke any mutating functions of the hash table.
 	 *
 	 * @param item Item that was removed from the hash table.
 	 */
-	void (*remove_callback)(link_t *item);
-} hash_table_operations_t;
+	void (*remove_callback)(ht_link_t *item);
+} hash_table_ops_t;
 
 /** Hash table structure. */
 typedef struct {
-	list_t *entry;
-	size_t entries;
-	size_t max_keys;
-	hash_table_operations_t *op;
+	hash_table_ops_t *op;
+	list_t *bucket;
+	size_t bucket_cnt;
+	size_t full_item_cnt;
+	size_t item_cnt;
+	size_t max_load;
+	bool apply_ongoing;
 } hash_table_t;
 
-#define hash_table_get_instance(item, type, member) \
-	list_get_instance((item), type, member)
+#define hash_table_get_inst(item, type, member) \
+	member_to_inst((item), type, member)
 
-extern void hash_table_create(hash_table_t *h, size_t m, size_t max_keys,
-    hash_table_operations_t *op);
-extern void hash_table_insert(hash_table_t *h, sysarg_t key[], link_t *item);
-extern link_t *hash_table_find(hash_table_t *h, sysarg_t key[]);
-extern void hash_table_remove(hash_table_t *h, sysarg_t key[], size_t keys);
+extern bool hash_table_create(hash_table_t *, size_t, size_t, 
+	hash_table_ops_t *);
+extern void hash_table_destroy(hash_table_t *);
+
+extern bool hash_table_empty(hash_table_t *);
+extern size_t hash_table_size(hash_table_t *);
+
+extern void hash_table_clear(hash_table_t *);
+extern void hash_table_insert(hash_table_t *, ht_link_t *);
+extern bool hash_table_insert_unique(hash_table_t *, ht_link_t *);
+extern ht_link_t *hash_table_find(const hash_table_t *, void *);
+extern ht_link_t *hash_table_find_next(const hash_table_t *, ht_link_t *);
+extern size_t hash_table_remove(hash_table_t *, void *);
+extern void hash_table_remove_item(hash_table_t *, ht_link_t *);
+extern void hash_table_apply(hash_table_t *, bool (*)(ht_link_t *, void *), 
+	void *);
+
 
 #endif
Index: kernel/generic/include/adt/list.h
===================================================================
--- kernel/generic/include/adt/list.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/adt/list.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,6 +37,7 @@
 #define KERN_LIST_H_
 
-#include <debug.h>
-#include <typedefs.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
 #include <trace.h>
 
@@ -52,10 +53,8 @@
 } list_t;
 
-
 extern bool list_member(const link_t *, const list_t *);
 extern void list_splice(list_t *, link_t *);
 extern unsigned long list_count(const list_t *);
 
-
 /** Declare and initialize statically allocated list.
  *
@@ -64,5 +63,23 @@
  */
 #define LIST_INITIALIZE(name) \
-	list_t name = { \
+	list_t name = LIST_INITIALIZER(name)
+
+/** Initializer for statically allocated list.
+ * 
+ * @code
+ * struct named_list {
+ *     const char *name;
+ *     list_t list;
+ * } var = { 
+ *     .name = "default name", 
+ *     .list = LIST_INITIALIZER(name_list.list) 
+ * };
+ * @endcode
+ *
+ * @param name Name of the new statically allocated list.
+ *
+ */
+#define LIST_INITIALIZER(name) \
+	{ \
 		.head = { \
 			.prev = &(name).head, \
@@ -87,5 +104,5 @@
 
 /** Unlike list_foreach(), allows removing items while traversing a list.
- * 
+ *
  * @code
  * list_t mylist;
@@ -117,7 +134,12 @@
 	    iterator = next_iter, next_iter = iterator->next)
 
-	
 #define assert_link_not_used(link) \
-	ASSERT(!link_used(link))
+	assert(!link_used(link))
+
+/** Returns true if the link is definitely part of a list. False if not sure. */
+static inline bool link_in_use(const link_t *link)
+{
+	return link->prev != NULL && link->next != NULL;
+}
 
 /** Initialize doubly-linked circular list link
@@ -246,7 +268,7 @@
  *
  */
-static inline link_t *list_last(list_t *list)
-{
-	return ((list->head.prev == &list->head) ? NULL : list->head.prev);
+static inline link_t *list_last(const list_t *list)
+{
+	return (list->head.prev == &list->head) ? NULL : list->head.prev;
 }
 
@@ -258,5 +280,5 @@
  * @return Next item or NULL if @a link is the last item.
  */
-static inline link_t *list_next(link_t *link, const list_t *list)
+static inline link_t *list_next(const link_t *link, const list_t *list)
 {
 	return (link->next == &list->head) ? NULL : link->next;
@@ -270,5 +292,5 @@
  * @return Previous item or NULL if @a link is the first item.
  */
-static inline link_t *list_prev(link_t *link, const list_t *list)
+static inline link_t *list_prev(const link_t *link, const list_t *list)
 {
 	return (link->prev == &list->head) ? NULL : link->prev;
@@ -353,10 +375,9 @@
  *
  */
-static inline link_t *list_nth(list_t *list, unsigned long n)
+static inline link_t *list_nth(const list_t *list, unsigned long n)
 {
 	unsigned long cnt = 0;
-	link_t *link;
 	
-	link = list_first(list);
+	link_t *link = list_first(list);
 	while (link != NULL) {
 		if (cnt == n)
@@ -389,5 +410,5 @@
 		return false;
 
-	ASSERT(link->prev != NULL && link->next != NULL);
+	assert(link->prev != NULL && link->next != NULL);
 	return true;
 }
Index: kernel/generic/include/assert.h
===================================================================
--- kernel/generic/include/assert.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/include/assert.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genericdebug
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_ASSERT_H_
+#define KERN_ASSERT_H_
+
+#include <panic.h>
+
+#ifdef CONFIG_DEBUG
+
+/** Debugging assert macro
+ *
+ * If CONFIG_DEBUG is set, the assert() macro
+ * evaluates expr and if it is false raises
+ * kernel panic.
+ *
+ * @param expr Expression which is expected to be true.
+ *
+ */
+#define assert(expr) \
+	do { \
+		if (!(expr)) \
+			panic_assert("%s() at %s:%u:\n%s", \
+			    __func__, __FILE__, __LINE__, #expr); \
+	} while (0)
+
+/** Debugging verbose assert macro
+ *
+ * If CONFIG_DEBUG is set, the assert_verbose() macro
+ * evaluates expr and if it is false raises
+ * kernel panic. The panic message contains also
+ * the supplied message.
+ *
+ * @param expr Expression which is expected to be true.
+ * @param msg  Additional message to show (string).
+ *
+ */
+#define assert_verbose(expr, msg) \
+	do { \
+		if (!(expr)) \
+			panic_assert("%s() at %s:%u:\n%s, %s", \
+			    __func__, __FILE__, __LINE__, #expr, msg); \
+	} while (0)
+
+/** Static assert macro
+ *
+ */
+#define static_assert \
+	_Static_assert
+
+#else /* CONFIG_DEBUG */
+
+#define assert(expr)
+#define assert_verbose(expr, msg)
+#define static_assert(expr, msg)
+
+#endif /* CONFIG_DEBUG */
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/byteorder.h
===================================================================
--- kernel/generic/include/byteorder.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/byteorder.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_BYTEORDER_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 #if !(defined(__BE__) ^ defined(__LE__))
Index: kernel/generic/include/cap/cap.h
===================================================================
--- kernel/generic/include/cap/cap.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/include/cap/cap.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2017 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_CAP_H_
+#define KERN_CAP_H_
+
+#include <typedefs.h>
+#include <adt/list.h>
+#include <adt/hash.h>
+#include <adt/hash_table.h>
+#include <lib/ra.h>
+#include <synch/mutex.h>
+#include <atomic.h>
+
+typedef int cap_handle_t;
+
+typedef enum {
+	CAP_STATE_FREE,
+	CAP_STATE_ALLOCATED,
+	CAP_STATE_PUBLISHED
+} cap_state_t;
+
+typedef enum {
+	KOBJECT_TYPE_PHONE,
+	KOBJECT_TYPE_IRQ,
+	KOBJECT_TYPE_MAX
+} kobject_type_t;
+
+struct task;
+struct phone;
+struct irq;
+
+struct kobject;
+typedef struct kobject_ops {
+	bool (*reclaim)(struct kobject *);
+	void (*destroy)(void *);
+} kobject_ops_t;
+
+/*
+ * Everything in kobject_t except for the atomic reference count is imutable.
+ */
+typedef struct kobject {
+	kobject_type_t type;
+	atomic_t refcnt;
+
+	kobject_ops_t *ops;
+
+	union {
+		void *raw;
+		struct phone *phone;
+		struct irq *irq;
+	};
+} kobject_t;
+
+/*
+ * A cap_t may only be accessed under the protection of the cap_info_t lock.
+ */
+typedef struct cap {
+	cap_state_t state;
+
+	struct task *task;
+	cap_handle_t handle;
+
+	/* Link to the task's capabilities of the same kobject type. */
+	link_t type_link;
+
+	ht_link_t caps_link;
+
+	/* The underlying kernel object. */
+	kobject_t *kobject;
+} cap_t;
+
+typedef struct cap_info {
+	mutex_t lock;
+
+	list_t type_list[KOBJECT_TYPE_MAX];
+
+	hash_table_t caps;
+	ra_arena_t *handles;
+} cap_info_t;
+
+extern void caps_init(void);
+extern int caps_task_alloc(struct task *);
+extern void caps_task_free(struct task *);
+extern void caps_task_init(struct task *);
+extern bool caps_apply_to_kobject_type(struct task *, kobject_type_t,
+    bool (*)(cap_t *, void *), void *);
+
+extern cap_handle_t cap_alloc(struct task *);
+extern void cap_publish(struct task *, cap_handle_t, kobject_t *);
+extern kobject_t *cap_unpublish(struct task *, cap_handle_t, kobject_type_t);
+extern void cap_free(struct task *, cap_handle_t);
+
+extern void kobject_initialize(kobject_t *, kobject_type_t, void *,
+    kobject_ops_t *);
+extern kobject_t *kobject_get(struct task *, cap_handle_t, kobject_type_t);
+extern void kobject_add_ref(kobject_t *);
+extern void kobject_put(kobject_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/config.h
===================================================================
--- kernel/generic/include/config.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/config.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -52,4 +52,5 @@
 #ifndef __ASM__
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/console/chardev.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,6 @@
 
 #include <adt/list.h>
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
 #include <synch/waitq.h>
 #include <synch/spinlock.h>
Index: kernel/generic/include/context.h
===================================================================
--- kernel/generic/include/context.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/context.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_CONTEXT_H_
 
-#include <typedefs.h>
 #include <trace.h>
 #include <arch/context.h>
Index: rnel/generic/include/ddi/device.h
===================================================================
--- kernel/generic/include/ddi/device.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genericddi
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_DEVICE_H_
-#define KERN_DEVICE_H_
-
-#include <typedefs.h>
-
-extern devno_t device_assign_devno(void);
-extern sysarg_t sys_device_assign_devno(void);
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/ddi/irq.h
===================================================================
--- kernel/generic/include/ddi/irq.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/ddi/irq.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,4 +43,5 @@
 #include <proc/task.h>
 #include <ipc/ipc.h>
+#include <mm/slab.h>
 
 typedef enum {
@@ -70,4 +71,6 @@
 	/** When false, notifications are not sent. */
 	bool notify;
+	/** True if the structure is in irq_uspace_hash_table_table */
+	bool hashed_in;
 	/** Answerbox for notifications. */
 	answerbox_t *answerbox;
@@ -76,14 +79,8 @@
 	/** Arguments that will be sent if the IRQ is claimed. */
 	uint32_t scratch[IPC_CALL_LEN];
-	/** Top-half pseudocode. */
+	/** Top-half IRQ code. */
 	irq_code_t *code;
 	/** Counter. */
 	size_t counter;
-	
-	/**
-	 * Link between IRQs that are notifying the same answerbox. The list is
-	 * protected by the answerbox irq_lock.
-	 */
-	link_t link;
 } ipc_notif_cfg_t;
 
@@ -91,10 +88,9 @@
  *
  * If one device has multiple interrupts, there will be multiple irq_t
- * instantions with the same devno.
- *
+ * instantions.
  */
 typedef struct irq {
 	/** Hash table link. */
-	link_t link;
+	ht_link_t link;
 	
 	/** Lock protecting everything in this structure
@@ -112,7 +108,4 @@
 	 */
 	bool preack;
-	
-	/** Unique device number. -1 if not yet assigned. */
-	devno_t devno;
 	
 	/** Actual IRQ number. -1 if not yet assigned. */
@@ -139,4 +132,6 @@
 extern hash_table_t irq_uspace_hash_table;
 
+extern slab_cache_t *irq_slab;
+
 extern inr_t last_inr;
 
Index: kernel/generic/include/debug.h
===================================================================
--- kernel/generic/include/debug.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/debug.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,64 +36,8 @@
 #define KERN_DEBUG_H_
 
-#include <panic.h>
 #include <log.h>
 #include <symtab_lookup.h>
 
 #define CALLER  ((uintptr_t) __builtin_return_address(0))
-
-#ifdef CONFIG_DEBUG
-
-/** Debugging ASSERT macro
- *
- * If CONFIG_DEBUG is set, the ASSERT() macro
- * evaluates expr and if it is false raises
- * kernel panic.
- *
- * @param expr Expression which is expected to be true.
- *
- */
-#define ASSERT(expr) \
-	do { \
-		if (!(expr)) \
-			panic_assert("%s() at %s:%u:\n%s", \
-			    __func__, __FILE__, __LINE__, #expr); \
-	} while (0)
-
-/** Debugging verbose ASSERT macro
- *
- * If CONFIG_DEBUG is set, the ASSERT() macro
- * evaluates expr and if it is false raises
- * kernel panic. The panic message contains also
- * the supplied message.
- *
- * @param expr Expression which is expected to be true.
- * @param msg  Additional message to show (string).
- *
- */
-#define ASSERT_VERBOSE(expr, msg) \
-	do { \
-		if (!(expr)) \
-			panic_assert("%s() at %s:%u:\n%s, %s", \
-			    __func__, __FILE__, __LINE__, #expr, msg); \
-	} while (0)
-
-/** Static assert macro
- *
- */
-#define STATIC_ASSERT(expr) \
-	_Static_assert(expr, "")
-
-#define STATIC_ASSERT_VERBOSE(expr, msg) \
-	_Static_assert(expr, msg)
-
-
-#else /* CONFIG_DEBUG */
-
-#define ASSERT(expr)
-#define ASSERT_VERBOSE(expr, msg)
-#define STATIC_ASSERT(expr)
-#define STATIC_ASSERT_VERBOSE(expr, msg)
-
-#endif /* CONFIG_DEBUG */
 
 #ifdef CONFIG_LOG
Index: kernel/generic/include/func.h
===================================================================
--- kernel/generic/include/func.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/func.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_FUNC_H_
 
-#include <typedefs.h>
 #include <atomic.h>
 
Index: kernel/generic/include/gsort.h
===================================================================
--- kernel/generic/include/gsort.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/include/gsort.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2005 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 KERN_GSORT_H_
+#define KERN_GSORT_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+
+typedef int (* sort_cmp_t)(void *, void *, void *);
+
+extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *);
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/ipc/ipc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,6 +42,6 @@
 #include <abi/proc/task.h>
 #include <typedefs.h>
-
-#define IPC_MAX_PHONES  64
+#include <mm/slab.h>
+#include <cap/cap.h>
 
 struct answerbox;
@@ -62,5 +62,5 @@
 
 /** Structure identifying phone (in TASK structure) */
-typedef struct {
+typedef struct phone {
 	mutex_t lock;
 	link_t link;
@@ -69,4 +69,5 @@
 	ipc_phone_state_t state;
 	atomic_t active_calls;
+	kobject_t *kobject;
 } phone_t;
 
@@ -94,6 +95,4 @@
 	/** Notifications from IRQ handlers. */
 	list_t irq_notifs;
-	/** IRQs with notifications to this answerbox. */
-	list_t irq_list;
 } answerbox_t;
 
@@ -170,4 +169,6 @@
 } call_t;
 
+extern slab_cache_t *phone_slab;
+
 extern answerbox_t *ipc_phone_0;
 
Index: kernel/generic/include/ipc/ipcrsc.h
===================================================================
--- kernel/generic/include/ipc/ipcrsc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/ipc/ipcrsc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,10 +38,10 @@
 #include <proc/task.h>
 #include <ipc/ipc.h>
+#include <cap/cap.h>
 
 extern call_t *get_call(sysarg_t);
-extern int phone_get(sysarg_t, phone_t **);
-extern int phone_alloc(task_t *);
-extern bool phone_connect(int, answerbox_t *);
-extern void phone_dealloc(int);
+extern cap_handle_t phone_alloc(task_t *);
+extern bool phone_connect(cap_handle_t, answerbox_t *);
+extern void phone_dealloc(cap_handle_t);
 
 #endif
Index: kernel/generic/include/ipc/irq.h
===================================================================
--- kernel/generic/include/ipc/irq.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/ipc/irq.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -47,12 +47,10 @@
 #include <adt/list.h>
 
-extern int ipc_irq_subscribe(answerbox_t *, inr_t, devno_t, sysarg_t,
-    irq_code_t *);
 
 extern irq_ownership_t ipc_irq_top_half_claim(irq_t *);
 extern void ipc_irq_top_half_handler(irq_t *);
 
-extern int ipc_irq_unsubscribe(answerbox_t *, inr_t, devno_t);
-extern void ipc_irq_cleanup(answerbox_t *);
+extern int ipc_irq_subscribe(answerbox_t *, inr_t, sysarg_t, irq_code_t *);
+extern int ipc_irq_unsubscribe(answerbox_t *, int);
 
 /*
Index: kernel/generic/include/ipc/sysipc.h
===================================================================
--- kernel/generic/include/ipc/sysipc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/ipc/sysipc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -56,6 +56,6 @@
 extern sysarg_t sys_ipc_hangup(sysarg_t);
 
-extern sysarg_t sys_ipc_irq_subscribe(inr_t, devno_t, sysarg_t, irq_code_t *);
-extern sysarg_t sys_ipc_irq_unsubscribe(inr_t, devno_t);
+extern sysarg_t sys_ipc_irq_subscribe(inr_t, sysarg_t, irq_code_t *);
+extern sysarg_t sys_ipc_irq_unsubscribe(sysarg_t);
 
 #ifdef __32_BITS__
Index: kernel/generic/include/lib/elf.h
===================================================================
--- kernel/generic/include/lib/elf.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/lib/elf.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define KERN_ELF_H_
 
-#include <typedefs.h>
 #include <abi/elf.h>
 #include <arch/elf.h>
Index: kernel/generic/include/lib/elf_load.h
===================================================================
--- kernel/generic/include/lib/elf_load.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/lib/elf_load.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,4 @@
 
 #include <arch/elf.h>
-#include <typedefs.h>
 
 /**
Index: kernel/generic/include/lib/memfnc.h
===================================================================
--- kernel/generic/include/lib/memfnc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/lib/memfnc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_LIB_MEMFNC_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 #include <cc.h>
 
Index: kernel/generic/include/lib/ra.h
===================================================================
--- kernel/generic/include/lib/ra.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/lib/ra.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -71,5 +71,13 @@
 typedef struct {
 	link_t segment_link;	/**< Span's segment list link. */
-	link_t fu_link;		/**< Span's free list or used hash link. */
+
+	/*
+	 * A segment cannot be both on the free list and in the used hash.
+	 * Their respective links can therefore occupy the same space.
+	 */
+	union {
+		link_t fl_link;		/**< Span's free list link. */
+		ht_link_t uh_link;	/**< Span's used hash link. */
+	};
 
 	uintptr_t base;		/**< Segment base. */
@@ -79,6 +87,7 @@
 extern void ra_init(void);
 extern ra_arena_t *ra_arena_create(void);
+extern void ra_arena_destroy(ra_arena_t *);
 extern bool ra_span_add(ra_arena_t *, uintptr_t, size_t);
-extern uintptr_t ra_alloc(ra_arena_t *, size_t, size_t);
+extern bool ra_alloc(ra_arena_t *, size_t, size_t, uintptr_t *);
 extern void ra_free(ra_arena_t *, uintptr_t, size_t);
 
Index: kernel/generic/include/lib/rd.h
===================================================================
--- kernel/generic/include/lib/rd.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/lib/rd.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_RD_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 
 extern void init_rd(void *, size_t);
Index: kernel/generic/include/log.h
===================================================================
--- kernel/generic/include/log.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/log.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,6 @@
 #define KERN_LOG_H_
 
-#include <typedefs.h>
 #include <stdarg.h>
+#include <stddef.h>
 #include <printf/verify.h>
 #include <abi/log.h>
Index: kernel/generic/include/macros.h
===================================================================
--- kernel/generic/include/macros.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/macros.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <trace.h>
 
Index: kernel/generic/include/mem.h
===================================================================
--- kernel/generic/include/mem.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/include/mem.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_MEM_H_
+#define KERN_MEM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <cc.h>
+
+#ifdef CONFIG_LTO
+#define DO_NOT_DISCARD ATTRIBUTE_USED
+#else
+#define DO_NOT_DISCARD
+#endif
+
+#define memset(dst, val, cnt)  __builtin_memset((dst), (val), (cnt))
+#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
+
+extern void memsetb(void *, size_t, uint8_t)
+    __attribute__((nonnull(1)));
+extern void memsetw(void *, size_t, uint16_t)
+    __attribute__((nonnull(1)));
+extern void *memmove(void *, const void *, size_t)
+    __attribute__((nonnull(1, 2))) DO_NOT_DISCARD;
+
+#endif
+
+/** @}
+ */
Index: rnel/generic/include/memstr.h
===================================================================
--- kernel/generic/include/memstr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,60 +1,0 @@
-/*
- * Copyright (c) 2001-2004 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup generic
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_MEMSTR_H_
-#define KERN_MEMSTR_H_
-
-#include <typedefs.h>
-#include <cc.h>
-
-#ifdef CONFIG_LTO
-#define DO_NOT_DISCARD ATTRIBUTE_USED
-#else
-#define DO_NOT_DISCARD
-#endif
-
-#define memset(dst, val, cnt)  __builtin_memset((dst), (val), (cnt))
-#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
-
-extern void memsetb(void *, size_t, uint8_t)
-    __attribute__((nonnull(1)));
-extern void memsetw(void *, size_t, uint16_t)
-    __attribute__((nonnull(1)));
-extern void *memmove(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2))) DO_NOT_DISCARD;
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/mm/reserve.h
===================================================================
--- kernel/generic/include/mm/reserve.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/mm/reserve.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,6 @@
 #define KERN_RESERVE_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
 
 extern void reserve_init(void);
Index: kernel/generic/include/panic.h
===================================================================
--- kernel/generic/include/panic.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/panic.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_PANIC_H_
 
+#include <stdbool.h>
+#include <stddef.h>
 #include <typedefs.h>
 #include <print.h>
Index: kernel/generic/include/preemption.h
===================================================================
--- kernel/generic/include/preemption.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/preemption.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,6 +37,6 @@
 
 #include <arch.h>
+#include <assert.h>
 #include <compiler/barrier.h>
-#include <debug.h>
 
 #define PREEMPTION_INC         (1 << 0)
@@ -54,5 +54,5 @@
 #define preemption_enable() \
 	do { \
-		ASSERT(PREEMPTION_DISABLED); \
+		assert(PREEMPTION_DISABLED); \
 		compiler_barrier(); \
 		THE->preemption -= PREEMPTION_INC; \
Index: kernel/generic/include/print.h
===================================================================
--- kernel/generic/include/print.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/print.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,6 @@
 #define KERN_PRINT_H_
 
-#include <typedefs.h>
 #include <stdarg.h>
+#include <stddef.h>
 #include <printf/verify.h>
 
Index: kernel/generic/include/printf/printf_core.h
===================================================================
--- kernel/generic/include/printf/printf_core.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/printf/printf_core.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,6 @@
 #define KERN_PRINTF_CORE_H_
 
-#include <typedefs.h>
 #include <stdarg.h>
+#include <stddef.h>
 
 /** Structure for specifying output methods for different printf clones. */
Index: kernel/generic/include/proc/scheduler.h
===================================================================
--- kernel/generic/include/proc/scheduler.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/proc/scheduler.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,7 @@
 #define KERN_SCHEDULER_H_
 
+#include <stddef.h>
 #include <synch/spinlock.h>
 #include <time/clock.h>
-#include <typedefs.h>
 #include <atomic.h>
 #include <adt/list.h>
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/proc/task.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,5 +48,5 @@
 #include <adt/cht.h>
 #include <adt/list.h>
-#include <security/cap.h>
+#include <security/perm.h>
 #include <arch/proc/task.h>
 #include <arch/proc/thread.h>
@@ -60,4 +60,5 @@
 #include <abi/sysinfo.h>
 #include <arch.h>
+#include <cap/cap.h>
 
 #define TASK                 THE->task
@@ -65,4 +66,5 @@
 
 struct thread;
+struct cap;
 
 /** Task structure. */
@@ -93,6 +95,9 @@
 	atomic_t lifecount;
 	
-	/** Task capabilities. */
-	cap_t capabilities;
+	/** Task permissions. */
+	perm_t perms;
+
+	/** Capabilities */
+	cap_info_t *cap_info;
 	
 	/* IPC stuff */
@@ -100,7 +105,4 @@
 	/** Receiving communication endpoint */
 	answerbox_t answerbox;
-
-	/** Sending communication endpoints */
-	phone_t phones[IPC_MAX_PHONES];
 
 	/** Spinlock protecting the active_calls list. */
@@ -159,6 +161,6 @@
 extern void task_print_list(bool);
 
-extern void cap_set(task_t *, cap_t);
-extern cap_t cap_get(task_t *);
+extern void perm_set(task_t *, perm_t);
+extern perm_t perm_get(task_t *);
 
 #ifndef task_create_arch
Index: rnel/generic/include/security/cap.h
===================================================================
--- kernel/generic/include/security/cap.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,94 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup generic
- * @{
- */
-/** @file
- */
-
-/**
- * @file
- * @brief Capabilities definitions.
- *
- * Capabilities represent virtual rights that entitle their
- * holder to perform certain security sensitive tasks.
- *
- * Each task can have arbitrary combination of the capabilities
- * defined in this file. Therefore, they are required to be powers
- * of two.
- */
-
-#ifndef __CAP_H__
-#define __CAP_H__
-
-#include <typedefs.h>
-
-/**
- * CAP_CAP allows its holder to grant/revoke arbitrary
- * privilege to/from other tasks.
- */
-#define CAP_CAP  (1 << 0)
-
-/**
- * CAP_MEM_MANAGER allows its holder to map physical memory
- * to other tasks.
- */
-#define CAP_MEM_MANAGER  (1 << 1)
-
-/**
- * CAP_IO_MANAGER allows its holder to access I/O space
- * to other tasks.
- */
-#define CAP_IO_MANAGER  (1 << 2)
-
-/**
- * CAP_IRQ_REG entitles its holder to register IRQ handlers.
- */
-#define CAP_IRQ_REG  (1 << 3)
-
-typedef uint32_t cap_t;
-
-#ifdef __32_BITS__
-
-extern sysarg_t sys_cap_grant(sysarg64_t *, cap_t);
-extern sysarg_t sys_cap_revoke(sysarg64_t *, cap_t);
-
-#endif  /* __32_BITS__ */
-
-#ifdef __64_BITS__
-
-extern sysarg_t sys_cap_grant(sysarg_t, cap_t);
-extern sysarg_t sys_cap_revoke(sysarg_t, cap_t);
-
-#endif  /* __64_BITS__ */
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/security/perm.h
===================================================================
--- kernel/generic/include/security/perm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/include/security/perm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file
+ */
+
+/**
+ * @file
+ * @brief Task permissions definitions.
+ *
+ * Permissions represent virtual rights that entitle their
+ * holder to perform certain security sensitive tasks.
+ *
+ * Each task can have arbitrary combination of the permissions 
+ * defined in this file. Therefore, they are required to be powers
+ * of two.
+ */
+
+#ifndef __PERM_H__
+#define __PERM_H__
+
+#include <typedefs.h>
+
+/**
+ * PERM_PERM allows its holder to grant/revoke arbitrary permission to/from
+ * other tasks.
+ */
+#define PERM_PERM        (1 << 0)
+
+/**
+ * PERM_MEM_MANAGER allows its holder to map physical memory to other tasks.
+ */
+#define PERM_MEM_MANAGER (1 << 1)
+
+/**
+ * PERM_IO_MANAGER allows its holder to access I/O space to other tasks.
+ */
+#define PERM_IO_MANAGER  (1 << 2)
+
+/**
+ * PERM_IRQ_REG entitles its holder to register IRQ handlers.
+ */
+#define PERM_IRQ_REG     (1 << 3)
+
+typedef uint32_t perm_t;
+
+#ifdef __32_BITS__
+
+extern sysarg_t sys_perm_grant(sysarg64_t *, perm_t);
+extern sysarg_t sys_perm_revoke(sysarg64_t *, perm_t);
+
+#endif  /* __32_BITS__ */
+
+#ifdef __64_BITS__
+
+extern sysarg_t sys_perm_grant(sysarg_t, perm_t);
+extern sysarg_t sys_perm_revoke(sysarg_t, perm_t);
+
+#endif  /* __64_BITS__ */
+
+#endif
+
+/** @}
+ */
Index: rnel/generic/include/sort.h
===================================================================
--- kernel/generic/include/sort.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2005 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 KERN_SORT_H_
-#define KERN_SORT_H_
-
-#include <typedefs.h>
-
-typedef int (* sort_cmp_t)(void *, void *, void *);
-
-extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *);
-extern bool qsort(void *, size_t, size_t, sort_cmp_t, void *);
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/stacktrace.h
===================================================================
--- kernel/generic/include/stacktrace.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/stacktrace.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_STACKTRACE_H_
 
+#include <stdbool.h>
 #include <typedefs.h>
 
Index: kernel/generic/include/stdbool.h
===================================================================
--- kernel/generic/include/stdbool.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/include/stdbool.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_BOOL_H_
+#define KERN_BOOL_H_
+
+#include <abi/bool.h>
+
+#define false  0
+#define true   1
+
+#define __bool_true_false_are_defined 1
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/stddef.h
===================================================================
--- kernel/generic/include/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/include/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_STDDEF_H_
+#define KERN_STDDEF_H_
+
+#include <arch/types.h>
+
+typedef native_t ptrdiff_t;
+
+#ifndef NULL
+	#define NULL  ((void *) 0)
+#endif
+
+#define offsetof(type,member) ((size_t) &(((type *) 0)->member))
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/stdint.h
===================================================================
--- kernel/generic/include/stdint.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/stdint.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #define KERN_STDINT_H_
 
+#include <arch/common.h>
+
 #define INT8_MIN  INT8_C(0x80)
 #define INT8_MAX  INT8_C(0x7F)
Index: kernel/generic/include/str.h
===================================================================
--- kernel/generic/include/str.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/str.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,7 @@
 #define KERN_STR_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
 
 /**< Common Unicode characters */
Index: kernel/generic/include/synch/condvar.h
===================================================================
--- kernel/generic/include/synch/condvar.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/synch/condvar.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_CONDVAR_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <synch/waitq.h>
 #include <synch/mutex.h>
Index: kernel/generic/include/synch/futex.h
===================================================================
--- kernel/generic/include/synch/futex.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/synch/futex.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <typedefs.h>
 #include <synch/waitq.h>
+#include <adt/hash_table.h>
 
 /** Kernel-side futex structure. */
@@ -46,5 +47,5 @@
 	waitq_t wq;
 	/** Futex hash table link. */
-	link_t ht_link;
+	ht_link_t ht_link;
 	/** Number of tasks that reference this futex. */
 	size_t refcount;
Index: kernel/generic/include/synch/mutex.h
===================================================================
--- kernel/generic/include/synch/mutex.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/synch/mutex.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,6 @@
 #define KERN_MUTEX_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
+#include <stdint.h>
 #include <synch/semaphore.h>
 #include <abi/synch.h>
Index: kernel/generic/include/synch/rcu.h
===================================================================
--- kernel/generic/include/synch/rcu.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/synch/rcu.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define KERN_RCU_H_
 
+#include <assert.h>
 #include <synch/rcu_types.h>
 #include <compiler/barrier.h>
@@ -162,5 +163,5 @@
 static inline void _rcu_record_qs(void)
 {
-	ASSERT(PREEMPTION_DISABLED || interrupts_disabled());
+	assert(PREEMPTION_DISABLED || interrupts_disabled());
 	
 	/* 
@@ -207,5 +208,5 @@
 static inline void rcu_read_lock(void)
 {
-	ASSERT(CPU);
+	assert(CPU);
 	preemption_disable();
 
@@ -222,5 +223,5 @@
 static inline void rcu_read_unlock(void)
 {
-	ASSERT(CPU);
+	assert(CPU);
 	preemption_disable();
 	
Index: kernel/generic/include/synch/semaphore.h
===================================================================
--- kernel/generic/include/synch/semaphore.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/synch/semaphore.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_SEMAPHORE_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 #include <synch/waitq.h>
 #include <abi/synch.h>
Index: kernel/generic/include/synch/spinlock.h
===================================================================
--- kernel/generic/include/synch/spinlock.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/synch/spinlock.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,9 +36,9 @@
 #define KERN_SPINLOCK_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
 #include <arch/barrier.h>
+#include <assert.h>
 #include <preemption.h>
 #include <atomic.h>
-#include <debug.h>
 #include <arch/asm.h>
 
@@ -80,5 +80,5 @@
 
 #define ASSERT_SPINLOCK(expr, lock) \
-	ASSERT_VERBOSE(expr, (lock)->name)
+	assert_verbose(expr, (lock)->name)
 
 #define spinlock_lock(lock)    spinlock_lock_debug((lock))
@@ -98,5 +98,5 @@
 
 #define ASSERT_SPINLOCK(expr, lock) \
-	ASSERT(expr)
+	assert(expr)
 
 #define spinlock_lock(lock)    atomic_lock_arch(&(lock)->val)
@@ -175,5 +175,5 @@
 #define SPINLOCK_STATIC_INITIALIZE_NAME(name, desc_name)
 
-#define ASSERT_SPINLOCK(expr, lock)  ASSERT(expr)
+#define ASSERT_SPINLOCK(expr, lock)  assert(expr)
 
 #define spinlock_initialize(lock, name)
Index: kernel/generic/include/syscall/copy.h
===================================================================
--- kernel/generic/include/syscall/copy.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/syscall/copy.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_COPY_H_
 
-#include <typedefs.h>
+#include <stddef.h>
 
 /** Label within memcpy_from_uspace() that contains return -1. */
Index: kernel/generic/include/sysinfo/sysinfo.h
===================================================================
--- kernel/generic/include/sysinfo/sysinfo.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/sysinfo/sysinfo.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 
 #include <typedefs.h>
+#include <stdbool.h>
 #include <str.h>
 #include <abi/sysinfo.h>
Index: kernel/generic/include/time/delay.h
===================================================================
--- kernel/generic/include/time/delay.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/time/delay.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_DELAY_H_
 
-#include <typedefs.h>
+#include <stdint.h>
 
 extern void delay(uint32_t microseconds);
Index: kernel/generic/include/time/timeout.h
===================================================================
--- kernel/generic/include/time/timeout.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/time/timeout.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,7 @@
 #define KERN_TIMEOUT_H_
 
-#include <typedefs.h>
 #include <adt/list.h>
 #include <cpu.h>
+#include <stdint.h>
 
 typedef void (* timeout_handler_t)(void *arg);
Index: kernel/generic/include/typedefs.h
===================================================================
--- kernel/generic/include/typedefs.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/include/typedefs.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,10 +39,4 @@
 #include <arch/common.h>
 #include <arch/types.h>
-#include <abi/bool.h>
-
-#define NULL  ((void *) 0)
-
-#define false  0
-#define true   1
 
 typedef struct {
@@ -55,11 +49,8 @@
 
 typedef int32_t inr_t;
-typedef int32_t devno_t;
 
 typedef volatile uint8_t ioport8_t;
 typedef volatile uint16_t ioport16_t;
 typedef volatile uint32_t ioport32_t;
-
-typedef native_t ptrdiff_t;
 
 #ifdef __32_BITS__
Index: kernel/generic/src/adt/avl.c
===================================================================
--- kernel/generic/src/adt/avl.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/adt/avl.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -51,5 +51,5 @@
 
 #include <adt/avl.h>
-#include <debug.h>
+#include <assert.h>
 
 #define LEFT 	0
@@ -165,6 +165,6 @@
 	avltree_key_t key;
 
-	ASSERT(t);
-	ASSERT(newnode);
+	assert(t);
+	assert(newnode);
 
 	/*
@@ -259,5 +259,5 @@
 			 * LR rotation.
 			 */
-			ASSERT(par->balance == 1);
+			assert(par->balance == 1);
 			
 			REBALANCE_INSERT_LR();
@@ -274,5 +274,5 @@
 			 * RL rotation.
 			 */
-			ASSERT(par->balance == -1);
+			assert(par->balance == -1);
 		
 			REBALANCE_INSERT_RL();
@@ -322,5 +322,5 @@
 				*dir = LEFT;
 		} else {
-			ASSERT(u->par->rgt == v);
+			assert(u->par->rgt == v);
 			if (!ro)
 				u->par->rgt = w;
@@ -373,6 +373,6 @@
 	int dir;
 
-	ASSERT(t);
-	ASSERT(node);
+	assert(t);
+	assert(node);
 	
 	if (node->lft == NULL) {
Index: kernel/generic/src/adt/bitmap.c
===================================================================
--- kernel/generic/src/adt/bitmap.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/adt/bitmap.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,8 +40,8 @@
 
 #include <adt/bitmap.h>
+#include <align.h>
+#include <assert.h>
+#include <macros.h>
 #include <typedefs.h>
-#include <align.h>
-#include <debug.h>
-#include <macros.h>
 
 #define ALL_ONES    0xff
@@ -112,5 +112,5 @@
 void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t count)
 {
-	ASSERT(start + count <= bitmap->elements);
+	assert(start + count <= bitmap->elements);
 	
 	if (count == 0)
@@ -166,5 +166,5 @@
 void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t count)
 {
-	ASSERT(start + count <= bitmap->elements);
+	assert(start + count <= bitmap->elements);
 	
 	if (count == 0)
@@ -222,6 +222,6 @@
 void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t count)
 {
-	ASSERT(count <= dst->elements);
-	ASSERT(count <= src->elements);
+	assert(count <= dst->elements);
+	assert(count <= src->elements);
 	
 	size_t i;
Index: kernel/generic/src/adt/btree.c
===================================================================
--- kernel/generic/src/adt/btree.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/adt/btree.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -49,6 +49,6 @@
 #include <adt/btree.h>
 #include <adt/list.h>
+#include <assert.h>
 #include <mm/slab.h>
-#include <debug.h>
 #include <panic.h>
 #include <print.h>
@@ -500,6 +500,6 @@
 	size_t j;
 	
-	ASSERT(median);
-	ASSERT(node->keys == BTREE_MAX_KEYS);
+	assert(median);
+	assert(node->keys == BTREE_MAX_KEYS);
 	
 	/*
@@ -625,5 +625,5 @@
 	btree_node_t *lnode;
 	
-	ASSERT(value);
+	assert(value);
 	
 	lnode = leaf_node;
@@ -725,5 +725,5 @@
 	size_t i;
 	
-	ASSERT(!ROOT_NODE(node));
+	assert(!ROOT_NODE(node));
 	
 	idx = find_key_by_subtree(node->parent, node, false);
@@ -837,5 +837,5 @@
 		
 		idx = find_key_by_subtree(parent, rnode, true);
-		ASSERT((int) idx != -1);
+		assert((int) idx != -1);
 		slab_free(btree_node_slab, rnode);
 		_btree_remove(t, parent->key[idx], parent);
@@ -951,5 +951,5 @@
 btree_node_t *btree_leaf_node_left_neighbour(btree_t *t, btree_node_t *node)
 {
-	ASSERT(LEAF_NODE(node));
+	assert(LEAF_NODE(node));
 	
 	if (node->leaf_link.prev != &t->leaf_list.head)
@@ -970,5 +970,5 @@
 btree_node_t *btree_leaf_node_right_neighbour(btree_t *t, btree_node_t *node)
 {
-	ASSERT(LEAF_NODE(node));
+	assert(LEAF_NODE(node));
 	
 	if (node->leaf_link.next != &t->leaf_list.head)
@@ -1002,9 +1002,9 @@
 		
 		hlp = list_first(&list);
-		ASSERT(hlp != NULL);
+		assert(hlp != NULL);
 		node = list_get_instance(hlp, btree_node_t, bfs_link);
 		list_remove(hlp);
 		
-		ASSERT(node);
+		assert(node);
 		
 		if (node->depth != depth) {
@@ -1032,5 +1032,5 @@
 	printf("Printing list of leaves:\n");
 	list_foreach(t->leaf_list, leaf_link, btree_node_t, node) {
-		ASSERT(node);
+		assert(node);
 		
 		printf("(");
Index: kernel/generic/src/adt/cht.c
===================================================================
--- kernel/generic/src/adt/cht.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/adt/cht.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -290,6 +290,5 @@
 #include <adt/cht.h>
 #include <adt/hash.h>
-#include <debug.h>
-#include <memstr.h>
+#include <assert.h>
 #include <mm/slab.h>
 #include <arch/barrier.h>
@@ -523,9 +522,9 @@
 	bool can_block, cht_ops_t *op)
 {
-	ASSERT(h);
-	ASSERT(op && op->hash && op->key_hash && op->equal && op->key_equal);
+	assert(h);
+	assert(op && op->hash && op->key_hash && op->equal && op->key_equal);
 	/* Memoized hashes are stored in the rcu_link.func function pointer. */
-	STATIC_ASSERT(sizeof(size_t) == sizeof(rcu_func_t));
-	ASSERT(sentinel.hash == (uintptr_t)sentinel.rcu_link.func);
+	static_assert(sizeof(size_t) == sizeof(rcu_func_t), "");
+	assert(sentinel.hash == (uintptr_t)sentinel.rcu_link.func);
 
 	/* All operations are compulsory. */
@@ -626,5 +625,5 @@
 	
 	/* You must clear the table of items. Otherwise cht_destroy will leak. */
-	ASSERT(atomic_get(&h->item_cnt) == 0);
+	assert(atomic_get(&h->item_cnt) == 0);
 }
 
@@ -686,7 +685,7 @@
 static inline cht_link_t *find_lazy(cht_t *h, void *key)
 {
-	ASSERT(h);
+	assert(h);
 	/* See docs to cht_find() and cht_find_lazy(). */
-	ASSERT(rcu_read_locked());
+	assert(rcu_read_locked());
 	
 	size_t hash = calc_key_hash(h, key);
@@ -732,7 +731,7 @@
 cht_link_t *cht_find_next_lazy(cht_t *h, const cht_link_t *item)
 {
-	ASSERT(h);
-	ASSERT(rcu_read_locked());
-	ASSERT(item);
+	assert(h);
+	assert(rcu_read_locked());
+	assert(item);
 	
 	return find_duplicate(h, item, calc_node_hash(h, item), get_next(item->link));
@@ -756,5 +755,5 @@
 	do {
 		cur = get_next(prev);
-		ASSERT(cur);
+		assert(cur);
 		prev = cur->link;
 	} while (node_hash(h, cur) < search_hash);
@@ -771,5 +770,5 @@
 		
 		cur = get_next(cur->link);
-		ASSERT(cur);
+		assert(cur);
 	} 
 	
@@ -791,6 +790,6 @@
 	marked_ptr_t old_head, size_t old_idx)
 {
-	ASSERT(N_INVALID == get_mark(old_head)); 
-	ASSERT(h->new_b);
+	assert(N_INVALID == get_mark(old_head)); 
+	assert(h->new_b);
 	
 	size_t new_idx = calc_bucket_idx(hash, h->new_b->order);
@@ -904,5 +903,5 @@
 			 * traversing search_head.
 			 */
-			ASSERT(N_JOIN & get_mark(get_next(old_head)->link));
+			assert(N_JOIN & get_mark(get_next(old_head)->link));
 			return search_bucket(h, old_head, key, hash);
 		}
@@ -914,10 +913,10 @@
 		 * sure all cpus see that the new table replaced the old one.
 		 */
-		ASSERT(h->b->order == h->new_b->order);
+		assert(h->b->order == h->new_b->order);
 		/* 
 		 * The resizer must ensure all new bucket heads are visible before
 		 * replacing the old table.
 		 */
-		ASSERT(N_NORMAL == get_mark(new_head));
+		assert(N_NORMAL == get_mark(new_head));
 		return search_bucket(h, new_head, key, hash);
 	}
@@ -962,6 +961,6 @@
 bool cht_insert_unique(cht_t *h, cht_link_t *item, cht_link_t **dup_item)
 {
-	ASSERT(rcu_read_locked());
-	ASSERT(dup_item);
+	assert(rcu_read_locked());
+	assert(dup_item);
 	return insert_impl(h, item, dup_item);
 }
@@ -1061,5 +1060,5 @@
 		return ret == make_link(wnd->cur, jf_mark);
 	} else {
-		ASSERT(walk_mode == WM_LEAVE_JOIN);
+		assert(walk_mode == WM_LEAVE_JOIN);
 
 		item->link = make_link(wnd->cur, N_NORMAL);
@@ -1088,6 +1087,6 @@
 	cht_link_t *cur, cht_link_t **dup_item)
 {
-	ASSERT(cur);
-	ASSERT(cur == &sentinel || hash <= node_hash(h, cur)
+	assert(cur);
+	assert(cur == &sentinel || hash <= node_hash(h, cur)
 		|| node_hash(h, cur) == h->invalid_hash);
 	
@@ -1111,13 +1110,13 @@
 	cht_link_t *start)
 {
-	ASSERT(hash <= node_hash(h, start) || h->invalid_hash == node_hash(h, start));
+	assert(hash <= node_hash(h, start) || h->invalid_hash == node_hash(h, start));
 
 	cht_link_t *cur = start;
 	
 try_again:	
-	ASSERT(cur);
+	assert(cur);
 
 	while (node_hash(h, cur) == hash) {
-		ASSERT(cur != &sentinel);
+		assert(cur != &sentinel);
 		
 		bool deleted = (N_DELETED & get_mark(cur->link));
@@ -1128,5 +1127,5 @@
 		
 		cur = get_next(cur->link);
-		ASSERT(cur);
+		assert(cur);
 	} 
 
@@ -1143,5 +1142,5 @@
 size_t cht_remove_key(cht_t *h, void *key)
 {
-	ASSERT(h);
+	assert(h);
 	
 	size_t hash = calc_key_hash(h, key);
@@ -1164,8 +1163,8 @@
 bool cht_remove_item(cht_t *h, cht_link_t *item)
 {
-	ASSERT(h);
-	ASSERT(item);
+	assert(h);
+	assert(item);
 	/* Otherwise a concurrent cht_remove_key might free the item. */
-	ASSERT(rcu_read_locked());
+	assert(rcu_read_locked());
 
 	/* 
@@ -1263,5 +1262,5 @@
 	bool *deleted_but_gc, bool *resizing)
 {
-	ASSERT(wnd->cur && wnd->cur != &sentinel);
+	assert(wnd->cur && wnd->cur != &sentinel);
 	
 	*deleted_but_gc = false;
@@ -1293,5 +1292,5 @@
 	bool *resizing)
 {
-	ASSERT(cur && cur != &sentinel);
+	assert(cur && cur != &sentinel);
 	
 	/* 
@@ -1311,5 +1310,5 @@
 		}
 	} else {
-		STATIC_ASSERT(N_JOIN == N_JOIN_FOLLOWS);
+		static_assert(N_JOIN == N_JOIN_FOLLOWS, "");
 		
 		/* Keep the N_JOIN/N_JOIN_FOLLOWS mark but strip N_DELETED. */
@@ -1330,6 +1329,6 @@
 	bool *resizing)
 {
-	ASSERT(wnd->cur != &sentinel);
-	ASSERT(wnd->cur && (N_DELETED & get_mark(wnd->cur->link)));
+	assert(wnd->cur != &sentinel);
+	assert(wnd->cur && (N_DELETED & get_mark(wnd->cur->link)));
 	
 	cht_link_t *next = get_next(wnd->cur->link);
@@ -1337,5 +1336,5 @@
 	if (walk_mode == WM_LEAVE_JOIN) {
 		/* Never try to unlink join nodes. */
-		ASSERT(!(N_JOIN & get_mark(wnd->cur->link)));
+		assert(!(N_JOIN & get_mark(wnd->cur->link)));
 
 		mark_t pred_mark = get_mark(*wnd->ppred);
@@ -1349,5 +1348,5 @@
 			return false;
 	} else {
-		ASSERT(walk_mode == WM_MOVE_JOIN_FOLLOWS || walk_mode == WM_NORMAL);
+		assert(walk_mode == WM_MOVE_JOIN_FOLLOWS || walk_mode == WM_NORMAL);
 		/* Move the JF mark if set. Clear DEL mark. */
 		mark_t cur_mark = N_JOIN_FOLLOWS & get_mark(wnd->cur->link);
@@ -1399,5 +1398,5 @@
 	equal_pred_t pred, void *pred_arg, wnd_t *wnd, bool *resizing)
 {
-	ASSERT(wnd->cur);
+	assert(wnd->cur);
 	
 	if (wnd->cur == &sentinel)
@@ -1416,5 +1415,5 @@
 		
 	while (cur_hash <= hash) {
-		ASSERT(wnd->cur && wnd->cur != &sentinel);
+		assert(wnd->cur && wnd->cur != &sentinel);
 		
 		/* GC any deleted nodes on the way. */
@@ -1437,5 +1436,5 @@
 	if (cur_hash == h->invalid_hash) {
 		next_wnd(wnd);
-		ASSERT(wnd->cur);
+		assert(wnd->cur);
 		goto try_again;
 	}
@@ -1470,5 +1469,5 @@
 {
 try_again:
-	ASSERT(wnd->cur);
+	assert(wnd->cur);
 
 	while (node_hash(h, wnd->cur) < hash) {
@@ -1483,5 +1482,5 @@
 		}
 		
-		ASSERT(wnd->cur);
+		assert(wnd->cur);
 	}
 	
@@ -1499,5 +1498,5 @@
 	bool *resizing)
 {
-	ASSERT(N_DELETED & get_mark(wnd->cur->link));
+	assert(N_DELETED & get_mark(wnd->cur->link));
 
 	/* Skip deleted JOIN nodes. */
@@ -1506,5 +1505,5 @@
 	} else {
 		/* Ordinary deleted node or a deleted JOIN_FOLLOWS. */
-		ASSERT(walk_mode != WM_LEAVE_JOIN 
+		assert(walk_mode != WM_LEAVE_JOIN 
 			|| !((N_JOIN | N_JOIN_FOLLOWS) & get_mark(wnd->cur->link)));
 
@@ -1547,6 +1546,6 @@
 	 * it 
 	 */
-	ASSERT(h->b->order > h->new_b->order);
-	ASSERT(wnd->cur);
+	assert(h->b->order > h->new_b->order);
+	assert(wnd->cur);
 	
 	/* Either we did not need the joining link or we have already followed it.*/
@@ -1621,13 +1620,13 @@
 		/* The hash belongs to the moved bucket. */
 		if (move_dest_idx == new_idx) {
-			ASSERT(pmoved_head == pnew_head);
+			assert(pmoved_head == pnew_head);
 			/* 
 			 * move_head() makes the new head of the moved bucket visible. 
 			 * The new head may be marked with a JOIN_FOLLOWS
 			 */
-			ASSERT(!(N_CONST & get_mark(*pmoved_head)));
+			assert(!(N_CONST & get_mark(*pmoved_head)));
 			*walk_mode = WM_MOVE_JOIN_FOLLOWS;
 		} else {
-			ASSERT(pmoved_head != pnew_head);
+			assert(pmoved_head != pnew_head);
 			/* 
 			 * The hash belongs to the bucket that is the result of splitting 
@@ -1644,5 +1643,5 @@
 				 * JOIN_FOLLOWS in this part of split bucket.
 				 */
-				ASSERT(N_NORMAL == get_mark(*pnew_head));
+				assert(N_NORMAL == get_mark(*pnew_head));
 			}
 			
@@ -1676,7 +1675,7 @@
 		
 		/* move_head() or join_buckets() makes it so or makes the mark visible.*/
-		ASSERT(N_INVALID == get_mark(*pold_head));
+		assert(N_INVALID == get_mark(*pold_head));
 		/* move_head() makes it visible. No JOIN_FOLLOWS used when shrinking. */
-		ASSERT(N_NORMAL == get_mark(*pnew_head));
+		assert(N_NORMAL == get_mark(*pnew_head));
 
 		*walk_mode = WM_LEAVE_JOIN;
@@ -1686,5 +1685,5 @@
 		 * readers to notice that the old table had been replaced.
 		 */
-		ASSERT(b == h->new_b);
+		assert(b == h->new_b);
 		*walk_mode = WM_NORMAL;
 	}
@@ -1713,5 +1712,5 @@
 {
 	/* Head move has to in progress already when calling this func. */
-	ASSERT(N_CONST & get_mark(*psrc_head));
+	assert(N_CONST & get_mark(*psrc_head));
 	
 	/* Head already moved. */
@@ -1726,5 +1725,5 @@
 	}
 	
-	ASSERT(!(N_CONST & get_mark(*pdest_head)));
+	assert(!(N_CONST & get_mark(*pdest_head)));
 }
 
@@ -1757,6 +1756,6 @@
 static void complete_head_move(marked_ptr_t *psrc_head, marked_ptr_t *pdest_head)
 {
-	ASSERT(N_JOIN_FOLLOWS != get_mark(*psrc_head));
-	ASSERT(N_CONST & get_mark(*psrc_head));
+	assert(N_JOIN_FOLLOWS != get_mark(*psrc_head));
+	assert(N_CONST & get_mark(*psrc_head));
 	
 	cht_link_t *next = get_next(*psrc_head);
@@ -1764,10 +1763,10 @@
 	DBG(marked_ptr_t ret = )
 		cas_link(pdest_head, &sentinel, N_INVALID, next, N_NORMAL);
-	ASSERT(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
+	assert(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
 	cas_order_barrier();
 	
 	DBG(ret = ) 
 		cas_link(psrc_head, next, N_CONST, next, N_INVALID);	
-	ASSERT(ret == make_link(next, N_CONST) || (N_INVALID == get_mark(ret)));
+	assert(ret == make_link(next, N_CONST) || (N_INVALID == get_mark(ret)));
 	cas_order_barrier();
 }
@@ -1862,5 +1861,5 @@
 	DBG(marked_ptr_t ret = )
 		cas_link(pdest_head, &sentinel, N_INVALID, wnd.cur, N_NORMAL);
-	ASSERT(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
+	assert(ret == make_link(&sentinel, N_INVALID) || (N_NORMAL == get_mark(ret)));
 	cas_order_barrier();
 	
@@ -1906,5 +1905,5 @@
 		
 		/* Must not report that the table is resizing if WM_MOVE_JOIN_FOLLOWS.*/
-		ASSERT(!resizing);
+		assert(!resizing);
 		/* 
 		 * Mark the last node of the first half of the split bucket 
@@ -2043,5 +2042,5 @@
 	DBG(marked_ptr_t ret = )
 		cas_link(psrc_head, join_node, N_CONST, join_node, N_INVALID);
-	ASSERT(ret == make_link(join_node, N_CONST) || (N_INVALID == get_mark(ret)));
+	assert(ret == make_link(join_node, N_CONST) || (N_INVALID == get_mark(ret)));
 	cas_order_barrier();
 	
@@ -2074,9 +2073,9 @@
 			continue;
 
-		ASSERT(!resizing);
+		assert(!resizing);
 		
 		if (wnd.cur != &sentinel) {
 			/* Must be from the new appended bucket. */
-			ASSERT(split_hash <= node_hash(h, wnd.cur) 
+			assert(split_hash <= node_hash(h, wnd.cur) 
 				|| h->invalid_hash == node_hash(h, wnd.cur));
 			return;
@@ -2097,5 +2096,5 @@
 static void free_later(cht_t *h, cht_link_t *item)
 {
-	ASSERT(item != &sentinel);
+	assert(item != &sentinel);
 	
 	/* 
@@ -2157,8 +2156,8 @@
 	
 #ifdef CONFIG_DEBUG
-	ASSERT(h->b);
+	assert(h->b);
 	/* Make resize_reqs visible. */
 	read_barrier();
-	ASSERT(0 < atomic_get(&h->resize_reqs));
+	assert(0 < atomic_get(&h->resize_reqs));
 #endif
 
@@ -2337,5 +2336,5 @@
 		/* Set the invalid joinee head to NULL. */
 		if (old_idx != move_src_idx) {
-			ASSERT(N_INVALID == get_mark(h->b->head[old_idx]));
+			assert(N_INVALID == get_mark(h->b->head[old_idx]));
 			
 			if (&sentinel != get_next(h->b->head[old_idx]))
@@ -2393,6 +2392,6 @@
 	marked_ptr_t *new_head)
 {
-	ASSERT(join_node != &sentinel);
-	ASSERT(join_node && (N_JOIN & get_mark(join_node->link)));
+	assert(join_node != &sentinel);
+	assert(join_node && (N_JOIN & get_mark(join_node->link)));
 	
 	bool done;
@@ -2410,5 +2409,5 @@
 		/* Done if the mark was cleared. Retry if a new node was inserted. */
 		done = (ret == jn_link);
-		ASSERT(ret == jn_link || (get_mark(ret) & N_JOIN));
+		assert(ret == jn_link || (get_mark(ret) & N_JOIN));
 	} while (!done);
 	
@@ -2433,5 +2432,5 @@
 			join_node, &wnd, &resizing);
 		
-		ASSERT(!resizing);
+		assert(!resizing);
 	} while (!done);
 }
@@ -2440,5 +2439,5 @@
 static void cleanup_join_follows(cht_t *h, marked_ptr_t *new_head)
 {
-	ASSERT(new_head);
+	assert(new_head);
 	
 	rcu_read_lock();
@@ -2465,7 +2464,7 @@
 		/* GC any deleted nodes on the way - even deleted JOIN_FOLLOWS. */
 		if (N_DELETED & get_mark(*cur_link)) {
-			ASSERT(cur_link != new_head);
-			ASSERT(wnd.ppred && wnd.cur && wnd.cur != &sentinel);
-			ASSERT(cur_link == &wnd.cur->link);
+			assert(cur_link != new_head);
+			assert(wnd.ppred && wnd.cur && wnd.cur != &sentinel);
+			assert(cur_link == &wnd.cur->link);
 
 			bool dummy;
@@ -2485,5 +2484,5 @@
 					cas_link(cur_link, next, N_JOIN_FOLLOWS, &sentinel, N_NORMAL);
 				
-				ASSERT(next == &sentinel 
+				assert(next == &sentinel 
 					|| ((N_JOIN | N_JOIN_FOLLOWS) & get_mark(ret)));
 
@@ -2506,5 +2505,5 @@
 
 		/* We must encounter a JF node before we reach the end of the bucket. */
-		ASSERT(wnd.cur && wnd.cur != &sentinel);
+		assert(wnd.cur && wnd.cur != &sentinel);
 		cur_link = &wnd.cur->link;
 	}
@@ -2520,5 +2519,5 @@
 static inline size_t calc_split_hash(size_t split_idx, size_t order)
 {
-	ASSERT(1 <= order && order <= 8 * sizeof(size_t));
+	assert(1 <= order && order <= 8 * sizeof(size_t));
 	return split_idx << (8 * sizeof(size_t) - order);
 }
@@ -2527,5 +2526,5 @@
 static inline size_t calc_bucket_idx(size_t hash, size_t order)
 {
-	ASSERT(1 <= order && order <= 8 * sizeof(size_t));
+	assert(1 <= order && order <= 8 * sizeof(size_t));
 	return hash >> (8 * sizeof(size_t) - order);
 }
@@ -2559,5 +2558,5 @@
 static inline size_t node_hash(cht_t *h, const cht_link_t *item)
 {
-	ASSERT(item->hash == h->invalid_hash 
+	assert(item->hash == h->invalid_hash 
 		|| item->hash == sentinel.hash
 		|| item->hash == calc_node_hash(h, item));
@@ -2569,5 +2568,5 @@
 static inline size_t calc_node_hash(cht_t *h, const cht_link_t *item)
 {
-	ASSERT(item != &sentinel);
+	assert(item != &sentinel);
 	/* 
 	 * Clear the lowest order bit in order for sentinel's node hash
@@ -2588,6 +2587,6 @@
 	marked_ptr_t ptr = (marked_ptr_t) next;
 	
-	ASSERT(!(ptr & N_MARK_MASK));
-	ASSERT(!((unsigned)mark & ~N_MARK_MASK));
+	assert(!(ptr & N_MARK_MASK));
+	assert(!((unsigned)mark & ~N_MARK_MASK));
 	
 	return ptr | mark;
@@ -2609,6 +2608,6 @@
 static inline void next_wnd(wnd_t *wnd)
 {
-	ASSERT(wnd);
-	ASSERT(wnd->cur);
+	assert(wnd);
+	assert(wnd->cur);
 
 	wnd->last = wnd->cur;
@@ -2636,5 +2635,5 @@
 	marked_ptr_t new)
 {
-	ASSERT(link != &sentinel.link);
+	assert(link != &sentinel.link);
 	/*
 	 * cas(x) on the same location x on one cpu must be ordered, but do not
Index: kernel/generic/src/adt/hash_table.c
===================================================================
--- kernel/generic/src/adt/hash_table.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/adt/hash_table.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,4 +1,6 @@
 /*
- * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2008 Jakub Jermar
+ * Copyright (c) 2012 Adam Hraska
+ * 
  * All rights reserved.
  *
@@ -27,166 +29,439 @@
  */
 
-/** @addtogroup genericadt
+/** @addtogroup libc
  * @{
  */
-
-/**
- * @file
- * @brief Implementation of generic chained hash table.
- *
- * This file contains implementation of generic chained hash table.
+/** @file
+ */
+
+/*
+ * This is an implementation of a generic resizable chained hash table.
+ * 
+ * The table grows to 2*n+1 buckets each time, starting at n == 89, 
+ * per Thomas Wang's recommendation:
+ * http://www.concentric.net/~Ttwang/tech/hashsize.htm
+ * 
+ * This policy produces prime table sizes for the first five resizes
+ * and generally produces table sizes which are either prime or 
+ * have fairly large (prime/odd) divisors. Having a prime table size
+ * mitigates the use of suboptimal hash functions and distributes
+ * items over the whole table.
  */
 
 #include <adt/hash_table.h>
 #include <adt/list.h>
-#include <typedefs.h>
-#include <debug.h>
 #include <mm/slab.h>
-#include <memstr.h>
+#include <assert.h>
+#include <str.h>
+
+/* Optimal initial bucket count. See comment above. */
+#define HT_MIN_BUCKETS  89
+/* The table is resized when the average load per bucket exceeds this number. */
+#define HT_MAX_LOAD     2
+
+
+static size_t round_up_size(size_t);
+static bool alloc_table(size_t, list_t **);
+static void clear_items(hash_table_t *);
+static void resize(hash_table_t *, size_t);
+static void grow_if_needed(hash_table_t *);
+static void shrink_if_needed(hash_table_t *);
+
+/* Dummy do nothing callback to invoke in place of remove_callback == NULL. */
+static void nop_remove_callback(ht_link_t *item)
+{
+	/* no-op */
+}
+
 
 /** Create chained hash table.
  *
- * @param h Hash table structure. Will be initialized by this call.
- * @param m Number of slots in the hash table.
- * @param max_keys Maximal number of keys needed to identify an item.
- * @param op Hash table operations structure.
- */
-void hash_table_create(hash_table_t *h, size_t m, size_t max_keys, hash_table_operations_t *op)
-{
-	size_t i;
-
-	ASSERT(h);
-	ASSERT(op);
-	ASSERT(op->hash);
-	ASSERT(op->compare);
-	ASSERT(max_keys > 0);
-	
-	h->entry = (list_t *) malloc(m * sizeof(list_t), 0);
-	if (!h->entry)
-		panic("Cannot allocate memory for hash table.");
-	
-	memsetb(h->entry, m * sizeof(list_t), 0);
-	
-	for (i = 0; i < m; i++)
-		list_initialize(&h->entry[i]);
-	
-	h->entries = m;
-	h->max_keys = max_keys;
+ * @param h        Hash table structure. Will be initialized by this call.
+ * @param init_size Initial desired number of hash table buckets. Pass zero
+ *                 if you want the default initial size. 
+ * @param max_load The table is resized when the average load per bucket
+ *                 exceeds this number. Pass zero if you want the default.
+ * @param op       Hash table operations structure. remove_callback()
+ *                 is optional and can be NULL if no action is to be taken
+ *                 upon removal. equal() is optional if and only if
+ *                 hash_table_insert_unique() will never be invoked.
+ *                 All other operations are mandatory. 
+ *
+ * @return True on success
+ *
+ */
+bool hash_table_create(hash_table_t *h, size_t init_size, size_t max_load,
+    hash_table_ops_t *op)
+{
+	assert(h);
+	assert(op && op->hash && op->key_hash && op->key_equal);
+	
+	/* Check for compulsory ops. */
+	if (!op || !op->hash || !op->key_hash || !op->key_equal)
+		return false;
+	
+	h->bucket_cnt = round_up_size(init_size);
+	
+	if (!alloc_table(h->bucket_cnt, &h->bucket))
+		return false;
+	
+	h->max_load = (max_load == 0) ? HT_MAX_LOAD : max_load;
+	h->item_cnt = 0;
 	h->op = op;
-}
-
-/** Insert item into hash table.
- *
- * @param h Hash table.
- * @param key Array of all keys necessary to compute hash index.
+	h->full_item_cnt = h->max_load * h->bucket_cnt;
+	h->apply_ongoing = false;
+
+	if (h->op->remove_callback == NULL) {
+		h->op->remove_callback = nop_remove_callback;
+	}
+	
+	return true;
+}
+
+/** Destroy a hash table instance.
+ *
+ * @param h Hash table to be destroyed.
+ *
+ */
+void hash_table_destroy(hash_table_t *h)
+{
+	assert(h && h->bucket);
+	assert(!h->apply_ongoing);
+	
+	clear_items(h);
+	
+	free(h->bucket);
+
+	h->bucket = NULL;
+	h->bucket_cnt = 0;
+}
+
+/** Returns true if there are no items in the table. */
+bool hash_table_empty(hash_table_t *h)
+{
+	assert(h && h->bucket);
+	return h->item_cnt == 0;
+}
+
+/** Returns the number of items in the table. */
+size_t hash_table_size(hash_table_t *h)
+{
+	assert(h && h->bucket);
+	return h->item_cnt;
+}
+
+/** Remove all elements from the hash table
+ *
+ * @param h Hash table to be cleared
+ */
+void hash_table_clear(hash_table_t *h)
+{
+	assert(h && h->bucket);
+	assert(!h->apply_ongoing);
+	
+	clear_items(h);
+	
+	/* Shrink the table to its minimum size if possible. */
+	if (HT_MIN_BUCKETS < h->bucket_cnt) {
+		resize(h, HT_MIN_BUCKETS);
+	}
+}
+
+/** Unlinks and removes all items but does not resize. */
+static void clear_items(hash_table_t *h)
+{
+	if (h->item_cnt == 0)
+		return;
+	
+	for (size_t idx = 0; idx < h->bucket_cnt; ++idx) {
+		list_foreach_safe(h->bucket[idx], cur, next) {
+			assert(cur);
+			ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
+			
+			list_remove(cur);
+			h->op->remove_callback(cur_link);
+		}
+	}
+	
+	h->item_cnt = 0;
+}
+
+/** Insert item into a hash table.
+ *
+ * @param h    Hash table.
  * @param item Item to be inserted into the hash table.
  */
-void hash_table_insert(hash_table_t *h, sysarg_t key[], link_t *item)
-{
-	size_t chain;
-	
-	ASSERT(item);
-	ASSERT(h);
-	ASSERT(h->op);
-	ASSERT(h->op->hash);
-	ASSERT(h->op->compare);
-	
-	chain = h->op->hash(key);
-	ASSERT(chain < h->entries);
-	
-	list_append(item, &h->entry[chain]);
+void hash_table_insert(hash_table_t *h, ht_link_t *item)
+{
+	assert(item);
+	assert(h && h->bucket);
+	assert(!h->apply_ongoing);
+	
+	size_t idx = h->op->hash(item) % h->bucket_cnt;
+	
+	list_append(&item->link, &h->bucket[idx]);
+	++h->item_cnt;
+	grow_if_needed(h);
+}
+
+
+/** Insert item into a hash table if not already present.
+ *
+ * @param h    Hash table.
+ * @param item Item to be inserted into the hash table.
+ * 
+ * @return False if such an item had already been inserted. 
+ * @return True if the inserted item was the only item with such a lookup key.
+ */
+bool hash_table_insert_unique(hash_table_t *h, ht_link_t *item)
+{
+	assert(item);
+	assert(h && h->bucket && h->bucket_cnt);
+	assert(h->op && h->op->hash && h->op->equal);
+	assert(!h->apply_ongoing);
+	
+	size_t idx = h->op->hash(item) % h->bucket_cnt;
+	
+	/* Check for duplicates. */
+	list_foreach(h->bucket[idx], link, ht_link_t, cur_link) {
+		/* 
+		 * We could filter out items using their hashes first, but 
+		 * calling equal() might very well be just as fast.
+		 */
+		if (h->op->equal(cur_link, item))
+			return false;
+	}
+	
+	list_append(&item->link, &h->bucket[idx]);
+	++h->item_cnt;
+	grow_if_needed(h);
+	
+	return true;
 }
 
 /** Search hash table for an item matching keys.
  *
- * @param h Hash table.
+ * @param h   Hash table.
  * @param key Array of all keys needed to compute hash index.
  *
  * @return Matching item on success, NULL if there is no such item.
- */
-link_t *hash_table_find(hash_table_t *h, sysarg_t key[])
-{
-	size_t chain;
-	
-	ASSERT(h);
-	ASSERT(h->op);
-	ASSERT(h->op->hash);
-	ASSERT(h->op->compare);
-	
-	chain = h->op->hash(key);
-	ASSERT(chain < h->entries);
-	
-	link_t *cur = list_first(&h->entry[chain]);
-	while (cur != NULL) {
-		if (h->op->compare(key, h->max_keys, cur)) {
-			/*
-			 * The entry is there.
+ *
+ */
+ht_link_t *hash_table_find(const hash_table_t *h, void *key)
+{
+	assert(h && h->bucket);
+	
+	size_t idx = h->op->key_hash(key) % h->bucket_cnt;
+
+	list_foreach(h->bucket[idx], link, ht_link_t, cur_link) {
+		/* 
+		 * Is this is the item we are looking for? We could have first 
+		 * checked if the hashes match but op->key_equal() may very well be 
+		 * just as fast as op->hash().
+		 */
+		if (h->op->key_equal(key, cur_link)) {
+			return cur_link;
+		}
+	}
+	
+	return NULL;
+}
+
+/** Find the next item equal to item. */
+ht_link_t *hash_table_find_next(const hash_table_t *h, ht_link_t *item)
+{
+	assert(item);
+	assert(h && h->bucket);
+
+	/* Traverse the circular list until we reach the starting item again. */
+	for (link_t *cur = item->link.next; cur != &item->link; cur = cur->next) {
+		assert(cur);
+		ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
+		/* 
+		 * Is this is the item we are looking for? We could have first 
+		 * checked if the hashes match but op->equal() may very well be 
+		 * just as fast as op->hash().
+		 */
+		if (h->op->equal(cur_link, item)) {
+			return cur_link;
+		}
+	}
+
+	return NULL;
+}
+
+/** Remove all matching items from hash table.
+ *
+ * For each removed item, h->remove_callback() is called.
+ *
+ * @param h    Hash table.
+ * @param key  Array of keys that will be compared against items of
+ *             the hash table.
+ * 
+ * @return Returns the number of removed items.
+ */
+size_t hash_table_remove(hash_table_t *h, void *key)
+{
+	assert(h && h->bucket);
+	assert(!h->apply_ongoing);
+	
+	size_t idx = h->op->key_hash(key) % h->bucket_cnt;
+
+	size_t removed = 0;
+	
+	list_foreach_safe(h->bucket[idx], cur, next) {
+		ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
+		
+		if (h->op->key_equal(key, cur_link)) {
+			++removed;
+			list_remove(cur);
+			h->op->remove_callback(cur_link);
+		}
+	}
+
+	h->item_cnt -= removed;
+	shrink_if_needed(h);
+	
+	return removed;
+}
+
+/** Removes an item already present in the table. The item must be in the table.*/
+void hash_table_remove_item(hash_table_t *h, ht_link_t *item)
+{
+	assert(item);
+	assert(h && h->bucket);
+	assert(link_in_use(&item->link));
+
+	list_remove(&item->link);
+	--h->item_cnt;
+	h->op->remove_callback(item);
+	shrink_if_needed(h);
+}
+
+/** Apply function to all items in hash table.
+ *
+ * @param h   Hash table.
+ * @param f   Function to be applied. Return false if no more items 
+ *            should be visited. The functor may only delete the supplied
+ *            item. It must not delete the successor of the item passed 
+ *            in the first argument.
+ * @param arg Argument to be passed to the function.
+ */
+void hash_table_apply(hash_table_t *h, bool (*f)(ht_link_t *, void *), void *arg)
+{	
+	assert(f);
+	assert(h && h->bucket);
+	
+	if (h->item_cnt == 0)
+		return;
+	
+	h->apply_ongoing = true;
+	
+	for (size_t idx = 0; idx < h->bucket_cnt; ++idx) {
+		list_foreach_safe(h->bucket[idx], cur, next) {
+			ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
+			/* 
+			 * The next pointer had already been saved. f() may safely 
+			 * delete cur (but not next!).
 			 */
-			return cur;
-		}
-		cur = list_next(cur, &h->entry[chain]);
-	}
-	
-	return NULL;
-}
-
-/** Remove all matching items from hash table.
- *
- * For each removed item, h->remove_callback() is called (if not NULL).
- *
- * @param h Hash table.
- * @param key Array of keys that will be compared against items of the hash table.
- * @param keys Number of keys in the key array.
- */
-void hash_table_remove(hash_table_t *h, sysarg_t key[], size_t keys)
-{
-	size_t chain;
-	
-	ASSERT(h);
-	ASSERT(h->op);
-	ASSERT(h->op->hash);
-	ASSERT(h->op->compare);
-	ASSERT(keys <= h->max_keys);
-	
-	
-	if (keys == h->max_keys) {
-		link_t *cur;
+			if (!f(cur_link, arg))
+				goto out;
+		}
+	}
+out:
+	h->apply_ongoing = false;
+	
+	shrink_if_needed(h);
+	grow_if_needed(h);
+}
+
+/** Rounds up size to the nearest suitable table size. */
+static size_t round_up_size(size_t size)
+{
+	size_t rounded_size = HT_MIN_BUCKETS;
+	
+	while (rounded_size < size) {
+		rounded_size = 2 * rounded_size + 1;
+	}
+	
+	return rounded_size;
+}
+
+/** Allocates and initializes the desired number of buckets. True if successful.*/
+static bool alloc_table(size_t bucket_cnt, list_t **pbuckets)
+{
+	assert(pbuckets && HT_MIN_BUCKETS <= bucket_cnt);
 		
-		/*
-		 * All keys are known, hash_table_find() can be used to find the entry.
+	list_t *buckets = malloc(bucket_cnt * sizeof(list_t), FRAME_ATOMIC);
+	if (!buckets)
+		return false;
+	
+	for (size_t i = 0; i < bucket_cnt; i++)
+		list_initialize(&buckets[i]);
+
+	*pbuckets = buckets;
+	return true;
+}
+
+
+/** Shrinks the table if the table is only sparely populated. */
+static inline void shrink_if_needed(hash_table_t *h)
+{
+	if (h->item_cnt <= h->full_item_cnt / 4 && HT_MIN_BUCKETS < h->bucket_cnt) {
+		/* 
+		 * Keep the bucket_cnt odd (possibly also prime). 
+		 * Shrink from 2n + 1 to n. Integer division discards the +1.
 		 */
-	
-		cur = hash_table_find(h, key);
-		if (cur) {
-			list_remove(cur);
-			if (h->op->remove_callback)
-				h->op->remove_callback(cur);
-		}
+		size_t new_bucket_cnt = h->bucket_cnt / 2;
+		resize(h, new_bucket_cnt);
+	}
+}
+
+/** Grows the table if table load exceeds the maximum allowed. */
+static inline void grow_if_needed(hash_table_t *h)
+{
+	/* Grow the table if the average bucket load exceeds the maximum. */
+	if (h->full_item_cnt < h->item_cnt) {
+		/* Keep the bucket_cnt odd (possibly also prime). */
+		size_t new_bucket_cnt = 2 * h->bucket_cnt + 1;
+		resize(h, new_bucket_cnt);
+	}
+}
+
+/** Allocates and rehashes items to a new table. Frees the old table. */
+static void resize(hash_table_t *h, size_t new_bucket_cnt) 
+{
+	assert(h && h->bucket);
+	assert(HT_MIN_BUCKETS <= new_bucket_cnt);
+	
+	/* We are traversing the table and resizing would mess up the buckets. */
+	if (h->apply_ongoing)
 		return;
-	}
-	
-	/*
-	 * Fewer keys were passed.
-	 * Any partially matching entries are to be removed.
-	 */
-	for (chain = 0; chain < h->entries; chain++) {
-		link_t *cur;
-		for (cur = h->entry[chain].head.next; cur != &h->entry[chain].head;
-		    cur = cur->next) {
-			if (h->op->compare(key, keys, cur)) {
-				link_t *hlp;
-				
-				hlp = cur;
-				cur = cur->prev;
-				
-				list_remove(hlp);
-				if (h->op->remove_callback)
-					h->op->remove_callback(hlp);
-				
-				continue;
+	
+	list_t *new_buckets;
+
+	/* Leave the table as is if we cannot resize. */
+	if (!alloc_table(new_bucket_cnt, &new_buckets))
+		return;
+	
+	if (0 < h->item_cnt) {
+		/* Rehash all the items to the new table. */
+		for (size_t old_idx = 0; old_idx < h->bucket_cnt; ++old_idx) {
+			list_foreach_safe(h->bucket[old_idx], cur, next) {
+				ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link);
+
+				size_t new_idx = h->op->hash(cur_link) % new_bucket_cnt;
+				list_remove(cur);
+				list_append(cur, &new_buckets[new_idx]);
 			}
 		}
 	}
-}
+	
+	free(h->bucket);
+	h->bucket = new_buckets;
+	h->bucket_cnt = new_bucket_cnt;
+	h->full_item_cnt = h->max_load * h->bucket_cnt;
+}
+
 
 /** @}
Index: kernel/generic/src/adt/list.c
===================================================================
--- kernel/generic/src/adt/list.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/adt/list.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -69,8 +69,8 @@
 
 /** Moves items of one list into another after the specified item.
- * 
- * Inserts all items of @a list after item at @a pos in another list. 
- * Both lists may be empty. 
- * 
+ *
+ * Inserts all items of @a list after item at @a pos in another list.
+ * Both lists may be empty.
+ *
  * @param list Source list to move after pos. Empty afterwards.
  * @param pos Source items will be placed after this item.
Index: kernel/generic/src/cap/cap.c
===================================================================
--- kernel/generic/src/cap/cap.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/src/cap/cap.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2017 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file
+ */
+
+/*
+ * HelenOS capabilities are task-local names for references to kernel objects.
+ * Kernel objects are reference-counted wrappers for a select group of objects
+ * allocated in and by the kernel that can be made accessible to userspace in a
+ * controlled way via integer handles.
+ *
+ * A kernel object (kobject_t) encapsulates one of the following raw objects:
+ *
+ * - IPC phone
+ * - IRQ object
+ *
+ * A capability (cap_t) is either free, allocated or published. Free
+ * capabilities can be allocated, which reserves the capability handle in the
+ * task-local capability space. Allocated capabilities can be published, which
+ * associates them with an existing kernel object. Userspace can only access
+ * published capabilities.
+ *
+ * A published capability may get unpublished, which disassociates it from the
+ * underlying kernel object and puts it back into the allocated state. An
+ * allocated capability can be freed to become available for future use.
+ *
+ * There is a 1:1 correspondence between a kernel object (kobject_t) and the
+ * actual raw object it encapsulates. A kernel object (kobject_t) may have
+ * multiple references, either implicit from one or more capabilities (cap_t),
+ * even from capabilities in different tasks, or explicit as a result of
+ * creating a new reference from a capability handle using kobject_get(), or
+ * creating a new reference from an already existing reference by
+ * kobject_add_ref() or as a result of unpublishing a capability and
+ * disassociating it from its kobject_t using cap_unpublish().
+ *
+ * As kernel objects are reference-counted, they get automatically destroyed
+ * when their last reference is dropped in kobject_put(). The idea is that
+ * whenever a kernel object is inserted into some sort of a container (e.g. a
+ * list or hash table), its reference count should be incremented via
+ * kobject_get() or kobject_add_ref(). When the kernel object is removed from
+ * the container, the reference count should go down via a call to
+ * kobject_put().
+ */
+
+#include <cap/cap.h>
+#include <proc/task.h>
+#include <synch/mutex.h>
+#include <abi/errno.h>
+#include <mm/slab.h>
+#include <adt/list.h>
+
+#include <stdint.h>
+
+#define MAX_CAPS	INT_MAX
+
+static slab_cache_t *cap_slab;
+
+static kobject_t *cap_unpublish_locked(task_t *, cap_handle_t, kobject_type_t);
+
+static size_t caps_hash(const ht_link_t *item)
+{
+	cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);
+	return hash_mix(cap->handle);
+}
+
+static size_t caps_key_hash(void *key)
+{
+	cap_handle_t *handle = (cap_handle_t *) key;
+	return hash_mix(*handle);
+}
+
+static bool caps_key_equal(void *key, const ht_link_t *item)
+{
+	cap_handle_t *handle = (cap_handle_t *) key;
+	cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);
+	return *handle == cap->handle;
+}
+
+static hash_table_ops_t caps_ops = {
+	.hash = caps_hash,
+	.key_hash = caps_key_hash,
+	.key_equal = caps_key_equal
+};
+
+void caps_init(void)
+{
+	cap_slab = slab_cache_create("cap_t", sizeof(cap_t), 0, NULL,
+	    NULL, 0);
+}
+
+/** Allocate the capability info structure
+ *
+ * @param task  Task for which to allocate the info structure.
+ */
+int caps_task_alloc(task_t *task)
+{
+	task->cap_info = (cap_info_t *) malloc(sizeof(cap_info_t),
+	    FRAME_ATOMIC);
+	if (!task->cap_info)
+		return ENOMEM;
+	task->cap_info->handles = ra_arena_create();
+	if (!task->cap_info->handles)
+		goto error_handles;
+	if (!ra_span_add(task->cap_info->handles, 0, MAX_CAPS))
+		goto error_span;
+	if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops))
+		goto error_span;
+	return EOK;
+
+error_span:
+	ra_arena_destroy(task->cap_info->handles);
+error_handles:
+	free(task->cap_info);
+	return ENOMEM;
+}
+
+/** Initialize the capability info structure
+ *
+ * @param task  Task for which to initialize the info structure.
+ */
+void caps_task_init(task_t *task)
+{
+	mutex_initialize(&task->cap_info->lock, MUTEX_PASSIVE);
+
+	for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
+		list_initialize(&task->cap_info->type_list[t]);
+}
+
+/** Deallocate the capability info structure
+ *
+ * @param task  Task from which to deallocate the info structure.
+ */
+void caps_task_free(task_t *task)
+{
+	hash_table_destroy(&task->cap_info->caps);
+	ra_arena_destroy(task->cap_info->handles);
+	free(task->cap_info);
+}
+
+/** Invoke callback function on task's capabilites of given type
+ *
+ * @param task  Task where the invocation should take place.
+ * @param type  Kernel object type of the task's capabilities that will be
+ *              subject to the callback invocation.
+ * @param cb    Callback function.
+ * @param arg   Argument for the callback function.
+ *
+ * @return True if the callback was called on all matching capabilities.
+ * @return False if the callback was applied only partially.
+ */
+bool caps_apply_to_kobject_type(task_t *task, kobject_type_t type,
+    bool (*cb)(cap_t *, void *), void *arg)
+{
+	bool done = true;
+
+	mutex_lock(&task->cap_info->lock);
+	list_foreach_safe(task->cap_info->type_list[type], cur, next) {
+		cap_t *cap = list_get_instance(cur, cap_t, type_link);
+		done = cb(cap, arg);
+		if (!done)
+			break;
+	}
+	mutex_unlock(&task->cap_info->lock);
+
+	return done;
+}
+
+/** Initialize capability and associate it with its handle
+ *
+ * @param cap     Address of the capability.
+ * @param task    Backling to the owning task.
+ * @param handle  Capability handle.
+ */
+static void cap_initialize(cap_t *cap, task_t *task, cap_handle_t handle)
+{
+	cap->state = CAP_STATE_FREE;
+	cap->task = task;
+	cap->handle = handle;
+	link_initialize(&cap->type_link);
+}
+
+/** Get capability using capability handle
+ *
+ * @param task    Task whose capability to get.
+ * @param handle  Capability handle of the desired capability.
+ * @param state   State in which the capability must be.
+ *
+ * @return Address of the desired capability if it exists and its state matches.
+ * @return NULL if no such capability exists or it's in a different state.
+ */
+static cap_t *cap_get(task_t *task, cap_handle_t handle, cap_state_t state)
+{
+	assert(mutex_locked(&task->cap_info->lock));
+
+	if ((handle < 0) || (handle >= MAX_CAPS))
+		return NULL;
+	ht_link_t *link = hash_table_find(&task->cap_info->caps, &handle);
+	if (!link)
+		return NULL;
+	cap_t *cap = hash_table_get_inst(link, cap_t, caps_link);
+	if (cap->state != state)
+		return NULL;
+	return cap;
+}
+
+static bool cap_reclaimer(ht_link_t *link, void *arg)
+{
+	cap_t **result = (cap_t **) arg;
+	cap_t *cap = hash_table_get_inst(link, cap_t, caps_link);
+
+	if (cap->state == CAP_STATE_PUBLISHED && cap->kobject->ops->reclaim &&
+	    cap->kobject->ops->reclaim(cap->kobject)) {
+		kobject_t *kobj = cap_unpublish_locked(cap->task, cap->handle,
+		    cap->kobject->type);
+		kobject_put(kobj);
+		cap_initialize(cap, cap->task, cap->handle);
+		*result = cap;
+		return false;
+	}
+
+	return true;
+}
+
+/** Allocate new capability
+ *
+ * @param task  Task for which to allocate the new capability.
+ *
+ * @return New capability handle on success.
+ * @return Negative error code in case of error.
+ */
+cap_handle_t cap_alloc(task_t *task)
+{
+	cap_t *cap = NULL;
+	cap_handle_t handle;
+
+	/*
+	 * First of all, see if we can reclaim a capability. Note that this
+	 * feature is only temporary and capability reclamaition will eventually
+	 * be phased out.
+	 */
+	mutex_lock(&task->cap_info->lock);
+	hash_table_apply(&task->cap_info->caps, cap_reclaimer, &cap);
+
+	/*
+	 * If we don't have a capability by now, try to allocate a new one.
+	 */
+	if (!cap) {
+		cap = slab_alloc(cap_slab, FRAME_ATOMIC);
+		if (!cap) {
+			mutex_unlock(&task->cap_info->lock);
+			return ENOMEM;
+		}
+		uintptr_t hbase;
+		if (!ra_alloc(task->cap_info->handles, 1, 1, &hbase)) {
+			slab_free(cap_slab, cap);
+			mutex_unlock(&task->cap_info->lock);
+			return ENOMEM;
+		}
+		cap_initialize(cap, task, (cap_handle_t) hbase);
+		hash_table_insert(&task->cap_info->caps, &cap->caps_link);
+	}
+
+	cap->state = CAP_STATE_ALLOCATED;
+	handle = cap->handle;
+	mutex_unlock(&task->cap_info->lock);
+
+	return handle;
+}
+
+/** Publish allocated capability
+ *
+ * The kernel object is moved into the capability. In other words, its reference
+ * is handed over to the capability. Once published, userspace can access and
+ * manipulate the capability.
+ *
+ * @param task    Task in which to publish the capability.
+ * @param handle  Capability handle.
+ * @param kobj    Kernel object.
+ */
+void
+cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj)
+{
+	mutex_lock(&task->cap_info->lock);
+	cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
+	assert(cap);
+	cap->state = CAP_STATE_PUBLISHED;
+	/* Hand over kobj's reference to cap */
+	cap->kobject = kobj;
+	list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]);
+	mutex_unlock(&task->cap_info->lock);
+}
+
+static kobject_t *
+cap_unpublish_locked(task_t *task, cap_handle_t handle, kobject_type_t type)
+{
+	kobject_t *kobj = NULL;
+
+	cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
+	if (cap) {
+		if (cap->kobject->type == type) {
+			/* Hand over cap's reference to kobj */
+			kobj = cap->kobject;
+			cap->kobject = NULL;
+			list_remove(&cap->type_link);
+			cap->state = CAP_STATE_ALLOCATED;
+		}
+	}
+
+	return kobj;
+}
+
+/** Unpublish published capability
+ *
+ * The kernel object is moved out of the capability. In other words, the
+ * capability's reference to the objects is handed over to the kernel object
+ * pointer returned by this function. Once unpublished, the capability does not
+ * refer to any kernel object anymore.
+ *
+ * @param task    Task in which to unpublish the capability.
+ * @param handle  Capability handle.
+ * @param type    Kernel object type of the object associated with the
+ *                capability.
+ */
+kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type)
+{
+
+	mutex_lock(&task->cap_info->lock);
+	kobject_t *kobj = cap_unpublish_locked(task, handle, type);
+	mutex_unlock(&task->cap_info->lock);
+
+	return kobj;
+}
+
+/** Free allocated capability
+ *
+ * @param task    Task in which to free the capability.
+ * @param handle  Capability handle.
+ */
+void cap_free(task_t *task, cap_handle_t handle)
+{
+	assert(handle >= 0);
+	assert(handle < MAX_CAPS);
+
+	mutex_lock(&task->cap_info->lock);
+	cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
+
+	assert(cap);
+
+	hash_table_remove_item(&task->cap_info->caps, &cap->caps_link);
+	ra_free(task->cap_info->handles, handle, 1);
+	slab_free(cap_slab, cap);
+	mutex_unlock(&task->cap_info->lock);
+}
+
+/** Initialize kernel object
+ *
+ * @param kobj  Kernel object to initialize.
+ * @param type  Type of the kernel object.
+ * @param raw   Raw pointer to the encapsulated object.
+ * @param ops   Pointer to kernel object operations for the respective type.
+ */
+void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw,
+    kobject_ops_t *ops)
+{
+	atomic_set(&kobj->refcnt, 1);
+	kobj->type = type;
+	kobj->raw = raw;
+	kobj->ops = ops;
+}
+
+/** Get new reference to kernel object from capability
+ *
+ * @param task    Task from which to get the reference.
+ * @param handle  Capability handle.
+ * @param type    Kernel object type of the object associated with the
+ *                capability referenced by handle.
+ *
+ * @return Kernel object with incremented reference count on success.
+ * @return NULL if there is no matching capability or kernel object.
+ */
+kobject_t *
+kobject_get(struct task *task, cap_handle_t handle, kobject_type_t type)
+{
+	kobject_t *kobj = NULL;
+
+	mutex_lock(&task->cap_info->lock);
+	cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
+	if (cap) {
+		if (cap->kobject->type == type) {
+			kobj = cap->kobject;
+			atomic_inc(&kobj->refcnt);
+		}
+	}
+	mutex_unlock(&task->cap_info->lock);
+
+	return kobj;
+}
+
+/** Record new reference
+ *
+ * @param kobj  Kernel object from which the new reference is created.
+ */
+void kobject_add_ref(kobject_t *kobj)
+{
+	atomic_inc(&kobj->refcnt);
+}
+
+/** Drop reference to kernel object
+ *
+ * The encapsulated object and the kobject_t wrapper are both destroyed when the
+ * last reference is dropped.
+ *
+ * @param kobj  Kernel object whose reference to drop.
+ */
+void kobject_put(kobject_t *kobj)
+{
+	if (atomic_postdec(&kobj->refcnt) == 1) {
+		kobj->ops->destroy(kobj->raw);
+		free(kobj);
+	}
+}
+
+/** @}
+ */
Index: kernel/generic/src/console/chardev.c
===================================================================
--- kernel/generic/src/console/chardev.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/console/chardev.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,4 +33,5 @@
  */
 
+#include <assert.h>
 #include <adt/list.h>
 #include <console/chardev.h>
@@ -66,5 +67,5 @@
 void indev_push_character(indev_t *indev, wchar_t ch)
 {
-	ASSERT(indev);
+	assert(indev);
 	
 	irq_spinlock_lock(&indev->lock, true);
Index: kernel/generic/src/console/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/console/cmd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,4 +41,5 @@
  */
 
+#include <assert.h>
 #include <console/cmd.h>
 #include <console/console.h>
@@ -54,5 +55,4 @@
 #include <str.h>
 #include <macros.h>
-#include <debug.h>
 #include <cpu.h>
 #include <mm/tlb.h>
@@ -917,5 +917,5 @@
 int cmd_uptime(cmd_arg_t *argv)
 {
-	ASSERT(uptime);
+	assert(uptime);
 	
 	/* This doesn't have to be very accurate */
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/console/console.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
  */
 
+#include <assert.h>
 #include <console/console.h>
 #include <console/chardev.h>
@@ -189,5 +190,5 @@
 	void *faddr = (void *) KA2PA(kio);
 	
-	ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
+	assert((uintptr_t) faddr % FRAME_SIZE == 0);
 	
 	kio_parea.pbase = (uintptr_t) faddr;
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/console/kconsole.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
  */
 
+#include <assert.h>
 #include <console/kconsole.h>
 #include <console/console.h>
@@ -54,5 +55,4 @@
 #include <str.h>
 #include <sysinfo/sysinfo.h>
-#include <ddi/device.h>
 #include <symtab.h>
 #include <errno.h>
@@ -633,6 +633,6 @@
     size_t *start, size_t *end)
 {
-	ASSERT(start != NULL);
-	ASSERT(end != NULL);
+	assert(start != NULL);
+	assert(end != NULL);
 	
 	bool found_start = false;
Index: kernel/generic/src/console/prompt.c
===================================================================
--- kernel/generic/src/console/prompt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/console/prompt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
  */
 
+#include <assert.h>
 #include <console/prompt.h>
 
@@ -49,6 +50,6 @@
 bool console_prompt_display_all_hints(indev_t *indev, size_t hints)
 {
-	ASSERT(indev);
-	ASSERT(hints > 0);
+	assert(indev);
+	assert(hints > 0);
 	
 	printf("Display all %zu possibilities? (y or n) ", hints);
@@ -81,6 +82,6 @@
 bool console_prompt_more_hints(indev_t *indev, size_t *display_hints)
 {
-	ASSERT(indev);
-	ASSERT(display_hints != NULL);
+	assert(indev);
+	assert(display_hints != NULL);
 	
 	printf("--More--");
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/cpu/cpu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,5 +45,5 @@
 #include <config.h>
 #include <panic.h>
-#include <memstr.h>
+#include <mem.h>
 #include <adt/list.h>
 #include <print.h>
Index: kernel/generic/src/cpu/cpu_mask.c
===================================================================
--- kernel/generic/src/cpu/cpu_mask.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/cpu/cpu_mask.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  * @brief CPU mask manipulation functions.
  */
+#include <assert.h>
 #include <cpu/cpu_mask.h>
 #include <cpu.h>
@@ -52,6 +53,6 @@
 static void cpu_mask_count(cpu_mask_t *cpus, size_t cpu_cnt)
 {
-	ASSERT(NULL != cpus);
-	ASSERT(cpu_cnt <= config.cpu_count);
+	assert(NULL != cpus);
+	assert(cpu_cnt <= config.cpu_count);
 	
 	for (size_t active_word = 0; 
@@ -87,5 +88,5 @@
 void cpu_mask_none(cpu_mask_t *cpus)
 {
-	ASSERT(cpus);
+	assert(cpus);
 	
 	size_t word_cnt = cpu_mask_size() / word_size;
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ddi/ddi.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,7 +40,8 @@
  */
 
+#include <assert.h>
 #include <ddi/ddi.h>
 #include <proc/task.h>
-#include <security/cap.h>
+#include <security/perm.h>
 #include <mm/frame.h>
 #include <mm/as.h>
@@ -96,5 +97,5 @@
  *
  * @return EOK on success.
- * @return EPERM if the caller lacks capabilities to use this syscall.
+ * @return EPERM if the caller lacks permissions to use this syscall.
  * @return EBADMEM if phys is not page aligned.
  * @return ENOENT if there is no task matching the specified ID or
@@ -106,5 +107,5 @@
     unsigned int flags, uintptr_t *virt, uintptr_t bound)
 {
-	ASSERT(TASK);
+	assert(TASK);
 	
 	if ((phys % FRAME_SIZE) != 0)
@@ -116,5 +117,5 @@
 	 */
 	bool priv =
-	    ((cap_get(TASK) & CAP_MEM_MANAGER) == CAP_MEM_MANAGER);
+	    ((perm_get(TASK) & PERM_MEM_MANAGER) == PERM_MEM_MANAGER);
 	
 	mem_backend_data_t backend_data;
@@ -211,5 +212,5 @@
 NO_TRACE static int physmem_unmap(uintptr_t virt)
 {
-	ASSERT(TASK);
+	assert(TASK);
 
 	return as_area_destroy(TASK->as, virt);
@@ -260,5 +261,5 @@
  * @param size   Size of the enabled I/O space.
  *
- * @return 0 on success, EPERM if the caller lacks capabilities to use this
+ * @return 0 on success, EPERM if the caller lacks permissions to use this
  *           syscall, ENOENT if there is no task matching the specified ID.
  *
@@ -269,6 +270,6 @@
 	 * Make sure the caller is authorised to make this syscall.
 	 */
-	cap_t caps = cap_get(TASK);
-	if (!(caps & CAP_IO_MANAGER))
+	perm_t perms = perm_get(TASK);
+	if (!(perms & PERM_IO_MANAGER))
 		return EPERM;
 	
@@ -301,5 +302,5 @@
  * @param size   Size of the enabled I/O space.
  *
- * @return 0 on success, EPERM if the caller lacks capabilities to use this
+ * @return 0 on success, EPERM if the caller lacks permissions to use this
  *           syscall, ENOENT if there is no task matching the specified ID.
  *
@@ -310,6 +311,6 @@
 	 * Make sure the caller is authorised to make this syscall.
 	 */
-	cap_t caps = cap_get(TASK);
-	if (!(caps & CAP_IO_MANAGER))
+	perm_t perms = perm_get(TASK);
+	if (!(perms & PERM_IO_MANAGER))
 		return EPERM;
 	
@@ -368,5 +369,5 @@
     unsigned int flags, uintptr_t *phys)
 {
-	ASSERT(TASK);
+	assert(TASK);
 	
 	// TODO: implement locking of non-anonymous mapping
@@ -378,5 +379,5 @@
     uintptr_t *virt, uintptr_t bound)
 {
-	ASSERT(TASK);
+	assert(TASK);
 	
 	size_t frames = SIZE2FRAMES(size);
Index: rnel/generic/src/ddi/device.c
===================================================================
--- kernel/generic/src/ddi/device.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genericddi
- * @{
- */
-/**
- * @file
- * @brief Device numbers.
- */
-
-#include <typedefs.h>
-#include <ddi/device.h>
-#include <atomic.h>
-#include <debug.h>
-
-static atomic_t last;
-
-/** Assign new device number.
- *
- * @return Unique device number.
- */
-devno_t device_assign_devno(void)
-{
-	devno_t devno = (devno_t) atomic_postinc(&last);
-	ASSERT(devno >= 0);
-	
-	return devno;
-}
-
-sysarg_t sys_device_assign_devno(void)
-{
-	return (sysarg_t) device_assign_devno();
-}
-
-/** @}
- */
Index: kernel/generic/src/ddi/irq.c
===================================================================
--- kernel/generic/src/ddi/irq.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ddi/irq.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -32,41 +32,13 @@
 /**
  * @file
- * @brief IRQ dispatcher.
- *
- * This file provides means of connecting IRQs with particular
- * devices and logic for dispatching interrupts to IRQ handlers
- * defined by those devices.
- *
- * This code is designed to support:
- * - multiple devices sharing single IRQ
- * - multiple IRQs per single device
- * - multiple instances of the same device
- *
- *
- * Note about architectures.
- *
- * Some architectures has the term IRQ well defined. Examples
- * of such architectures include amd64, ia32 and mips32. Some
- * other architectures, such as sparc64, don't use the term
- * at all. In those cases, we boldly step forward and define what
- * an IRQ is.
- *
- * The implementation is generic enough and still allows the
- * architectures to use the hardware layout effectively.
- * For instance, on amd64 and ia32, where there is only 16
- * IRQs, the irq_hash_table can be optimized to a one-dimensional
- * array. Next, when it is known that the IRQ numbers (aka INR's)
- * are unique, the claim functions can always return IRQ_ACCEPT.
- *
- *
- * Note about the irq_hash_table.
- *
- * The hash table is configured to use two keys: inr and devno.
- * However, the hash index is computed only from inr. Moreover,
- * if devno is -1, the match is based on the return value of
- * the claim() function instead of on devno.
+ * @brief IRQ dispatcher
+ *
+ * This file provides means of connecting IRQs with respective device drivers
+ * and logic for dispatching interrupts to IRQ handlers defined by those
+ * drivers.
  */
 
 #include <ddi/irq.h>
+#include <adt/hash.h>
 #include <adt/hash_table.h>
 #include <mm/slab.h>
@@ -75,11 +47,10 @@
 #include <console/console.h>
 #include <interrupt.h>
-#include <memstr.h>
+#include <mem.h>
 #include <arch.h>
 
-#define KEY_INR    0
-#define KEY_DEVNO  1
-
-/** Spinlock protecting the kernel IRQ hash table.
+slab_cache_t *irq_slab = NULL;
+
+/** Spinlock protecting the kernel IRQ hash table
  *
  * This lock must be taken only when interrupts are disabled.
@@ -91,5 +62,5 @@
 static hash_table_t irq_kernel_hash_table;
 
-/** Spinlock protecting the uspace IRQ hash table.
+/** Spinlock protecting the uspace IRQ hash table
  *
  * This lock must be taken only when interrupts are disabled.
@@ -98,78 +69,43 @@
 IRQ_SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock);
 
-/** The uspace IRQ hash table. */
+/** The uspace IRQ hash table */
 hash_table_t irq_uspace_hash_table;
 
-/**
- * Hash table operations for cases when we know that
- * there will be collisions between different keys.
- *
- */
-static size_t irq_ht_hash(sysarg_t *key);
-static bool irq_ht_compare(sysarg_t *key, size_t keys, link_t *item);
-static void irq_ht_remove(link_t *item);
-
-static hash_table_operations_t irq_ht_ops = {
+static size_t irq_ht_hash(const ht_link_t *);
+static size_t irq_ht_key_hash(void *);
+static bool irq_ht_equal(const ht_link_t *, const ht_link_t *);
+static bool irq_ht_key_equal(void *, const ht_link_t *);
+
+static hash_table_ops_t irq_ht_ops = {
 	.hash = irq_ht_hash,
-	.compare = irq_ht_compare,
-	.remove_callback = irq_ht_remove,
+	.key_hash = irq_ht_key_hash,
+	.equal = irq_ht_equal,
+	.key_equal = irq_ht_key_equal
 };
 
-/**
- * Hash table operations for cases when we know that
- * there will be no collisions between different keys.
- * However, there might be still collisions among
- * elements with single key (sharing of one IRQ).
- *
- */
-static size_t irq_lin_hash(sysarg_t *key);
-static bool irq_lin_compare(sysarg_t *key, size_t keys, link_t *item);
-static void irq_lin_remove(link_t *item);
-
-static hash_table_operations_t irq_lin_ops = {
-	.hash = irq_lin_hash,
-	.compare = irq_lin_compare,
-	.remove_callback = irq_lin_remove,
-};
-
-/** Number of buckets in either of the hash tables. */
-static size_t buckets;
-
-/** Last valid INR. */
+/** Last valid INR */
 inr_t last_inr = 0;
 
-/** Initialize IRQ subsystem.
- *
- * @param inrs   Numbers of unique IRQ numbers or INRs.
- * @param chains Number of chains in the hash table.
+/** Initialize IRQ subsystem
+ *
+ * @param inrs    Numbers of unique IRQ numbers or INRs.
+ * @param chains  Number of buckets in the hash table.
  *
  */
 void irq_init(size_t inrs, size_t chains)
 {
-	buckets = chains;
 	last_inr = inrs - 1;
 
-	/*
-	 * Be smart about the choice of the hash table operations.
-	 * In cases in which inrs equals the requested number of
-	 * chains (i.e. where there is no collision between
-	 * different keys), we can use optimized set of operations.
-	 */
-	if (inrs == chains) {
-		hash_table_create(&irq_uspace_hash_table, chains, 2,
-		    &irq_lin_ops);
-		hash_table_create(&irq_kernel_hash_table, chains, 2,
-		    &irq_lin_ops);
-	} else {
-		hash_table_create(&irq_uspace_hash_table, chains, 2,
-		    &irq_ht_ops);
-		hash_table_create(&irq_kernel_hash_table, chains, 2,
-		    &irq_ht_ops);
-	}
-}
-
-/** Initialize one IRQ structure.
- *
- * @param irq Pointer to the IRQ structure to be initialized.
+	irq_slab = slab_cache_create("irq_t", sizeof(irq_t), 0, NULL, NULL,
+	    FRAME_ATOMIC);
+	assert(irq_slab);
+
+	hash_table_create(&irq_uspace_hash_table, chains, 0, &irq_ht_ops);
+	hash_table_create(&irq_kernel_hash_table, chains, 0, &irq_ht_ops);
+}
+
+/** Initialize one IRQ structure
+ *
+ * @param irq  Pointer to the IRQ structure to be initialized.
  *
  */
@@ -177,97 +113,60 @@
 {
 	memsetb(irq, sizeof(irq_t), 0);
-	link_initialize(&irq->link);
 	irq_spinlock_initialize(&irq->lock, "irq.lock");
-	link_initialize(&irq->notif_cfg.link);
 	irq->inr = -1;
-	irq->devno = -1;
 	
 	irq_initialize_arch(irq);
 }
 
-/** Register IRQ for device.
- *
- * The irq structure must be filled with information
- * about the interrupt source and with the claim()
- * function pointer and handler() function pointer.
- *
- * @param irq IRQ structure belonging to a device.
- *
- * @return True on success, false on failure.
+/** Register IRQ for device
+ *
+ * The irq structure must be filled with information about the interrupt source
+ * and with the claim() function pointer and handler() function pointer.
+ *
+ * @param irq  IRQ structure belonging to a device.
  *
  */
 void irq_register(irq_t *irq)
 {
-	sysarg_t key[] = {
-		(sysarg_t) irq->inr,
-		(sysarg_t) irq->devno
-	};
-	
 	irq_spinlock_lock(&irq_kernel_hash_table_lock, true);
 	irq_spinlock_lock(&irq->lock, false);
-	hash_table_insert(&irq_kernel_hash_table, key, &irq->link);
+	hash_table_insert(&irq_kernel_hash_table, &irq->link);
 	irq_spinlock_unlock(&irq->lock, false);
 	irq_spinlock_unlock(&irq_kernel_hash_table_lock, true);
 }
 
-/** Search and lock the uspace IRQ hash table.
- *
- */
-static irq_t *irq_dispatch_and_lock_uspace(inr_t inr)
-{
-	link_t *lnk;
-	sysarg_t key[] = {
-		(sysarg_t) inr,
-		(sysarg_t) -1    /* Search will use claim() instead of devno */
-	};
-	
-	irq_spinlock_lock(&irq_uspace_hash_table_lock, false);
-	lnk = hash_table_find(&irq_uspace_hash_table, key);
-	if (lnk) {
-		irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
-		irq_spinlock_unlock(&irq_uspace_hash_table_lock, false);
-		return irq;
+/** Search and lock an IRQ hash table */
+static irq_t *
+irq_dispatch_and_lock_table(hash_table_t *h, irq_spinlock_t *l, inr_t inr)
+{
+	irq_spinlock_lock(l, false);
+	for (ht_link_t *lnk = hash_table_find(h, &inr); lnk;
+	    lnk = hash_table_find_next(h, lnk)) {
+		irq_t *irq = hash_table_get_inst(lnk, irq_t, link);
+		irq_spinlock_lock(&irq->lock, false);
+		if (irq->claim(irq) == IRQ_ACCEPT) {
+			/* leave irq locked */
+			irq_spinlock_unlock(l, false);
+			return irq;
+		}
+		irq_spinlock_unlock(&irq->lock, false);
 	}
-	irq_spinlock_unlock(&irq_uspace_hash_table_lock, false);
+	irq_spinlock_unlock(l, false);
 	
 	return NULL;
 }
 
-/** Search and lock the kernel IRQ hash table.
- *
- */
-static irq_t *irq_dispatch_and_lock_kernel(inr_t inr)
-{
-	link_t *lnk;
-	sysarg_t key[] = {
-		(sysarg_t) inr,
-		(sysarg_t) -1    /* Search will use claim() instead of devno */
-	};
-	
-	irq_spinlock_lock(&irq_kernel_hash_table_lock, false);
-	lnk = hash_table_find(&irq_kernel_hash_table, key);
-	if (lnk) {
-		irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
-		irq_spinlock_unlock(&irq_kernel_hash_table_lock, false);
-		return irq;
-	}
-	irq_spinlock_unlock(&irq_kernel_hash_table_lock, false);
-	
-	return NULL;
-}
-
-/** Dispatch the IRQ.
- *
- * We assume this function is only called from interrupt
- * context (i.e. that interrupts are disabled prior to
- * this call).
- *
- * This function attempts to lookup a fitting IRQ
- * structure. In case of success, return with interrupts
- * disabled and holding the respective structure.
- *
- * @param inr Interrupt number (aka inr or irq).
- *
- * @return IRQ structure of the respective device or NULL.
+/** Dispatch the IRQ
+ *
+ * We assume this function is only called from interrupt context (i.e. that
+ * interrupts are disabled prior to this call).
+ *
+ * This function attempts to lookup a fitting IRQ structure. In case of success,
+ * return with interrupts disabled and holding the respective structure.
+ *
+ * @param inr  Interrupt number (aka inr or irq).
+ *
+ * @return IRQ structure of the respective device
+ * @return NULL if no IRQ structure found
  *
  */
@@ -275,176 +174,57 @@
 {
 	/*
-	 * If the kernel console override is on,
-	 * then try first the kernel handlers
-	 * and eventually fall back to uspace
-	 * handlers.
+	 * If the kernel console override is on, then try first the kernel
+	 * handlers and eventually fall back to uspace handlers.
 	 *
-	 * In the usual case the uspace handlers
-	 * have precedence.
+	 * In the usual case the uspace handlers have precedence.
 	 */
 	
 	if (console_override) {
-		irq_t *irq = irq_dispatch_and_lock_kernel(inr);
+		irq_t *irq = irq_dispatch_and_lock_table(&irq_kernel_hash_table,
+		    &irq_kernel_hash_table_lock, inr);
 		if (irq)
 			return irq;
 		
-		return irq_dispatch_and_lock_uspace(inr);
+		return irq_dispatch_and_lock_table(&irq_uspace_hash_table,
+		    &irq_uspace_hash_table_lock, inr);
 	}
 	
-	irq_t *irq = irq_dispatch_and_lock_uspace(inr);
+	irq_t *irq = irq_dispatch_and_lock_table(&irq_uspace_hash_table,
+	    &irq_uspace_hash_table_lock, inr);
 	if (irq)
 		return irq;
 	
-	return irq_dispatch_and_lock_kernel(inr);
-}
-
-/** Compute hash index for the key.
- *
- * This function computes hash index into
- * the IRQ hash table for which there
- * can be collisions between different
- * INRs.
- *
- * The devno is not used to compute the hash.
- *
- * @param key The first of the keys is inr and the second is devno or -1.
- *
- * @return Index into the hash table.
- *
- */
-size_t irq_ht_hash(sysarg_t key[])
-{
-	inr_t inr = (inr_t) key[KEY_INR];
-	return inr % buckets;
-}
-
-/** Compare hash table element with a key.
- *
- * There are two things to note about this function.
- * First, it is used for the more complex architecture setup
- * in which there are way too many interrupt numbers (i.e. inr's)
- * to arrange the hash table so that collisions occur only
- * among same inrs of different devnos. So the explicit check
- * for inr match must be done.
- * Second, if devno is -1, the second key (i.e. devno) is not
- * used for the match and the result of the claim() function
- * is used instead.
- *
- * This function assumes interrupts are already disabled.
- *
- * @param key  Keys (i.e. inr and devno).
- * @param keys This is 2.
- * @param item The item to compare the key with.
- *
- * @return True on match or false otherwise.
- *
- */
-bool irq_ht_compare(sysarg_t key[], size_t keys, link_t *item)
-{
-	irq_t *irq = hash_table_get_instance(item, irq_t, link);
-	inr_t inr = (inr_t) key[KEY_INR];
-	devno_t devno = (devno_t) key[KEY_DEVNO];
-	
-	bool rv;
-	
-	irq_spinlock_lock(&irq->lock, false);
-	if (devno == -1) {
-		/* Invoked by irq_dispatch_and_lock(). */
-		rv = ((irq->inr == inr) &&
-		    (irq->claim(irq) == IRQ_ACCEPT));
-	} else {
-		/* Invoked by irq_find_and_lock(). */
-		rv = ((irq->inr == inr) && (irq->devno == devno));
-	}
-	
-	/* unlock only on non-match */
-	if (!rv)
-		irq_spinlock_unlock(&irq->lock, false);
-	
-	return rv;
-}
-
-/** Unlock IRQ structure after hash_table_remove().
- *
- * @param lnk Link in the removed and locked IRQ structure.
- */
-void irq_ht_remove(link_t *lnk)
-{
-	irq_t *irq __attribute__((unused))
-	    = hash_table_get_instance(lnk, irq_t, link);
-	irq_spinlock_unlock(&irq->lock, false);
-}
-
-/** Compute hash index for the key.
- *
- * This function computes hash index into
- * the IRQ hash table for which there
- * are no collisions between different
- * INRs.
- *
- * @param key The first of the keys is inr and the second is devno or -1.
- *
- * @return Index into the hash table.
- *
- */
-size_t irq_lin_hash(sysarg_t key[])
-{
-	inr_t inr = (inr_t) key[KEY_INR];
-	return inr;
-}
-
-/** Compare hash table element with a key.
- *
- * There are two things to note about this function.
- * First, it is used for the less complex architecture setup
- * in which there are not too many interrupt numbers (i.e. inr's)
- * to arrange the hash table so that collisions occur only
- * among same inrs of different devnos. So the explicit check
- * for inr match is not done.
- * Second, if devno is -1, the second key (i.e. devno) is not
- * used for the match and the result of the claim() function
- * is used instead.
- *
- * This function assumes interrupts are already disabled.
- *
- * @param key  Keys (i.e. inr and devno).
- * @param keys This is 2.
- * @param item The item to compare the key with.
- *
- * @return True on match or false otherwise.
- *
- */
-bool irq_lin_compare(sysarg_t key[], size_t keys, link_t *item)
-{
-	irq_t *irq = list_get_instance(item, irq_t, link);
-	devno_t devno = (devno_t) key[KEY_DEVNO];
-	bool rv;
-	
-	irq_spinlock_lock(&irq->lock, false);
-	if (devno == -1) {
-		/* Invoked by irq_dispatch_and_lock() */
-		rv = (irq->claim(irq) == IRQ_ACCEPT);
-	} else {
-		/* Invoked by irq_find_and_lock() */
-		rv = (irq->devno == devno);
-	}
-	
-	/* unlock only on non-match */
-	if (!rv)
-		irq_spinlock_unlock(&irq->lock, false);
-	
-	return rv;
-}
-
-/** Unlock IRQ structure after hash_table_remove().
- *
- * @param lnk Link in the removed and locked IRQ structure.
- *
- */
-void irq_lin_remove(link_t *lnk)
-{
-	irq_t *irq __attribute__((unused))
-	    = hash_table_get_instance(lnk, irq_t, link);
-	irq_spinlock_unlock(&irq->lock, false);
+	return irq_dispatch_and_lock_table(&irq_kernel_hash_table,
+	    &irq_kernel_hash_table_lock, inr);
+}
+
+/** Return the hash of the key stored in the item. */
+size_t irq_ht_hash(const ht_link_t *item)
+{
+	irq_t *irq = hash_table_get_inst(item, irq_t, link);
+	return hash_mix(irq->inr);
+}
+
+/** Return the hash of the key. */
+size_t irq_ht_key_hash(void *key)
+{
+	inr_t *inr = (inr_t *) key;
+	return hash_mix(*inr);
+}
+
+/** Return true if the items have the same lookup key. */
+bool irq_ht_equal(const ht_link_t *item1, const ht_link_t *item2)
+{
+	irq_t *irq1 = hash_table_get_inst(item1, irq_t, link);
+	irq_t *irq2 = hash_table_get_inst(item2, irq_t, link);
+	return irq1->inr == irq2->inr;
+}
+
+/** Return true if the key is equal to the item's lookup key. */
+bool irq_ht_key_equal(void *key, const ht_link_t *item)
+{
+	inr_t *inr = (inr_t *) key;
+	irq_t *irq = hash_table_get_inst(item, irq_t, link);
+	return irq->inr == *inr;
 }
 
Index: kernel/generic/src/debug/stacktrace.c
===================================================================
--- kernel/generic/src/debug/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/debug/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,6 +34,6 @@
 
 #include <stacktrace.h>
+#include <stdbool.h>
 #include <interrupt.h>
-#include <typedefs.h>
 #include <symtab.h>
 #include <print.h>
Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/interrupt/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,6 +40,6 @@
  */
 
+#include <assert.h>
 #include <interrupt.h>
-#include <debug.h>
 #include <console/kconsole.h>
 #include <console/console.h>
@@ -76,5 +76,5 @@
 {
 #if (IVT_ITEMS > 0)
-	ASSERT(n < IVT_ITEMS);
+	assert(n < IVT_ITEMS);
 #endif
 	
@@ -102,5 +102,5 @@
 {
 #if (IVT_ITEMS > 0)
-	ASSERT(n < IVT_ITEMS);
+	assert(n < IVT_ITEMS);
 #endif
 	
Index: kernel/generic/src/ipc/event.c
===================================================================
--- kernel/generic/src/ipc/event.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/event.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <ipc/event.h>
 #include <mm/slab.h>
@@ -41,5 +42,4 @@
 #include <console/console.h>
 #include <proc/task.h>
-#include <memstr.h>
 #include <errno.h>
 #include <arch.h>
@@ -60,5 +60,5 @@
 static event_t *evno2event(int evno, task_t *task)
 {
-	ASSERT(evno < EVENT_TASK_END);
+	assert(evno < EVENT_TASK_END);
 	
 	event_t *event;
@@ -124,5 +124,5 @@
 void event_set_unmask_callback(event_type_t evno, event_callback_t callback)
 {
-	ASSERT(evno < EVENT_END);
+	assert(evno < EVENT_END);
 	
 	_event_set_unmask_callback(evno2event(evno, NULL), callback);
@@ -132,6 +132,6 @@
     event_callback_t callback)
 {
-	ASSERT(evno >= (int) EVENT_END);
-	ASSERT(evno < EVENT_TASK_END);
+	assert(evno >= (int) EVENT_END);
+	assert(evno < EVENT_TASK_END);
 		
 	_event_set_unmask_callback(evno2event(evno, task), callback);
@@ -209,5 +209,5 @@
     sysarg_t a3, sysarg_t a4, sysarg_t a5)
 {
-	ASSERT(evno < EVENT_END);
+	assert(evno < EVENT_END);
 	
 	return event_enqueue(evno2event(evno, NULL), mask, a1, a2, a3, a4, a5);
@@ -237,6 +237,6 @@
     sysarg_t a1, sysarg_t a2, sysarg_t a3, sysarg_t a4, sysarg_t a5)
 {
-	ASSERT(evno >= (int) EVENT_END);
-	ASSERT(evno < EVENT_TASK_END);
+	assert(evno >= (int) EVENT_END);
+	assert(evno < EVENT_TASK_END);
 	
 	return event_enqueue(evno2event(evno, task), mask, a1, a2, a3, a4, a5);
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/ipc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,8 +38,10 @@
  */
 
+#include <assert.h>
 #include <synch/spinlock.h>
 #include <synch/mutex.h>
 #include <synch/waitq.h>
 #include <ipc/ipc.h>
+#include <ipc/ipcrsc.h>
 #include <abi/ipc/methods.h>
 #include <ipc/kbox.h>
@@ -51,6 +53,5 @@
 #include <arch.h>
 #include <proc/task.h>
-#include <memstr.h>
-#include <debug.h>
+#include <mem.h>
 #include <print.h>
 #include <console/console.h>
@@ -58,4 +59,5 @@
 #include <arch/interrupt.h>
 #include <ipc/irq.h>
+#include <cap/cap.h>
 
 static void ipc_forget_call(call_t *);
@@ -64,6 +66,8 @@
 answerbox_t *ipc_phone_0 = NULL;
 
-static slab_cache_t *ipc_call_slab;
-static slab_cache_t *ipc_answerbox_slab;
+static slab_cache_t *call_slab;
+static slab_cache_t *answerbox_slab;
+
+slab_cache_t *phone_slab = NULL; 
 
 /** Initialize a call structure.
@@ -93,5 +97,5 @@
 		if (call->buffer)
 			free(call->buffer);
-		slab_free(ipc_call_slab, call);
+		slab_free(call_slab, call);
 	}
 }
@@ -110,5 +114,5 @@
 call_t *ipc_call_alloc(unsigned int flags)
 {
-	call_t *call = slab_alloc(ipc_call_slab, flags);
+	call_t *call = slab_alloc(call_slab, flags);
 	if (call) {
 		_ipc_call_init(call);
@@ -145,5 +149,4 @@
 	list_initialize(&box->answers);
 	list_initialize(&box->irq_notifs);
-	list_initialize(&box->irq_list);
 	box->task = task;
 }
@@ -151,7 +154,9 @@
 /** Connect a phone to an answerbox.
  *
- * @param phone Initialized phone structure.
- * @param box   Initialized answerbox structure.
- * @return      True if the phone was connected, false otherwise.
+ * This function must be passed a reference to phone->kobject.
+ *
+ * @param phone  Initialized phone structure.
+ * @param box    Initialized answerbox structure.
+ * @return       True if the phone was connected, false otherwise.
  */
 bool ipc_phone_connect(phone_t *phone, answerbox_t *box)
@@ -166,4 +171,5 @@
 		phone->state = IPC_PHONE_CONNECTED;
 		phone->callee = box;
+		/* Pass phone->kobject reference to box->connected_phones */
 		list_append(&phone->link, &box->connected_phones);
 	}
@@ -171,4 +177,9 @@
 	irq_spinlock_unlock(&box->lock, true);
 	mutex_unlock(&phone->lock);
+
+	if (!active) {
+		/* We still have phone->kobject's reference; drop it */
+		kobject_put(phone->kobject);
+	}
 
 	return active;
@@ -188,4 +199,5 @@
 	phone->state = IPC_PHONE_FREE;
 	atomic_set(&phone->active_calls, 0);
+	phone->kobject = NULL;
 }
 
@@ -200,5 +212,5 @@
 int ipc_call_sync(phone_t *phone, call_t *request)
 {
-	answerbox_t *mybox = slab_alloc(ipc_answerbox_slab, 0);
+	answerbox_t *mybox = slab_alloc(answerbox_slab, 0);
 	ipc_answerbox_init(mybox, TASK);
 	
@@ -208,5 +220,5 @@
 	int rc = ipc_call(phone, request);
 	if (rc != EOK) {
-		slab_free(ipc_answerbox_slab, mybox);
+		slab_free(answerbox_slab, mybox);
 		return rc;
 	}
@@ -227,5 +239,5 @@
 		spinlock_lock(&TASK->active_calls_lock);
 
-		ASSERT(!request->forget);
+		assert(!request->forget);
 
 		bool answered = !request->active;
@@ -253,7 +265,7 @@
 		}
 	}
-	ASSERT(!answer || request == answer);
-	
-	slab_free(ipc_answerbox_slab, mybox);
+	assert(!answer || request == answer);
+	
+	slab_free(answerbox_slab, mybox);
 	return rc;
 }
@@ -453,4 +465,7 @@
 		list_remove(&phone->link);
 		irq_spinlock_unlock(&box->lock, true);
+
+		/* Drop the answerbox reference */
+		kobject_put(phone->kobject);
 		
 		call_t *call = ipc_call_alloc(0);
@@ -631,5 +646,5 @@
 		
 		/* Disconnect phone */
-		ASSERT(phone->state == IPC_PHONE_CONNECTED);
+		assert(phone->state == IPC_PHONE_CONNECTED);
 		
 		list_remove(&phone->link);
@@ -655,4 +670,6 @@
 
 			task_release(phone->caller);
+
+			kobject_put(phone->kobject);
 			
 			/* Must start again */
@@ -661,4 +678,5 @@
 		
 		mutex_unlock(&phone->lock);
+		kobject_put(phone->kobject);
 	}
 	
@@ -668,6 +686,6 @@
 static void ipc_forget_call(call_t *call)
 {
-	ASSERT(spinlock_locked(&TASK->active_calls_lock));
-	ASSERT(spinlock_locked(&call->forget_lock));
+	assert(spinlock_locked(&TASK->active_calls_lock));
+	assert(spinlock_locked(&call->forget_lock));
 
 	/*
@@ -707,5 +725,5 @@
 		 * Nota bene: there may still be answers waiting for pick up.
 		 */
-		spinlock_unlock(&TASK->active_calls_lock);	
+		spinlock_unlock(&TASK->active_calls_lock);
 		return;	
 	}
@@ -720,5 +738,5 @@
 		 * call on the list.
 		 */
-		spinlock_unlock(&TASK->active_calls_lock);	
+		spinlock_unlock(&TASK->active_calls_lock);
 		goto restart;
 	}
@@ -727,4 +745,50 @@
 
 	goto restart;
+}
+
+static bool phone_cap_wait_cb(cap_t *cap, void *arg)
+{
+	phone_t *phone = cap->kobject->phone;
+	bool *restart = (bool *) arg;
+
+	mutex_lock(&phone->lock);
+	if ((phone->state == IPC_PHONE_HUNGUP) &&
+	    (atomic_get(&phone->active_calls) == 0)) {
+		phone->state = IPC_PHONE_FREE;
+		phone->callee = NULL;
+	}
+
+	/*
+	 * We might have had some IPC_PHONE_CONNECTING phones at the beginning
+	 * of ipc_cleanup(). Depending on whether these were forgotten or
+	 * answered, they will eventually enter the IPC_PHONE_FREE or
+	 * IPC_PHONE_CONNECTED states, respectively.  In the latter case, the
+	 * other side may slam the open phones at any time, in which case we
+	 * will get an IPC_PHONE_SLAMMED phone.
+	 */
+	if ((phone->state == IPC_PHONE_CONNECTED) ||
+	    (phone->state == IPC_PHONE_SLAMMED)) {
+		mutex_unlock(&phone->lock);
+		ipc_phone_hangup(phone);
+		/*
+		 * Now there may be one extra active call, which needs to be
+		 * forgotten.
+		 */
+		ipc_forget_all_active_calls();
+		*restart = true;
+		return false;
+	}
+
+	/*
+	 * If the hangup succeeded, it has sent a HANGUP message, the IPC is now
+	 * in HUNGUP state, we wait for the reply to come
+	 */
+	if (phone->state != IPC_PHONE_FREE) {
+		mutex_unlock(&phone->lock);
+		return false;
+	}
+
+	mutex_unlock(&phone->lock);
+	return true;
 }
 
@@ -733,5 +797,5 @@
 {
 	call_t *call;
-	size_t i;
+	bool restart;
 
 restart:
@@ -740,54 +804,16 @@
 	 * Locking is needed as there may be connection handshakes in progress.
 	 */
-	for (i = 0; i < IPC_MAX_PHONES; i++) {
-		phone_t *phone = &TASK->phones[i];
-
-		mutex_lock(&phone->lock);	
-		if ((phone->state == IPC_PHONE_HUNGUP) &&
-		    (atomic_get(&phone->active_calls) == 0)) {
-			phone->state = IPC_PHONE_FREE;
-			phone->callee = NULL;
-		}
-
-		/*
-		 * We might have had some IPC_PHONE_CONNECTING phones at the
-		 * beginning of ipc_cleanup(). Depending on whether these were
-		 * forgotten or answered, they will eventually enter the
-		 * IPC_PHONE_FREE or IPC_PHONE_CONNECTED states, respectively.
-		 * In the latter case, the other side may slam the open phones
-		 * at any time, in which case we will get an IPC_PHONE_SLAMMED
-		 * phone.
-		 */
-		if ((phone->state == IPC_PHONE_CONNECTED) ||
-		    (phone->state == IPC_PHONE_SLAMMED)) {
-			mutex_unlock(&phone->lock);
-			ipc_phone_hangup(phone);
-			/*
-			 * Now there may be one extra active call, which needs
-			 * to be forgotten.
-			 */
-			ipc_forget_all_active_calls();
-			goto restart;
-		}
-
-		/*
-		 * If the hangup succeeded, it has sent a HANGUP message, the
-		 * IPC is now in HUNGUP state, we wait for the reply to come
-		 */
-		if (phone->state != IPC_PHONE_FREE) {
-			mutex_unlock(&phone->lock);
-			break;
-		}
-
-		mutex_unlock(&phone->lock);
-	}
-		
-	/* Got into cleanup */
-	if (i == IPC_MAX_PHONES)
+	restart = false;
+	if (caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
+	    phone_cap_wait_cb, &restart)) {
+		/* Got into cleanup */
 		return;
-		
+	}
+	if (restart)
+		goto restart;
+	
 	call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
 	    SYNCH_FLAGS_NONE);
-	ASSERT(call->flags & (IPC_CALL_ANSWERED | IPC_CALL_NOTIF));
+	assert(call->flags & (IPC_CALL_ANSWERED | IPC_CALL_NOTIF));
 
 	SYSIPC_OP(answer_process, call);
@@ -795,4 +821,16 @@
 	ipc_call_free(call);
 	goto restart;
+}
+
+static bool phone_cap_cleanup_cb(cap_t *cap, void *arg)
+{
+	ipc_phone_hangup(cap->kobject->phone);
+	return true;
+}
+
+static bool irq_cap_cleanup_cb(cap_t *cap, void *arg)
+{
+	ipc_irq_unsubscribe(&TASK->answerbox, cap->handle);
+	return true;
 }
 
@@ -816,12 +854,13 @@
 
 	/* Disconnect all our phones ('ipc_phone_hangup') */
-	for (size_t i = 0; i < IPC_MAX_PHONES; i++)
-		ipc_phone_hangup(&TASK->phones[i]);
+	caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
+	    phone_cap_cleanup_cb, NULL);
 	
 	/* Unsubscribe from any event notifications. */
 	event_cleanup_answerbox(&TASK->answerbox);
 	
-	/* Disconnect all connected irqs */
-	ipc_irq_cleanup(&TASK->answerbox);
+	/* Disconnect all connected IRQs */
+	caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_IRQ, irq_cap_cleanup_cb,
+	    NULL);
 	
 	/* Disconnect all phones connected to our regular answerbox */
@@ -847,8 +886,10 @@
 void ipc_init(void)
 {
-	ipc_call_slab = slab_cache_create("call_t", sizeof(call_t), 0, NULL,
+	call_slab = slab_cache_create("call_t", sizeof(call_t), 0, NULL,
 	    NULL, 0);
-	ipc_answerbox_slab = slab_cache_create("answerbox_t",
-	    sizeof(answerbox_t), 0, NULL, NULL, 0);
+	phone_slab = slab_cache_create("phone_t", sizeof(phone_t), 0, NULL,
+	    NULL, 0);
+	answerbox_slab = slab_cache_create("answerbox_t", sizeof(answerbox_t),
+	    0, NULL, NULL, 0);
 }
 
@@ -885,4 +926,39 @@
 }
 
+static bool print_task_phone_cb(cap_t *cap, void *arg)
+{
+	phone_t *phone = cap->kobject->phone;
+
+	mutex_lock(&phone->lock);
+	if (phone->state != IPC_PHONE_FREE) {
+		printf("%-11d %7" PRIun " ", cap->handle,
+		    atomic_get(&phone->active_calls));
+		
+		switch (phone->state) {
+		case IPC_PHONE_CONNECTING:
+			printf("connecting");
+			break;
+		case IPC_PHONE_CONNECTED:
+			printf("connected to %" PRIu64 " (%s)",
+			    phone->callee->task->taskid,
+			    phone->callee->task->name);
+			break;
+		case IPC_PHONE_SLAMMED:
+			printf("slammed by %p", phone->callee);
+			break;
+		case IPC_PHONE_HUNGUP:
+			printf("hung up by %p", phone->callee);
+			break;
+		default:
+			break;
+		}
+		
+		printf("\n");
+	}
+	mutex_unlock(&phone->lock);
+
+	return true;
+}
+
 /** List answerbox contents.
  *
@@ -894,53 +970,17 @@
 	irq_spinlock_lock(&tasks_lock, true);
 	task_t *task = task_find_by_id(taskid);
-	
 	if (!task) {
 		irq_spinlock_unlock(&tasks_lock, true);
 		return;
 	}
-	
-	/* Hand-over-hand locking */
-	irq_spinlock_exchange(&tasks_lock, &task->lock);
-	
-	printf("[phone id] [calls] [state\n");
-	
-	size_t i;
-	for (i = 0; i < IPC_MAX_PHONES; i++) {
-		if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) {
-			printf("%-10zu (mutex busy)\n", i);
-			continue;
-		}
-		
-		if (task->phones[i].state != IPC_PHONE_FREE) {
-			printf("%-10zu %7" PRIun " ", i,
-			    atomic_get(&task->phones[i].active_calls));
-			
-			switch (task->phones[i].state) {
-			case IPC_PHONE_CONNECTING:
-				printf("connecting");
-				break;
-			case IPC_PHONE_CONNECTED:
-				printf("connected to %" PRIu64 " (%s)",
-				    task->phones[i].callee->task->taskid,
-				    task->phones[i].callee->task->name);
-				break;
-			case IPC_PHONE_SLAMMED:
-				printf("slammed by %p",
-				    task->phones[i].callee);
-				break;
-			case IPC_PHONE_HUNGUP:
-				printf("hung up by %p",
-				    task->phones[i].callee);
-				break;
-			default:
-				break;
-			}
-			
-			printf("\n");
-		}
-		
-		mutex_unlock(&task->phones[i].lock);
-	}
-	
+	task_hold(task);
+	irq_spinlock_unlock(&tasks_lock, true);
+	
+	printf("[phone cap] [calls] [state\n");
+	
+	caps_apply_to_kobject_type(task, KOBJECT_TYPE_PHONE,
+	    print_task_phone_cb, NULL);
+	
+	irq_spinlock_lock(&task->lock, true);
 	irq_spinlock_lock(&task->answerbox.lock, false);
 	
@@ -964,4 +1004,6 @@
 	irq_spinlock_unlock(&task->answerbox.lock, false);
 	irq_spinlock_unlock(&task->lock, true);
+
+	task_release(task);
 }
 
Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
  *
  * The pattern of usage of the resources is:
- * - allocate empty phone slot, connect | deallocate slot
+ * - allocate empty phone capability slot, connect | deallocate slot
  * - disconnect connected phone (some messages might be on the fly)
  * - find phone in slot and send a message using phone
@@ -53,5 +53,5 @@
  *   atomic on all platforms)
  *
- * - To find an empty phone slot, the TASK must be locked
+ * - To find an empty phone capability slot, the TASK must be locked
  * - To answer a message, the answerbox must be locked
  * - The locking of phone and answerbox is done at the ipc_ level.
@@ -77,10 +77,10 @@
  *
  * *** Connect_to_me ***
- * The caller sends IPC_M_CONNECT_TO_ME. 
+ * The caller sends IPC_M_CONNECT_TO_ME.
  * The server receives an automatically opened phoneid. If it accepts
- * (RETVAL=0), it can use the phoneid immediately. 
- * Possible race condition can arise, when the client receives messages from new
- * connection before getting response for connect_to_me message. Userspace
- * should implement handshake protocol that would control it.
+ * (RETVAL=0), it can use the phoneid immediately.  Possible race condition can
+ * arise, when the client receives messages from new connection before getting
+ * response for connect_to_me message. Userspace should implement handshake
+ * protocol that would control it.
  *
  * Phone hangup
@@ -89,18 +89,19 @@
  * - The phone is disconnected (no more messages can be sent over this phone),
  *   all in-progress messages are correctly handled. The answerbox receives
- *   IPC_M_PHONE_HUNGUP call from the phone that hung up. When all async
- *   calls are answered, the phone is deallocated.
+ *   IPC_M_PHONE_HUNGUP call from the phone that hung up. When all async calls
+ *   are answered, the phone is deallocated.
  *
  * *** The answerbox hangs up (ipc_answer(EHANGUP))
- * - The phone is disconnected. EHANGUP response code is sent
- *   to the calling task. All new calls through this phone
- *   get a EHUNGUP error code, the task is expected to
- *   send an sys_ipc_hangup after cleaning up its internal structures.
+ * - The phone is disconnected. EHANGUP response code is sent to the calling
+ *   task. All new calls through this phone get a EHUNGUP error code, the task
+ *   is expected to send an sys_ipc_hangup after cleaning up its internal
+ *   structures.
+ *
  *
  * Call forwarding
  *
- * The call can be forwarded, so that the answer to call is passed directly
- * to the original sender. However, this poses special problems regarding 
- * routing of hangup messages.
+ * The call can be forwarded, so that the answer to call is passed directly to
+ * the original sender. However, this poses special problems regarding routing
+ * of hangup messages.
  *
  * sys_ipc_hangup -> IPC_M_PHONE_HUNGUP
@@ -131,6 +132,8 @@
 #include <proc/task.h>
 #include <ipc/ipcrsc.h>
-#include <debug.h>
+#include <assert.h>
 #include <abi/errno.h>
+#include <cap/cap.h>
+#include <mm/slab.h>
 
 /** Find call_t * in call table according to callid.
@@ -138,9 +141,8 @@
  * @todo Some speedup (hash table?)
  *
- * @param callid Userspace hash of the call. Currently it is the call
- *               structure kernel address.
- *
- * @return NULL on not found, otherwise pointer to the call
- *         structure.
+ * @param callid Userspace hash of the call. Currently it is the call structure
+ *               kernel address.
+ *
+ * @return NULL on not found, otherwise pointer to the call structure.
  *
  */
@@ -162,66 +164,63 @@
 }
 
-/** Get phone from the current task by ID.
- *
- * @param phoneid Phone ID.
- * @param phone   Place to store pointer to phone.
- *
- * @return EOK on success, EINVAL if ID is invalid.
- *
- */
-int phone_get(sysarg_t phoneid, phone_t **phone)
-{
-	if (phoneid >= IPC_MAX_PHONES)
-		return EINVAL;
-	
-	*phone = &TASK->phones[phoneid];
-	return EOK;
-}
-
-/** Allocate new phone slot in the specified task.
- *
- * @param task Task for which to allocate a new phone.
- *
- * @return New phone handle or -1 if the phone handle limit is
- *         exceeded.
- *
- */
-int phone_alloc(task_t *task)
-{
-	irq_spinlock_lock(&task->lock, true);
-	
-	size_t i;
-	for (i = 0; i < IPC_MAX_PHONES; i++) {
-		phone_t *phone = &task->phones[i];
-
-		if ((phone->state == IPC_PHONE_HUNGUP) &&
-		    (atomic_get(&phone->active_calls) == 0))
-			phone->state = IPC_PHONE_FREE;
+static bool phone_reclaim(kobject_t *kobj)
+{
+	bool gc = false;
+
+	mutex_lock(&kobj->phone->lock);
+	if (kobj->phone->state == IPC_PHONE_HUNGUP &&
+	    atomic_get(&kobj->phone->active_calls) == 0)
+		gc = true;
+	mutex_unlock(&kobj->phone->lock);
+
+	return gc;
+}
+
+static void phone_destroy(void *arg)
+{
+	phone_t *phone = (phone_t *) arg;
+	slab_free(phone_slab, phone);
+}
+
+static kobject_ops_t phone_kobject_ops = {
+	.reclaim = phone_reclaim,
+	.destroy = phone_destroy
+};
+
+
+/** Allocate new phone in the specified task.
+ *
+ * @param task  Task for which to allocate a new phone.
+ *
+ * @return  New phone capability handle.
+ * @return  Negative error code if a new capability cannot be allocated.
+ */
+cap_handle_t phone_alloc(task_t *task)
+{
+	cap_handle_t handle = cap_alloc(task);
+	if (handle >= 0) {
+		phone_t *phone = slab_alloc(phone_slab, FRAME_ATOMIC);
+		if (!phone) {
+			cap_free(TASK, handle);
+			return ENOMEM;
+		}
+		kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
+		if (!kobject) {
+			cap_free(TASK, handle);
+			slab_free(phone_slab, phone);
+			return ENOMEM;
+		}
+
+		ipc_phone_init(phone, task);
+		phone->state = IPC_PHONE_CONNECTING;
+
+		kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone,
+		    &phone_kobject_ops);
+		phone->kobject = kobject;
 		
-		if (phone->state == IPC_PHONE_FREE) {
-			phone->state = IPC_PHONE_CONNECTING;
-			break;
-		}
+		cap_publish(task, handle, kobject);
 	}
 	
-	irq_spinlock_unlock(&task->lock, true);
-	
-	if (i == IPC_MAX_PHONES)
-		return -1;
-	
-	return i;
-}
-
-/** Mark a phone structure free.
- *
- * @param phone Phone structure to be marked free.
- *
- */
-static void phone_deallocp(phone_t *phone)
-{
-	ASSERT(phone->state == IPC_PHONE_CONNECTING);
-	
-	/* Atomic operation */
-	phone->state = IPC_PHONE_FREE;
+	return handle;
 }
 
@@ -230,29 +229,36 @@
  * All already sent messages will be correctly processed.
  *
- * @param phoneid Phone handle of the phone to be freed.
- *
- */
-void phone_dealloc(int phoneid)
-{
-	phone_deallocp(&TASK->phones[phoneid]);
+ * @param handle Phone capability handle of the phone to be freed.
+ *
+ */
+void phone_dealloc(cap_handle_t handle)
+{
+	kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!kobj)
+		return;
+	
+	assert(kobj->phone);
+	assert(kobj->phone->state == IPC_PHONE_CONNECTING);
+	
+	kobject_put(kobj);
+	cap_free(TASK, handle);
 }
 
 /** Connect phone to a given answerbox.
  *
- * @param phoneid Phone handle to be connected.
- * @param box     Answerbox to which to connect the phone handle.
+ * @param handle  Capability handle of the phone to be connected.
+ * @param box     Answerbox to which to connect the phone.
  * @return        True if the phone was connected, false otherwise.
- *
- * The procedure _enforces_ that the user first marks the phone
- * busy (e.g. via phone_alloc) and then connects the phone, otherwise
- * race condition may appear.
- *
- */
-bool phone_connect(int phoneid, answerbox_t *box)
-{
-	phone_t *phone = &TASK->phones[phoneid];
-	
-	ASSERT(phone->state == IPC_PHONE_CONNECTING);
-	return ipc_phone_connect(phone, box);
+ */
+bool phone_connect(cap_handle_t handle, answerbox_t *box)
+{
+	kobject_t *phone_obj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!phone_obj)
+		return false;
+	
+	assert(phone_obj->phone->state == IPC_PHONE_CONNECTING);
+	
+	/* Hand over phone_obj reference to the answerbox */
+	return ipc_phone_connect(phone_obj->phone, box);
 }
 
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/irq.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,7 +37,8 @@
  *
  * This framework allows applications to subscribe to receive a notification
- * when interrupt is detected. The application may provide a simple 'top-half'
- * handler as part of its registration, which can perform simple operations
- * (read/write port/memory, add information to notification IPC message).
+ * when an interrupt is detected. The application may provide a simple
+ * 'top-half' handler as part of its registration, which can perform simple
+ * operations (read/write port/memory, add information to notification IPC
+ * message).
  *
  * The structure of a notification message is as follows:
@@ -50,26 +51,8 @@
  * - in_phone_hash: interrupt counter (may be needed to assure correct order
  *                  in multithreaded drivers)
- *
- * Note on synchronization for ipc_irq_subscribe(), ipc_irq_unsubscribe(),
- * ipc_irq_cleanup() and IRQ handlers:
- *
- *   By always taking all of the uspace IRQ hash table lock, IRQ structure lock
- *   and answerbox lock, we can rule out race conditions between the
- *   registration functions and also the cleanup function. Thus the observer can
- *   either see the IRQ structure present in both the hash table and the
- *   answerbox list or absent in both. Views in which the IRQ structure would be
- *   linked in the hash table but not in the answerbox list, or vice versa, are
- *   not possible.
- *
- *   By always taking the hash table lock and the IRQ structure lock, we can
- *   rule out a scenario in which we would free up an IRQ structure, which is
- *   still referenced by, for example, an IRQ handler. The locking scheme forces
- *   us to lock the IRQ structure only after any progressing IRQs on that
- *   structure are finished. Because we hold the hash table lock, we prevent new
- *   IRQs from taking new references to the IRQ structure.
- *
  */
 
 #include <arch.h>
+#include <assert.h>
 #include <mm/slab.h>
 #include <mm/page.h>
@@ -83,4 +66,5 @@
 #include <print.h>
 #include <macros.h>
+#include <cap/cap.h>
 
 static void ranges_unmap(irq_pio_range_t *ranges, size_t rangecount)
@@ -117,5 +101,5 @@
 	}
 	
-	/* Rewrite the pseudocode addresses from physical to kernel virtual. */
+	/* Rewrite the IRQ code addresses from physical to kernel virtual. */
 	for (size_t i = 0; i < cmdcount; i++) {
 		uintptr_t addr;
@@ -175,8 +159,7 @@
 }
 
-/** Statically check the top-half pseudocode
- *
- * Check the top-half pseudocode for invalid or unsafe
- * constructs.
+/** Statically check the top-half IRQ code
+ *
+ * Check the top-half IRQ code for invalid or unsafe constructs.
  *
  */
@@ -215,7 +198,7 @@
 }
 
-/** Free the top-half pseudocode.
- *
- * @param code Pointer to the top-half pseudocode.
+/** Free the top-half IRQ code.
+ *
+ * @param code Pointer to the top-half IRQ code.
  *
  */
@@ -230,9 +213,9 @@
 }
 
-/** Copy the top-half pseudocode from userspace into the kernel.
- *
- * @param ucode Userspace address of the top-half pseudocode.
- *
- * @return Kernel address of the copied pseudocode.
+/** Copy the top-half IRQ code from userspace into the kernel.
+ *
+ * @param ucode Userspace address of the top-half IRQ code.
+ *
+ * @return Kernel address of the copied IRQ code.
  *
  */
@@ -288,24 +271,31 @@
 }
 
+static void irq_destroy(void *arg)
+{
+	irq_t *irq = (irq_t *) arg;
+
+	/* Free up the IRQ code and associated structures. */
+	code_free(irq->notif_cfg.code);
+	slab_free(irq_slab, irq);
+}
+
+static kobject_ops_t irq_kobject_ops = {
+	.destroy = irq_destroy
+};
+
 /** Subscribe an answerbox as a receiving end for IRQ notifications.
  *
  * @param box     Receiving answerbox.
  * @param inr     IRQ number.
- * @param devno   Device number.
- * @param imethod Interface and method to be associated with the
- *                notification.
- * @param ucode   Uspace pointer to top-half pseudocode.
- *
- * @return EOK on success or a negative error code.
- *
- */
-int ipc_irq_subscribe(answerbox_t *box, inr_t inr, devno_t devno,
-    sysarg_t imethod, irq_code_t *ucode)
-{
-	sysarg_t key[] = {
-		(sysarg_t) inr,
-		(sysarg_t) devno
-	};
-	
+ * @param imethod Interface and method to be associated with the notification.
+ * @param ucode   Uspace pointer to top-half IRQ code.
+ *
+ * @return  IRQ capability handle.
+ * @return  Negative error code.
+ *
+ */
+int ipc_irq_subscribe(answerbox_t *box, inr_t inr, sysarg_t imethod,
+    irq_code_t *ucode)
+{
 	if ((inr < 0) || (inr > last_inr))
 		return ELIMIT;
@@ -320,10 +310,24 @@
 	
 	/*
-	 * Allocate and populate the IRQ structure.
+	 * Allocate and populate the IRQ kernel object.
 	 */
-	irq_t *irq = malloc(sizeof(irq_t), 0);
+	cap_handle_t handle = cap_alloc(TASK);
+	if (handle < 0)
+		return handle;
+	
+	irq_t *irq = (irq_t *) slab_alloc(irq_slab, FRAME_ATOMIC);
+	if (!irq) {
+		cap_free(TASK, handle);
+		return ENOMEM;
+	}
+
+	kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
+	if (!kobject) {
+		cap_free(TASK, handle);
+		slab_free(irq_slab, irq);
+		return ENOMEM;
+	}
 	
 	irq_initialize(irq);
-	irq->devno = devno;
 	irq->inr = inr;
 	irq->claim = ipc_irq_top_half_claim;
@@ -336,164 +340,54 @@
 	
 	/*
-	 * Enlist the IRQ structure in the uspace IRQ hash table and the
-	 * answerbox's list.
+	 * Insert the IRQ structure into the uspace IRQ hash table.
 	 */
 	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
-	
-	link_t *hlp = hash_table_find(&irq_uspace_hash_table, key);
-	if (hlp) {
-		irq_t *hirq = hash_table_get_instance(hlp, irq_t, link);
-		
-		/* hirq is locked */
-		irq_spinlock_unlock(&hirq->lock, false);
-		code_free(code);
-		irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
-		
-		free(irq);
-		return EEXIST;
-	}
-	
-	/* Locking is not really necessary, but paranoid */
 	irq_spinlock_lock(&irq->lock, false);
-	irq_spinlock_lock(&box->irq_lock, false);
-	
-	hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
-	list_append(&irq->notif_cfg.link, &box->irq_list);
-	
-	irq_spinlock_unlock(&box->irq_lock, false);
+	
+	irq->notif_cfg.hashed_in = true;
+	hash_table_insert(&irq_uspace_hash_table, &irq->link);
+	
 	irq_spinlock_unlock(&irq->lock, false);
 	irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
+
+	kobject_initialize(kobject, KOBJECT_TYPE_IRQ, irq, &irq_kobject_ops);
+	cap_publish(TASK, handle, kobject);
+	
+	return handle;
+}
+
+/** Unsubscribe task from IRQ notification.
+ *
+ * @param box     Answerbox associated with the notification.
+ * @param handle  IRQ capability handle.
+ *
+ * @return EOK on success or a negative error code.
+ *
+ */
+int ipc_irq_unsubscribe(answerbox_t *box, int handle)
+{
+	kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_IRQ);
+	if (!kobj)
+		return ENOENT;
+	
+	assert(kobj->irq->notif_cfg.answerbox == box);
+
+	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
+	irq_spinlock_lock(&kobj->irq->lock, false);
+	
+	if (kobj->irq->notif_cfg.hashed_in) {
+		/* Remove the IRQ from the uspace IRQ hash table. */
+		hash_table_remove_item(&irq_uspace_hash_table,
+		    &kobj->irq->link);
+		kobj->irq->notif_cfg.hashed_in = false;
+	}
+
+	irq_spinlock_unlock(&kobj->irq->lock, false);
+	irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
+
+	kobject_put(kobj);
+	cap_free(TASK, handle);
 	
 	return EOK;
-}
-
-/** Unsubscribe task from IRQ notification.
- *
- * @param box   Answerbox associated with the notification.
- * @param inr   IRQ number.
- * @param devno Device number.
- *
- * @return EOK on success or a negative error code.
- *
- */
-int ipc_irq_unsubscribe(answerbox_t *box, inr_t inr, devno_t devno)
-{
-	sysarg_t key[] = {
-		(sysarg_t) inr,
-		(sysarg_t) devno
-	};
-	
-	if ((inr < 0) || (inr > last_inr))
-		return ELIMIT;
-	
-	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
-	link_t *lnk = hash_table_find(&irq_uspace_hash_table, key);
-	if (!lnk) {
-		irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
-		return ENOENT;
-	}
-	
-	irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
-	
-	/* irq is locked */
-	irq_spinlock_lock(&box->irq_lock, false);
-	
-	ASSERT(irq->notif_cfg.answerbox == box);
-	
-	/* Remove the IRQ from the answerbox's list. */
-	list_remove(&irq->notif_cfg.link);
-	
-	/*
-	 * We need to drop the IRQ lock now because hash_table_remove() will try
-	 * to reacquire it. That basically violates the natural locking order,
-	 * but a deadlock in hash_table_remove() is prevented by the fact that
-	 * we already held the IRQ lock and didn't drop the hash table lock in
-	 * the meantime.
-	 */
-	irq_spinlock_unlock(&irq->lock, false);
-	
-	/* Remove the IRQ from the uspace IRQ hash table. */
-	hash_table_remove(&irq_uspace_hash_table, key, 2);
-	
-	irq_spinlock_unlock(&box->irq_lock, false);
-	irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
-	
-	/* Free up the pseudo code and associated structures. */
-	code_free(irq->notif_cfg.code);
-	
-	/* Free up the IRQ structure. */
-	free(irq);
-	
-	return EOK;
-}
-
-/** Disconnect all IRQ notifications from an answerbox.
- *
- * This function is effective because the answerbox contains
- * list of all irq_t structures that are subscribed to
- * send notifications to it.
- *
- * @param box Answerbox for which we want to carry out the cleanup.
- *
- */
-void ipc_irq_cleanup(answerbox_t *box)
-{
-loop:
-	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
-	irq_spinlock_lock(&box->irq_lock, false);
-	
-	while (!list_empty(&box->irq_list)) {
-		DEADLOCK_PROBE_INIT(p_irqlock);
-		
-		irq_t *irq = list_get_instance(list_first(&box->irq_list), irq_t,
-		    notif_cfg.link);
-		
-		if (!irq_spinlock_trylock(&irq->lock)) {
-			/*
-			 * Avoid deadlock by trying again.
-			 */
-			irq_spinlock_unlock(&box->irq_lock, false);
-			irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
-			DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);
-			goto loop;
-		}
-		
-		sysarg_t key[2];
-		key[0] = irq->inr;
-		key[1] = irq->devno;
-		
-		ASSERT(irq->notif_cfg.answerbox == box);
-		
-		/* Unlist from the answerbox. */
-		list_remove(&irq->notif_cfg.link);
-		
-		/*
-		 * We need to drop the IRQ lock now because hash_table_remove()
-		 * will try to reacquire it. That basically violates the natural
-		 * locking order, but a deadlock in hash_table_remove() is
-		 * prevented by the fact that we already held the IRQ lock and
-		 * didn't drop the hash table lock in the meantime.
-		 */
-		irq_spinlock_unlock(&irq->lock, false);
-		
-		/* Remove from the hash table. */
-		hash_table_remove(&irq_uspace_hash_table, key, 2);
-		
-		/*
-		 * Release both locks so that we can free the pseudo code.
-		 */
-		irq_spinlock_unlock(&box->irq_lock, false);
-		irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
-		
-		code_free(irq->notif_cfg.code);
-		free(irq);
-		
-		/* Reacquire both locks before taking another round. */
-		irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
-		irq_spinlock_lock(&box->irq_lock, false);
-	}
-	
-	irq_spinlock_unlock(&box->irq_lock, false);
-	irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
 }
 
@@ -515,10 +409,10 @@
 }
 
-/** Apply the top-half pseudo code to find out whether to accept the IRQ or not.
+/** Apply the top-half IRQ code to find out whether to accept the IRQ or not.
  *
  * @param irq IRQ structure.
  *
- * @return IRQ_ACCEPT if the interrupt is accepted by the
- *         pseudocode, IRQ_DECLINE otherwise.
+ * @return IRQ_ACCEPT if the interrupt is accepted by the IRQ code.
+ * @return IRQ_DECLINE if the interrupt is not accepted byt the IRQ code.
  *
  */
@@ -607,8 +501,8 @@
 void ipc_irq_top_half_handler(irq_t *irq)
 {
-	ASSERT(irq);
-	
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&irq->lock));
+	assert(irq);
+	
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&irq->lock));
 	
 	if (irq->notif_cfg.answerbox) {
Index: kernel/generic/src/ipc/kbox.c
===================================================================
--- kernel/generic/src/ipc/kbox.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/kbox.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -206,5 +206,5 @@
  * cleanup code.
  *
- * @return Phone id on success, or negative error code.
+ * @return Phone capability handle on success, or negative error code.
  *
  */
@@ -236,16 +236,19 @@
 	}
 	
-	int newphid = phone_alloc(TASK);
-	if (newphid < 0) {
-		mutex_unlock(&task->kb.cleanup_lock);
-		return ELIMIT;
-	}
-	
+	cap_handle_t phone_handle = phone_alloc(TASK);
+	if (phone_handle < 0) {
+		mutex_unlock(&task->kb.cleanup_lock);
+		return phone_handle;
+	}
+	
+	kobject_t *phone_obj = kobject_get(TASK, phone_handle,
+	    KOBJECT_TYPE_PHONE);
 	/* Connect the newly allocated phone to the kbox */
-	(void) ipc_phone_connect(&TASK->phones[newphid], &task->kb.box);
+	/* Hand over phone_obj's reference to ipc_phone_connect() */
+	(void) ipc_phone_connect(phone_obj->phone, &task->kb.box);
 	
 	if (task->kb.thread != NULL) {
 		mutex_unlock(&task->kb.cleanup_lock);
-		return newphid;
+		return phone_handle;
 	}
 	
@@ -263,5 +266,5 @@
 	mutex_unlock(&task->kb.cleanup_lock);
 	
-	return newphid;
+	return phone_handle;
 }
 
Index: rnel/generic/src/ipc/ops/clnestab.c
===================================================================
--- kernel/generic/src/ipc/ops/clnestab.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,88 +1,0 @@
-/*
- * Copyright (c) 2012 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 genericipc
- * @{
- */
-/** @file
- */
-
-#include <ipc/sysipc_ops.h>
-#include <ipc/ipc.h>
-#include <synch/mutex.h>
-#include <abi/errno.h>
-
-static int request_preprocess(call_t *call, phone_t *phone)
-{
-	IPC_SET_ARG5(call->data, (sysarg_t) phone);
-
-	return EOK;	
-}
-
-static int answer_cleanup(call_t *answer, ipc_data_t *olddata)
-{
-	phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
-
-	mutex_lock(&phone->lock);
-	if (phone->state == IPC_PHONE_CONNECTED) {
-		irq_spinlock_lock(&phone->callee->lock, true);
-		list_remove(&phone->link);
-		phone->state = IPC_PHONE_SLAMMED;
-		irq_spinlock_unlock(&phone->callee->lock, true);
-	}
-	mutex_unlock(&phone->lock);
-
-	return EOK;
-}
-
-static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
-{
-
-	if (IPC_GET_RETVAL(answer->data) != EOK) {
-		/*
-		 * The other party on the cloned phone rejected our request
-		 * for connection on the protocol level.  We need to break the
-		 * connection without sending IPC_M_HUNGUP back.
-		 */
-		answer_cleanup(answer, olddata);
-	}
-	
-	return EOK;
-}
-
-sysipc_ops_t ipc_m_clone_establish_ops = {
-	.request_preprocess = request_preprocess,
-	.request_forget = null_request_forget,
-	.request_process = null_request_process,
-	.answer_cleanup = answer_cleanup,
-	.answer_preprocess = answer_preprocess,
-	.answer_process = null_answer_process,
-};
-
-/** @}
- */
Index: kernel/generic/src/ipc/ops/conctmeto.c
===================================================================
--- kernel/generic/src/ipc/ops/conctmeto.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/ops/conctmeto.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,5 +1,5 @@
 /*
  * Copyright (c) 2006 Ondrej Palkovsky
- * Copyright (c) 2012 Jakub Jermar 
+ * Copyright (c) 2012 Jakub Jermar
  * All rights reserved.
  *
@@ -42,13 +42,16 @@
 static int request_preprocess(call_t *call, phone_t *phone)
 {
-	int newphid = phone_alloc(TASK);
+	cap_handle_t phone_handle = phone_alloc(TASK);
 
-	/* Remember the phoneid or the error. */
-	call->priv = newphid;
-	if (newphid < 0)
-		return ELIMIT;
-		
+	/* Remember the phone capability or the error. */
+	call->priv = phone_handle;
+	if (phone_handle < 0)
+		return phone_handle;
+
 	/* Set arg5 for server */
-	IPC_SET_ARG5(call->data, (sysarg_t) &TASK->phones[newphid]);
+	kobject_t *phone_obj = kobject_get(TASK, phone_handle,
+	    KOBJECT_TYPE_PHONE);
+	/* Hand over phone_obj's reference to ARG5 */
+	IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
 
 	return EOK;
@@ -57,5 +60,10 @@
 static int request_forget(call_t *call)
 {
-	phone_dealloc(call->priv);
+	cap_handle_t phone_handle = (cap_handle_t) call->priv;
+	phone_dealloc(phone_handle);
+	/* Hand over reference from ARG5 to phone->kobject */
+	phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
+	/* Drop phone_obj's reference */
+	kobject_put(phone->kobject);
 	return EOK;
 }
@@ -63,9 +71,14 @@
 static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
 {
+	/* Hand over reference from ARG5 to phone */
 	phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
 
 	/* If the user accepted call, connect */
-	if (IPC_GET_RETVAL(answer->data) == EOK)
+	if (IPC_GET_RETVAL(answer->data) == EOK) {
+		/* Hand over reference from phone to the answerbox */
 		(void) ipc_phone_connect(phone, &TASK->answerbox);
+	} else {
+		kobject_put(phone->kobject);
+	}
 
 	return EOK;
@@ -74,16 +87,16 @@
 static int answer_process(call_t *answer)
 {
-	int newphid = (int) answer->priv;
+	cap_handle_t phone_handle = (cap_handle_t) answer->priv;
 
 	if (IPC_GET_RETVAL(answer->data)) {
-		if (newphid >= 0) {
+		if (phone_handle >= 0) {
 			/*
 			 * The phone was indeed allocated and now needs
 			 * to be deallocated.
 			 */
-			phone_dealloc(newphid);
+			phone_dealloc(phone_handle);
 		}
 	} else {
-		IPC_SET_ARG5(answer->data, newphid);
+		IPC_SET_ARG5(answer->data, phone_handle);
 	}
 	
Index: kernel/generic/src/ipc/ops/concttome.c
===================================================================
--- kernel/generic/src/ipc/ops/concttome.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/ops/concttome.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,5 +1,5 @@
 /*
  * Copyright (c) 2006 Ondrej Palkovsky
- * Copyright (c) 2012 Jakub Jermar 
+ * Copyright (c) 2012 Jakub Jermar
  * All rights reserved.
  *
@@ -42,7 +42,7 @@
 static int request_process(call_t *call, answerbox_t *box)
 {
-	int phoneid = phone_alloc(TASK);
+	cap_handle_t phone_handle = phone_alloc(TASK);
 
-	IPC_SET_ARG5(call->data, phoneid);
+	IPC_SET_ARG5(call->data, phone_handle);
 	
 	return EOK;
@@ -51,8 +51,8 @@
 static int answer_cleanup(call_t *answer, ipc_data_t *olddata)
 {
-	int phoneid = (int) IPC_GET_ARG5(*olddata);
+	cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
 
-	if (phoneid >= 0)
-		phone_dealloc(phoneid);
+	if (phone_handle >= 0)
+		phone_dealloc(phone_handle);
 
 	return EOK;
@@ -61,15 +61,18 @@
 static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
 {
-	int phoneid = (int) IPC_GET_ARG5(*olddata);
+	cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
 
 	if (IPC_GET_RETVAL(answer->data) != EOK) {
 		/* The connection was not accepted */
 		answer_cleanup(answer, olddata);
-	} else if (phoneid >= 0) {
+	} else if (phone_handle >= 0) {
 		/* The connection was accepted */
-		if (phone_connect(phoneid, &answer->sender->answerbox)) {
-			/* Set 'phone hash' as arg5 of response */
+		if (phone_connect(phone_handle, &answer->sender->answerbox)) {
+			/* Set 'phone hash' as ARG5 of response */
+			kobject_t *phone_obj = kobject_get(TASK, phone_handle,
+			    KOBJECT_TYPE_PHONE);
 			IPC_SET_ARG5(answer->data,
-			    (sysarg_t) &TASK->phones[phoneid]);
+			    (sysarg_t) phone_obj->phone);
+			kobject_put(phone_obj);
 		} else {
 			/* The answerbox is shutting down. */
Index: rnel/generic/src/ipc/ops/connclone.c
===================================================================
--- kernel/generic/src/ipc/ops/connclone.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,144 +1,0 @@
-/*
- * Copyright (c) 2012 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 genericipc
- * @{
- */
-/** @file
- */
-
-#include <ipc/sysipc_ops.h>
-#include <ipc/ipc.h>
-#include <ipc/ipcrsc.h>
-#include <synch/mutex.h>
-#include <abi/errno.h>
-#include <arch.h>
-
-static void phones_lock(phone_t *p1, phone_t *p2)
-{
-	if (p1 < p2) {
-		mutex_lock(&p1->lock);
-		mutex_lock(&p2->lock);
-	} else if (p1 > p2) {
-		mutex_lock(&p2->lock);
-		mutex_lock(&p1->lock);
-	} else
-		mutex_lock(&p1->lock);
-}
-
-static void phones_unlock(phone_t *p1, phone_t *p2)
-{
-	mutex_unlock(&p1->lock);
-	if (p1 != p2)
-		mutex_unlock(&p2->lock);
-}
-
-static int request_preprocess(call_t *call, phone_t *phone)
-{
-	phone_t *cloned_phone;
-
-	if (phone_get(IPC_GET_ARG1(call->data), &cloned_phone) != EOK)
-		return ENOENT;
-		
-	phones_lock(cloned_phone, phone);
-		
-	if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
-	    phone->state != IPC_PHONE_CONNECTED) {
-		phones_unlock(cloned_phone, phone);
-		return EINVAL;
-	}
-		
-	/*
-	 * We can be pretty sure now that both tasks exist and we are
-	 * connected to them. As we continue to hold the phone locks,
-	 * we are effectively preventing them from finishing their
-	 * potential cleanup.
-	 *
-	 */
-	int newphid = phone_alloc(phone->callee->task);
-	if (newphid < 0) {
-		phones_unlock(cloned_phone, phone);
-		return ELIMIT;
-	}
-		
-	(void) ipc_phone_connect(&phone->callee->task->phones[newphid],
-	    cloned_phone->callee);
-	phones_unlock(cloned_phone, phone);
-		
-	/* Set the new phone for the callee. */
-	IPC_SET_ARG1(call->data, newphid);
-
-	return EOK;
-}
-
-static int answer_cleanup(call_t *answer, ipc_data_t *olddata)
-{
-	int phoneid = (int) IPC_GET_ARG1(*olddata);
-	phone_t *phone = &TASK->phones[phoneid];
-
-	/*
-	 * In this case, the connection was established at the request
-	 * time and therefore we need to slam the phone.  We don't
-	 * merely hangup as that would result in sending IPC_M_HUNGUP
-	 * to the third party on the other side of the cloned phone.
-	 */
-	mutex_lock(&phone->lock);
-	if (phone->state == IPC_PHONE_CONNECTED) {
-		irq_spinlock_lock(&phone->callee->lock, true);
-		list_remove(&phone->link);
-		phone->state = IPC_PHONE_SLAMMED;
-		irq_spinlock_unlock(&phone->callee->lock, true);
-	}
-	mutex_unlock(&phone->lock);
-
-	return EOK;
-}
-
-static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
-{
-	if (IPC_GET_RETVAL(answer->data) != EOK) {
-		/*
-		 * The recipient of the cloned phone rejected the offer.
-		 */
-		answer_cleanup(answer, olddata);
-	}
-
-	return EOK;
-}
-
-sysipc_ops_t ipc_m_connection_clone_ops = {
-	.request_preprocess = request_preprocess,
-	.request_forget = null_request_forget,
-	.request_process = null_request_process,
-	.answer_cleanup = answer_cleanup,
-	.answer_preprocess = answer_preprocess,
-	.answer_process = null_answer_process,
-};
-
-/** @}
- */
Index: kernel/generic/src/ipc/ops/dataread.c
===================================================================
--- kernel/generic/src/ipc/ops/dataread.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/ops/dataread.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,4 +33,5 @@
  */
 
+#include <assert.h>
 #include <ipc/sysipc_ops.h>
 #include <ipc/ipc.h>
@@ -58,5 +59,5 @@
 static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
 {
-	ASSERT(!answer->buffer);
+	assert(!answer->buffer);
 
 	if (!IPC_GET_RETVAL(answer->data)) {
Index: kernel/generic/src/ipc/ops/datawrite.c
===================================================================
--- kernel/generic/src/ipc/ops/datawrite.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/ops/datawrite.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,4 +33,5 @@
  */
 
+#include <assert.h>
 #include <ipc/sysipc_ops.h>
 #include <ipc/ipc.h>
@@ -70,5 +71,5 @@
 static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
 {
-	ASSERT(answer->buffer);
+	assert(answer->buffer);
 
 	if (!IPC_GET_RETVAL(answer->data)) {
Index: kernel/generic/src/ipc/ops/stchngath.c
===================================================================
--- kernel/generic/src/ipc/ops/stchngath.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/ops/stchngath.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,23 +43,26 @@
 static int request_preprocess(call_t *call, phone_t *phone)
 {
-	phone_t *sender_phone;
 	task_t *other_task_s;
 
-	if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
+	kobject_t *sender_obj = kobject_get(TASK, IPC_GET_ARG5(call->data),
+	    KOBJECT_TYPE_PHONE);
+	if (!sender_obj)
 		return ENOENT;
 
-	mutex_lock(&sender_phone->lock);
-	if (sender_phone->state != IPC_PHONE_CONNECTED) {
-		mutex_unlock(&sender_phone->lock);
+	mutex_lock(&sender_obj->phone->lock);
+	if (sender_obj->phone->state != IPC_PHONE_CONNECTED) {
+		mutex_unlock(&sender_obj->phone->lock);
+		kobject_put(sender_obj);
 		return EINVAL;
 	}
 
-	other_task_s = sender_phone->callee->task;
+	other_task_s = sender_obj->phone->callee->task;
 
-	mutex_unlock(&sender_phone->lock);
+	mutex_unlock(&sender_obj->phone->lock);
 
 	/* Remember the third party task hash. */
 	IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
 
+	kobject_put(sender_obj);
 	return EOK;
 }
@@ -71,23 +74,23 @@
 	if (!IPC_GET_RETVAL(answer->data)) {
 		/* The recipient authorized the change of state. */
-		phone_t *recipient_phone;
 		task_t *other_task_s;
 		task_t *other_task_r;
 
-		rc = phone_get(IPC_GET_ARG1(answer->data),
-		    &recipient_phone);
-		if (rc != EOK) {
+		kobject_t *recipient_obj = kobject_get(TASK,
+		    IPC_GET_ARG1(answer->data), KOBJECT_TYPE_PHONE);
+		if (!recipient_obj) {
 			IPC_SET_RETVAL(answer->data, ENOENT);
 			return ENOENT;
 		}
 
-		mutex_lock(&recipient_phone->lock);
-		if (recipient_phone->state != IPC_PHONE_CONNECTED) {
-			mutex_unlock(&recipient_phone->lock);
+		mutex_lock(&recipient_obj->phone->lock);
+		if (recipient_obj->phone->state != IPC_PHONE_CONNECTED) {
+			mutex_unlock(&recipient_obj->phone->lock);
 			IPC_SET_RETVAL(answer->data, EINVAL);
+			kobject_put(recipient_obj);
 			return EINVAL;
 		}
 
-		other_task_r = recipient_phone->callee->task;
+		other_task_r = recipient_obj->phone->callee->task;
 		other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
 
@@ -110,5 +113,6 @@
 		}
 
-		mutex_unlock(&recipient_phone->lock);
+		mutex_unlock(&recipient_obj->phone->lock);
+		kobject_put(recipient_obj);
 	}
 
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/sysipc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,6 +34,7 @@
 
 #include <arch.h>
+#include <assert.h>
 #include <errno.h>
-#include <memstr.h>
+#include <mem.h>
 #include <ipc/ipc.h>
 #include <abi/ipc/methods.h>
@@ -48,5 +49,5 @@
 #include <arch/interrupt.h>
 #include <syscall/copy.h>
-#include <security/cap.h>
+#include <security/perm.h>
 #include <console/console.h>
 #include <print.h>
@@ -84,6 +85,4 @@
 {
 	switch (imethod) {
-	case IPC_M_CONNECTION_CLONE:
-	case IPC_M_CLONE_ESTABLISH:
 	case IPC_M_PHONE_HUNGUP:
 		/* This message is meant only for the original recipient. */
@@ -134,6 +133,4 @@
 {
 	switch (IPC_GET_IMETHOD(call->data)) {
-	case IPC_M_CONNECTION_CLONE:
-	case IPC_M_CLONE_ESTABLISH:
 	case IPC_M_CONNECT_TO_ME:
 	case IPC_M_CONNECT_ME_TO:
@@ -174,5 +171,5 @@
 		return rc;
 	} else {
-		ASSERT(answer->active);
+		assert(answer->active);
 
 		/*
@@ -263,7 +260,7 @@
 /** Make a call over IPC and wait for reply.
  *
- * @param phoneid     Phone handle for the call.
- * @param data[inout] Structure with request/reply data.
- * @param priv        Value to be stored in call->priv.
+ * @param handle       Phone capability handle for the call.
+ * @param data[inout]  Structure with request/reply data.
+ * @param priv         Value to be stored in call->priv.
  *
  * @return EOK on success.
@@ -271,8 +268,8 @@
  *
  */
-int ipc_req_internal(int phoneid, ipc_data_t *data, sysarg_t priv)
-{
-	phone_t *phone;
-	if (phone_get(phoneid, &phone) != EOK)
+int ipc_req_internal(cap_handle_t handle, ipc_data_t *data, sysarg_t priv)
+{
+	kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!kobj->phone)
 		return ENOENT;
 	
@@ -281,5 +278,5 @@
 	memcpy(call->data.args, data->args, sizeof(data->args));
 	
-	int rc = request_preprocess(call, phone);
+	int rc = request_preprocess(call, kobj->phone);
 	if (!rc) {
 #ifdef CONFIG_UDEBUG
@@ -288,5 +285,5 @@
 
 		ipc_call_hold(call);
-		rc = ipc_call_sync(phone, call);
+		rc = ipc_call_sync(kobj->phone, call);
 		spinlock_lock(&call->forget_lock);
 		bool forgotten = call->forget;
@@ -313,7 +310,8 @@
 				 * We are no longer expected to free it.
 				 */
-				ASSERT(rc == EINTR);
+				assert(rc == EINTR);
 			}
-			return rc;	
+			kobject_put(kobj);
+			return rc;
 		}
 
@@ -324,4 +322,5 @@
 	memcpy(data->args, call->data.args, sizeof(data->args));
 	ipc_call_free(call);
+	kobject_put(kobj);
 	
 	return EOK;
@@ -349,10 +348,10 @@
  * the generic function sys_ipc_call_async_slow().
  *
- * @param phoneid Phone handle for the call.
- * @param imethod Interface and method of the call.
- * @param arg1    Service-defined payload argument.
- * @param arg2    Service-defined payload argument.
- * @param arg3    Service-defined payload argument.
- * @param arg4    Service-defined payload argument.
+ * @param handle   Phone capability handle for the call.
+ * @param imethod  Interface and method of the call.
+ * @param arg1     Service-defined payload argument.
+ * @param arg2     Service-defined payload argument.
+ * @param arg3     Service-defined payload argument.
+ * @param arg4     Service-defined payload argument.
  *
  * @return Call hash on success.
@@ -362,13 +361,15 @@
  *
  */
-sysarg_t sys_ipc_call_async_fast(sysarg_t phoneid, sysarg_t imethod,
+sysarg_t sys_ipc_call_async_fast(sysarg_t handle, sysarg_t imethod,
     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
 {
-	phone_t *phone;
-	if (phone_get(phoneid, &phone) != EOK)
+	kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!kobj)
 		return IPC_CALLRET_FATAL;
 	
-	if (check_call_limit(phone))
+	if (check_call_limit(kobj->phone)) {
+		kobject_put(kobj);
 		return IPC_CALLRET_TEMPORARY;
+	}
 	
 	call_t *call = ipc_call_alloc(0);
@@ -385,11 +386,12 @@
 	IPC_SET_ARG5(call->data, 0);
 	
-	int res = request_preprocess(call, phone);
+	int res = request_preprocess(call, kobj->phone);
 	
 	if (!res)
-		ipc_call(phone, call);
+		ipc_call(kobj->phone, call);
 	else
-		ipc_backsend_err(phone, call, res);
-	
+		ipc_backsend_err(kobj->phone, call, res);
+	
+	kobject_put(kobj);
 	return (sysarg_t) call;
 }
@@ -397,5 +399,5 @@
 /** Make an asynchronous IPC call allowing to transmit the entire payload.
  *
- * @param phoneid Phone handle for the call.
+ * @param handle  Phone capability for the call.
  * @param data    Userspace address of call data with the request.
  *
@@ -403,12 +405,14 @@
  *
  */
-sysarg_t sys_ipc_call_async_slow(sysarg_t phoneid, ipc_data_t *data)
-{
-	phone_t *phone;
-	if (phone_get(phoneid, &phone) != EOK)
+sysarg_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data)
+{
+	kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!kobj)
 		return IPC_CALLRET_FATAL;
 
-	if (check_call_limit(phone))
+	if (check_call_limit(kobj->phone)) {
+		kobject_put(kobj);
 		return IPC_CALLRET_TEMPORARY;
+	}
 
 	call_t *call = ipc_call_alloc(0);
@@ -417,14 +421,16 @@
 	if (rc != 0) {
 		ipc_call_free(call);
+		kobject_put(kobj);
 		return (sysarg_t) rc;
 	}
 	
-	int res = request_preprocess(call, phone);
+	int res = request_preprocess(call, kobj->phone);
 	
 	if (!res)
-		ipc_call(phone, call);
+		ipc_call(kobj->phone, call);
 	else
-		ipc_backsend_err(phone, call, res);
-	
+		ipc_backsend_err(kobj->phone, call, res);
+	
+	kobject_put(kobj);
 	return (sysarg_t) call;
 }
@@ -434,16 +440,16 @@
  * Common code for both the fast and the slow version.
  *
- * @param callid  Hash of the call to forward.
- * @param phoneid Phone handle to use for forwarding.
- * @param imethod New interface and method to use for the forwarded call.
- * @param arg1    New value of the first argument for the forwarded call.
- * @param arg2    New value of the second argument for the forwarded call.
- * @param arg3    New value of the third argument for the forwarded call.
- * @param arg4    New value of the fourth argument for the forwarded call.
- * @param arg5    New value of the fifth argument for the forwarded call.
- * @param mode    Flags that specify mode of the forward operation.
- * @param slow    If true, arg3, arg4 and arg5 are considered. Otherwise
- *                the function considers only the fast version arguments:
- *                i.e. arg1 and arg2.
+ * @param callid   Hash of the call to forward.
+ * @param handle   Phone capability to use for forwarding.
+ * @param imethod  New interface and method to use for the forwarded call.
+ * @param arg1     New value of the first argument for the forwarded call.
+ * @param arg2     New value of the second argument for the forwarded call.
+ * @param arg3     New value of the third argument for the forwarded call.
+ * @param arg4     New value of the fourth argument for the forwarded call.
+ * @param arg5     New value of the fifth argument for the forwarded call.
+ * @param mode     Flags that specify mode of the forward operation.
+ * @param slow     If true, arg3, arg4 and arg5 are considered. Otherwise
+ *                 the function considers only the fast version arguments:
+ *                 i.e. arg1 and arg2.
  *
  * @return 0 on succes, otherwise an error code.
@@ -452,5 +458,5 @@
  *
  */
-static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t phoneid,
+static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t handle,
     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow)
@@ -467,7 +473,7 @@
 	bool after_forward = false;
 	int rc;
-	phone_t *phone;
-	
-	if (phone_get(phoneid, &phone) != EOK) {
+
+	kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!kobj) {
 		rc = ENOENT;
 		goto error;
@@ -515,5 +521,5 @@
 	}
 	
-	rc = ipc_forward(call, phone, &TASK->answerbox, mode);
+	rc = ipc_forward(call, kobj->phone, &TASK->answerbox, mode);
 	if (rc != EOK) {
 		after_forward = true;
@@ -521,4 +527,5 @@
 	}
 
+	kobject_put(kobj);
 	return EOK;
 
@@ -531,4 +538,6 @@
 		ipc_answer(&TASK->answerbox, call);
 
+	if (kobj)
+		kobject_put(kobj);
 	return rc;
 }
@@ -543,18 +552,18 @@
  * arguments are not set and these values are ignored.
  *
- * @param callid  Hash of the call to forward.
- * @param phoneid Phone handle to use for forwarding.
- * @param imethod New interface and method to use for the forwarded call.
- * @param arg1    New value of the first argument for the forwarded call.
- * @param arg2    New value of the second argument for the forwarded call.
- * @param mode    Flags that specify mode of the forward operation.
+ * @param callid   Hash of the call to forward.
+ * @param handle   Phone handle to use for forwarding.
+ * @param imethod  New interface and method to use for the forwarded call.
+ * @param arg1     New value of the first argument for the forwarded call.
+ * @param arg2     New value of the second argument for the forwarded call.
+ * @param mode     Flags that specify mode of the forward operation.
  *
  * @return 0 on succes, otherwise an error code.
  *
  */
-sysarg_t sys_ipc_forward_fast(sysarg_t callid, sysarg_t phoneid,
+sysarg_t sys_ipc_forward_fast(sysarg_t callid, sysarg_t handle,
     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
 {
-	return sys_ipc_forward_common(callid, phoneid, imethod, arg1, arg2, 0, 0,
+	return sys_ipc_forward_common(callid, handle, imethod, arg1, arg2, 0, 0,
 	    0, mode, false); 
 }
@@ -570,5 +579,5 @@
  *
  * @param callid  Hash of the call to forward.
- * @param phoneid Phone handle to use for forwarding.
+ * @param handle  Phone handle to use for forwarding.
  * @param data    Userspace address of the new IPC data.
  * @param mode    Flags that specify mode of the forward operation.
@@ -577,5 +586,5 @@
  *
  */
-sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t phoneid,
+sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t handle,
     ipc_data_t *data, unsigned int mode)
 {
@@ -586,5 +595,5 @@
 		return (sysarg_t) rc;
 	
-	return sys_ipc_forward_common(callid, phoneid,
+	return sys_ipc_forward_common(callid, handle,
 	    IPC_GET_IMETHOD(newdata), IPC_GET_ARG1(newdata),
 	    IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata),
@@ -684,19 +693,21 @@
 /** Hang up a phone.
  *
- * @param Phone handle of the phone to be hung up.
+ * @param handle  Phone capability handle of the phone to be hung up.
  *
  * @return 0 on success or an error code.
  *
  */
-sysarg_t sys_ipc_hangup(sysarg_t phoneid)
-{
-	phone_t *phone;
-	
-	if (phone_get(phoneid, &phone) != EOK)
+sysarg_t sys_ipc_hangup(sysarg_t handle)
+{
+	kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!kobj)
 		return ENOENT;
 	
-	if (ipc_phone_hangup(phone))
+	if (ipc_phone_hangup(kobj->phone)) {
+		kobject_put(kobj);
 		return -1;
-	
+	}
+	
+	kobject_put(kobj);
 	return 0;
 }
@@ -755,5 +766,5 @@
 		}
 		
-		STRUCT_TO_USPACE(&calldata->args, &call->data.args);
+		STRUCT_TO_USPACE(calldata, &call->data);
 		ipc_call_free(call);
 		
@@ -801,18 +812,18 @@
  *
  * @param inr     IRQ number.
- * @param devno   Device number.
  * @param imethod Interface and method to be associated with the notification.
  * @param ucode   Uspace pointer to the top-half pseudocode.
  *
- * @return EPERM or a return code returned by ipc_irq_subscribe().
- *
- */
-sysarg_t sys_ipc_irq_subscribe(inr_t inr, devno_t devno, sysarg_t imethod,
-    irq_code_t *ucode)
-{
-	if (!(cap_get(TASK) & CAP_IRQ_REG))
+ * @return IRQ kernel object capability
+ * @return EPERM
+ * @return Error code returned by ipc_irq_subscribe().
+ *
+ */
+sysarg_t sys_ipc_irq_subscribe(inr_t inr, sysarg_t imethod, irq_code_t *ucode)
+{
+	if (!(perm_get(TASK) & PERM_IRQ_REG))
 		return EPERM;
 	
-	return ipc_irq_subscribe(&TASK->answerbox, inr, devno, imethod, ucode);
+	return ipc_irq_subscribe(&TASK->answerbox, inr, imethod, ucode);
 }
 
@@ -825,10 +836,10 @@
  *
  */
-sysarg_t sys_ipc_irq_unsubscribe(inr_t inr, devno_t devno)
-{
-	if (!(cap_get(TASK) & CAP_IRQ_REG))
+sysarg_t sys_ipc_irq_unsubscribe(sysarg_t cap)
+{
+	if (!(perm_get(TASK) & PERM_IRQ_REG))
 		return EPERM;
 	
-	ipc_irq_unsubscribe(&TASK->answerbox, inr, devno);
+	ipc_irq_unsubscribe(&TASK->answerbox, cap);
 	
 	return 0;
Index: kernel/generic/src/ipc/sysipc_ops.c
===================================================================
--- kernel/generic/src/ipc/sysipc_ops.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/ipc/sysipc_ops.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,6 +38,4 @@
 
 /* Forward declarations. */
-sysipc_ops_t ipc_m_connection_clone_ops;
-sysipc_ops_t ipc_m_clone_establish_ops;
 sysipc_ops_t ipc_m_connect_to_me_ops;
 sysipc_ops_t ipc_m_connect_me_to_ops;
@@ -51,6 +49,4 @@
 
 static sysipc_ops_t *sysipc_ops[] = {
-	[IPC_M_CONNECTION_CLONE] = &ipc_m_connection_clone_ops,
-	[IPC_M_CLONE_ESTABLISH] = &ipc_m_clone_establish_ops,
 	[IPC_M_CONNECT_TO_ME] = &ipc_m_connect_to_me_ops,
 	[IPC_M_CONNECT_ME_TO] = &ipc_m_connect_me_to_ops,
Index: kernel/generic/src/lib/elf.c
===================================================================
--- kernel/generic/src/lib/elf.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/lib/elf.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,6 +37,6 @@
  */
 
+#include <assert.h>
 #include <lib/elf.h>
-#include <debug.h>
 #include <typedefs.h>
 #include <mm/as.h>
@@ -44,5 +44,4 @@
 #include <mm/slab.h>
 #include <align.h>
-#include <memstr.h>
 #include <macros.h>
 #include <arch.h>
@@ -139,5 +138,5 @@
 const char *elf_error(unsigned int rc)
 {
-	ASSERT(rc < sizeof(error_codes) / sizeof(char *));
+	assert(rc < sizeof(error_codes) / sizeof(char *));
 	
 	return error_codes[rc];
Index: kernel/generic/src/lib/gsort.c
===================================================================
--- kernel/generic/src/lib/gsort.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/src/lib/gsort.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2005 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
+ * @brief Sorting functions.
+ *
+ * This files contains functions implementing several sorting
+ * algorithms (e.g. quick sort and gnome sort).
+ *
+ */
+
+#include <gsort.h>
+#include <mem.h>
+#include <mm/slab.h>
+
+/** Immediate buffer size.
+ *
+ * For small buffer sizes avoid doing malloc()
+ * and use the stack.
+ *
+ */
+#define IBUF_SIZE  32
+
+/** Array accessor.
+ *
+ */
+#define INDEX(buf, i, elem_size)  ((buf) + (i) * (elem_size))
+
+/** Gnome sort
+ *
+ * Apply generic gnome sort algorithm on supplied data,
+ * using pre-allocated buffer.
+ *
+ * @param data      Pointer to data to be sorted.
+ * @param cnt       Number of elements to be sorted.
+ * @param elem_size Size of one element.
+ * @param cmp       Comparator function.
+ * @param arg       3rd argument passed to cmp.
+ * @param slot      Pointer to scratch memory buffer
+ *                  elem_size bytes long.
+ *
+ */
+static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
+    void *arg, void *slot)
+{
+	size_t i = 0;
+	
+	while (i < cnt) {
+		if ((i != 0) &&
+		    (cmp(INDEX(data, i, elem_size),
+		    INDEX(data, i - 1, elem_size), arg) == -1)) {
+			memcpy(slot, INDEX(data, i, elem_size), elem_size);
+			memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
+			    elem_size);
+			memcpy(INDEX(data, i - 1, elem_size), slot, elem_size);
+			i--;
+		} else
+			i++;
+	}
+}
+
+/** Gnome sort wrapper
+ *
+ * This is only a wrapper that takes care of memory
+ * allocations for storing the slot element for generic
+ * gnome sort algorithm.
+ *
+ * @param data      Pointer to data to be sorted.
+ * @param cnt       Number of elements to be sorted.
+ * @param elem_size Size of one element.
+ * @param cmp       Comparator function.
+ * @param arg       3rd argument passed to cmp.
+ *
+ * @return True if sorting succeeded.
+ *
+ */
+bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
+{
+	uint8_t ibuf_slot[IBUF_SIZE];
+	void *slot;
+	
+	if (elem_size > IBUF_SIZE) {
+		slot = (void *) malloc(elem_size, 0);
+		if (!slot)
+			return false;
+	} else
+		slot = (void *) ibuf_slot;
+	
+	_gsort(data, cnt, elem_size, cmp, arg, slot);
+	
+	if (elem_size > IBUF_SIZE)
+		free(slot);
+	
+	return true;
+}
+
+/** @}
+ */
Index: kernel/generic/src/lib/mem.c
===================================================================
--- kernel/generic/src/lib/mem.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/src/lib/mem.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * 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 generic
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Memory string operations.
+ *
+ * This file provides architecture independent functions to manipulate blocks
+ * of memory. These functions are optimized as much as generic functions of
+ * this type can be.
+ */
+
+#include <mem.h>
+#include <typedefs.h>
+
+/** Fill block of memory.
+ *
+ * Fill cnt bytes at dst address with the value val.
+ *
+ * @param dst Destination address to fill.
+ * @param cnt Number of bytes to fill.
+ * @param val Value to fill.
+ *
+ */
+void memsetb(void *dst, size_t cnt, uint8_t val)
+{
+	memset(dst, val, cnt);
+}
+
+/** Fill block of memory.
+ *
+ * Fill cnt words at dst address with the value val. The filling
+ * is done word-by-word.
+ *
+ * @param dst Destination address to fill.
+ * @param cnt Number of words to fill.
+ * @param val Value to fill.
+ *
+ */
+void memsetw(void *dst, size_t cnt, uint16_t val)
+{
+	size_t i;
+	uint16_t *ptr = (uint16_t *) dst;
+	
+	for (i = 0; i < cnt; i++)
+		ptr[i] = val;
+}
+
+/** Move memory block with possible overlapping.
+ *
+ * Copy cnt bytes from src address to dst address. The source
+ * and destination memory areas may overlap.
+ *
+ * @param dst Destination address to copy to.
+ * @param src Source address to copy from.
+ * @param cnt Number of bytes to copy.
+ *
+ * @return Destination address.
+ *
+ */
+void *memmove(void *dst, const void *src, size_t cnt)
+{
+	/* Nothing to do? */
+	if (src == dst)
+		return dst;
+	
+	/* Non-overlapping? */
+	if ((dst >= src + cnt) || (src >= dst + cnt))
+		return memcpy(dst, src, cnt);
+	
+	uint8_t *dp;
+	const uint8_t *sp;
+	
+	/* Which direction? */
+	if (src > dst) {
+		/* Forwards. */
+		dp = dst;
+		sp = src;
+		
+		while (cnt-- != 0)
+			*dp++ = *sp++;
+	} else {
+		/* Backwards. */
+		dp = dst + (cnt - 1);
+		sp = src + (cnt - 1);
+		
+		while (cnt-- != 0)
+			*dp-- = *sp--;
+	}
+	
+	return dst;
+}
+
+/** @}
+ */
Index: rnel/generic/src/lib/memstr.c
===================================================================
--- kernel/generic/src/lib/memstr.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,125 +1,0 @@
-/*
- * Copyright (c) 2001-2004 Jakub Jermar
- * 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 generic
- * @{
- */
-
-/**
- * @file
- * @brief Memory string operations.
- *
- * This file provides architecture independent functions to manipulate blocks
- * of memory. These functions are optimized as much as generic functions of
- * this type can be.
- */
-
-#include <memstr.h>
-#include <typedefs.h>
-
-/** Fill block of memory.
- *
- * Fill cnt bytes at dst address with the value val.
- *
- * @param dst Destination address to fill.
- * @param cnt Number of bytes to fill.
- * @param val Value to fill.
- *
- */
-void memsetb(void *dst, size_t cnt, uint8_t val)
-{
-	memset(dst, val, cnt);
-}
-
-/** Fill block of memory.
- *
- * Fill cnt words at dst address with the value val. The filling
- * is done word-by-word.
- *
- * @param dst Destination address to fill.
- * @param cnt Number of words to fill.
- * @param val Value to fill.
- *
- */
-void memsetw(void *dst, size_t cnt, uint16_t val)
-{
-	size_t i;
-	uint16_t *ptr = (uint16_t *) dst;
-	
-	for (i = 0; i < cnt; i++)
-		ptr[i] = val;
-}
-
-/** Move memory block with possible overlapping.
- *
- * Copy cnt bytes from src address to dst address. The source
- * and destination memory areas may overlap.
- *
- * @param dst Destination address to copy to.
- * @param src Source address to copy from.
- * @param cnt Number of bytes to copy.
- *
- * @return Destination address.
- *
- */
-void *memmove(void *dst, const void *src, size_t cnt)
-{
-	/* Nothing to do? */
-	if (src == dst)
-		return dst;
-	
-	/* Non-overlapping? */
-	if ((dst >= src + cnt) || (src >= dst + cnt))
-		return memcpy(dst, src, cnt);
-	
-	uint8_t *dp;
-	const uint8_t *sp;
-	
-	/* Which direction? */
-	if (src > dst) {
-		/* Forwards. */
-		dp = dst;
-		sp = src;
-		
-		while (cnt-- != 0)
-			*dp++ = *sp++;
-	} else {
-		/* Backwards. */
-		dp = dst + (cnt - 1);
-		sp = src + (cnt - 1);
-		
-		while (cnt-- != 0)
-			*dp-- = *sp--;
-	}
-	
-	return dst;
-}
-
-/** @}
- */
Index: kernel/generic/src/lib/ra.c
===================================================================
--- kernel/generic/src/lib/ra.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/lib/ra.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,11 +43,12 @@
  */
 
+#include <assert.h>
 #include <lib/ra.h>
 #include <typedefs.h>
 #include <mm/slab.h>
 #include <bitops.h>
-#include <debug.h>
 #include <panic.h>
 #include <adt/list.h>
+#include <adt/hash.h>
 #include <adt/hash_table.h>
 #include <align.h>
@@ -57,23 +58,30 @@
 static slab_cache_t *ra_segment_cache;
 
-#define USED_BUCKETS	1024
-
-static size_t used_hash(sysarg_t *key)
-{
-	return ((*key >> 2) & (USED_BUCKETS - 1));
-}
-
-static bool used_compare(sysarg_t *key, size_t keys, link_t *item)
-{
-	ra_segment_t *seg;
-
-	seg = hash_table_get_instance(item, ra_segment_t, fu_link);
-	return seg->base == *key;
-}
-
-static hash_table_operations_t used_ops = {
+/** Return the hash of the key stored in the item */
+static size_t used_hash(const ht_link_t *item)
+{
+	ra_segment_t *seg = hash_table_get_inst(item, ra_segment_t, uh_link);
+	return hash_mix(seg->base);
+}
+
+/** Return the hash of the key */
+static size_t used_key_hash(void *key)
+{
+	uintptr_t *base = (uintptr_t *) key;
+	return hash_mix(*base);
+}
+
+/** Return true if the key is equal to the item's lookup key */
+static bool used_key_equal(void *key, const ht_link_t *item)
+{
+	uintptr_t *base = (uintptr_t *) key;
+	ra_segment_t *seg = hash_table_get_inst(item, ra_segment_t, uh_link);
+	return seg->base == *base;
+}
+
+static hash_table_ops_t used_ops = {
 	.hash = used_hash,
-	.compare = used_compare,
-	.remove_callback = NULL,
+	.key_hash = used_key_hash,
+	.key_equal = used_key_equal
 };
 
@@ -97,5 +105,5 @@
 
 	link_initialize(&seg->segment_link);
-	link_initialize(&seg->fu_link);
+	link_initialize(&seg->fl_link);
 
 	seg->base = base;
@@ -160,5 +168,5 @@
 	list_initialize(&span->segments);
 
-	hash_table_create(&span->used, USED_BUCKETS, 1, &used_ops);
+	hash_table_create(&span->used, 0, 0, &used_ops);
 
 	for (i = 0; i <= span->max_order; i++)
@@ -171,7 +179,23 @@
 
 	/* Insert the first segment into the respective free list. */
-	list_append(&seg->fu_link, &span->free[span->max_order]);
+	list_append(&seg->fl_link, &span->free[span->max_order]);
 
 	return span;
+}
+
+static void ra_span_destroy(ra_span_t *span)
+{
+	hash_table_destroy(&span->used);
+
+	list_foreach_safe(span->segments, cur, next) {
+		ra_segment_t *seg = list_get_instance(cur, ra_segment_t,
+		    segment_link);
+		list_remove(&seg->segment_link);
+		if (seg->flags & RA_SEGMENT_FREE)
+			list_remove(&seg->fl_link);
+		ra_segment_destroy(seg);
+	}
+
+	free(span);
 }
 
@@ -191,16 +215,23 @@
 }
 
+void ra_arena_destroy(ra_arena_t *arena)
+{
+	/*
+	 * No locking necessary as this is the cleanup and all users should have
+	 * stopped using the arena already.
+	 */
+	list_foreach_safe(arena->spans, cur, next) {
+		ra_span_t *span = list_get_instance(cur, ra_span_t, span_link);
+		list_remove(&span->span_link);
+		ra_span_destroy(span);
+	}
+
+	free(arena);
+}
+
 /** Add a span to arena. */
 bool ra_span_add(ra_arena_t *arena, uintptr_t base, size_t size)
 {
 	ra_span_t *span;
-
-	/*
-	 * At the moment, we can only create resources that don't include 0.
-	 * If 0 needs to be considered as a valid resource, we would need to
-	 * slightly change the API of the resource allocator.
-	 */
-	if (base == 0)
-		return false;
 
 	span = ra_span_create(base, size);
@@ -215,5 +246,6 @@
 }
 
-static uintptr_t ra_span_alloc(ra_span_t *span, size_t size, size_t align)
+static bool
+ra_span_alloc(ra_span_t *span, size_t size, size_t align, uintptr_t *base)
 {
 	/*
@@ -239,7 +271,7 @@
 		/* Take the first segment from the free list. */
 		seg = list_get_instance(list_first(&span->free[order]),
-		    ra_segment_t, fu_link);
-
-		ASSERT(seg->flags & RA_SEGMENT_FREE);
+		    ra_segment_t, fl_link);
+
+		assert(seg->flags & RA_SEGMENT_FREE);
 
 		/*
@@ -259,5 +291,5 @@
 		newbase = ALIGN_UP(seg->base, align);
 		if (newbase + size != seg->base + ra_segment_size_get(seg)) {
-			ASSERT(newbase + (size - 1) < seg->base +
+			assert(newbase + (size - 1) < seg->base +
 			    (ra_segment_size_get(seg) - 1));
 			succ = ra_segment_create(newbase + size);
@@ -281,5 +313,5 @@
 			    &seg->segment_link);
 			pred_order = fnzb(ra_segment_size_get(pred));
-			list_append(&pred->fu_link, &span->free[pred_order]);
+			list_append(&pred->fl_link, &span->free[pred_order]);
 		}
 		if (succ) {
@@ -289,20 +321,20 @@
 			    &seg->segment_link);
 			succ_order = fnzb(ra_segment_size_get(succ));
-			list_append(&succ->fu_link, &span->free[succ_order]);
+			list_append(&succ->fl_link, &span->free[succ_order]);
 		}
 
 		/* Now remove the found segment from the free list. */
-		list_remove(&seg->fu_link);
+		list_remove(&seg->fl_link);
 		seg->base = newbase;
 		seg->flags &= ~RA_SEGMENT_FREE;
 
 		/* Hash-in the segment into the used hash. */
-		sysarg_t key = seg->base;
-		hash_table_insert(&span->used, &key, &seg->fu_link);
-
-		return newbase;
-	}
-
-	return 0;
+		hash_table_insert(&span->used, &seg->uh_link);
+
+		*base = newbase;
+		return true;
+	}
+
+	return false;
 }
 
@@ -310,5 +342,5 @@
 {
 	sysarg_t key = base;
-	link_t *link;
+	ht_link_t *link;
 	ra_segment_t *seg;
 	ra_segment_t *pred;
@@ -324,14 +356,14 @@
 		    PRIxn ", size=%" PRIdn ").", base, size);
 	}
-	seg = hash_table_get_instance(link, ra_segment_t, fu_link);
+	seg = hash_table_get_inst(link, ra_segment_t, uh_link);
 
 	/*
 	 * Hash out the segment.
 	 */
-	hash_table_remove(&span->used, &key, 1);
-
-	ASSERT(!(seg->flags & RA_SEGMENT_FREE));
-	ASSERT(seg->base == base);
-	ASSERT(ra_segment_size_get(seg) == size);
+	hash_table_remove_item(&span->used, link);
+
+	assert(!(seg->flags & RA_SEGMENT_FREE));
+	assert(seg->base == base);
+	assert(ra_segment_size_get(seg) == size);
 
 	/*
@@ -339,8 +371,8 @@
 	 */
 	if (list_first(&span->segments) != &seg->segment_link) {
-		pred = hash_table_get_instance(seg->segment_link.prev,
+		pred = hash_table_get_inst(seg->segment_link.prev,
 		    ra_segment_t, segment_link);
 
-		ASSERT(pred->base < seg->base);
+		assert(pred->base < seg->base);
 
 		if (pred->flags & RA_SEGMENT_FREE) {
@@ -351,5 +383,5 @@
 			 * away.
 			 */
-			list_remove(&pred->fu_link);
+			list_remove(&pred->fl_link);
 			list_remove(&pred->segment_link);
 			seg->base = pred->base;
@@ -361,7 +393,7 @@
 	 * Check whether the segment can be coalesced with its right neighbor.
 	 */
-	succ = hash_table_get_instance(seg->segment_link.next, ra_segment_t,
+	succ = hash_table_get_inst(seg->segment_link.next, ra_segment_t,
 	    segment_link);
-	ASSERT(succ->base > seg->base);
+	assert(succ->base > seg->base);
 	if (succ->flags & RA_SEGMENT_FREE) {
 		/*
@@ -370,5 +402,5 @@
 		 * and throw it away.
 		 */
-		list_remove(&succ->fu_link);
+		list_remove(&succ->fl_link);
 		list_remove(&succ->segment_link);
 		ra_segment_destroy(succ);
@@ -378,25 +410,26 @@
 	seg->flags |= RA_SEGMENT_FREE;
 	order = fnzb(ra_segment_size_get(seg));
-	list_append(&seg->fu_link, &span->free[order]);
+	list_append(&seg->fl_link, &span->free[order]);
 }
 
 /** Allocate resources from arena. */
-uintptr_t ra_alloc(ra_arena_t *arena, size_t size, size_t alignment)
-{
-	uintptr_t base = 0;
-
-	ASSERT(size >= 1);
-	ASSERT(alignment >= 1);
-	ASSERT(ispwr2(alignment));
+bool
+ra_alloc(ra_arena_t *arena, size_t size, size_t alignment, uintptr_t *base)
+{
+	bool success = false;
+
+	assert(size >= 1);
+	assert(alignment >= 1);
+	assert(ispwr2(alignment));
 
 	irq_spinlock_lock(&arena->lock, true);
 	list_foreach(arena->spans, span_link, ra_span_t, span) {
-		base = ra_span_alloc(span, size, alignment);
-		if (base)
+		success = ra_span_alloc(span, size, alignment, base);
+		if (success)
 			break;
 	}
 	irq_spinlock_unlock(&arena->lock, true);
 
-	return base;
+	return success;
 }
 
Index: kernel/generic/src/lib/rd.c
===================================================================
--- kernel/generic/src/lib/rd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/lib/rd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
  */
 
+#include <assert.h>
 #include <log.h>
 #include <lib/rd.h>
@@ -56,5 +57,5 @@
 {
 	uintptr_t base = (uintptr_t) data;
-	ASSERT((base % FRAME_SIZE) == 0);
+	assert((base % FRAME_SIZE) == 0);
 	
 	rd_parea.pbase = base;
Index: rnel/generic/src/lib/sort.c
===================================================================
--- kernel/generic/src/lib/sort.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,227 +1,0 @@
-/*
- * Copyright (c) 2005 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
- * @brief Sorting functions.
- *
- * This files contains functions implementing several sorting
- * algorithms (e.g. quick sort and gnome sort).
- *
- */
-
-#include <mm/slab.h>
-#include <memstr.h>
-#include <sort.h>
-
-/** Immediate buffer size.
- *
- * For small buffer sizes avoid doing malloc()
- * and use the stack.
- *
- */
-#define IBUF_SIZE  32
-
-/** Array accessor.
- *
- */
-#define INDEX(buf, i, elem_size)  ((buf) + (i) * (elem_size))
-
-/** Gnome sort
- *
- * Apply generic gnome sort algorithm on supplied data,
- * using pre-allocated buffer.
- *
- * @param data      Pointer to data to be sorted.
- * @param cnt       Number of elements to be sorted.
- * @param elem_size Size of one element.
- * @param cmp       Comparator function.
- * @param arg       3rd argument passed to cmp.
- * @param slot      Pointer to scratch memory buffer
- *                  elem_size bytes long.
- *
- */
-static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
-    void *arg, void *slot)
-{
-	size_t i = 0;
-	
-	while (i < cnt) {
-		if ((i > 0) &&
-		    (cmp(INDEX(data, i, elem_size),
-		    INDEX(data, i - 1, elem_size), arg) == -1)) {
-			memcpy(slot, INDEX(data, i, elem_size), elem_size);
-			memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
-			    elem_size);
-			memcpy(INDEX(data, i - 1, elem_size), slot, elem_size);
-			i--;
-		} else
-			i++;
-	}
-}
-
-/** Quicksort
- *
- * Apply generic quicksort algorithm on supplied data,
- * using pre-allocated buffers.
- *
- * @param data      Pointer to data to be sorted.
- * @param cnt       Number of elements to be sorted.
- * @param elem_size Size of one element.
- * @param cmp       Comparator function.
- * @param arg       3rd argument passed to cmp.
- * @param slot      Pointer to scratch memory buffer
- *                  elem_size bytes long.
- * @param pivot     Pointer to scratch memory buffer
- *                  elem_size bytes long.
- *
- */
-static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
-    void *arg, void *slot, void *pivot)
-{
-	if (cnt > 4) {
-		size_t i = 0;
-		size_t j = cnt - 1;
-		
-		memcpy(pivot, data, elem_size);
-		
-		while (true) {
-			while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))
-				i++;
-			
-			while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
-				j--;
-			
-			if (i < j) {
-				memcpy(slot, INDEX(data, i, elem_size), elem_size);
-				memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size),
-				    elem_size);
-				memcpy(INDEX(data, j, elem_size), slot, elem_size);
-			} else
-				break;
-		}
-		
-		_qsort(data, j + 1, elem_size, cmp, arg, slot, pivot);
-		_qsort(INDEX(data, j + 1, elem_size), cnt - j - 1, elem_size,
-		    cmp, arg, slot, pivot);
-	} else
-		_gsort(data, cnt, elem_size, cmp, arg, slot);
-}
-
-/** Gnome sort wrapper
- *
- * This is only a wrapper that takes care of memory
- * allocations for storing the slot element for generic
- * gnome sort algorithm.
- *
- * This function can sleep.
- *
- * @param data      Pointer to data to be sorted.
- * @param cnt       Number of elements to be sorted.
- * @param elem_size Size of one element.
- * @param cmp       Comparator function.
- * @param arg       3rd argument passed to cmp.
- *
- * @return True if sorting succeeded.
- *
- */
-bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
-{
-	uint8_t ibuf_slot[IBUF_SIZE];
-	void *slot;
-	
-	if (elem_size > IBUF_SIZE) {
-		slot = (void *) malloc(elem_size, 0);
-		if (!slot)
-			return false;
-	} else
-		slot = (void *) ibuf_slot;
-	
-	_gsort(data, cnt, elem_size, cmp, arg, slot);
-	
-	if (elem_size > IBUF_SIZE)
-		free(slot);
-	
-	return true;
-}
-
-/** Quicksort wrapper
- *
- * This is only a wrapper that takes care of memory
- * allocations for storing the pivot and temporary elements
- * for generic quicksort algorithm.
- *
- * This function can sleep.
- *
- * @param data      Pointer to data to be sorted.
- * @param cnt       Number of elements to be sorted.
- * @param elem_size Size of one element.
- * @param cmp       Comparator function.
- * @param arg       3rd argument passed to cmp.
- *
- * @return True if sorting succeeded.
- *
- */
-bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
-{
-	uint8_t ibuf_slot[IBUF_SIZE];
-	uint8_t ibuf_pivot[IBUF_SIZE];
-	void *slot;
-	void *pivot;
-	
-	if (elem_size > IBUF_SIZE) {
-		slot = (void *) malloc(elem_size, 0);
-		if (!slot)
-			return false;
-		
-		pivot = (void *) malloc(elem_size, 0);
-		if (!pivot) {
-			free(slot);
-			return false;
-		}
-	} else {
-		slot = (void *) ibuf_slot;
-		pivot = (void *) ibuf_pivot;
-	}
-	
-	_qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
-	
-	if (elem_size > IBUF_SIZE) {
-		free(pivot);
-		free(slot);
-	}
-	
-	return true;
-}
-
-/** @}
- */
Index: kernel/generic/src/lib/str.c
===================================================================
--- kernel/generic/src/lib/str.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/lib/str.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -109,5 +109,5 @@
 #include <errno.h>
 #include <align.h>
-#include <debug.h>
+#include <assert.h>
 #include <macros.h>
 #include <mm/slab.h>
@@ -567,6 +567,6 @@
 {
 	/* There must be space for a null terminator in the buffer. */
-	ASSERT(size > 0);
-	ASSERT(src != NULL);
+	assert(size > 0);
+	assert(src != NULL);
 	
 	size_t src_off = 0;
@@ -601,5 +601,5 @@
 {
 	/* There must be space for a null terminator in the buffer. */
-	ASSERT(size > 0);
+	assert(size > 0);
 	
 	size_t src_off = 0;
@@ -635,5 +635,5 @@
 	size_t size = str_size(src) + 1;
 	char *dest = malloc(size, 0);
-	ASSERT(dest);
+	assert(dest);
 	
 	str_cpy(dest, size, src);
@@ -668,5 +668,5 @@
 	
 	char *dest = malloc(size + 1, 0);
-	ASSERT(dest);
+	assert(dest);
 	
 	str_ncpy(dest, size + 1, src, size);
@@ -691,5 +691,5 @@
 
 	/* There must be space for a null terminator in the buffer. */
-	ASSERT(size > 0);
+	assert(size > 0);
 
 	src_idx = 0;
@@ -797,7 +797,7 @@
     bool *neg, uint64_t *result)
 {
-	ASSERT(endptr != NULL);
-	ASSERT(neg != NULL);
-	ASSERT(result != NULL);
+	assert(endptr != NULL);
+	assert(neg != NULL);
+	assert(result != NULL);
 	
 	*neg = false;
@@ -918,5 +918,5 @@
     bool strict, uint64_t *result)
 {
-	ASSERT(result != NULL);
+	assert(result != NULL);
 	
 	bool neg;
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/main/kinit.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,4 +42,5 @@
  */
 
+#include <assert.h>
 #include <main/kinit.h>
 #include <config.h>
@@ -60,12 +61,11 @@
 #include <print.h>
 #include <log.h>
-#include <memstr.h>
+#include <mem.h>
 #include <console/console.h>
 #include <interrupt.h>
 #include <console/kconsole.h>
-#include <security/cap.h>
+#include <security/perm.h>
 #include <lib/rd.h>
 #include <ipc/ipc.h>
-#include <debug.h>
 #include <str.h>
 #include <sysinfo/stats.h>
@@ -240,5 +240,5 @@
 			name = "<unknown>";
 		
-		STATIC_ASSERT(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN);
+		static_assert(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN, "");
 		str_cpy(namebuf, TASK_NAME_BUFLEN, INIT_PREFIX);
 		str_cpy(namebuf + INIT_PREFIX_LEN,
@@ -251,5 +251,5 @@
 		    init.tasks[i].size,
 		    PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
-		ASSERT(page);
+		assert(page);
 		
 		int rc = program_create_from_image((void *) page, namebuf,
@@ -259,8 +259,9 @@
 			if (programs[i].task != NULL) {
 				/*
-				 * Set capabilities to init userspace tasks.
+				 * Set permissions to init userspace tasks.
 				 */
-				cap_set(programs[i].task, CAP_CAP | CAP_MEM_MANAGER |
-				    CAP_IO_MANAGER | CAP_IRQ_REG);
+				perm_set(programs[i].task,
+				    PERM_PERM | PERM_MEM_MANAGER |
+				    PERM_IO_MANAGER | PERM_IRQ_REG);
 				
 				if (!ipc_phone_0) {
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/main/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,8 +48,9 @@
 
 #include <arch/asm.h>
+#include <debug.h>
 #include <context.h>
 #include <print.h>
 #include <panic.h>
-#include <debug.h>
+#include <assert.h>
 #include <config.h>
 #include <time/clock.h>
@@ -91,4 +92,5 @@
 #include <sysinfo/stats.h>
 #include <lib/ra.h>
+#include <cap/cap.h>
 
 /* Ensure [u]int*_t types are of correct size.
@@ -98,5 +100,5 @@
  */
 #define CHECK_INT_TYPE_(signness, size) \
-	STATIC_ASSERT_VERBOSE(sizeof(signness##size##_t) * 8 == size, \
+	static_assert(sizeof(signness##size##_t) * 8 == size, \
 	    #signness #size "_t does not have " #size " bits");
 
@@ -276,4 +278,5 @@
 	timeout_init();
 	scheduler_init();
+	caps_init();
 	task_init();
 	thread_init();
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/as.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -67,7 +67,7 @@
 #include <arch/asm.h>
 #include <panic.h>
-#include <debug.h>
+#include <assert.h>
 #include <print.h>
-#include <memstr.h>
+#include <mem.h>
 #include <macros.h>
 #include <bitops.h>
@@ -189,6 +189,6 @@
 	DEADLOCK_PROBE_INIT(p_asidlock);
 	
-	ASSERT(as != AS);
-	ASSERT(atomic_get(&as->refcount) == 0);
+	assert(as != AS);
+	assert(atomic_get(&as->refcount) == 0);
 	
 	/*
@@ -236,5 +236,5 @@
 	bool cond = true;
 	while (cond) {
-		ASSERT(!list_empty(&as->as_area_btree.leaf_list));
+		assert(!list_empty(&as->as_area_btree.leaf_list));
 		
 		btree_node_t *node =
@@ -298,6 +298,6 @@
     size_t count, bool guarded, as_area_t *avoid)
 {
-	ASSERT((addr % PAGE_SIZE) == 0);
-	ASSERT(mutex_locked(&as->lock));
+	assert((addr % PAGE_SIZE) == 0);
+	assert(mutex_locked(&as->lock));
 
 	/*
@@ -455,5 +455,5 @@
     size_t size, bool guarded)
 {
-	ASSERT(mutex_locked(&as->lock));
+	assert(mutex_locked(&as->lock));
 	
 	if (size == 0)
@@ -532,5 +532,5 @@
 	
 	mutex_lock(&sh_info->lock);
-	ASSERT(sh_info->refcount);
+	assert(sh_info->refcount);
 	
 	if (--sh_info->refcount == 0) {
@@ -696,5 +696,5 @@
 NO_TRACE static as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
 {
-	ASSERT(mutex_locked(&as->lock));
+	assert(mutex_locked(&as->lock));
 	
 	btree_node_t *leaf;
@@ -827,5 +827,5 @@
 		bool cond = true;
 		while (cond) {
-			ASSERT(!list_empty(&area->used_space.leaf_list));
+			assert(!list_empty(&area->used_space.leaf_list));
 			
 			btree_node_t *node =
@@ -893,7 +893,7 @@
 					    ptr + P2SZ(i), false, &pte);
 					
-					ASSERT(found);
-					ASSERT(PTE_VALID(&pte));
-					ASSERT(PTE_PRESENT(&pte));
+					assert(found);
+					assert(PTE_VALID(&pte));
+					assert(PTE_PRESENT(&pte));
 					
 					if ((area->backend) &&
@@ -1008,7 +1008,7 @@
 				     ptr + P2SZ(size), false, &pte);
 				
-				ASSERT(found);
-				ASSERT(PTE_VALID(&pte));
-				ASSERT(PTE_PRESENT(&pte));
+				assert(found);
+				assert(PTE_VALID(&pte));
+				assert(PTE_PRESENT(&pte));
 				
 				if ((area->backend) &&
@@ -1194,5 +1194,5 @@
 NO_TRACE bool as_area_check_access(as_area_t *area, pf_access_t access)
 {
-	ASSERT(mutex_locked(&area->lock));
+	assert(mutex_locked(&area->lock));
 	
 	int flagmap[] = {
@@ -1321,7 +1321,7 @@
 				    ptr + P2SZ(size), false, &pte);
 				
-				ASSERT(found);
-				ASSERT(PTE_VALID(&pte));
-				ASSERT(PTE_PRESENT(&pte));
+				assert(found);
+				assert(PTE_VALID(&pte));
+				assert(PTE_PRESENT(&pte));
 				
 				old_frame[frame_idx++] = PTE_GET_FRAME(&pte);
@@ -1541,5 +1541,5 @@
 	 */
 	if (old_as) {
-		ASSERT(old_as->cpu_refcount);
+		assert(old_as->cpu_refcount);
 		
 		if ((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
@@ -1550,5 +1550,5 @@
 			 * ASID.
 			 */
-			ASSERT(old_as->asid != ASID_INVALID);
+			assert(old_as->asid != ASID_INVALID);
 			
 			list_append(&old_as->inactive_as_with_asid_link,
@@ -1597,5 +1597,5 @@
 NO_TRACE unsigned int as_area_get_flags(as_area_t *area)
 {
-	ASSERT(mutex_locked(&area->lock));
+	assert(mutex_locked(&area->lock));
 	
 	return area_flags_to_page_flags(area->flags);
@@ -1615,6 +1615,6 @@
 NO_TRACE pte_t *page_table_create(unsigned int flags)
 {
-	ASSERT(as_operations);
-	ASSERT(as_operations->page_table_create);
+	assert(as_operations);
+	assert(as_operations->page_table_create);
 	
 	return as_operations->page_table_create(flags);
@@ -1630,6 +1630,6 @@
 NO_TRACE void page_table_destroy(pte_t *page_table)
 {
-	ASSERT(as_operations);
-	ASSERT(as_operations->page_table_destroy);
+	assert(as_operations);
+	assert(as_operations->page_table_destroy);
 	
 	as_operations->page_table_destroy(page_table);
@@ -1651,6 +1651,6 @@
 NO_TRACE void page_table_lock(as_t *as, bool lock)
 {
-	ASSERT(as_operations);
-	ASSERT(as_operations->page_table_lock);
+	assert(as_operations);
+	assert(as_operations->page_table_lock);
 	
 	as_operations->page_table_lock(as, lock);
@@ -1665,6 +1665,6 @@
 NO_TRACE void page_table_unlock(as_t *as, bool unlock)
 {
-	ASSERT(as_operations);
-	ASSERT(as_operations->page_table_unlock);
+	assert(as_operations);
+	assert(as_operations->page_table_unlock);
 	
 	as_operations->page_table_unlock(as, unlock);
@@ -1680,6 +1680,6 @@
 NO_TRACE bool page_table_locked(as_t *as)
 {
-	ASSERT(as_operations);
-	ASSERT(as_operations->page_table_locked);
+	assert(as_operations);
+	assert(as_operations->page_table_locked);
 
 	return as_operations->page_table_locked(as);
@@ -1724,7 +1724,7 @@
 bool used_space_insert(as_area_t *area, uintptr_t page, size_t count)
 {
-	ASSERT(mutex_locked(&area->lock));
-	ASSERT(IS_ALIGNED(page, PAGE_SIZE));
-	ASSERT(count);
+	assert(mutex_locked(&area->lock));
+	assert(IS_ALIGNED(page, PAGE_SIZE));
+	assert(count);
 	
 	btree_node_t *leaf = NULL;
@@ -1737,5 +1737,5 @@
 	}
 
-	ASSERT(leaf != NULL);
+	assert(leaf != NULL);
 	
 	if (!leaf->keys) {
@@ -2010,7 +2010,7 @@
 bool used_space_remove(as_area_t *area, uintptr_t page, size_t count)
 {
-	ASSERT(mutex_locked(&area->lock));
-	ASSERT(IS_ALIGNED(page, PAGE_SIZE));
-	ASSERT(count);
+	assert(mutex_locked(&area->lock));
+	assert(IS_ALIGNED(page, PAGE_SIZE));
+	assert(count);
 	
 	btree_node_t *leaf;
@@ -2257,5 +2257,5 @@
 			as_area_t *area = node->value[i];
 			
-			ASSERT(area_idx < area_cnt);
+			assert(area_idx < area_cnt);
 			mutex_lock(&area->lock);
 			
Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/backend_anon.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
  */
 
+#include <assert.h>
 #include <mm/as.h>
 #include <mm/page.h>
@@ -51,5 +52,5 @@
 #include <typedefs.h>
 #include <align.h>
-#include <memstr.h>
+#include <mem.h>
 #include <arch.h>
 
@@ -113,7 +114,7 @@
 void anon_share(as_area_t *area)
 {
-	ASSERT(mutex_locked(&area->as->lock));
-	ASSERT(mutex_locked(&area->lock));
-	ASSERT(!(area->flags & AS_AREA_LATE_RESERVE));
+	assert(mutex_locked(&area->as->lock));
+	assert(mutex_locked(&area->lock));
+	assert(!(area->flags & AS_AREA_LATE_RESERVE));
 
 	/*
@@ -138,7 +139,7 @@
 				    base + P2SZ(j), false, &pte);
 
-				ASSERT(found);
-				ASSERT(PTE_VALID(&pte));
-				ASSERT(PTE_PRESENT(&pte));
+				assert(found);
+				assert(PTE_VALID(&pte));
+				assert(PTE_PRESENT(&pte));
 
 				btree_insert(&area->sh_info->pagemap,
@@ -190,7 +191,7 @@
 	uintptr_t frame;
 
-	ASSERT(page_table_locked(AS));
-	ASSERT(mutex_locked(&area->lock));
-	ASSERT(IS_ALIGNED(upage, PAGE_SIZE));
+	assert(page_table_locked(AS));
+	assert(mutex_locked(&area->lock));
+	assert(IS_ALIGNED(upage, PAGE_SIZE));
 
 	if (!as_area_check_access(area, access))
@@ -294,6 +295,6 @@
 void anon_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
 {
-	ASSERT(page_table_locked(area->as));
-	ASSERT(mutex_locked(&area->lock));
+	assert(page_table_locked(area->as));
+	assert(mutex_locked(&area->lock));
 
 	if (area->flags & AS_AREA_LATE_RESERVE) {
Index: kernel/generic/src/mm/backend_elf.c
===================================================================
--- kernel/generic/src/mm/backend_elf.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/backend_elf.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 
 #include <lib/elf.h>
-#include <debug.h>
+#include <assert.h>
 #include <typedefs.h>
 #include <mm/as.h>
@@ -48,5 +48,5 @@
 #include <genarch/mm/page_ht.h>
 #include <align.h>
-#include <memstr.h>
+#include <mem.h>
 #include <macros.h>
 #include <arch.h>
@@ -142,6 +142,6 @@
 	uintptr_t start_anon = entry->p_vaddr + entry->p_filesz;
 
-	ASSERT(mutex_locked(&area->as->lock));
-	ASSERT(mutex_locked(&area->lock));
+	assert(mutex_locked(&area->as->lock));
+	assert(mutex_locked(&area->lock));
 
 	/*
@@ -200,7 +200,7 @@
 				    base + P2SZ(j), false, &pte);
 
-				ASSERT(found);
-				ASSERT(PTE_VALID(&pte));
-				ASSERT(PTE_PRESENT(&pte));
+				assert(found);
+				assert(PTE_VALID(&pte));
+				assert(PTE_PRESENT(&pte));
 
 				btree_insert(&area->sh_info->pagemap,
@@ -261,7 +261,7 @@
 	bool dirty = false;
 
-	ASSERT(page_table_locked(AS));
-	ASSERT(mutex_locked(&area->lock));
-	ASSERT(IS_ALIGNED(upage, PAGE_SIZE));
+	assert(page_table_locked(AS));
+	assert(mutex_locked(&area->lock));
+	assert(IS_ALIGNED(upage, PAGE_SIZE));
 
 	if (!as_area_check_access(area, access))
@@ -345,6 +345,6 @@
 			    base + i * FRAME_SIZE, true, &pte);
 
-			ASSERT(found);
-			ASSERT(PTE_PRESENT(&pte));
+			assert(found);
+			assert(PTE_PRESENT(&pte));
 
 			frame = PTE_GET_FRAME(&pte);
@@ -424,9 +424,9 @@
 	uintptr_t start_anon;
 
-	ASSERT(page_table_locked(area->as));
-	ASSERT(mutex_locked(&area->lock));
-
-	ASSERT(page >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE));
-	ASSERT(page < entry->p_vaddr + entry->p_memsz);
+	assert(page_table_locked(area->as));
+	assert(mutex_locked(&area->lock));
+
+	assert(page >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE));
+	assert(page < entry->p_vaddr + entry->p_memsz);
 
 	start_anon = entry->p_vaddr + entry->p_filesz;
Index: kernel/generic/src/mm/backend_phys.c
===================================================================
--- kernel/generic/src/mm/backend_phys.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/backend_phys.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
  */
 
-#include <debug.h>
+#include <assert.h>
 #include <typedefs.h>
 #include <mm/as.h>
@@ -43,5 +43,4 @@
 #include <mm/frame.h>
 #include <mm/slab.h>
-#include <memstr.h>
 #include <macros.h>
 #include <arch.h>
@@ -96,6 +95,6 @@
 void phys_share(as_area_t *area)
 {
-	ASSERT(mutex_locked(&area->as->lock));
-	ASSERT(mutex_locked(&area->lock));
+	assert(mutex_locked(&area->as->lock));
+	assert(mutex_locked(&area->lock));
 }
 
@@ -136,12 +135,12 @@
 	uintptr_t base = area->backend_data.base;
 
-	ASSERT(page_table_locked(AS));
-	ASSERT(mutex_locked(&area->lock));
-	ASSERT(IS_ALIGNED(upage, PAGE_SIZE));
+	assert(page_table_locked(AS));
+	assert(mutex_locked(&area->lock));
+	assert(IS_ALIGNED(upage, PAGE_SIZE));
 
 	if (!as_area_check_access(area, access))
 		return AS_PF_FAULT;
 
-	ASSERT(upage - area->base < area->backend_data.frames * FRAME_SIZE);
+	assert(upage - area->base < area->backend_data.frames * FRAME_SIZE);
 	page_mapping_insert(AS, upage, base + (upage - area->base),
 	    as_area_get_flags(area));
Index: kernel/generic/src/mm/backend_user.c
===================================================================
--- kernel/generic/src/mm/backend_user.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/backend_user.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -46,5 +46,5 @@
 #include <typedefs.h>
 #include <align.h>
-#include <debug.h>
+#include <assert.h>
 #include <errno.h>
 #include <log.h>
@@ -108,7 +108,7 @@
 int user_page_fault(as_area_t *area, uintptr_t upage, pf_access_t access)
 {
-	ASSERT(page_table_locked(AS));
-	ASSERT(mutex_locked(&area->lock));
-	ASSERT(IS_ALIGNED(upage, PAGE_SIZE));
+	assert(page_table_locked(AS));
+	assert(mutex_locked(&area->lock));
+	assert(IS_ALIGNED(upage, PAGE_SIZE));
 
 	if (!as_area_check_access(area, access))
@@ -162,6 +162,6 @@
 void user_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
 {
-	ASSERT(page_table_locked(area->as));
-	ASSERT(mutex_locked(&area->lock));
+	assert(page_table_locked(area->as));
+	assert(mutex_locked(&area->lock));
 
 	pfn_t pfn = ADDR2PFN(frame);
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/frame.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -47,5 +47,5 @@
 #include <mm/as.h>
 #include <panic.h>
-#include <debug.h>
+#include <assert.h>
 #include <adt/list.h>
 #include <synch/mutex.h>
@@ -349,5 +349,5 @@
 NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t index)
 {
-	ASSERT(index < zone->count);
+	assert(index < zone->count);
 	
 	return &zone->frames[index];
@@ -370,5 +370,5 @@
     pfn_t constraint)
 {
-	ASSERT(zone->flags & ZONE_AVAILABLE);
+	assert(zone->flags & ZONE_AVAILABLE);
 	
 	/* Allocate frames from zone */
@@ -377,6 +377,6 @@
 	    FRAME_LOWPRIO, constraint, &index);
 	
-	ASSERT(avail);
-	ASSERT(index != (size_t) -1);
+	assert(avail);
+	assert(index != (size_t) -1);
 	
 	/* Update frame reference count */
@@ -384,5 +384,5 @@
 		frame_t *frame = zone_get_frame(zone, index + i);
 		
-		ASSERT(frame->refcount == 0);
+		assert(frame->refcount == 0);
 		frame->refcount = 1;
 	}
@@ -407,9 +407,9 @@
 NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t index)
 {
-	ASSERT(zone->flags & ZONE_AVAILABLE);
+	assert(zone->flags & ZONE_AVAILABLE);
 	
 	frame_t *frame = zone_get_frame(zone, index);
 	
-	ASSERT(frame->refcount > 0);
+	assert(frame->refcount > 0);
 	
 	if (!--frame->refcount) {
@@ -429,5 +429,5 @@
 NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t index)
 {
-	ASSERT(zone->flags & ZONE_AVAILABLE);
+	assert(zone->flags & ZONE_AVAILABLE);
 	
 	frame_t *frame = zone_get_frame(zone, index);
@@ -456,9 +456,9 @@
     void *confdata)
 {
-	ASSERT(zones.info[z1].flags & ZONE_AVAILABLE);
-	ASSERT(zones.info[z2].flags & ZONE_AVAILABLE);
-	ASSERT(zones.info[z1].flags == zones.info[z2].flags);
-	ASSERT(zones.info[z1].base < zones.info[z2].base);
-	ASSERT(!overlaps(zones.info[z1].base, zones.info[z1].count,
+	assert(zones.info[z1].flags & ZONE_AVAILABLE);
+	assert(zones.info[z2].flags & ZONE_AVAILABLE);
+	assert(zones.info[z1].flags == zones.info[z2].flags);
+	assert(zones.info[z1].base < zones.info[z2].base);
+	assert(!overlaps(zones.info[z1].base, zones.info[z1].count,
 	    zones.info[z2].base, zones.info[z2].count));
 	
@@ -509,5 +509,5 @@
 NO_TRACE static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
 {
-	ASSERT(zones.info[znum].flags & ZONE_AVAILABLE);
+	assert(zones.info[znum].flags & ZONE_AVAILABLE);
 	
 	size_t cframes = SIZE2FRAMES(zone_conf_size(count));
@@ -704,5 +704,5 @@
 		 * the assert
 		 */
-		ASSERT(confframe != ADDR2PFN((uintptr_t ) NULL));
+		assert(confframe != ADDR2PFN((uintptr_t ) NULL));
 		
 		/* Update the known end of physical memory. */
@@ -792,5 +792,5 @@
 	size_t znum = find_zone(pfn, 1, hint);
 	
-	ASSERT(znum != (size_t) -1);
+	assert(znum != (size_t) -1);
 	
 	zone_get_frame(&zones.info[znum],
@@ -806,5 +806,5 @@
 	size_t znum = find_zone(pfn, 1, hint);
 	
-	ASSERT(znum != (size_t) -1);
+	assert(znum != (size_t) -1);
 	
 	void *res = zone_get_frame(&zones.info[znum],
@@ -830,5 +830,5 @@
     uintptr_t constraint, size_t *pzone)
 {
-	ASSERT(count > 0);
+	assert(count > 0);
 	
 	size_t hint = pzone ? (*pzone) : 0;
@@ -970,5 +970,5 @@
 		size_t znum = find_zone(pfn, 1, 0);
 		
-		ASSERT(znum != (size_t) -1);
+		assert(znum != (size_t) -1);
 		
 		freed += zone_frame_free(&zones.info[znum],
@@ -1030,5 +1030,5 @@
 	size_t znum = find_zone(pfn, 1, 0);
 	
-	ASSERT(znum != (size_t) -1);
+	assert(znum != (size_t) -1);
 	
 	zones.info[znum].frames[pfn - zones.info[znum].base].refcount++;
@@ -1153,8 +1153,8 @@
     uint64_t *free)
 {
-	ASSERT(total != NULL);
-	ASSERT(unavail != NULL);
-	ASSERT(busy != NULL);
-	ASSERT(free != NULL);
+	assert(total != NULL);
+	assert(unavail != NULL);
+	assert(busy != NULL);
+	assert(free != NULL);
 	
 	irq_spinlock_lock(&zones.lock, true);
Index: kernel/generic/src/mm/km.c
===================================================================
--- kernel/generic/src/mm/km.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/km.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <mm/km.h>
 #include <arch/mm/km.h>
+#include <assert.h>
 #include <mm/page.h>
 #include <mm/frame.h>
@@ -44,5 +45,4 @@
 #include <typedefs.h>
 #include <lib/ra.h>
-#include <debug.h>
 #include <arch.h>
 #include <align.h>
@@ -95,5 +95,5 @@
 {
 	km_ni_arena = ra_arena_create();
-	ASSERT(km_ni_arena != NULL);
+	assert(km_ni_arena != NULL);
 	km_non_identity_arch_init();
 	config.non_identity_configured = true;
@@ -112,10 +112,14 @@
 
 	span_added = ra_span_add(km_ni_arena, base, size);
-	ASSERT(span_added);
+	assert(span_added);
 }
 
 uintptr_t km_page_alloc(size_t size, size_t align)
 {
-	return ra_alloc(km_ni_arena, size, align);
+	uintptr_t base;
+	if (ra_alloc(km_ni_arena, size, align, &base))
+		return base;
+	else
+		return (uintptr_t) NULL;
 }
 
@@ -132,6 +136,6 @@
 	uintptr_t offs;
 
-	ASSERT(ALIGN_DOWN(paddr, FRAME_SIZE) == paddr);
-	ASSERT(ALIGN_UP(size, FRAME_SIZE) == size);
+	assert(ALIGN_DOWN(paddr, FRAME_SIZE) == paddr);
+	assert(ALIGN_UP(size, FRAME_SIZE) == size);
 
 	/* Enforce natural or at least PAGE_SIZE alignment. */
@@ -154,6 +158,6 @@
 	ipl_t ipl;
 
-	ASSERT(ALIGN_DOWN(vaddr, PAGE_SIZE) == vaddr);
-	ASSERT(ALIGN_UP(size, PAGE_SIZE) == size);
+	assert(ALIGN_DOWN(vaddr, PAGE_SIZE) == vaddr);
+	assert(ALIGN_UP(size, PAGE_SIZE) == size);
 
 	page_table_lock(AS_KERNEL, true);
@@ -240,7 +244,7 @@
 uintptr_t km_temporary_page_get(uintptr_t *framep, frame_flags_t flags)
 {
-	ASSERT(THREAD);
-	ASSERT(framep);
-	ASSERT(!(flags & ~(FRAME_NO_RESERVE | FRAME_ATOMIC)));
+	assert(THREAD);
+	assert(framep);
+	assert(!(flags & ~(FRAME_NO_RESERVE | FRAME_ATOMIC)));
 	
 	/*
@@ -281,5 +285,5 @@
 void km_temporary_page_put(uintptr_t page)
 {
-	ASSERT(THREAD);
+	assert(THREAD);
 
 	if (km_is_non_identity(page))
Index: kernel/generic/src/mm/page.c
===================================================================
--- kernel/generic/src/mm/page.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/page.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -69,7 +69,6 @@
 #include <typedefs.h>
 #include <arch/asm.h>
-#include <memstr.h>
-#include <debug.h>
 #include <arch.h>
+#include <assert.h>
 #include <syscall/copy.h>
 #include <errno.h>
@@ -99,8 +98,8 @@
     unsigned int flags)
 {
-	ASSERT(page_table_locked(as));
-	
-	ASSERT(page_mapping_operations);
-	ASSERT(page_mapping_operations->mapping_insert);
+	assert(page_table_locked(as));
+	
+	assert(page_mapping_operations);
+	assert(page_mapping_operations->mapping_insert);
 
 	page_mapping_operations->mapping_insert(as, ALIGN_DOWN(page, PAGE_SIZE),
@@ -123,8 +122,8 @@
 NO_TRACE void page_mapping_remove(as_t *as, uintptr_t page)
 {
-	ASSERT(page_table_locked(as));
-	
-	ASSERT(page_mapping_operations);
-	ASSERT(page_mapping_operations->mapping_remove);
+	assert(page_table_locked(as));
+	
+	assert(page_mapping_operations);
+	assert(page_mapping_operations->mapping_remove);
 	
 	page_mapping_operations->mapping_remove(as,
@@ -148,8 +147,8 @@
     pte_t *pte)
 {
-	ASSERT(nolock || page_table_locked(as));
-	
-	ASSERT(page_mapping_operations);
-	ASSERT(page_mapping_operations->mapping_find);
+	assert(nolock || page_table_locked(as));
+	
+	assert(page_mapping_operations);
+	assert(page_mapping_operations->mapping_find);
 	
 	return page_mapping_operations->mapping_find(as,
@@ -169,8 +168,8 @@
     pte_t *pte)
 {
-	ASSERT(nolock || page_table_locked(as));
-	
-	ASSERT(page_mapping_operations);
-	ASSERT(page_mapping_operations->mapping_find);
+	assert(nolock || page_table_locked(as));
+	
+	assert(page_mapping_operations);
+	assert(page_mapping_operations->mapping_find);
 	
 	page_mapping_operations->mapping_update(as,
@@ -185,6 +184,6 @@
 void page_mapping_make_global(uintptr_t base, size_t size)
 {
-	ASSERT(page_mapping_operations);
-	ASSERT(page_mapping_operations->mapping_make_global);
+	assert(page_mapping_operations);
+	assert(page_mapping_operations->mapping_make_global);
 	
 	return page_mapping_operations->mapping_make_global(base, size);
Index: kernel/generic/src/mm/reserve.c
===================================================================
--- kernel/generic/src/mm/reserve.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/reserve.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
  */
 
+#include <assert.h>
 #include <mm/reserve.h>
 #include <mm/frame.h>
@@ -42,5 +43,4 @@
 #include <typedefs.h>
 #include <arch/types.h>
-#include <debug.h>
 
 static bool reserve_initialized = false;
@@ -72,5 +72,5 @@
 	bool reserved = false;
 
-	ASSERT(reserve_initialized);
+	assert(reserve_initialized);
 
 	irq_spinlock_lock(&reserve_lock, true);
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/slab.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -101,8 +101,9 @@
  */
 
+#include <assert.h>
 #include <synch/spinlock.h>
 #include <mm/slab.h>
 #include <adt/list.h>
-#include <memstr.h>
+#include <mem.h>
 #include <align.h>
 #include <mm/frame.h>
@@ -111,5 +112,4 @@
 #include <arch.h>
 #include <panic.h>
-#include <debug.h>
 #include <bitops.h>
 #include <macros.h>
@@ -260,5 +260,5 @@
 		slab = obj2slab(obj);
 	
-	ASSERT(slab->cache == cache);
+	assert(slab->cache == cache);
 	
 	size_t freed = 0;
@@ -268,5 +268,5 @@
 	
 	irq_spinlock_lock(&cache->slablock, true);
-	ASSERT(slab->available < cache->objects);
+	assert(slab->available < cache->objects);
 	
 	*((size_t *) obj) = slab->nextavail;
@@ -417,5 +417,5 @@
 	slab_magazine_t *lastmag = cache->mag_cache[CPU->id].last;
 	
-	ASSERT(irq_spinlock_locked(&cache->mag_cache[CPU->id].lock));
+	assert(irq_spinlock_locked(&cache->mag_cache[CPU->id].lock));
 	
 	if (cmag) { /* First try local CPU magazines */
@@ -484,5 +484,5 @@
 	slab_magazine_t *lastmag = cache->mag_cache[CPU->id].last;
 	
-	ASSERT(irq_spinlock_locked(&cache->mag_cache[CPU->id].lock));
+	assert(irq_spinlock_locked(&cache->mag_cache[CPU->id].lock));
 	
 	if (cmag) {
@@ -586,5 +586,5 @@
 NO_TRACE static bool make_magcache(slab_cache_t *cache)
 {
-	ASSERT(_slab_initialized >= 2);
+	assert(_slab_initialized >= 2);
 	
 	cache->mag_cache = malloc(sizeof(slab_mag_cache_t) * config.cpu_count,
@@ -610,5 +610,5 @@
     unsigned int kmflag), size_t (*destructor)(void *obj), unsigned int flags)
 {
-	ASSERT(size > 0);
+	assert(size > 0);
 	
 	memsetb(cache, sizeof(*cache), 0);
@@ -948,6 +948,6 @@
 void *malloc(size_t size, unsigned int flags)
 {
-	ASSERT(_slab_initialized);
-	ASSERT(size <= (1 << SLAB_MAX_MALLOC_W));
+	assert(_slab_initialized);
+	assert(size <= (1 << SLAB_MAX_MALLOC_W));
 	
 	if (size < (1 << SLAB_MIN_MALLOC_W))
@@ -961,6 +961,6 @@
 void *realloc(void *ptr, size_t size, unsigned int flags)
 {
-	ASSERT(_slab_initialized);
-	ASSERT(size <= (1 << SLAB_MAX_MALLOC_W));
+	assert(_slab_initialized);
+	assert(size <= (1 << SLAB_MAX_MALLOC_W));
 	
 	void *new_ptr;
Index: kernel/generic/src/mm/tlb.c
===================================================================
--- kernel/generic/src/mm/tlb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/mm/tlb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,4 +43,5 @@
 #include <mm/asid.h>
 #include <arch/mm/tlb.h>
+#include <assert.h>
 #include <smp/ipi.h>
 #include <synch/spinlock.h>
@@ -50,5 +51,4 @@
 #include <arch.h>
 #include <panic.h>
-#include <debug.h>
 #include <cpu.h>
 
@@ -152,5 +152,5 @@
 void tlb_shootdown_ipi_recv(void)
 {
-	ASSERT(CPU);
+	assert(CPU);
 	
 	CPU->tlb_active = false;
@@ -159,5 +159,5 @@
 	
 	irq_spinlock_lock(&CPU->lock, false);
-	ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN);
+	assert(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN);
 	
 	size_t i;
@@ -176,5 +176,5 @@
 			break;
 		case TLB_INVL_PAGES:
-			ASSERT(count);
+			assert(count);
 			tlb_invalidate_pages(asid, page, count);
 			break;
Index: kernel/generic/src/printf/printf_core.c
===================================================================
--- kernel/generic/src/printf/printf_core.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/printf/printf_core.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,4 +41,5 @@
 #include <stdarg.h>
 #include <macros.h>
+#include <stddef.h>
 #include <str.h>
 #include <arch.h>
Index: kernel/generic/src/printf/vsnprintf.c
===================================================================
--- kernel/generic/src/printf/vsnprintf.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/printf/vsnprintf.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #include <printf/printf_core.h>
 #include <str.h>
-#include <memstr.h>
+#include <mem.h>
 #include <errno.h>
 
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/proc/program.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -46,5 +46,5 @@
 #include <ipc/ipc.h>
 #include <ipc/ipcrsc.h>
-#include <security/cap.h>
+#include <security/perm.h>
 #include <lib/elf_load.h>
 #include <errno.h>
@@ -244,6 +244,6 @@
 		return rc;
 	
-	// FIXME: control the capabilities
-	cap_set(prg.task, cap_get(TASK));
+	// FIXME: control the permissions 
+	perm_set(prg.task, perm_get(TASK));
 	program_ready(&prg);
 	
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/proc/scheduler.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
  */
 
+#include <assert.h>
 #include <proc/scheduler.h>
 #include <proc/thread.h>
@@ -64,5 +65,4 @@
 #include <print.h>
 #include <log.h>
-#include <debug.h>
 #include <stacktrace.h>
 
@@ -200,5 +200,5 @@
 static thread_t *find_best_thread(void)
 {
-	ASSERT(CPU != NULL);
+	assert(CPU != NULL);
 	
 loop:
@@ -225,5 +225,5 @@
 	}
 
-	ASSERT(!CPU->idle);
+	assert(!CPU->idle);
 	
 	unsigned int i;
@@ -322,5 +322,5 @@
 	volatile ipl_t ipl;
 	
-	ASSERT(CPU != NULL);
+	assert(CPU != NULL);
 	
 	ipl = interrupts_disable();
@@ -403,7 +403,7 @@
 	as_t *old_as = AS;
 	
-	ASSERT((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
-	ASSERT(CPU != NULL);
-	ASSERT(interrupts_disabled());
+	assert((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
+	assert(CPU != NULL);
+	assert(interrupts_disabled());
 	
 	/*
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/proc/task.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
  */
 
+#include <assert.h>
 #include <proc/thread.h>
 #include <proc/task.h>
@@ -49,4 +50,5 @@
 #include <adt/btree.h>
 #include <adt/list.h>
+#include <cap/cap.h>
 #include <ipc/ipc.h>
 #include <ipc/ipcrsc.h>
@@ -56,5 +58,4 @@
 #include <func.h>
 #include <str.h>
-#include <memstr.h>
 #include <syscall/copy.h>
 #include <macros.h>
@@ -83,4 +84,5 @@
 static void task_kill_internal(task_t *);
 static int tsk_constructor(void *, unsigned int);
+static size_t tsk_destructor(void *obj);
 
 /** Initialize kernel tasks support.
@@ -92,5 +94,5 @@
 	avltree_create(&tasks_tree);
 	task_slab = slab_cache_create("task_t", sizeof(task_t), 0,
-	    tsk_constructor, NULL, 0);
+	    tsk_constructor, tsk_destructor, 0);
 }
 
@@ -159,4 +161,8 @@
 {
 	task_t *task = (task_t *) obj;
+
+	int rc = caps_task_alloc(task);
+	if (rc != EOK)
+		return rc;
 	
 	atomic_set(&task->refcount, 0);
@@ -169,8 +175,4 @@
 	ipc_answerbox_init(&task->answerbox, task);
 	
-	size_t i;
-	for (i = 0; i < IPC_MAX_PHONES; i++)
-		ipc_phone_init(&task->phones[i], task);
-
 	spinlock_initialize(&task->active_calls_lock, "active_calls_lock");
 	list_initialize(&task->active_calls);
@@ -186,4 +188,12 @@
 }
 
+size_t tsk_destructor(void *obj)
+{
+	task_t *task = (task_t *) obj;
+	
+	caps_task_free(task);
+	return 0;
+}
+
 /** Create new task with no threads.
  *
@@ -203,7 +213,9 @@
 	
 	task->container = CONTAINER;
-	task->capabilities = 0;
+	task->perms = 0;
 	task->ucycles = 0;
 	task->kcycles = 0;
+
+	caps_task_init(task);
 
 	task->ipc_info.call_sent = 0;
@@ -228,6 +240,10 @@
 	
 	if ((ipc_phone_0) &&
-	    (container_check(ipc_phone_0->task->container, task->container)))
-		(void) ipc_phone_connect(&task->phones[0], ipc_phone_0);
+	    (container_check(ipc_phone_0->task->container, task->container))) {
+		cap_handle_t phone_handle = phone_alloc(task);
+		kobject_t *phone_obj = kobject_get(task, phone_handle,
+		    KOBJECT_TYPE_PHONE);
+		(void) ipc_phone_connect(phone_obj->phone, ipc_phone_0);
+	}
 	
 	futex_task_init(task);
@@ -420,6 +436,6 @@
 task_t *task_find_by_id(task_id_t id)
 {
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&tasks_lock));
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&tasks_lock));
 
 	avltree_node_t *node =
@@ -444,6 +460,6 @@
 void task_get_accounting(task_t *task, uint64_t *ucycles, uint64_t *kcycles)
 {
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&task->lock));
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&task->lock));
 
 	/* Accumulated values of task */
@@ -603,5 +619,5 @@
 	if (*additional)
 		printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c "
-		    "%9" PRIua, task->taskid, ucycles, usuffix, kcycles,
+		    "%9" PRIua "\n", task->taskid, ucycles, usuffix, kcycles,
 		    ksuffix, atomic_get(&task->refcount));
 	else
@@ -609,13 +625,4 @@
 		    task->taskid, task->name, task->container, task, task->as);
 #endif
-	
-	if (*additional) {
-		size_t i;
-		for (i = 0; i < IPC_MAX_PHONES; i++) {
-			if (task->phones[i].callee)
-				printf(" %zu:%p", i, task->phones[i].callee);
-		}
-		printf("\n");
-	}
 	
 	irq_spinlock_unlock(&task->lock, false);
Index: kernel/generic/src/proc/the.c
===================================================================
--- kernel/generic/src/proc/the.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/proc/the.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,5 @@
 
 #include <arch.h>
-#include <debug.h>
+#include <assert.h>
 
 /** Initialize THE structure
@@ -60,5 +60,5 @@
 	the->as = NULL;
 	the->magic = MAGIC;
-#ifdef RCU_PREEMPT_A	
+#ifdef RCU_PREEMPT_A
 	the->rcu_nesting = 0;
 #endif
@@ -75,5 +75,5 @@
 NO_TRACE void the_copy(the_t *src, the_t *dst)
 {
-	ASSERT(src->magic == MAGIC);
+	assert(src->magic == MAGIC);
 	*dst = *src;
 }
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/proc/thread.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
  */
 
+#include <assert.h>
 #include <proc/scheduler.h>
 #include <proc/thread.h>
@@ -61,8 +62,7 @@
 #include <arch/faddr.h>
 #include <atomic.h>
-#include <memstr.h>
+#include <mem.h>
 #include <print.h>
 #include <mm/slab.h>
-#include <debug.h>
 #include <main/uinit.h>
 #include <syscall/copy.h>
@@ -228,5 +228,5 @@
 #endif
 	
-	return 1;  /* One page freed */
+	return STACK_FRAMES;  /* number of frames freed */
 }
 
@@ -268,5 +268,5 @@
 static void before_thread_is_ready(thread_t *thread)
 {
-	ASSERT(irq_spinlock_locked(&thread->lock));
+	assert(irq_spinlock_locked(&thread->lock));
 	workq_before_thread_is_ready(thread);
 }
@@ -283,5 +283,5 @@
 	irq_spinlock_lock(&thread->lock, true);
 	
-	ASSERT(thread->state != Ready);
+	assert(thread->state != Ready);
 
 	before_thread_is_ready(thread);
@@ -293,5 +293,5 @@
 	if (thread->wired || thread->nomigrate || thread->fpu_context_engaged) {
 		/* Cannot ready to another CPU */
-		ASSERT(thread->cpu != NULL);
+		assert(thread->cpu != NULL);
 		cpu = thread->cpu;
 	} else if (thread->stolen) {
@@ -300,5 +300,5 @@
 	} else if (thread->cpu) {
 		/* Prefer the CPU on which the thread ran last */
-		ASSERT(thread->cpu != NULL);
+		assert(thread->cpu != NULL);
 		cpu = thread->cpu;
 	} else {
@@ -431,8 +431,8 @@
 void thread_destroy(thread_t *thread, bool irq_res)
 {
-	ASSERT(irq_spinlock_locked(&thread->lock));
-	ASSERT((thread->state == Exiting) || (thread->state == Lingering));
-	ASSERT(thread->task);
-	ASSERT(thread->cpu);
+	assert(irq_spinlock_locked(&thread->lock));
+	assert((thread->state == Exiting) || (thread->state == Lingering));
+	assert(thread->task);
+	assert(thread->cpu);
 	
 	irq_spinlock_lock(&thread->cpu->lock, false);
@@ -561,5 +561,5 @@
 void thread_interrupt(thread_t *thread)
 {
-	ASSERT(thread != NULL);
+	assert(thread != NULL);
 	
 	irq_spinlock_lock(&thread->lock, true);
@@ -582,5 +582,5 @@
 bool thread_interrupted(thread_t *thread)
 {
-	ASSERT(thread != NULL);
+	assert(thread != NULL);
 	
 	bool interrupted;
@@ -596,5 +596,5 @@
 void thread_migration_disable(void)
 {
-	ASSERT(THREAD);
+	assert(THREAD);
 	
 	THREAD->nomigrate++;
@@ -604,6 +604,6 @@
 void thread_migration_enable(void)
 {
-	ASSERT(THREAD);
-	ASSERT(THREAD->nomigrate > 0);
+	assert(THREAD);
+	assert(THREAD->nomigrate > 0);
 	
 	if (THREAD->nomigrate > 0)
@@ -650,5 +650,5 @@
 	
 	irq_spinlock_lock(&thread->lock, true);
-	ASSERT(!thread->detached);
+	assert(!thread->detached);
 	irq_spinlock_unlock(&thread->lock, true);
 	
@@ -671,5 +671,5 @@
 	 */
 	irq_spinlock_lock(&thread->lock, true);
-	ASSERT(!thread->detached);
+	assert(!thread->detached);
 	
 	if (thread->state == Lingering) {
@@ -809,6 +809,6 @@
 bool thread_exists(thread_t *thread)
 {
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&threads_lock));
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&threads_lock));
 
 	avltree_node_t *node =
@@ -830,6 +830,6 @@
 	uint64_t time = get_cycle();
 
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&THREAD->lock));
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&THREAD->lock));
 	
 	if (user)
@@ -867,6 +867,6 @@
 thread_t *thread_find_by_id(thread_id_t thread_id)
 {
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&threads_lock));
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&threads_lock));
 	
 	thread_iterator_t iterator;
Index: rnel/generic/src/security/cap.c
===================================================================
--- kernel/generic/src/security/cap.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,229 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup generic
- * @{
- */
-
-/**
- * @file cap.c
- * @brief Capabilities control.
- *
- * @see cap.h
- */
-
-#include <security/cap.h>
-#include <proc/task.h>
-#include <synch/spinlock.h>
-#include <syscall/copy.h>
-#include <arch.h>
-#include <errno.h>
-
-/** Set capabilities.
- *
- * @param task Task whose capabilities are to be changed.
- * @param caps New set of capabilities.
- *
- */
-void cap_set(task_t *task, cap_t caps)
-{
-	irq_spinlock_lock(&task->lock, true);
-	task->capabilities = caps;
-	irq_spinlock_unlock(&task->lock, true);
-}
-
-/** Get capabilities.
- *
- * @param task Task whose capabilities are to be returned.
- *
- * @return Task's capabilities.
- *
- */
-cap_t cap_get(task_t *task)
-{
-	irq_spinlock_lock(&task->lock, true);
-	cap_t caps = task->capabilities;
-	irq_spinlock_unlock(&task->lock, true);
-	
-	return caps;
-}
-
-/** Grant capabilities to a task.
- *
- * The calling task must have the CAP_CAP capability.
- *
- * @param taskid Destination task ID.
- * @param caps   Capabilities to grant.
- *
- * @return Zero on success or an error code from @ref errno.h.
- *
- */
-static sysarg_t cap_grant(task_id_t taskid, cap_t caps)
-{
-	if (!(cap_get(TASK) & CAP_CAP))
-		return (sysarg_t) EPERM;
-	
-	irq_spinlock_lock(&tasks_lock, true);
-	task_t *task = task_find_by_id(taskid);
-	
-	if ((!task) || (!container_check(CONTAINER, task->container))) {
-		irq_spinlock_unlock(&tasks_lock, true);
-		return (sysarg_t) ENOENT;
-	}
-	
-	irq_spinlock_lock(&task->lock, false);
-	task->capabilities |= caps;
-	irq_spinlock_unlock(&task->lock, false);
-	
-	irq_spinlock_unlock(&tasks_lock, true);
-	return 0;
-}
-
-/** Revoke capabilities from a task.
- *
- * The calling task must have the CAP_CAP capability or the caller must
- * attempt to revoke capabilities from itself.
- *
- * @param taskid Destination task ID.
- * @param caps   Capabilities to revoke.
- *
- * @return Zero on success or an error code from @ref errno.h.
- *
- */
-static sysarg_t cap_revoke(task_id_t taskid, cap_t caps)
-{
-	irq_spinlock_lock(&tasks_lock, true);
-	
-	task_t *task = task_find_by_id(taskid);
-	if ((!task) || (!container_check(CONTAINER, task->container))) {
-		irq_spinlock_unlock(&tasks_lock, true);
-		return (sysarg_t) ENOENT;
-	}
-	
-	/*
-	 * Revoking capabilities is different from granting them in that
-	 * a task can revoke capabilities from itself even if it
-	 * doesn't have CAP_CAP.
-	 */
-	irq_spinlock_unlock(&TASK->lock, false);
-	
-	if ((!(TASK->capabilities & CAP_CAP)) || (task != TASK)) {
-		irq_spinlock_unlock(&TASK->lock, false);
-		irq_spinlock_unlock(&tasks_lock, true);
-		return (sysarg_t) EPERM;
-	}
-	
-	task->capabilities &= ~caps;
-	irq_spinlock_unlock(&TASK->lock, false);
-	
-	irq_spinlock_unlock(&tasks_lock, true);
-	return 0;
-}
-
-#ifdef __32_BITS__
-
-/** Grant capabilities to a task (32 bits)
- *
- * The calling task must have the CAP_CAP capability.
- *
- * @param uspace_taskid User-space pointer to destination task ID.
- * @param caps          Capabilities to grant.
- *
- * @return Zero on success or an error code from @ref errno.h.
- *
- */
-sysarg_t sys_cap_grant(sysarg64_t *uspace_taskid, cap_t caps)
-{
-	sysarg64_t taskid;
-	int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(sysarg64_t));
-	if (rc != 0)
-		return (sysarg_t) rc;
-	
-	return cap_grant((task_id_t) taskid, caps);
-}
-
-/** Revoke capabilities from a task (32 bits)
- *
- * The calling task must have the CAP_CAP capability or the caller must
- * attempt to revoke capabilities from itself.
- *
- * @param uspace_taskid User-space pointer to destination task ID.
- * @param caps          Capabilities to revoke.
- *
- * @return Zero on success or an error code from @ref errno.h.
- *
- */
-sysarg_t sys_cap_revoke(sysarg64_t *uspace_taskid, cap_t caps)
-{
-	sysarg64_t taskid;
-	int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(sysarg64_t));
-	if (rc != 0)
-		return (sysarg_t) rc;
-	
-	return cap_revoke((task_id_t) taskid, caps);
-}
-
-#endif  /* __32_BITS__ */
-
-#ifdef __64_BITS__
-
-/** Grant capabilities to a task (64 bits)
- *
- * The calling task must have the CAP_CAP capability.
- *
- * @param taskid Destination task ID.
- * @param caps   Capabilities to grant.
- *
- * @return Zero on success or an error code from @ref errno.h.
- *
- */
-sysarg_t sys_cap_grant(sysarg_t taskid, cap_t caps)
-{
-	return cap_grant((task_id_t) taskid, caps);
-}
-
-/** Revoke capabilities from a task (64 bits)
- *
- * The calling task must have the CAP_CAP capability or the caller must
- * attempt to revoke capabilities from itself.
- *
- * @param taskid Destination task ID.
- * @param caps   Capabilities to revoke.
- *
- * @return Zero on success or an error code from @ref errno.h.
- *
- */
-sysarg_t sys_cap_revoke(sysarg_t taskid, cap_t caps)
-{
-	return cap_revoke((task_id_t) taskid, caps);
-}
-
-#endif  /* __64_BITS__ */
-
-/** @}
- */
Index: kernel/generic/src/security/perm.c
===================================================================
--- kernel/generic/src/security/perm.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ kernel/generic/src/security/perm.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+
+/**
+ * @file perm.c
+ * @brief Task permissions control.
+ *
+ * @see perm.h
+ */
+
+#include <security/perm.h>
+#include <proc/task.h>
+#include <synch/spinlock.h>
+#include <syscall/copy.h>
+#include <arch.h>
+#include <errno.h>
+
+/** Set permissions.
+ *
+ * @param task  Task whose permissions are to be changed.
+ * @param perms New set of permissions.
+ *
+ */
+void perm_set(task_t *task, perm_t perms)
+{
+	irq_spinlock_lock(&task->lock, true);
+	task->perms = perms;
+	irq_spinlock_unlock(&task->lock, true);
+}
+
+/** Get permissions.
+ *
+ * @param task Task whose permissions are to be returned.
+ *
+ * @return Task's permissions.
+ *
+ */
+perm_t perm_get(task_t *task)
+{
+	irq_spinlock_lock(&task->lock, true);
+	perm_t perms = task->perms;
+	irq_spinlock_unlock(&task->lock, true);
+	
+	return perms;
+}
+
+/** Grant permissions to a task.
+ *
+ * The calling task must have the PERM_PERM permission.
+ *
+ * @param taskid Destination task ID.
+ * @param perms   Permissions to grant.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ *
+ */
+static sysarg_t perm_grant(task_id_t taskid, perm_t perms)
+{
+	if (!(perm_get(TASK) & PERM_PERM))
+		return (sysarg_t) EPERM;
+	
+	irq_spinlock_lock(&tasks_lock, true);
+	task_t *task = task_find_by_id(taskid);
+	
+	if ((!task) || (!container_check(CONTAINER, task->container))) {
+		irq_spinlock_unlock(&tasks_lock, true);
+		return (sysarg_t) ENOENT;
+	}
+	
+	irq_spinlock_lock(&task->lock, false);
+	task->perms |= perms;
+	irq_spinlock_unlock(&task->lock, false);
+	
+	irq_spinlock_unlock(&tasks_lock, true);
+	return 0;
+}
+
+/** Revoke permissions from a task.
+ *
+ * The calling task must have the PERM_PERM permission or the caller must
+ * attempt to revoke permissions from itself.
+ *
+ * @param taskid Destination task ID.
+ * @param perms   Permissions to revoke.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ *
+ */
+static sysarg_t perm_revoke(task_id_t taskid, perm_t perms)
+{
+	irq_spinlock_lock(&tasks_lock, true);
+	
+	task_t *task = task_find_by_id(taskid);
+	if ((!task) || (!container_check(CONTAINER, task->container))) {
+		irq_spinlock_unlock(&tasks_lock, true);
+		return (sysarg_t) ENOENT;
+	}
+	
+	/*
+	 * Revoking permissions is different from granting them in that
+	 * a task can revoke permissions from itself even if it
+	 * doesn't have PERM_PERM.
+	 */
+	irq_spinlock_unlock(&TASK->lock, false);
+	
+	if ((!(TASK->perms & PERM_PERM)) || (task != TASK)) {
+		irq_spinlock_unlock(&TASK->lock, false);
+		irq_spinlock_unlock(&tasks_lock, true);
+		return (sysarg_t) EPERM;
+	}
+	
+	task->perms &= ~perms;
+	irq_spinlock_unlock(&TASK->lock, false);
+	
+	irq_spinlock_unlock(&tasks_lock, true);
+	return 0;
+}
+
+#ifdef __32_BITS__
+
+/** Grant permissions to a task (32 bits)
+ *
+ * The calling task must have the PERM_PERM permission.
+ *
+ * @param uspace_taskid User-space pointer to destination task ID.
+ * @param perms         Permissions to grant.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ *
+ */
+sysarg_t sys_perm_grant(sysarg64_t *uspace_taskid, perm_t perms)
+{
+	sysarg64_t taskid;
+	int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(sysarg64_t));
+	if (rc != 0)
+		return (sysarg_t) rc;
+	
+	return perm_grant((task_id_t) taskid, perms);
+}
+
+/** Revoke permissions from a task (32 bits)
+ *
+ * The calling task must have the PERM_PERM permission or the caller must
+ * attempt to revoke permissions from itself.
+ *
+ * @param uspace_taskid User-space pointer to destination task ID.
+ * @param perms         Perms to revoke.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ *
+ */
+sysarg_t sys_perm_revoke(sysarg64_t *uspace_taskid, perm_t perms)
+{
+	sysarg64_t taskid;
+	int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(sysarg64_t));
+	if (rc != 0)
+		return (sysarg_t) rc;
+	
+	return perm_revoke((task_id_t) taskid, perms);
+}
+
+#endif  /* __32_BITS__ */
+
+#ifdef __64_BITS__
+
+/** Grant permissions to a task (64 bits)
+ *
+ * The calling task must have the PERM_PERM permission.
+ *
+ * @param taskid Destination task ID.
+ * @param perms  Permissions to grant.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ *
+ */
+sysarg_t sys_perm_grant(sysarg_t taskid, perm_t perms)
+{
+	return perm_grant((task_id_t) taskid, perms);
+}
+
+/** Revoke permissions from a task (64 bits)
+ *
+ * The calling task must have the PERM_PERM permission or the caller must
+ * attempt to revoke permissions from itself.
+ *
+ * @param taskid Destination task ID.
+ * @param perms  Permissions to revoke.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ *
+ */
+sysarg_t sys_perm_revoke(sysarg_t taskid, perm_t perms)
+{
+	return perm_revoke((task_id_t) taskid, perms);
+}
+
+#endif  /* __64_BITS__ */
+
+/** @}
+ */
Index: kernel/generic/src/smp/smp_call.c
===================================================================
--- kernel/generic/src/smp/smp_call.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/smp/smp_call.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,7 +40,7 @@
 #include <arch/asm.h>  /* interrupt_disable */
 #include <arch.h>
+#include <assert.h>
 #include <config.h>
 #include <preemption.h>
-#include <debug.h>
 #include <cpu.h>
 
@@ -53,6 +53,6 @@
 void smp_call_init(void)
 {
-	ASSERT(CPU);
-	ASSERT(PREEMPTION_DISABLED || interrupts_disabled());
+	assert(CPU);
+	assert(PREEMPTION_DISABLED || interrupts_disabled());
 	
 	spinlock_initialize(&CPU->smp_calls_lock, "cpu[].smp_calls_lock");
@@ -131,6 +131,6 @@
 	 * for an acknowledgment of the IPI from the other cpu.
 	 */
-	ASSERT(!interrupts_disabled());
-	ASSERT(call_info != NULL);
+	assert(!interrupts_disabled());
+	assert(call_info != NULL);
 	
 	/* Discard invalid calls. */
@@ -207,6 +207,6 @@
 void smp_call_ipi_recv(void)
 {
-	ASSERT(interrupts_disabled());
-	ASSERT(CPU);
+	assert(interrupts_disabled());
+	assert(CPU);
 	
 	list_t calls_list;
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/synch/futex.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -61,4 +61,5 @@
  */
 
+#include <assert.h>
 #include <synch/futex.h>
 #include <synch/mutex.h>
@@ -73,4 +74,5 @@
 #include <genarch/mm/page_ht.h>
 #include <adt/cht.h>
+#include <adt/hash.h>
 #include <adt/hash_table.h>
 #include <adt/list.h>
@@ -79,6 +81,4 @@
 #include <panic.h>
 #include <errno.h>
-
-#define FUTEX_HT_SIZE	1024	/* keep it a power of 2 */
 
 /** Task specific pointer to a global kernel futex object. */
@@ -107,7 +107,8 @@
 static bool find_futex_paddr(uintptr_t uaddr, uintptr_t *phys_addr);
 
-static size_t futex_ht_hash(sysarg_t *key);
-static bool futex_ht_compare(sysarg_t *key, size_t keys, link_t *item);
-static void futex_ht_remove_callback(link_t *item);
+static size_t futex_ht_hash(const ht_link_t *item);
+static size_t futex_ht_key_hash(void *key);
+static bool futex_ht_key_equal(void *key, const ht_link_t *item);
+static void futex_ht_remove_callback(ht_link_t *item);
 
 static size_t task_fut_ht_hash(const cht_link_t *link);
@@ -130,7 +131,8 @@
 
 /** Global kernel futex hash table operations. */
-static hash_table_operations_t futex_ht_ops = {
+static hash_table_ops_t futex_ht_ops = {
 	.hash = futex_ht_hash,
-	.compare = futex_ht_compare,
+	.key_hash = futex_ht_key_hash,
+	.key_equal = futex_ht_key_equal,
 	.remove_callback = futex_ht_remove_callback
 };
@@ -148,5 +150,5 @@
 void futex_init(void)
 {
-	hash_table_create(&futex_ht, FUTEX_HT_SIZE, 1, &futex_ht_ops);
+	hash_table_create(&futex_ht, 0, 0, &futex_ht_ops);
 }
 
@@ -233,5 +235,4 @@
 {
 	waitq_initialize(&futex->wq);
-	link_initialize(&futex->ht_link);
 	futex->paddr = paddr;
 	futex->refcount = 1;
@@ -241,6 +242,6 @@
 static void futex_add_ref(futex_t *futex)
 {
-	ASSERT(spinlock_locked(&futex_ht_lock));
-	ASSERT(0 < futex->refcount);
+	assert(spinlock_locked(&futex_ht_lock));
+	assert(0 < futex->refcount);
 	++futex->refcount;
 }
@@ -249,11 +250,11 @@
 static void futex_release_ref(futex_t *futex)
 {
-	ASSERT(spinlock_locked(&futex_ht_lock));
-	ASSERT(0 < futex->refcount);
+	assert(spinlock_locked(&futex_ht_lock));
+	assert(0 < futex->refcount);
 	
 	--futex->refcount;
 	
 	if (0 == futex->refcount) {
-		hash_table_remove(&futex_ht, &futex->paddr, 1);
+		hash_table_remove(&futex_ht, &futex->paddr);
 	}
 }
@@ -346,5 +347,5 @@
 	spinlock_lock(&futex_ht_lock);
 	
-	link_t *fut_link = hash_table_find(&futex_ht, &phys_addr);
+	ht_link_t *fut_link = hash_table_find(&futex_ht, &phys_addr);
 	
 	if (fut_link) {
@@ -354,5 +355,5 @@
 	} else {
 		futex_initialize(futex, phys_addr);
-		hash_table_insert(&futex_ht, &phys_addr, &futex->ht_link);
+		hash_table_insert(&futex_ht, &futex->ht_link);
 	}
 	
@@ -436,42 +437,35 @@
 
 
-/** Compute hash index into futex hash table.
- *
- * @param key		Address where the key (i.e. physical address of futex
- *			counter) is stored.
- *
- * @return		Index into futex hash table.
- */
-size_t futex_ht_hash(sysarg_t *key)
-{
-	return (*key & (FUTEX_HT_SIZE - 1));
-}
-
-/** Compare futex hash table item with a key.
- *
- * @param key		Address where the key (i.e. physical address of futex
- *			counter) is stored.
- *
- * @return		True if the item matches the key. False otherwise.
- */
-bool futex_ht_compare(sysarg_t *key, size_t keys, link_t *item)
+/** Return the hash of the key stored in the item */
+size_t futex_ht_hash(const ht_link_t *item)
+{
+	futex_t *futex = hash_table_get_inst(item, futex_t, ht_link);
+	return hash_mix(futex->paddr);
+}
+
+/** Return the hash of the key */
+size_t futex_ht_key_hash(void *key)
+{
+	uintptr_t *paddr = (uintptr_t *) key;
+	return hash_mix(*paddr);
+}
+
+/** Return true if the key is equal to the item's lookup key. */
+bool futex_ht_key_equal(void *key, const ht_link_t *item)
+{
+	uintptr_t *paddr = (uintptr_t *) key;
+	futex_t *futex = hash_table_get_inst(item, futex_t, ht_link);
+	return *paddr == futex->paddr;
+}
+
+/** Callback for removal items from futex hash table.
+ *
+ * @param item		Item removed from the hash table.
+ */
+void futex_ht_remove_callback(ht_link_t *item)
 {
 	futex_t *futex;
 
-	ASSERT(keys == 1);
-
-	futex = hash_table_get_instance(item, futex_t, ht_link);
-	return *key == futex->paddr;
-}
-
-/** Callback for removal items from futex hash table.
- *
- * @param item		Item removed from the hash table.
- */
-void futex_ht_remove_callback(link_t *item)
-{
-	futex_t *futex;
-
-	futex = hash_table_get_instance(item, futex_t, ht_link);
+	futex = hash_table_get_inst(item, futex_t, ht_link);
 	free(futex);
 }
Index: kernel/generic/src/synch/mutex.c
===================================================================
--- kernel/generic/src/synch/mutex.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/synch/mutex.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,7 @@
  */
 
+#include <assert.h>
 #include <synch/mutex.h>
 #include <synch/semaphore.h>
-#include <debug.h>
 #include <arch.h>
 #include <stacktrace.h>
@@ -88,7 +88,7 @@
 		rc = _semaphore_down_timeout(&mtx->sem, usec, flags);
 	} else {
-		ASSERT((mtx->type == MUTEX_ACTIVE) || (!THREAD));
-		ASSERT(usec == SYNCH_NO_TIMEOUT);
-		ASSERT(!(flags & SYNCH_FLAGS_INTERRUPTIBLE));
+		assert((mtx->type == MUTEX_ACTIVE) || (!THREAD));
+		assert(usec == SYNCH_NO_TIMEOUT);
+		assert(!(flags & SYNCH_FLAGS_INTERRUPTIBLE));
 		
 		unsigned int cnt = 0;
Index: kernel/generic/src/synch/rcu.c
===================================================================
--- kernel/generic/src/synch/rcu.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/synch/rcu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -123,5 +123,6 @@
  * 
  */
- 
+
+#include <assert.h>
 #include <synch/rcu.h>
 #include <synch/condvar.h>
@@ -404,5 +405,5 @@
 	/* Stop and wait for reclaimers. */
 	for (unsigned int cpu_id = 0; cpu_id < config.cpu_active; ++cpu_id) {
-		ASSERT(cpus[cpu_id].rcu.reclaimer_thr != NULL);
+		assert(cpus[cpu_id].rcu.reclaimer_thr != NULL);
 	
 		if (cpus[cpu_id].rcu.reclaimer_thr) {
@@ -487,5 +488,5 @@
 static void read_unlock_impl(size_t *pnesting_cnt)
 {
-	ASSERT(PREEMPTION_DISABLED || interrupts_disabled());
+	assert(PREEMPTION_DISABLED || interrupts_disabled());
 	
 	if (0 == --(*pnesting_cnt)) {
@@ -509,5 +510,5 @@
 void _rcu_signal_read_unlock(void)
 {
-	ASSERT(PREEMPTION_DISABLED || interrupts_disabled());
+	assert(PREEMPTION_DISABLED || interrupts_disabled());
 	
 	/*
@@ -531,5 +532,5 @@
 	 */
 	if (THREAD && local_atomic_exchange(&THREAD->rcu.was_preempted, false)) {
-		ASSERT(link_used(&THREAD->rcu.preempt_link));
+		assert(link_used(&THREAD->rcu.preempt_link));
 
 		rm_preempted_reader();
@@ -563,5 +564,5 @@
 {
 	/* Calling from a reader section will deadlock. */
-	ASSERT(!rcu_read_locked());
+	assert(!rcu_read_locked());
 	
 	synch_item_t completion; 
@@ -576,5 +577,5 @@
 {
 	synch_item_t *completion = member_to_inst(rcu_item, synch_item_t, rcu_item);
-	ASSERT(completion);
+	assert(completion);
 	waitq_wakeup(&completion->wq, WAKEUP_FIRST);
 }
@@ -615,5 +616,5 @@
 static void add_barrier_cb(void *arg)
 {
-	ASSERT(interrupts_disabled() || PREEMPTION_DISABLED);
+	assert(interrupts_disabled() || PREEMPTION_DISABLED);
 	atomic_inc(&rcu.barrier_wait_cnt);
 	rcu_call(&CPU->rcu.barrier_item, barrier_complete);
@@ -657,5 +658,5 @@
 	rcu_func_t func)
 {
-	ASSERT(rcu_item);
+	assert(rcu_item);
 	
 	rcu_item->func = func;
@@ -689,5 +690,5 @@
 static bool cur_cbs_empty(void)
 {
-	ASSERT(THREAD && THREAD->wired);
+	assert(THREAD && THREAD->wired);
 	return NULL == CPU->rcu.cur_cbs;
 }
@@ -695,5 +696,5 @@
 static bool next_cbs_empty(void)
 {
-	ASSERT(THREAD && THREAD->wired);
+	assert(THREAD && THREAD->wired);
 	return NULL == CPU->rcu.next_cbs;
 }
@@ -702,5 +703,5 @@
 static bool arriving_cbs_empty(void)
 {
-	ASSERT(THREAD && THREAD->wired);
+	assert(THREAD && THREAD->wired);
 	/* 
 	 * Accessing with interrupts enabled may at worst lead to 
@@ -719,6 +720,6 @@
 static void reclaimer(void *arg)
 {
-	ASSERT(THREAD && THREAD->wired);
-	ASSERT(THREAD == CPU->rcu.reclaimer_thr);
+	assert(THREAD && THREAD->wired);
+	assert(THREAD == CPU->rcu.reclaimer_thr);
 
 	rcu_gp_t last_compl_gp = 0;
@@ -726,5 +727,5 @@
 	
 	while (ok && wait_for_pending_cbs()) {
-		ASSERT(CPU->rcu.reclaimer_thr == THREAD);
+		assert(CPU->rcu.reclaimer_thr == THREAD);
 		
 		exec_completed_cbs(last_compl_gp);
@@ -765,5 +766,5 @@
 	/* Both next_cbs and cur_cbs GP elapsed. */
 	if (CPU->rcu.next_cbs_gp <= last_completed_gp) {
-		ASSERT(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
+		assert(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
 		
 		size_t exec_cnt = CPU->rcu.cur_cbs_cnt + CPU->rcu.next_cbs_cnt;
@@ -864,5 +865,5 @@
 	 */
 	if (CPU->rcu.next_cbs) {
-		ASSERT(CPU->rcu.parriving_cbs_tail != &CPU->rcu.arriving_cbs);
+		assert(CPU->rcu.parriving_cbs_tail != &CPU->rcu.arriving_cbs);
 		
 		CPU->rcu.arriving_cbs = NULL;
@@ -913,5 +914,5 @@
 	}
 	
-	ASSERT(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
+	assert(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
 	
 	return expedite;	
@@ -933,6 +934,6 @@
 	spinlock_lock(&rcu.gp_lock);
 
-	ASSERT(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
-	ASSERT(CPU->rcu.cur_cbs_gp <= _rcu_cur_gp + 1);
+	assert(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
+	assert(CPU->rcu.cur_cbs_gp <= _rcu_cur_gp + 1);
 	
 	while (rcu.completed_gp < CPU->rcu.cur_cbs_gp) {
@@ -1029,5 +1030,5 @@
 static void sample_local_cpu(void *arg)
 {
-	ASSERT(interrupts_disabled());
+	assert(interrupts_disabled());
 	cpu_mask_t *reader_cpus = (cpu_mask_t *)arg;
 	
@@ -1054,5 +1055,5 @@
 void rcu_after_thread_ran(void)
 {
-	ASSERT(interrupts_disabled());
+	assert(interrupts_disabled());
 
 	/* 
@@ -1116,5 +1117,5 @@
 void rcu_before_thread_runs(void)
 {
-	ASSERT(!rcu_read_locked());
+	assert(!rcu_read_locked());
 	
 	/* Load the thread's saved nesting count from before it was preempted. */
@@ -1129,5 +1130,5 @@
 void rcu_thread_exiting(void)
 {
-	ASSERT(THE->rcu_nesting == 0);
+	assert(THE->rcu_nesting == 0);
 	
 	/* 
@@ -1157,5 +1158,5 @@
 void _rcu_preempted_unlock(void)
 {
-	ASSERT(0 == THE->rcu_nesting || RCU_WAS_PREEMPTED == THE->rcu_nesting);
+	assert(0 == THE->rcu_nesting || RCU_WAS_PREEMPTED == THE->rcu_nesting);
 	
 	size_t prev = local_atomic_exchange(&THE->rcu_nesting, 0);
@@ -1220,6 +1221,6 @@
 	}
 	
-	ASSERT(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
-	ASSERT(_rcu_cur_gp <= CPU->rcu.cur_cbs_gp);
+	assert(CPU->rcu.cur_cbs_gp <= CPU->rcu.next_cbs_gp);
+	assert(_rcu_cur_gp <= CPU->rcu.cur_cbs_gp);
 	
 	/* 
@@ -1262,5 +1263,5 @@
 static bool cv_wait_for_gp(rcu_gp_t wait_on_gp)
 {
-	ASSERT(spinlock_locked(&rcu.gp_lock));
+	assert(spinlock_locked(&rcu.gp_lock));
 	
 	bool interrupted = false;
@@ -1284,5 +1285,5 @@
 
 		if (detector_idle) {
-			ASSERT(_rcu_cur_gp == rcu.completed_gp);
+			assert(_rcu_cur_gp == rcu.completed_gp);
 			condvar_signal(&rcu.req_gp_changed);
 		}
@@ -1323,5 +1324,5 @@
 static bool wait_for_detect_req(void)
 {
-	ASSERT(spinlock_locked(&rcu.gp_lock));
+	assert(spinlock_locked(&rcu.gp_lock));
 	
 	bool interrupted = false;
@@ -1340,5 +1341,5 @@
 static void end_cur_gp(void)
 {
-	ASSERT(spinlock_locked(&rcu.gp_lock));
+	assert(spinlock_locked(&rcu.gp_lock));
 	
 	rcu.completed_gp = _rcu_cur_gp;
@@ -1423,6 +1424,6 @@
 static void sample_local_cpu(void *arg)
 {
-	ASSERT(interrupts_disabled());
-	ASSERT(!CPU->rcu.is_delaying_gp);
+	assert(interrupts_disabled());
+	assert(!CPU->rcu.is_delaying_gp);
 	
 	/* Cpu did not pass a quiescent state yet. */
@@ -1430,5 +1431,5 @@
 		/* Interrupted a reader in a reader critical section. */
 		if (0 < CPU->rcu.nesting_cnt) {
-			ASSERT(!CPU->idle);
+			assert(!CPU->idle);
 			/* 
 			 * Note to notify the detector from rcu_read_unlock(). 
@@ -1492,5 +1493,5 @@
 void rcu_after_thread_ran(void)
 {
-	ASSERT(interrupts_disabled());
+	assert(interrupts_disabled());
 
 	/* 
@@ -1559,6 +1560,6 @@
 void rcu_before_thread_runs(void)
 {
-	ASSERT(PREEMPTION_DISABLED || interrupts_disabled());
-	ASSERT(0 == CPU->rcu.nesting_cnt);
+	assert(PREEMPTION_DISABLED || interrupts_disabled());
+	assert(0 == CPU->rcu.nesting_cnt);
 	
 	/* Load the thread's saved nesting count from before it was preempted. */
@@ -1590,7 +1591,7 @@
 void rcu_thread_exiting(void)
 {
-	ASSERT(THREAD != NULL);
-	ASSERT(THREAD->state == Exiting);
-	ASSERT(PREEMPTION_DISABLED || interrupts_disabled());
+	assert(THREAD != NULL);
+	assert(THREAD->state == Exiting);
+	assert(PREEMPTION_DISABLED || interrupts_disabled());
 	
 	/* 
@@ -1615,5 +1616,5 @@
 static void start_new_gp(void)
 {
-	ASSERT(spinlock_locked(&rcu.gp_lock));
+	assert(spinlock_locked(&rcu.gp_lock));
 	
 	irq_spinlock_lock(&rcu.preempt_lock, true);
@@ -1734,5 +1735,5 @@
 static void upd_missed_gp_in_wait(rcu_gp_t completed_gp)
 {
-	ASSERT(CPU->rcu.cur_cbs_gp <= completed_gp);
+	assert(CPU->rcu.cur_cbs_gp <= completed_gp);
 	
 	size_t delta = (size_t)(completed_gp - CPU->rcu.cur_cbs_gp);
@@ -1764,5 +1765,5 @@
 	irq_spinlock_lock(&rcu.preempt_lock, true);
 	
-	ASSERT(link_used(&THREAD->rcu.preempt_link));
+	assert(link_used(&THREAD->rcu.preempt_link));
 
 	bool prev_empty = list_empty(&rcu.cur_preempted);
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/synch/waitq.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,4 +44,5 @@
  */
 
+#include <assert.h>
 #include <synch/waitq.h>
 #include <synch/spinlock.h>
@@ -203,5 +204,5 @@
 		irq_spinlock_lock(&thread->lock, false);
 		
-		ASSERT(thread->sleep_interruptible);
+		assert(thread->sleep_interruptible);
 		
 		if ((thread->timeout_pending) &&
@@ -264,5 +265,5 @@
 int waitq_sleep_timeout(waitq_t *wq, uint32_t usec, unsigned int flags)
 {
-	ASSERT((!PREEMPTION_DISABLED) || (PARAM_NON_BLOCKING(flags, usec)));
+	assert((!PREEMPTION_DISABLED) || (PARAM_NON_BLOCKING(flags, usec)));
 	
 	ipl_t ipl = waitq_sleep_prepare(wq);
@@ -496,5 +497,5 @@
 static void waitq_complete_wakeup(waitq_t *wq)
 {
-	ASSERT(interrupts_disabled());
+	assert(interrupts_disabled());
 	
 	irq_spinlock_lock(&wq->lock, false);
@@ -520,6 +521,6 @@
 	size_t count = 0;
 
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&wq->lock));
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&wq->lock));
 	
 loop:
Index: kernel/generic/src/synch/workqueue.c
===================================================================
--- kernel/generic/src/synch/workqueue.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/synch/workqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
  */
 
+#include <assert.h>
 #include <synch/workqueue.h>
 #include <synch/spinlock.h>
@@ -189,5 +190,5 @@
 	if (workq) {
 		if (workq_init(workq, name)) {
-			ASSERT(!workq_corrupted(workq));
+			assert(!workq_corrupted(workq));
 			return workq;
 		}
@@ -202,5 +203,5 @@
 void workq_destroy(struct work_queue *workq)
 {
-	ASSERT(!workq_corrupted(workq));
+	assert(!workq_corrupted(workq));
 	
 	irq_spinlock_lock(&workq->lock, true);
@@ -214,5 +215,5 @@
 		workq_stop(workq);
 	} else {
-		ASSERT(0 == running_workers);
+		assert(0 == running_workers);
 	}
 	
@@ -264,5 +265,5 @@
 static bool add_worker(struct work_queue *workq)
 {
-	ASSERT(!workq_corrupted(workq));
+	assert(!workq_corrupted(workq));
 
 	thread_t *thread = thread_create(worker_thread, workq, TASK, 
@@ -273,5 +274,5 @@
 		
 		/* cur_worker_cnt proactively increased in signal_worker_logic() .*/
-		ASSERT(0 < workq->cur_worker_cnt);
+		assert(0 < workq->cur_worker_cnt);
 		--workq->cur_worker_cnt;
 		
@@ -312,5 +313,5 @@
 		
 		/* cur_worker_cnt proactively increased in signal_worker() .*/
-		ASSERT(0 < workq->cur_worker_cnt);
+		assert(0 < workq->cur_worker_cnt);
 		--workq->cur_worker_cnt;
 	}
@@ -334,5 +335,5 @@
 void workq_stop(struct work_queue *workq)
 {
-	ASSERT(!workq_corrupted(workq));
+	assert(!workq_corrupted(workq));
 	
 	interrupt_workers(workq);
@@ -346,5 +347,5 @@
 
 	/* workq_stop() may only be called once. */
-	ASSERT(!workq->stopping);
+	assert(!workq->stopping);
 	workq->stopping = true;
 	
@@ -358,5 +359,5 @@
 static void wait_for_workers(struct work_queue *workq)
 {
-	ASSERT(!PREEMPTION_DISABLED);
+	assert(!PREEMPTION_DISABLED);
 	
 	irq_spinlock_lock(&workq->lock, true);
@@ -375,5 +376,5 @@
 	}
 	
-	ASSERT(list_empty(&workq->workers));
+	assert(list_empty(&workq->workers));
 	
 	/* Wait for deferred add_worker_op(), signal_worker_op() to finish. */
@@ -473,5 +474,5 @@
 	work_func_t func, bool can_block)
 {
-	ASSERT(!workq_corrupted(workq));
+	assert(!workq_corrupted(workq));
 	
 	bool success = true;
@@ -521,17 +522,17 @@
 static size_t active_workers_now(struct work_queue *workq)
 {
-	ASSERT(irq_spinlock_locked(&workq->lock));
+	assert(irq_spinlock_locked(&workq->lock));
 	
 	/* Workers blocked are sleeping in the work function (ie not idle). */
-	ASSERT(workq->blocked_worker_cnt <= workq->cur_worker_cnt);
+	assert(workq->blocked_worker_cnt <= workq->cur_worker_cnt);
 	/* Idle workers are waiting for more work to arrive in condvar_wait. */
-	ASSERT(workq->idle_worker_cnt <= workq->cur_worker_cnt);
+	assert(workq->idle_worker_cnt <= workq->cur_worker_cnt);
 	
 	/* Idle + blocked workers == sleeping worker threads. */
 	size_t sleeping_workers = workq->blocked_worker_cnt + workq->idle_worker_cnt;
 	
-	ASSERT(sleeping_workers	<= workq->cur_worker_cnt);
+	assert(sleeping_workers	<= workq->cur_worker_cnt);
 	/* Workers pending activation are idle workers not yet given a time slice. */
-	ASSERT(workq->activate_pending <= workq->idle_worker_cnt);
+	assert(workq->activate_pending <= workq->idle_worker_cnt);
 	
 	/* 
@@ -550,5 +551,5 @@
 static size_t active_workers(struct work_queue *workq)
 {
-	ASSERT(irq_spinlock_locked(&workq->lock));
+	assert(irq_spinlock_locked(&workq->lock));
 	
 	/* 
@@ -573,10 +574,10 @@
 static void signal_worker_op(struct work_queue *workq)
 {
-	ASSERT(!workq_corrupted(workq));
+	assert(!workq_corrupted(workq));
 
 	condvar_signal(&workq->activate_worker);
 	
 	irq_spinlock_lock(&workq->lock, true);
-	ASSERT(0 < workq->pending_op_cnt);
+	assert(0 < workq->pending_op_cnt);
 	--workq->pending_op_cnt;
 	irq_spinlock_unlock(&workq->lock, true);
@@ -593,6 +594,6 @@
 static signal_op_t signal_worker_logic(struct work_queue *workq, bool can_block)
 {
-	ASSERT(!workq_corrupted(workq));
-	ASSERT(irq_spinlock_locked(&workq->lock));
+	assert(!workq_corrupted(workq));
+	assert(irq_spinlock_locked(&workq->lock));
 	
 	/* Only signal workers if really necessary. */
@@ -645,5 +646,5 @@
 			 */
 			if (need_worker && !can_block && 0 == active) {
-				ASSERT(0 == workq->idle_worker_cnt);
+				assert(0 == workq->idle_worker_cnt);
 				
 				irq_spinlock_lock(&nonblock_adder.lock, true);
@@ -681,5 +682,5 @@
 	}
 	
-	ASSERT(arg != NULL);
+	assert(arg != NULL);
 	
 	struct work_queue *workq = arg;
@@ -697,5 +698,5 @@
 static bool dequeue_work(struct work_queue *workq, work_t **pwork_item)
 {
-	ASSERT(!workq_corrupted(workq));
+	assert(!workq_corrupted(workq));
 	
 	irq_spinlock_lock(&workq->lock, true);
@@ -704,5 +705,5 @@
 	if (!workq->stopping && worker_unnecessary(workq)) {
 		/* There are too many workers for this load. Exit. */
-		ASSERT(0 < workq->cur_worker_cnt);
+		assert(0 < workq->cur_worker_cnt);
 		--workq->cur_worker_cnt;
 		list_remove(&THREAD->workq_link);
@@ -729,5 +730,5 @@
 		
 #ifdef CONFIG_DEBUG
-		ASSERT(!work_item_corrupted(*pwork_item));
+		assert(!work_item_corrupted(*pwork_item));
 		(*pwork_item)->cookie = 0;
 #endif
@@ -738,5 +739,5 @@
 	} else {
 		/* Requested to stop and no more work queued. */
-		ASSERT(workq->stopping);
+		assert(workq->stopping);
 		--workq->cur_worker_cnt;
 		stop = true;
@@ -751,5 +752,5 @@
 static bool worker_unnecessary(struct work_queue *workq)
 {
-	ASSERT(irq_spinlock_locked(&workq->lock));
+	assert(irq_spinlock_locked(&workq->lock));
 	
 	/* No work is pending. We don't need too many idle threads. */
@@ -775,11 +776,11 @@
 	
 	/* Ignore lock ordering just here. */
-	ASSERT(irq_spinlock_locked(&workq->lock));
+	assert(irq_spinlock_locked(&workq->lock));
 	
 	_condvar_wait_timeout_irq_spinlock(&workq->activate_worker,
 		&workq->lock, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
 
-	ASSERT(!workq_corrupted(workq));
-	ASSERT(irq_spinlock_locked(&workq->lock));
+	assert(!workq_corrupted(workq));
+	assert(irq_spinlock_locked(&workq->lock));
 	
 	THREAD->workq_idling = false;
@@ -791,14 +792,14 @@
 void workq_before_thread_is_ready(thread_t *thread)
 {
-	ASSERT(thread);
-	ASSERT(irq_spinlock_locked(&thread->lock));
+	assert(thread);
+	assert(irq_spinlock_locked(&thread->lock));
 
 	/* Worker's work func() is about to wake up from sleeping. */
 	if (thread->workq && thread->workq_blocked) {
 		/* Must be blocked in user work func() and not be waiting for work. */
-		ASSERT(!thread->workq_idling);
-		ASSERT(thread->state == Sleeping);
-		ASSERT(THREAD != thread);
-		ASSERT(!workq_corrupted(thread->workq));
+		assert(!thread->workq_idling);
+		assert(thread->state == Sleeping);
+		assert(THREAD != thread);
+		assert(!workq_corrupted(thread->workq));
 		
 		/* Protected by thread->lock */
@@ -814,11 +815,11 @@
 void workq_after_thread_ran(void)
 {
-	ASSERT(THREAD);
-	ASSERT(irq_spinlock_locked(&THREAD->lock));
+	assert(THREAD);
+	assert(irq_spinlock_locked(&THREAD->lock));
 
 	/* Worker's work func() is about to sleep/block. */
 	if (THREAD->workq && THREAD->state == Sleeping && !THREAD->workq_idling) {
-		ASSERT(!THREAD->workq_blocked);
-		ASSERT(!workq_corrupted(THREAD->workq));
+		assert(!THREAD->workq_blocked);
+		assert(!workq_corrupted(THREAD->workq));
 		
 		THREAD->workq_blocked = true;
@@ -834,5 +835,5 @@
 		
 		if (op) {
-			ASSERT(add_worker_noblock_op == op || signal_worker_op == op);
+			assert(add_worker_noblock_op == op || signal_worker_op == op);
 			op(THREAD->workq);
 		}
@@ -903,5 +904,5 @@
 			struct work_queue, nb_link);
 
-		ASSERT(!workq_corrupted(*pworkq));
+		assert(!workq_corrupted(*pworkq));
 		
 		list_remove(&(*pworkq)->nb_link);
Index: kernel/generic/src/syscall/copy.c
===================================================================
--- kernel/generic/src/syscall/copy.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/syscall/copy.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
  */
 
+#include <assert.h>
 #include <syscall/copy.h>
 #include <proc/thread.h>
@@ -63,6 +64,6 @@
 	int rc;
 	
-	ASSERT(THREAD);
-	ASSERT(!THREAD->in_copy_from_uspace);
+	assert(THREAD);
+	assert(!THREAD->in_copy_from_uspace);
 	
 	if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
@@ -114,6 +115,6 @@
 	int rc;
 	
-	ASSERT(THREAD);
-	ASSERT(!THREAD->in_copy_to_uspace);
+	assert(THREAD);
+	assert(!THREAD->in_copy_to_uspace);
 	
 	if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/syscall/syscall.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,5 +45,4 @@
 #include <arch.h>
 #include <debug.h>
-#include <ddi/device.h>
 #include <interrupt.h>
 #include <ipc/sysipc.h>
@@ -53,5 +52,5 @@
 #include <ddi/ddi.h>
 #include <ipc/event.h>
-#include <security/cap.h>
+#include <security/perm.h>
 #include <sysinfo/sysinfo.h>
 #include <console/console.h>
@@ -123,80 +122,78 @@
 syshandler_t syscall_table[SYSCALL_END] = {
 	/* System management syscalls. */
-	(syshandler_t) sys_kio,
+	[SYS_KIO] = (syshandler_t) sys_kio,
 	
 	/* Thread and task related syscalls. */
-	(syshandler_t) sys_thread_create,
-	(syshandler_t) sys_thread_exit,
-	(syshandler_t) sys_thread_get_id,
-	(syshandler_t) sys_thread_usleep,
-	(syshandler_t) sys_thread_udelay,
-	
-	(syshandler_t) sys_task_get_id,
-	(syshandler_t) sys_task_set_name,
-	(syshandler_t) sys_task_kill,
-	(syshandler_t) sys_task_exit,
-	(syshandler_t) sys_program_spawn_loader,
+	[SYS_THREAD_CREATE] = (syshandler_t) sys_thread_create,
+	[SYS_THREAD_EXIT] = (syshandler_t) sys_thread_exit,
+	[SYS_THREAD_GET_ID] = (syshandler_t) sys_thread_get_id,
+	[SYS_THREAD_USLEEP] = (syshandler_t) sys_thread_usleep,
+	[SYS_THREAD_UDELAY] = (syshandler_t) sys_thread_udelay,
+	
+	[SYS_TASK_GET_ID] = (syshandler_t) sys_task_get_id,
+	[SYS_TASK_SET_NAME] = (syshandler_t) sys_task_set_name,
+	[SYS_TASK_KILL] = (syshandler_t) sys_task_kill,
+	[SYS_TASK_EXIT] = (syshandler_t) sys_task_exit,
+	[SYS_PROGRAM_SPAWN_LOADER] = (syshandler_t) sys_program_spawn_loader,
 	
 	/* Synchronization related syscalls. */
-	(syshandler_t) sys_futex_sleep,
-	(syshandler_t) sys_futex_wakeup,
-	(syshandler_t) sys_smc_coherence,
-	(syshandler_t) sys_smp_memory_barrier,
-	
+	[SYS_FUTEX_SLEEP] = (syshandler_t) sys_futex_sleep,
+	[SYS_FUTEX_WAKEUP] = (syshandler_t) sys_futex_wakeup,
+	[SYS_SMC_COHERENCE] = (syshandler_t) sys_smc_coherence,
+	[SYS_SMP_MEMORY_BARRIER] = (syshandler_t) sys_smp_memory_barrier,
 	
 	/* Address space related syscalls. */
-	(syshandler_t) sys_as_area_create,
-	(syshandler_t) sys_as_area_resize,
-	(syshandler_t) sys_as_area_change_flags,
-	(syshandler_t) sys_as_area_destroy,
+	[SYS_AS_AREA_CREATE] = (syshandler_t) sys_as_area_create,
+	[SYS_AS_AREA_RESIZE] = (syshandler_t) sys_as_area_resize,
+	[SYS_AS_AREA_CHANGE_FLAGS] = (syshandler_t) sys_as_area_change_flags,
+	[SYS_AS_AREA_DESTROY] = (syshandler_t) sys_as_area_destroy,
 	
 	/* Page mapping related syscalls. */
-	(syshandler_t) sys_page_find_mapping,
+	[SYS_PAGE_FIND_MAPPING] = (syshandler_t) sys_page_find_mapping,
 	
 	/* IPC related syscalls. */
-	(syshandler_t) sys_ipc_call_async_fast,
-	(syshandler_t) sys_ipc_call_async_slow,
-	(syshandler_t) sys_ipc_answer_fast,
-	(syshandler_t) sys_ipc_answer_slow,
-	(syshandler_t) sys_ipc_forward_fast,
-	(syshandler_t) sys_ipc_forward_slow,
-	(syshandler_t) sys_ipc_wait_for_call,
-	(syshandler_t) sys_ipc_poke,
-	(syshandler_t) sys_ipc_hangup,
-	(syshandler_t) sys_ipc_connect_kbox,
+	[SYS_IPC_CALL_ASYNC_FAST] = (syshandler_t) sys_ipc_call_async_fast,
+	[SYS_IPC_CALL_ASYNC_SLOW] = (syshandler_t) sys_ipc_call_async_slow,
+	[SYS_IPC_ANSWER_FAST] = (syshandler_t) sys_ipc_answer_fast,
+	[SYS_IPC_ANSWER_SLOW] = (syshandler_t) sys_ipc_answer_slow,
+	[SYS_IPC_FORWARD_FAST] = (syshandler_t) sys_ipc_forward_fast,
+	[SYS_IPC_FORWARD_SLOW] = (syshandler_t) sys_ipc_forward_slow,
+	[SYS_IPC_WAIT] = (syshandler_t) sys_ipc_wait_for_call,
+	[SYS_IPC_POKE] = (syshandler_t) sys_ipc_poke,
+	[SYS_IPC_HANGUP] = (syshandler_t) sys_ipc_hangup,
+	[SYS_IPC_CONNECT_KBOX] = (syshandler_t) sys_ipc_connect_kbox,
 	
 	/* Event notification syscalls. */
-	(syshandler_t) sys_ipc_event_subscribe,
-	(syshandler_t) sys_ipc_event_unsubscribe,
-	(syshandler_t) sys_ipc_event_unmask,
-	
-	/* Capabilities related syscalls. */
-	(syshandler_t) sys_cap_grant,
-	(syshandler_t) sys_cap_revoke,
+	[SYS_IPC_EVENT_SUBSCRIBE] = (syshandler_t) sys_ipc_event_subscribe,
+	[SYS_IPC_EVENT_UNSUBSCRIBE] = (syshandler_t) sys_ipc_event_unsubscribe,
+	[SYS_IPC_EVENT_UNMASK] = (syshandler_t) sys_ipc_event_unmask,
+	
+	/* Permission related syscalls. */
+	[SYS_PERM_GRANT] = (syshandler_t) sys_perm_grant,
+	[SYS_PERM_REVOKE] = (syshandler_t) sys_perm_revoke,
 	
 	/* DDI related syscalls. */
-	(syshandler_t) sys_device_assign_devno,
-	(syshandler_t) sys_physmem_map,
-	(syshandler_t) sys_physmem_unmap,
-	(syshandler_t) sys_dmamem_map,
-	(syshandler_t) sys_dmamem_unmap,
-	(syshandler_t) sys_iospace_enable,
-	(syshandler_t) sys_iospace_disable,
-	
-	(syshandler_t) sys_ipc_irq_subscribe,
-	(syshandler_t) sys_ipc_irq_unsubscribe,
+	[SYS_PHYSMEM_MAP] = (syshandler_t) sys_physmem_map,
+	[SYS_PHYSMEM_UNMAP] = (syshandler_t) sys_physmem_unmap,
+	[SYS_DMAMEM_MAP] = (syshandler_t) sys_dmamem_map,
+	[SYS_DMAMEM_UNMAP] = (syshandler_t) sys_dmamem_unmap,
+	[SYS_IOSPACE_ENABLE] = (syshandler_t) sys_iospace_enable,
+	[SYS_IOSPACE_DISABLE] = (syshandler_t) sys_iospace_disable,
+	
+	[SYS_IPC_IRQ_SUBSCRIBE] = (syshandler_t) sys_ipc_irq_subscribe,
+	[SYS_IPC_IRQ_UNSUBSCRIBE] = (syshandler_t) sys_ipc_irq_unsubscribe,
 	
 	/* Sysinfo syscalls. */
-	(syshandler_t) sys_sysinfo_get_keys_size,
-	(syshandler_t) sys_sysinfo_get_keys,
-	(syshandler_t) sys_sysinfo_get_val_type,
-	(syshandler_t) sys_sysinfo_get_value,
-	(syshandler_t) sys_sysinfo_get_data_size,
-	(syshandler_t) sys_sysinfo_get_data,
+	[SYS_SYSINFO_GET_KEYS_SIZE] = (syshandler_t) sys_sysinfo_get_keys_size,
+	[SYS_SYSINFO_GET_KEYS] = (syshandler_t) sys_sysinfo_get_keys,
+	[SYS_SYSINFO_GET_VAL_TYPE] = (syshandler_t) sys_sysinfo_get_val_type,
+	[SYS_SYSINFO_GET_VALUE] = (syshandler_t) sys_sysinfo_get_value,
+	[SYS_SYSINFO_GET_DATA_SIZE] = (syshandler_t) sys_sysinfo_get_data_size,
+	[SYS_SYSINFO_GET_DATA] = (syshandler_t) sys_sysinfo_get_data,
 	
 	/* Kernel console syscalls. */
-	(syshandler_t) sys_debug_console,
-	
-	(syshandler_t) sys_klog,
+	[SYS_DEBUG_CONSOLE] = (syshandler_t) sys_debug_console,
+	
+	[SYS_KLOG] = (syshandler_t) sys_klog,
 };
 
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/sysinfo/stats.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
  */
 
+#include <assert.h>
 #include <typedefs.h>
 #include <abi/sysinfo.h>
@@ -45,4 +46,5 @@
 #include <proc/thread.h>
 #include <interrupt.h>
+#include <stdbool.h>
 #include <str.h>
 #include <errno.h>
@@ -230,6 +232,6 @@
 static void produce_stats_task(task_t *task, stats_task_t *stats_task)
 {
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&task->lock));
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&task->lock));
 	
 	stats_task->task_id = task->taskid;
@@ -332,6 +334,6 @@
 static void produce_stats_thread(thread_t *thread, stats_thread_t *stats_thread)
 {
-	ASSERT(interrupts_disabled());
-	ASSERT(irq_spinlock_locked(&thread->lock));
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&thread->lock));
 	
 	stats_thread->thread_id = thread->tid;
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
  */
 
+#include <assert.h>
 #include <sysinfo/sysinfo.h>
 #include <mm/slab.h>
@@ -125,5 +126,5 @@
     sysinfo_item_t *subtree, sysinfo_return_t **ret, bool dry_run)
 {
-	ASSERT(subtree != NULL);
+	assert(subtree != NULL);
 	
 	sysinfo_item_t *cur = subtree;
@@ -191,5 +192,5 @@
     sysinfo_item_t **psubtree)
 {
-	ASSERT(psubtree != NULL);
+	assert(psubtree != NULL);
 	
 	if (*psubtree == NULL) {
@@ -204,9 +205,9 @@
 		*psubtree =
 		    (sysinfo_item_t *) slab_alloc(sysinfo_item_slab, 0);
-		ASSERT(*psubtree);
+		assert(*psubtree);
 		
 		/* Fill in item name up to the delimiter */
 		(*psubtree)->name = str_ndup(name, i);
-		ASSERT((*psubtree)->name);
+		assert((*psubtree)->name);
 		
 		/* Create subtree items */
@@ -268,5 +269,5 @@
 			sysinfo_item_t *item =
 			    (sysinfo_item_t *) slab_alloc(sysinfo_item_slab, 0);
-			ASSERT(item);
+			assert(item);
 			
 			cur->next = item;
@@ -274,5 +275,5 @@
 			/* Fill in item name up to the delimiter */
 			item->name = str_ndup(name, i);
-			ASSERT(item->name);
+			assert(item->name);
 			
 			/* Create subtree items */
@@ -291,5 +292,5 @@
 	
 	/* Unreachable */
-	ASSERT(false);
+	assert(false);
 	return NULL;
 }
@@ -649,5 +650,5 @@
 	
 	char *path = (char *) malloc(size + 1, 0);
-	ASSERT(path);
+	assert(path);
 	
 	if ((copy_from_uspace(path, ptr, size + 1) == 0) &&
@@ -699,4 +700,5 @@
 	
 	sysinfo_return_t ret;
+	ret.tag = SYSINFO_VAL_UNDEFINED;
 	
 	if (subtree != NULL) {
@@ -729,7 +731,4 @@
 			ret.data.size = size;
 		}
-	} else {
-		/* No item in the fixed sysinfo tree */
-		ret.tag = SYSINFO_VAL_UNDEFINED;
 	}
 	
@@ -760,5 +759,5 @@
 	
 	char *path = (char *) malloc(size + 1, 0);
-	ASSERT(path);
+	assert(path);
 	
 	if ((copy_from_uspace(path, ptr, size + 1) == 0) &&
Index: kernel/generic/src/udebug/udebug.c
===================================================================
--- kernel/generic/src/udebug/udebug.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/udebug/udebug.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,6 +38,7 @@
  */
 
+#include <assert.h>
+#include <debug.h>
 #include <synch/waitq.h>
-#include <debug.h>
 #include <udebug/udebug.h>
 #include <errno.h>
@@ -116,6 +117,6 @@
 void udebug_stoppable_begin(void)
 {
-	ASSERT(THREAD);
-	ASSERT(TASK);
+	assert(THREAD);
+	assert(TASK);
 	
 	mutex_lock(&TASK->udebug.lock);
@@ -125,5 +126,5 @@
 	/* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */
 	mutex_lock(&THREAD->udebug.lock);
-	ASSERT(THREAD->udebug.stoppable == false);
+	assert(THREAD->udebug.stoppable == false);
 	THREAD->udebug.stoppable = true;
 	
@@ -136,5 +137,5 @@
 		
 		call_t *db_call = TASK->udebug.begin_call;
-		ASSERT(db_call);
+		assert(db_call);
 		
 		TASK->udebug.dt_state = UDEBUG_TS_ACTIVE;
@@ -158,5 +159,5 @@
 			call_t *go_call = THREAD->udebug.go_call;
 			THREAD->udebug.go_call = NULL;
-			ASSERT(go_call);
+			assert(go_call);
 			
 			IPC_SET_RETVAL(go_call->data, 0);
@@ -195,5 +196,5 @@
 	} else {
 		++TASK->udebug.not_stoppable_count;
-		ASSERT(THREAD->udebug.stoppable == true);
+		assert(THREAD->udebug.stoppable == true);
 		THREAD->udebug.stoppable = false;
 		
@@ -398,5 +399,5 @@
 int udebug_task_cleanup(struct task *task)
 {
-	ASSERT(mutex_locked(&task->udebug.lock));
+	assert(mutex_locked(&task->udebug.lock));
 
 	if ((task->udebug.dt_state != UDEBUG_TS_BEGINNING) &&
Index: kernel/generic/src/udebug/udebug_ipc.c
===================================================================
--- kernel/generic/src/udebug/udebug_ipc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/udebug/udebug_ipc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,6 @@
  * functions from the udebug_ops module which implement them.
  */
- 
+
+#include <assert.h>
 #include <proc/task.h>
 #include <proc/thread.h>
@@ -355,5 +356,5 @@
 	}
 
-	ASSERT(buffer != NULL);
+	assert(buffer != NULL);
 
 	/*
@@ -401,5 +402,5 @@
 	}
 
-	ASSERT(buffer != NULL);
+	assert(buffer != NULL);
 
 	IPC_SET_RETVAL(call->data, 0);
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -51,5 +51,5 @@
 #include <udebug/udebug.h>
 #include <udebug/udebug_ops.h>
-#include <memstr.h>
+#include <mem.h>
 
 /** Prepare a thread for a debugging operation.
Index: kernel/test/cht/cht1.c
===================================================================
--- kernel/test/cht/cht1.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/cht/cht1.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,7 +27,7 @@
  */
 
+#include <assert.h>
 #include <test.h>
 #include <print.h>
-#include <debug.h>
 #include <adt/cht.h>
 #include <synch/rcu.h>
@@ -45,5 +45,5 @@
 {
 	val_t *v = member_to_inst(item, val_t, link);
-	ASSERT(v->hash == (v->unique_id % 10));
+	assert(v->hash == (v->unique_id % 10));
 	return v->hash;
 }
@@ -70,5 +70,5 @@
 {
 	val_t *v = member_to_inst(item, val_t, link);
-	ASSERT(!v->deleted);
+	assert(!v->deleted);
 	v->deleted = true;
 	free(v);
@@ -364,5 +364,5 @@
 {
 	stress_work_t *work = (stress_work_t *)arg;
-	ASSERT(0 == *work->stop);
+	assert(0 == *work->stop);
 	
 	size_t loops = 0;
@@ -528,5 +528,5 @@
 			thr[i] = thread_create(resize_stresser, &pwork[i], TASK, 0, "cht-resize");
 		
-		ASSERT(thr[i]);
+		assert(thr[i]);
 		thread_wire(thr[i], &cpus[i % config.cpu_active]);
 		thread_ready(thr[i]);
Index: kernel/test/debug/mips1_skip.c
===================================================================
--- kernel/test/debug/mips1_skip.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/debug/mips1_skip.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,4 +28,5 @@
 
 #include <test.h>
+#include <stddef.h>
 
 const char *test_mips1(void)
Index: kernel/test/mm/falloc2.c
===================================================================
--- kernel/test/mm/falloc2.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/mm/falloc2.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 #include <debug.h>
 #include <proc/thread.h>
-#include <memstr.h>
+#include <mem.h>
 #include <arch.h>
 
Index: kernel/test/mm/purge1_skip.c
===================================================================
--- kernel/test/mm/purge1_skip.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/mm/purge1_skip.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,4 +27,5 @@
  */
 
+#include <stddef.h>
 #include <test.h>
 
Index: kernel/test/mm/slab1.c
===================================================================
--- kernel/test/mm/slab1.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/mm/slab1.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -32,5 +32,5 @@
 #include <proc/thread.h>
 #include <arch.h>
-#include <memstr.h>
+#include <mem.h>
 
 #define VAL_COUNT  1024
Index: kernel/test/mm/slab2.c
===================================================================
--- kernel/test/mm/slab2.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/mm/slab2.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
 #include <arch.h>
 #include <mm/frame.h>
-#include <memstr.h>
+#include <mem.h>
 #include <synch/condvar.h>
 #include <synch/mutex.h>
Index: kernel/test/print/print1.c
===================================================================
--- kernel/test/print/print1.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/print/print1.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,4 +28,5 @@
 
 #include <print.h>
+#include <stddef.h>
 #include <test.h>
 
Index: kernel/test/print/print2.c
===================================================================
--- kernel/test/print/print2.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/print/print2.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,4 +28,5 @@
 
 #include <print.h>
+#include <stddef.h>
 #include <test.h>
 
@@ -61,5 +62,5 @@
 	TPRINTF("Real output:     [%td] [%tu] [%tx] [%ti] [%to]\n\n", d, neg_d, neg_d, d, neg_d);
 	
-	sysarg_t nat = UINTN_C(0x12345678);
+	sysarg_t nat = 0x12345678;
 	
 	TPRINTF("Testing printf(\"%%#" PRIx64 " %%#" PRIx32 " %%#" PRIx16 " %%#" PRIx8 " %%#" PRIxn " %%#" PRIx64 " %%s\", (uint64_t) UINT64_C(0x1234567887654321), (uint32_t) UINT32_C(0x12345678), (uint16_t) UINT16_C(0x1234), (uint8_t) UINT8_C(0x12), nat, (uint64_t) UINT64_C(0x1234567887654321), \"Lovely string\"):\n");
Index: kernel/test/print/print3.c
===================================================================
--- kernel/test/print/print3.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/print/print3.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,6 +27,7 @@
  */
 
+#include <macros.h>
 #include <print.h>
-#include <macros.h>
+#include <stddef.h>
 #include <test.h>
 
Index: kernel/test/print/print4.c
===================================================================
--- kernel/test/print/print4.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/print/print4.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,4 +28,5 @@
 
 #include <print.h>
+#include <stddef.h>
 #include <test.h>
 
Index: kernel/test/print/print5.c
===================================================================
--- kernel/test/print/print5.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/print/print5.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,4 +40,5 @@
 
 #include <print.h>
+#include <stddef.h>
 #include <test.h>
 
Index: kernel/test/smpcall/smpcall1.c
===================================================================
--- kernel/test/smpcall/smpcall1.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/smpcall/smpcall1.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,4 +30,5 @@
 #include <debug.h>
 
+#include <assert.h>
 #include <test.h>
 #include <smp/smp_call.h>
@@ -50,5 +51,5 @@
 static void inc(void *p)
 {
-	ASSERT(interrupts_disabled());
+	assert(interrupts_disabled());
 
 	size_t *pcall_cnt = (size_t*)p;
Index: kernel/test/synch/rcu1.c
===================================================================
--- kernel/test/synch/rcu1.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/synch/rcu1.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,4 +27,5 @@
  */
 
+#include <assert.h>
 #include <test.h>
 #include <arch.h>
@@ -81,5 +82,5 @@
 static void run_thread(size_t k, void (*func)(void*), void *arg)
 {
-	ASSERT(thread[k] == NULL);
+	assert(thread[k] == NULL);
 	
 	thread[k] = thread_create(func, arg, TASK, THREAD_FLAG_NONE, 
@@ -130,5 +131,5 @@
 static void run_one(void (*func)(void*), void *arg)
 {
-	ASSERT(one_idx < MAX_THREADS);
+	assert(one_idx < MAX_THREADS);
 	run_thread(one_idx, func, arg);
 	++one_idx;
@@ -138,5 +139,5 @@
 static void join_one(void)
 {
-	ASSERT(0 < one_idx && one_idx <= MAX_THREADS);
+	assert(0 < one_idx && one_idx <= MAX_THREADS);
 
 	--one_idx;
@@ -168,5 +169,5 @@
 static void get_seq(size_t from, size_t to, size_t steps, size_t *seq)
 {
-	ASSERT(0 < steps && from <= to && 0 < to);
+	assert(0 < steps && from <= to && 0 < to);
 	size_t inc = (to - from) / (steps - 1);
 	
@@ -304,5 +305,5 @@
 static void one_cb_done(rcu_item_t *item)
 {
-	ASSERT( ((item_w_cookie_t *)item)->cookie == magic_cookie);
+	assert( ((item_w_cookie_t *)item)->cookie == magic_cookie);
 	one_cb_is_done = 1;
 	TPRINTF("Callback()\n");
@@ -388,4 +389,9 @@
 static void seq_func(void *arg)
 {
+	/*
+	 * Temporarily workaround GCC 7.1.0 internal
+	 * compiler error when compiling for riscv64.
+	 */
+#ifndef KARCH_riscv64
 	seq_work_t *work = (seq_work_t*)arg;
 	
@@ -434,5 +440,8 @@
 		}
 		
-	} 
+	}
+#else
+	(void) seq_cb;
+#endif
 }
 
@@ -560,5 +569,5 @@
 {
 	preempt_t *p = (preempt_t*)arg;
-	ASSERT(!p->e.exited);
+	assert(!p->e.exited);
 
 	TPRINTF("reader_prev{ ");
@@ -580,5 +589,5 @@
 {
 	preempt_t *p = (preempt_t*)arg;
-	ASSERT(!p->e.exited);
+	assert(!p->e.exited);
 	
 	TPRINTF("reader_inside_cur{ ");
@@ -605,5 +614,5 @@
 {
 	preempt_t *p = (preempt_t*)arg;
-	ASSERT(!p->e.exited);
+	assert(!p->e.exited);
 	
 	TPRINTF("reader_cur{ ");
@@ -627,5 +636,5 @@
 {
 	preempt_t *p = (preempt_t*)arg;
-	ASSERT(!p->e.exited);
+	assert(!p->e.exited);
 	
 	TPRINTF("reader_next1{ ");
@@ -649,5 +658,5 @@
 {
 	preempt_t *p = (preempt_t*)arg;
-	ASSERT(!p->e.exited);
+	assert(!p->e.exited);
 	
 	TPRINTF("reader_next2{ ");
Index: kernel/test/synch/workq-test-core.h
===================================================================
--- kernel/test/synch/workq-test-core.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/synch/workq-test-core.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,4 +27,5 @@
  */
 
+#include <assert.h>
 #include <test.h>
 #include <arch.h>
@@ -32,5 +33,5 @@
 #include <print.h>
 #include <proc/thread.h>
-#include <memstr.h>
+#include <mem.h>
 #include <synch/workqueue.h>
 
@@ -72,5 +73,5 @@
 {
 	test_work_t *child = malloc(sizeof(test_work_t), 0);
-	ASSERT(child);
+	assert(child);
 	if (child) {
 		child->master = false;
Index: kernel/test/synch/workqueue2.c
===================================================================
--- kernel/test/synch/workqueue2.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/synch/workqueue2.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,4 @@
 #include <arch.h>
 #include <print.h>
-#include <memstr.h>
 #include <synch/workqueue.h>
 
Index: kernel/test/synch/workqueue3.c
===================================================================
--- kernel/test/synch/workqueue3.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/synch/workqueue3.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,5 +30,4 @@
 #include <arch.h>
 #include <print.h>
-#include <memstr.h>
 #include <synch/workqueue.h>
 
Index: kernel/test/test.c
===================================================================
--- kernel/test/test.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/test.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 
 #include <test.h>
+#include <stddef.h>
 #include <str.h>
 
Index: kernel/test/test.h
===================================================================
--- kernel/test/test.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ kernel/test/test.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define KERN_TEST_H_
 
-#include <typedefs.h>
+#include <stdbool.h>
 
 extern bool test_quiet;
Index: tools/autotool.py
===================================================================
--- tools/autotool.py	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ tools/autotool.py	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -54,4 +54,5 @@
 PACKAGE_GCC = "preferably version 4.7.0 or newer"
 PACKAGE_CROSS = "use tools/toolchain.sh to build the cross-compiler toolchain"
+PACKAGE_CLANG = "reasonably recent version of clang needs to be installed"
 
 COMPILER_FAIL = "The compiler is probably not capable to compile HelenOS."
@@ -208,22 +209,20 @@
 
 def get_target(config):
+	platform = None
+	gnu_target = None
+	helenos_target = None
 	target = None
-	gnu_target = None
-	clang_target = None
-	helenos_target = None
 	cc_args = []
 	
 	if (config['PLATFORM'] == "abs32le"):
 		check_config(config, "CROSS_TARGET")
-		target = config['CROSS_TARGET']
+		platform = config['CROSS_TARGET']
 		
 		if (config['CROSS_TARGET'] == "arm32"):
 			gnu_target = "arm-linux-gnueabi"
-			clang_target = "arm-unknown-none"
 			helenos_target = "arm-helenos-gnueabi"
 		
 		if (config['CROSS_TARGET'] == "ia32"):
 			gnu_target = "i686-pc-linux-gnu"
-			clang_target = "i686-unknown-none"
 			helenos_target = "i686-pc-helenos"
 		
@@ -231,27 +230,23 @@
 			cc_args.append("-mabi=32")
 			gnu_target = "mipsel-linux-gnu"
-			clang_target = "mipsel-unknown-none"
 			helenos_target = "mipsel-helenos"
 	
 	if (config['PLATFORM'] == "amd64"):
-		target = config['PLATFORM']
-		gnu_target = "amd64-linux-gnu"
-		clang_target = "x86_64-unknown-none"
+		platform = config['PLATFORM']
+		gnu_target = "amd64-unknown-elf"
 		helenos_target = "amd64-helenos"
 	
 	if (config['PLATFORM'] == "arm32"):
-		target = config['PLATFORM']
+		platform = config['PLATFORM']
 		gnu_target = "arm-linux-gnueabi"
-		clang_target = "arm-unknown-none-eabi"
 		helenos_target = "arm-helenos-gnueabi"
 	
 	if (config['PLATFORM'] == "ia32"):
-		target = config['PLATFORM']
+		platform = config['PLATFORM']
 		gnu_target = "i686-pc-linux-gnu"
-		clang_target = "i686-unknown-none"
 		helenos_target = "i686-pc-helenos"
 	
 	if (config['PLATFORM'] == "ia64"):
-		target = config['PLATFORM']
+		platform = config['PLATFORM']
 		gnu_target = "ia64-pc-linux-gnu"
 		helenos_target = "ia64-pc-helenos"
@@ -262,13 +257,11 @@
 		
 		if ((config['MACHINE'] == "msim") or (config['MACHINE'] == "lmalta")):
-			target = config['PLATFORM']
+			platform = config['PLATFORM']
 			gnu_target = "mipsel-linux-gnu"
-			clang_target = "mipsel-unknown-none"
 			helenos_target = "mipsel-helenos"
 		
 		if ((config['MACHINE'] == "bmalta")):
-			target = "mips32eb"
+			platform = "mips32eb"
 			gnu_target = "mips-linux-gnu"
-			clang_target = "mips-unknown-none"
 			helenos_target = "mips-helenos"
 	
@@ -278,28 +271,29 @@
 		
 		if (config['MACHINE'] == "msim"):
-			target = config['PLATFORM']
+			platform = config['PLATFORM']
 			gnu_target = "mips64el-linux-gnu"
-			clang_target = "mips64el-unknown-none"
 			helenos_target = "mips64el-helenos"
 	
 	if (config['PLATFORM'] == "ppc32"):
-		target = config['PLATFORM']
+		platform = config['PLATFORM']
 		gnu_target = "ppc-linux-gnu"
-		clang_target = "ppc-unknown-none"
 		helenos_target = "ppc-helenos"
 	
 	if (config['PLATFORM'] == "riscv64"):
-		target = config['PLATFORM']
+		platform = config['PLATFORM']
 		gnu_target = "riscv64-unknown-linux-gnu"
-		clang_target = "riscv-unknown-none"
 		helenos_target = "riscv64-helenos"
 	
 	if (config['PLATFORM'] == "sparc64"):
-		target = config['PLATFORM']
+		platform = config['PLATFORM']
 		gnu_target = "sparc64-linux-gnu"
-		clang_target = "sparc-unknown-none"
 		helenos_target = "sparc64-helenos"
 	
-	return (target, cc_args, gnu_target, clang_target, helenos_target)
+	if (config['COMPILER'] == "gcc_helenos"):
+		target = helenos_target
+	else:
+		target = gnu_target
+	
+	return (platform, cc_args, target)
 
 def check_app(args, name, details):
@@ -351,4 +345,14 @@
 	return found
 
+def check_clang(path, prefix, common, details):
+	"Check for clang"
+	
+	common['CLANG'] = "%sclang" % prefix
+	
+	if (not path is None):
+		common['CLANG'] = "%s/%s" % (path, common['CLANG'])
+	
+	check_app([common['CLANG'], "--version"], "clang", details)
+
 def check_gcc(path, prefix, common, details):
 	"Check for GCC"
@@ -427,6 +431,5 @@
 	outf.close()
 	
-	args = [common['CC']]
-	args.extend(common['CC_ARGS'])
+	args = common['CC_AUTOGEN'].split(' ')
 	args.extend(["-S", "-o", PROBE_OUTPUT, PROBE_SOURCE])
 	
@@ -547,6 +550,5 @@
 	outf.close()
 	
-	args = [common['CC']]
-	args.extend(common['CC_ARGS'])
+	args = common['CC_AUTOGEN'].split(' ')
 	args.extend(["-S", "-o", PROBE_INT128_OUTPUT, PROBE_INT128_SOURCE])
 	
@@ -849,40 +851,37 @@
 		check_app(["make", "--version"], "Make utility", "preferably GNU Make")
 		check_app(["makedepend", "-f", "-"], "Makedepend utility", "usually part of imake or xutils")
+		check_app(["unzip"], "unzip utility", "usually part of zip/unzip utilities")
+		
+		platform, cc_args, target = get_target(config)
+		
+		if (platform is None) or (target is None):
+			print_error(["Unsupported compiler target.",
+				     "Please contact the developers of HelenOS."])
+		
+		path = "%s/%s/bin" % (cross_prefix, target)
+		
+		# Compatibility with earlier toolchain paths.
+		if not os.path.exists(path):
+			if (config['COMPILER'] == "gcc_helenos"):
+				check_path = "%s/%s/%s" % (cross_helenos_prefix, platform, target)
+				if not os.path.exists(check_path):
+					print_error(["Toolchain for target is not installed, or CROSS_PREFIX is not set correctly."])
+				path = "%s/%s/bin" % (cross_helenos_prefix, platform)
+			else:
+				check_path = "%s/%s/%s" % (cross_prefix, platform, target)
+				if not os.path.exists(check_path):
+					print_error(["Toolchain for target is not installed, or CROSS_PREFIX is not set correctly."])
+				path = "%s/%s/bin" % (cross_prefix, platform)
+		
+		prefix = "%s-" % target
 		
 		# Compiler
-		common['CC_ARGS'] = []
-		if (config['COMPILER'] == "gcc_cross"):
-			target, cc_args, gnu_target, clang_target, helenos_target = get_target(config)
-			
-			if (target is None) or (gnu_target is None):
-				print_error(["Unsupported compiler target for GNU GCC.",
-				             "Please contact the developers of HelenOS."])
-			
-			path = "%s/%s/bin" % (cross_prefix, target)
-			prefix = "%s-" % gnu_target
-			
+		if (config['COMPILER'] == "gcc_cross" or config['COMPILER'] == "gcc_helenos"):
 			check_gcc(path, prefix, common, PACKAGE_CROSS)
 			check_binutils(path, prefix, common, PACKAGE_CROSS)
 			
 			check_common(common, "GCC")
-			common['CC'] = common['GCC']
-			common['CC_ARGS'].extend(cc_args)
-		
-		if (config['COMPILER'] == "gcc_helenos"):
-			target, cc_args, gnu_target, clang_target, helenos_target = get_target(config)
-			
-			if (target is None) or (helenos_target is None):
-				print_error(["Unsupported compiler target for GNU GCC.",
-				             "Please contact the developers of HelenOS."])
-			
-			path = "%s/%s/bin" % (cross_helenos_prefix, target)
-			prefix = "%s-" % helenos_target
-			
-			check_gcc(path, prefix, common, PACKAGE_CROSS)
-			check_binutils(path, prefix, common, PACKAGE_CROSS)
-			
-			check_common(common, "GCC")
-			common['CC'] = common['GCC']
-			common['CC_ARGS'].extend(cc_args)
+			common['CC'] = " ".join([common['GCC']] + cc_args)
+			common['CC_AUTOGEN'] = common['CC']
 		
 		if (config['COMPILER'] == "gcc_native"):
@@ -892,32 +891,19 @@
 			check_common(common, "GCC")
 			common['CC'] = common['GCC']
-		
-		if (config['COMPILER'] == "icc"):
-			check_app([common['CC'], "-V"], "Intel C++ Compiler", "support is experimental")
-			check_gcc(None, "", common, PACKAGE_GCC)
-			check_binutils(None, binutils_prefix, common, PACKAGE_BINUTILS)
+			common['CC_AUTOGEN'] = common['CC']
+		
+		if (config['COMPILER'] == "clang"):
+			check_binutils(path, prefix, common, PACKAGE_CROSS)
+			check_clang(path, prefix, common, PACKAGE_CLANG)
 			
-			common['CC'] = "icc"
-		
-		if (config['COMPILER'] == "clang"):
-			target, cc_args, gnu_target, clang_target, helenos_target = get_target(config)
+			check_common(common, "CLANG")
+			common['CC'] = " ".join([common['CLANG']] + cc_args)
+			common['CC_AUTOGEN'] = common['CC'] + " -no-integrated-as"
 			
-			if (target is None) or (gnu_target is None) or (clang_target is None):
-				print_error(["Unsupported compiler target for clang.",
-				             "Please contact the developers of HelenOS."])
+			if (config['INTEGRATED_AS'] == "yes"):
+				common['CC'] += " -integrated-as"
 			
-			path = "%s/%s/bin" % (cross_prefix, target)
-			prefix = "%s-" % gnu_target
-			
-			check_app(["clang", "--version"], "clang compiler", "preferably version 1.0 or newer")
-			check_gcc(path, prefix, common, PACKAGE_GCC)
-			check_binutils(path, prefix, common, PACKAGE_BINUTILS)
-			
-			check_common(common, "GCC")
-			common['CC'] = "clang"
-			common['CC_ARGS'].extend(cc_args)
-			common['CC_ARGS'].append("-target")
-			common['CC_ARGS'].append(clang_target)
-			common['CLANG_TARGET'] = clang_target
+			if (config['INTEGRATED_AS'] == "no"):
+				common['CC'] += " -no-integrated-as"
 		
 		check_python()
Index: tools/ew.py
===================================================================
--- tools/ew.py	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ tools/ew.py	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -219,5 +219,5 @@
 
 def spike_run(platform, machine, processor):
-	run_in_console('spike image.boot', 'HelenOS/risvc64 on Spike')
+	run_in_console('spike -m1073741824:1073741824 image.boot', 'HelenOS/risvc64 on Spike')
 
 emulators = {
Index: tools/mkarray.py
===================================================================
--- tools/mkarray.py	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ tools/mkarray.py	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,29 +28,58 @@
 #
 """
-C structure creator
+Binary inline data packer
 """
 
 import sys
 import os
-import struct
+import zlib
+import zipfile
+import binascii
 
 def usage(prname):
 	"Print usage syntax"
-	print("%s <DESTINATION> <LABEL> <AS_PROLOG> [SOURCE ...]" % prname)
+	print("%s [--deflate] <DESTINATION> <LABEL> <AS_PROLOG> <SECTION> [SOURCE ...]" % prname)
+
+def arg_check():
+	if (len(sys.argv) < 5):
+		usage(sys.argv[0])
+		sys.exit()
+
+def deflate(data):
+	"Compress using deflate algorithm (without any headers)"
+	return zlib.compress(data, 9)[2:-4]
+
+def chunks(string, length):
+	"Produce string chunks"
+	for start in range(0, len(string), length):
+		yield string[start:start + length]
 
 def main():
-	if (len(sys.argv) < 4):
-		usage(sys.argv[0])
-		return
+	arg_check()
+	
+	if sys.argv[1] == "--deflate":
+		sys.argv.pop(1)
+		arg_check()
+		compress = True
+	else:
+		compress = False
 	
 	dest = sys.argv[1]
 	label = sys.argv[2]
 	as_prolog = sys.argv[3]
+	section = sys.argv[4]
 	
 	header_ctx = []
+	desc_ctx = []
+	size_ctx = []
 	data_ctx = []
 	
-	for src in sys.argv[4:]:
+	src_cnt = 0
+	
+	archive = zipfile.ZipFile("%s.zip" % dest, "w", zipfile.ZIP_STORED)
+	
+	for src in sys.argv[5:]:
 		basename = os.path.basename(src)
+		plainname = os.path.splitext(basename)[0]
 		symbol = basename.replace(".", "_")
 		
@@ -61,68 +90,97 @@
 		src_in.close()
 		
-		data_rec = "\t.byte "
+		length = len(src_data)
 		
-		fmt = 'B'
-		item_size = struct.calcsize(fmt)
-		offset = 0
-		cnt = 0
+		if compress:
+			src_data = deflate(src_data)
+			src_fname = os.path.basename("%s.deflate" % src)
+			archive.writestr(src_fname, src_data)
+		else:
+			src_fname = src
 		
-		while (len(src_data[offset:]) >= item_size):
-			byte = struct.unpack_from(fmt, src_data, offset)
-			
-			if (offset > 0):
-				if ((cnt % 15) == 0):
-					data_rec += "\n\t.byte "
-				else:
-					data_rec += ", "
-			
-			data_rec += "0x%x" % byte
-			offset += item_size
-			cnt += 1
+		if sys.version_info < (3,):
+			src_data = bytearray(src_data)
 		
-		data_rec += "\n"
+		length_out = len(src_data)
 		
-		header_ctx.append("extern uint64_t %s_size;" % symbol)
 		header_ctx.append("extern uint8_t %s[];" % symbol)
-		
-		data_ctx.append(".globl %s_size" % symbol)
-		data_ctx.append(".balign 8");
-		data_ctx.append(".size %s_size, 8" % symbol)
-		data_ctx.append("%s_size:" % symbol)
-		data_ctx.append("\t.quad %u\n" % offset)
+		header_ctx.append("extern size_t %s_size;" % symbol)
 		
 		data_ctx.append(".globl %s" % symbol)
 		data_ctx.append(".balign 8")
-		data_ctx.append(".size %s, %u" % (symbol, offset))
+		data_ctx.append(".size %s, %u" % (symbol, length_out))
 		data_ctx.append("%s:" % symbol)
-		data_ctx.append(data_rec)
+		data_ctx.append("\t.incbin \"%s\"\n" % src_fname)
+		
+		desc_field = []
+		desc_field.append("\t{")
+		desc_field.append("\t\t.name = \"%s\"," % plainname)
+		desc_field.append("\t\t.addr = (void *) %s," % symbol)
+		desc_field.append("\t\t.size = %u," % length_out)
+		desc_field.append("\t\t.inflated = %u," % length)
+		
+		if compress:
+			desc_field.append("\t\t.compressed = true")
+		else:
+			desc_field.append("\t\t.compressed = false")
+		
+		desc_field.append("\t}")
+		
+		desc_ctx.append("\n".join(desc_field))
+		
+		size_ctx.append("size_t %s_size = %u;" % (symbol, length_out))
+		
+		src_cnt += 1
 	
-	header = open("%s.h" % dest, "w")
+	data = ''
+	data += '/***************************************\n'
+	data += ' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n'
+	data += ' * Generated by: tools/mkarray.py      *\n'
+	data += ' ***************************************/\n\n'
+	data += "#ifndef %sS_H_\n" % label.upper()
+	data += "#define %sS_H_\n\n" % label.upper()
+	data += "#include <stddef.h>\n"
+	data += "#include <stdint.h>\n"
+	data += "#include <stdbool.h>\n\n"
+	data += "#define %sS  %u\n\n" % (label.upper(), src_cnt)
+	data += "typedef struct {\n"
+	data += "\tconst char *name;\n"
+	data += "\tvoid *addr;\n"
+	data += "\tsize_t size;\n"
+	data += "\tsize_t inflated;\n"
+	data += "\tbool compressed;\n"
+	data += "} %s_t;\n\n" % label
+	data += "extern %s_t %ss[];\n\n" % (label, label)
+	data += "\n".join(header_ctx)
+	data += "\n\n"
+	data += "#endif\n"
+	archive.writestr("%s.h" % dest, data)
 	
-	header.write('/***************************************\n')
-	header.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
-	header.write(' * Generated by: tools/mkarray.py      *\n')
-	header.write(' ***************************************/\n\n')
-	header.write("#ifndef %s_H_\n" % label)
-	header.write("#define %s_H_\n\n" % label)
-	header.write("#include <stddef.h>\n")
-	header.write("#include <stdint.h>\n\n")
-	header.write("\n".join(header_ctx))
-	header.write("\n\n")
-	header.write("#endif\n")
+	data = ''
+	data += '/***************************************\n'
+	data += ' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n'
+	data += ' * Generated by: tools/mkarray.py      *\n'
+	data += ' ***************************************/\n\n'
+	data += as_prolog
+	data += "%s\n\n" % section
+	data += "\n".join(data_ctx)
+	data += "\n"
+	archive.writestr("%s.s" % dest, data)
 	
-	header.close()
+	data = ''
+	data += '/***************************************\n'
+	data += ' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n'
+	data += ' * Generated by: tools/mkarray.py      *\n'
+	data += ' ***************************************/\n\n'
+	data += "#include \"%s.h\"\n\n" % dest
+	data += "%s_t %ss[] = {\n" % (label, label)
+	data += ",\n".join(desc_ctx)
+	data += "\n"
+	data += "};\n\n"
+	data += "\n".join(size_ctx)
+	data += "\n"
+	archive.writestr("%s_desc.c" % dest, data)
 	
-	data = open("%s.s" % dest, "w")
-	
-	data.write('/***************************************\n')
-	data.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
-	data.write(' * Generated by: tools/mkarray.py      *\n')
-	data.write(' ***************************************/\n\n')
-	data.write(as_prolog)
-	data.write('.data\n\n')
-	data.write("\n".join(data_ctx))
-	
-	data.close()
+	archive.close()
 
 if __name__ == '__main__':
Index: ols/pack.py
===================================================================
--- tools/pack.py	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,200 +1,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2008 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.
-#
-"""
-Binary package creator
-"""
-
-import sys
-import os
-import subprocess
-import zlib
-import shutil
-
-SANDBOX = 'pack'
-LINK = '_link.ld'
-COMPONENTS = '_components'
-
-def usage(prname):
-	"Print usage syntax"
-	print("%s <OBJCOPY> <FORMAT> <ARCH> <ARCH_PATH> [COMPONENTS ...]" % prname)
-
-def deflate(data):
-	"Compress using deflate algorithm (without any headers)"
-	return zlib.compress(data, 9)[2:-4]
-
-def print_error(msg):
-	"Print a bold error message"
-	
-	sys.stderr.write("\n")
-	sys.stderr.write("######################################################################\n")
-	sys.stderr.write("HelenOS build sanity check error:\n")
-	sys.stderr.write("\n")
-	sys.stderr.write("%s\n" % "\n".join(msg))
-	sys.stderr.write("######################################################################\n")
-	sys.stderr.write("\n")
-	
-	sys.exit(1)
-
-def sandbox_enter():
-	"Create a temporal sandbox directory for packing"
-	
-	if (os.path.exists(SANDBOX)):
-		if (os.path.isdir(SANDBOX)):
-			try:
-				shutil.rmtree(SANDBOX)
-			except:
-				print_error(["Unable to cleanup the directory \"%s\"." % SANDBOX])
-		else:
-			print_error(["Please inspect and remove unexpected directory,",
-			             "entry \"%s\"." % SANDBOX])
-	
-	try:
-		os.mkdir(SANDBOX)
-	except:
-		print_error(["Unable to create sandbox directory \"%s\"." % SANDBOX])
-	
-	owd = os.getcwd()
-	os.chdir(SANDBOX)
-	
-	return owd
-
-def sandbox_leave(owd):
-	"Leave the temporal sandbox directory"
-	
-	os.chdir(owd)
-
-def main():
-	if (len(sys.argv) < 5):
-		usage(sys.argv[0])
-		return
-	
-	objcopy = sys.argv[1]
-	format = sys.argv[2]
-	arch = sys.argv[3]
-	arch_path = sys.argv[4]
-	
-	header_ctx = []
-	data_ctx = []
-	link_ctx = []
-	cnt = 0
-	for component in sys.argv[5:]:
-		basename = os.path.basename(component)
-		plainname = os.path.splitext(basename)[0]
-		obj = "%s.co" % plainname
-		symbol = "_binary_%s" % basename.replace(".", "_")
-		
-		print("%s -> %s" % (component, obj))
-		
-		comp_in = open(component, "rb")
-		comp_data = comp_in.read()
-		comp_in.close()
-		
-		comp_deflate = deflate(comp_data)
-		
-		owd = sandbox_enter()
-		
-		try:
-			comp_out = open(basename, "wb")
-			comp_out.write(comp_deflate)
-			comp_out.close()
-			
-			subprocess.call([objcopy,
-				"-I", "binary",
-				"-O", format,
-				"-B", arch,
-				"--rename-section", ".data=.%s_image" % plainname,
-				basename, os.path.join(owd, obj)])
-			
-		finally:
-			sandbox_leave(owd)
-		
-		link_ctx.append("\t\t*(.%s_image);" % plainname)
-		
-		header_rec = "extern int %s_start;\n" % symbol
-		header_rec += "extern int %s_size;\n" % symbol
-		header_ctx.append(header_rec)
-		
-		data_rec = "\t{\n"
-		data_rec += "\t\t.name = \"%s\",\n" % plainname
-		data_rec += "\t\t.start = (void *) &%s_start,\n" % symbol
-		data_rec += "\t\t.size = (size_t) &%s_size,\n" % symbol
-		data_rec += "\t\t.inflated = %d\n" % len(comp_data)
-		data_rec += "\t}"
-		data_ctx.append(data_rec)
-		
-		cnt += 1
-	
-	header = open(os.path.join(arch_path, "include", "%s.h" % COMPONENTS), "w")
-	
-	header.write('/***************************************\n')
-	header.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
-	header.write(' * Generated by: tools/pack.py         *\n')
-	header.write(' ***************************************/\n\n')
-	header.write("#ifndef BOOT_COMPONENTS_H_\n")
-	header.write("#define BOOT_COMPONENTS_H_\n\n")
-	header.write("#include <typedefs.h>\n\n")
-	header.write("#define COMPONENTS  %d\n\n" % cnt)
-	header.write("typedef struct {\n")
-	header.write("\tconst char *name;\n")
-	header.write("\tvoid *start;\n")
-	header.write("\tsize_t size;\n")
-	header.write("\tsize_t inflated;\n")
-	header.write("} component_t;\n\n")
-	header.write("extern component_t components[];\n\n")
-	header.write("\n".join(header_ctx))
-	header.write("\n")
-	header.write("#endif\n")
-	
-	header.close()
-	
-	data = open(os.path.join(arch_path, "src", "%s.c" % COMPONENTS), "w")
-	
-	data.write('/***************************************\n')
-	data.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
-	data.write(' * Generated by: tools/pack.py         *\n')
-	data.write(' ***************************************/\n\n')
-	data.write("#include <typedefs.h>\n")
-	data.write("#include <arch/%s.h>\n\n" % COMPONENTS)
-	data.write("component_t components[] = {\n")
-	data.write(",\n".join(data_ctx))
-	data.write("\n")
-	data.write("};\n")
-	
-	data.close()
-	
-	link_in = open(os.path.join(arch_path, "%s.in" % LINK), "r")
-	template = link_in.read()
-	link_in.close()
-	
-	link_out = open(os.path.join(arch_path, "%s.comp" % LINK), "w")
-	link_out.write(template.replace("[[COMPONENTS]]", "\n".join(link_ctx)))
-	link_out.close()
-
-if __name__ == '__main__':
-	main()
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ tools/toolchain.sh	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -73,5 +73,4 @@
 REAL_INSTALL=true
 USE_HELENOS_TARGET=false
-INSTALL_DIR="${BASEDIR}/PKG"
 
 #
@@ -283,4 +282,6 @@
 	ORIGINAL="`pwd`"
 	
+	mkdir -p "${OUTSIDE}"
+	
 	cd "${OUTSIDE}"
 	check_error $? "Unable to change directory to ${OUTSIDE}."
@@ -358,5 +359,5 @@
 	case "$1" in
 		"amd64")
-			LINUX_TARGET="amd64-linux-gnu"
+			LINUX_TARGET="amd64-unknown-elf"
 			HELENOS_TARGET="amd64-helenos"
 			;;
@@ -418,5 +419,6 @@
 	fi
 	
-	WORKDIR="${BASEDIR}/${PLATFORM}"
+	WORKDIR="${BASEDIR}/${TARGET}"
+	INSTALL_DIR="${WORKDIR}/PKG"
 	BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
 	GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
@@ -427,13 +429,6 @@
 		CROSS_PREFIX="/usr/local/cross"
 	fi
-	if [ -z "${CROSS_HELENOS_PREFIX}" ] ; then
-		CROSS_HELENOS_PREFIX="/usr/local/cross-helenos"
-	fi
-	
-	if $USE_HELENOS_TARGET ; then
-		PREFIX="${CROSS_HELENOS_PREFIX}/${PLATFORM}"
-	else
-		PREFIX="${CROSS_PREFIX}/${PLATFORM}"
-	fi
+	
+	PREFIX="${CROSS_PREFIX}/${TARGET}"
 	
 	echo ">>> Downloading tarballs"
@@ -443,8 +438,6 @@
 	
 	echo ">>> Removing previous content"
-	$REAL_INSTALL && cleanup_dir "${PREFIX}"
 	cleanup_dir "${WORKDIR}"
 	
-	$REAL_INSTALL && create_dir "${PREFIX}" "destination directory"
 	create_dir "${OBJDIR}" "GCC object directory"
 	
@@ -478,5 +471,5 @@
 		"--target=${TARGET}" \
 		"--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
-		--disable-nls --disable-werror
+		--disable-nls --disable-werror --enable-gold
 	check_error $? "Error configuring binutils."
 	
@@ -486,9 +479,5 @@
 	
 	change_title "binutils: install (${PLATFORM})"
-	if $REAL_INSTALL ; then
-		make install
-	else
-		make install "DESTDIR=${INSTALL_DIR}"
-	fi
+	make install "DESTDIR=${INSTALL_DIR}"
 	check_error $? "Error installing binutils."
 	
@@ -513,9 +502,5 @@
 	
 	change_title "GCC: install (${PLATFORM})"
-	if $REAL_INSTALL ; then
-		PATH="${PATH}:${PREFIX}/bin" make install-gcc
-	else
-		PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
-	fi
+	PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
 	check_error $? "Error installing GCC."
 	
@@ -531,5 +516,5 @@
 			"--target=${TARGET}" \
 			"--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
-			--enable-werror=no
+			--enable-werror=no --without-guile
 		check_error $? "Error configuring GDB."
 		
@@ -539,12 +524,21 @@
 		
 		change_title "GDB: make (${PLATFORM})"
-		if $REAL_INSTALL ; then
-			PATH="${PATH}:${PREFIX}/bin" make install
-		else
-			PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
-		fi
+		PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
 		check_error $? "Error installing GDB."
 	fi
 	
+	# Symlink clang and lld to the install path.
+	CLANG=`which clang 2> /dev/null || echo "/usr/bin/clang"`
+	LLD=`which ld.lld 2> /dev/null || echo "/usr/bin/ld.lld"`
+	
+	ln -s $CLANG "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-clang"
+	ln -s $LLD "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-ld.lld"
+	
+	if $REAL_INSTALL ; then
+		echo ">>> Moving to the destination directory."
+		cleanup_dir "${PREFIX}"
+		echo mv "${INSTALL_DIR}/${PREFIX}" "${PREFIX}"
+		mv "${INSTALL_DIR}/${PREFIX}" "${PREFIX}"
+	fi
 	
 	cd "${BASEDIR}"
Index: tools/xcw/bin/helenos-pkg-config
===================================================================
--- tools/xcw/bin/helenos-pkg-config	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ tools/xcw/bin/helenos-pkg-config	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -47,4 +47,10 @@
     $SRC_ROOT/uspace/lib/softrend/libsoftrend.a"
 
+libhound_cflags="-I$SRC_ROOT/uspace/lib/hound/include"
+libhound_libs="$SRC_ROOT/uspace/lib/hound/libhound.a"
+
+libpcm_cflags="-I$SRC_ROOT/uspace/lib/pcm/include"
+libpcm_libs="$SRC_ROOT/uspace/lib/pcm/libpcm.a"
+
 action=none
 pkg=
@@ -60,4 +66,6 @@
 	    (libdraw) ;;
 	    (libmath) ;;
+	    (libhound) ;;
+	    (libpcm) ;;
 	    (*) echo "Unknown package $1" >&2; exit 1;;
 	    esac
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,4 +48,5 @@
 	app/fontviewer \
 	app/getterm \
+	app/gunzip \
 	app/init \
 	app/inet \
@@ -80,4 +81,5 @@
 	app/nic \
 	app/ping \
+	app/pkg \
 	app/sysinfo \
 	app/sysinst \
@@ -133,4 +135,7 @@
 	srv/hid/remcons \
 	srv/hw/char/s3c24xx_uart \
+	srv/hw/irc/apic \
+	srv/hw/irc/i8259 \
+	srv/hw/irc/obio \
 	srv/hid/rfb \
 	drv/audio/hdaudio \
@@ -141,13 +146,7 @@
 	drv/block/ata_bd \
 	drv/block/ddisk \
-	drv/char/i8042 \
-	drv/char/pl050 \
-	drv/char/ps2mouse \
-	drv/char/atkbd \
-	drv/char/xtkbd \
-	drv/test/test1 \
-	drv/test/test2 \
-	drv/test/test3 \
-	drv/fb/kfb \
+	drv/bus/adb/cuda_adb \
+	drv/bus/isa \
+	drv/bus/pci/pciintel \
 	drv/bus/usb/ehci \
 	drv/bus/usb/ohci \
@@ -160,4 +159,16 @@
 	drv/bus/usb/vhc \
 	drv/bus/usb/xhci \
+	drv/char/i8042 \
+	drv/char/ns8250 \
+	drv/char/pl050 \
+	drv/char/ps2mouse \
+	drv/char/atkbd \
+	drv/char/xtkbd \
+	drv/test/test1 \
+	drv/test/test2 \
+	drv/test/test3 \
+	drv/fb/amdm37x_dispc \
+	drv/fb/kfb \
+	drv/intctl/icp-ic \
 	drv/nic/ne2k \
 	drv/nic/e1k \
@@ -165,56 +176,16 @@
 	drv/nic/rtl8169 \
 	drv/nic/ar9271 \
-	drv/platform/icp
-
-## Platform-specific hardware support
-#
-
-ifeq ($(UARCH), $(filter $(UARCH),amd64 ia32 ia64))
-	DIRS += \
-		drv/platform/pc \
-		drv/bus/pci/pciintel \
-		drv/bus/isa \
-		drv/char/ns8250 \
-		drv/time/cmos-rtc \
-		srv/hw/irc/apic \
-		srv/hw/irc/i8259
-endif
-
-ifeq ($(UARCH), $(filter $(UARCH),mips32 mips32eb))
-ifeq ($(MACHINE),msim)
-	DIRS += \
-		drv/platform/msim
-else
-	DIRS += \
-		drv/platform/malta \
-		drv/bus/pci/pciintel \
-		drv/bus/isa
-endif
-endif
-
-ifeq ($(UARCH),ppc32)
-	DIRS += \
-		drv/platform/mac \
-		drv/bus/pci/pciintel \
-		srv/hw/bus/cuda_adb
-endif
-
+	drv/platform/amdm37x \
+	drv/platform/icp \
+	drv/platform/mac \
+	drv/platform/malta \
+	drv/platform/msim \
+	drv/platform/pc \
+	drv/time/cmos-rtc
+
+## sun4u driver won't compile on 32-bit targets
 ifeq ($(UARCH),sparc64)
 	DIRS += \
-		srv/hw/irc/obio
-ifeq ($(MACHINE),generic)
-	DIRS += \
-		drv/platform/sun4u \
-		drv/bus/pci/pciintel \
-		drv/bus/isa \
-		drv/char/ns8250
-endif
-endif
-
-ifeq ($(UARCH),arm32)
-	DIRS += \
-		drv/platform/amdm37x \
-		drv/fb/amdm37x_dispc \
-		srv/hw/irc/icp-ic
+		drv/platform/sun4u
 endif
 
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -160,6 +160,13 @@
 LIBNETTL_PREFIX = $(LIB_PREFIX)/nettl
 
-AFLAGS = --fatal-warnings
+AFLAGS =
 LFLAGS = --fatal-warnings
+
+# FIXME: This condition is a workaround for issues #692 and #693.
+ifneq ($(KARCH),ia64)
+ifneq ($(KARCH),mips32)
+	AFLAGS += --fatal-warnings
+endif
+endif
 
 ifeq ($(STATIC_NEEDED),y)
@@ -203,16 +210,11 @@
 endif
 
-ifeq ($(CONFIG_OPTIMIZE_FOR_SIZE),y)
-	OPTIMIZATION = s
-else
-	OPTIMIZATION = 3
-endif
-
 # PCUT-based unit tests
 ifneq ($(TEST_SOURCES),)
 	TEST_OUTPUT = $(TEST_BINARY)
+	TEST_DISASM = $(TEST_BINARY).disasm
 	TEST_CFLAGS = -I$(LIB_PREFIX)/pcut/include -D__helenos__
 	TEST_OUTPUT_LIBS = $(LIB_PREFIX)/pcut/libpcut.a
-	EXTRA_CLEAN += $(TEST_OUTPUT) $(TEST_OUTPUT).map
+	EXTRA_CLEAN += $(TEST_OUTPUT) $(TEST_OUTPUT).map $(TEST_DISASM)
 ifneq ($(LIBRARY),)
 	TEST_OUTPUT_LIBS += $(OUTPUT)
@@ -226,5 +228,5 @@
 	-[ -f $(DEPEND) ] && cp -a $(DEPEND) $(DEPEND_PREV)
 
-all-test: $(TEST_OUTPUT)
+all-test: $(TEST_OUTPUT) $(TEST_DISASM)
 
 clean:
@@ -233,85 +235,74 @@
 	find . -name '*.lo' -follow -exec rm \{\} \;
 
-GCC_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Wextra -Wno-clobbered -Wno-unused-parameter -Wmissing-prototypes \
+COMMON_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
+	-ffreestanding -fno-builtin -nostdlib -nostdinc -fexec-charset=UTF-8 \
+	-finput-charset=UTF-8 -D__$(ENDIANESS)__
+
+GCC_CFLAGS = -ffunction-sections -Wall -Wextra -Wno-clobbered \
+	-Wno-unused-parameter -Wmissing-prototypes -std=gnu99 \
+	-Werror-implicit-function-declaration \
+	-Wwrite-strings -pipe
+
+# -Wno-missing-prototypes is there because it warns about main().
+# This should be fixed elsewhere.
+CLANG_CFLAGS = -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-typedef-redefinition \
+	-Wno-missing-prototypes -Wno-unused-command-line-argument \
 	-std=gnu99 -Werror-implicit-function-declaration -Wwrite-strings \
-	-pipe -ggdb -D__$(ENDIANESS)__
-
-ICC_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Wextra -Wno-clobbered -Wno-unused-parameter -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -Wwrite-strings \
-	-pipe -g -D__$(ENDIANESS)__
-
-# clang does not support following options but I am not sure whether
-# something won't break because of that:
-# -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) -finput-charset=UTF-8
-CLANG_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
-	-ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
-	-std=gnu99 -Werror-implicit-function-declaration -Wwrite-strings \
-	-integrated-as -pipe -g -target $(CLANG_TARGET) -D__$(ENDIANESS)__
+	-pipe -fno-stack-protector -fno-PIC
+
+ifeq ($(CONFIG_DEBUG),y)
+	COMMON_CFLAGS += -Werror
+endif
+
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	GCC_CFLAGS += -ggdb
+	CLANG_CFLAGS += -g
+endif
+
+# Prepare for POSIX before including platform specific stuff
+ifeq ($(POSIX_COMPAT),y)
+	CFLAGS += -I$(LIBPOSIX_PREFIX)/include/posix -I$(LIBPOSIX_PREFIX)/include/
+	BASE_LIBS = $(LIBPOSIX_PREFIX)/libposixaslibc.a $(LIBPOSIX_PREFIX)/libc4posix.a $(LIBSOFTINT_PREFIX)/libsoftint.a
+endif
+
+## Setup platform configuration
+#
+
+-include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.common
+
+## Compilation options
+#
+
+JOBFILE = $(LIBC_PREFIX)/../../../tools/jobfile.py
+
+ifeq ($(COMPILER),gcc_cross)
+	CFLAGS += $(COMMON_CFLAGS) $(GCC_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
+
+ifeq ($(COMPILER),gcc_helenos)
+	CFLAGS += $(COMMON_CFLAGS) $(GCC_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
+
+ifeq ($(COMPILER),gcc_native)
+	CFLAGS += $(COMMON_CFLAGS) $(GCC_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
+
+ifeq ($(COMPILER),clang)
+	CFLAGS += $(COMMON_CFLAGS) $(CLANG_CFLAGS)
+	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+endif
 
 LIB_CFLAGS = $(CFLAGS) -fPIC
 LIB_LFLAGS = $(LFLAGS) -shared -soname $(LSONAME) --whole-archive
 
-ifeq ($(CONFIG_DEBUG),y)
-	GCC_CFLAGS += -Werror
-	ICC_CFLAGS += -Werror
-endif
-
-ifeq ($(CONFIG_LINE_DEBUG),y)
-	GCC_CFLAGS += -ggdb
-	ICC_CFLAGS += -g
-	CLANG_CFLAGS += -g
-endif
-
-# Prepare for POSIX before including platform specific stuff
-ifeq ($(POSIX_COMPAT),y)
-	CFLAGS = -I$(LIBPOSIX_PREFIX)/include/posix -I$(LIBPOSIX_PREFIX)/include/
-	BASE_LIBS = $(LIBPOSIX_PREFIX)/libposixaslibc.a $(LIBPOSIX_PREFIX)/libc4posix.a $(LIBSOFTINT_PREFIX)/libsoftint.a
-endif
-
-## Setup platform configuration
-#
-
--include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.common
-
-## Compilation options
-#
-
-JOBFILE = $(LIBC_PREFIX)/../../../tools/jobfile.py
-
-ifeq ($(COMPILER),gcc_cross)
-	CFLAGS += $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),gcc_helenos)
-	CFLAGS += $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),gcc_native)
-	CFLAGS += $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),icc)
-	CFLAGS += $(ICC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),clang)
-	CFLAGS += $(CLANG_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
 ifneq ($(MAKECMDGOALS),clean)
 -include $(DEPEND)
 endif
+
+AS_CFLAGS := $(addprefix -Xassembler ,$(AFLAGS))
+LD_CFLAGS := $(addprefix -Xlinker ,$(LFLAGS))
 
 OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
@@ -320,5 +311,5 @@
 
 ifneq ($(BINARY),)
-%.disasm: $(BINARY)
+$(BINARY).disasm: $(BINARY)
 ifeq ($(CONFIG_LINE_DEBUG),y)
 	$(OBJDUMP) -d -S $< > $@
@@ -335,5 +326,5 @@
 
 ifneq ($(SLIBRARY),)
-%.disasm: $(LOUTPUT)
+$(LOUTPUT).disasm: $(LOUTPUT)
 ifeq ($(CONFIG_LINE_DEBUG),y)
 	$(OBJDUMP) -d -S $< > $@
@@ -368,8 +359,14 @@
 	$(STRIP) $(TEST_OUTPUT)
 endif
+$(TEST_BINARY).disasm: $(TEST_BINARY)
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	$(OBJDUMP) -d -S $< > $@
+else
+	$(OBJDUMP) -d $< > $@
+endif
 endif
 
 %.o: %.S $(DEPEND)
-	$(GCC) $(DEFS) $(GCC_CFLAGS) $(EXTRA_CFLAGS) -D__ASM__ -c $< -o $@
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) -D__ASM__
@@ -377,5 +374,5 @@
 
 %.o: %.s $(DEPEND)
-	$(AS) $(AFLAGS) -o $@ $<
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm
@@ -395,5 +392,5 @@
 
 %.lo: %.S $(DEPEND)
-	$(CC) $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) -D__ASM__ -c $< -o $@
+	$(CC) $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) -D__ASM__
@@ -401,5 +398,5 @@
 
 %.lo: %.s $(DEPEND)
-	$(AS) $(AFLAGS) -o $@ $<
+	$(CC) $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm
Index: uspace/app/barber/Makefile
===================================================================
--- uspace/app/barber/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/barber/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,7 +44,11 @@
 MATH = y
 
+IMG = image
+IMGS = $(IMG)s
+
 SOURCES = \
 	barber.c \
-	images.s
+	$(IMGS).s \
+	$(IMGS)_desc.c
 
 IMAGES = \
@@ -80,9 +84,18 @@
 	gfx/frame30.tga.gz
 
-PRE_DEPEND = images.s images.h
-EXTRA_CLEAN = images.s images.h
+PRE_DEPEND = $(IMGS).s $(IMGS).h $(IMGS)_desc.c
+EXTRA_CLEAN = $(IMGS).s $(IMGS).h $(IMGS)_desc.c $(IMGS).zip
 
 include $(USPACE_PREFIX)/Makefile.common
 
-images.s images.h: $(IMAGES)
-	$(ROOT_PATH)/tools/mkarray.py images COMPOSITOR_IMAGES "$(AS_PROLOG)" $^
+$(IMGS).s: $(IMGS).zip
+	unzip -p $< $@ > $@
+
+$(IMGS).h: $(IMGS).zip
+	unzip -p $< $@ > $@
+
+$(IMGS)_desc.c: $(IMGS).zip
+	unzip -p $< $@ > $@
+
+$(IMGS).zip: $(IMAGES)
+	$(ROOT_PATH)/tools/mkarray.py $(IMGS) $(IMG) "$(AS_PROLOG)" .data $^
Index: uspace/app/barber/barber.c
===================================================================
--- uspace/app/barber/barber.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/barber/barber.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -51,5 +51,5 @@
 #define NAME  "barber"
 
-#define FRAMES  30
+#define FRAMES  IMAGES
 
 #define MIN_FPS  1
@@ -99,38 +99,8 @@
 static bool decode_frames(void)
 {
-	frames[0] = decode_tga_gz((void *) frame01_tga_gz, frame01_tga_gz_size, 0);
-	frames[1] = decode_tga_gz((void *) frame02_tga_gz, frame02_tga_gz_size, 0);
-	frames[2] = decode_tga_gz((void *) frame03_tga_gz, frame03_tga_gz_size, 0);
-	frames[3] = decode_tga_gz((void *) frame04_tga_gz, frame04_tga_gz_size, 0);
-	frames[4] = decode_tga_gz((void *) frame05_tga_gz, frame05_tga_gz_size, 0);
-	frames[5] = decode_tga_gz((void *) frame06_tga_gz, frame06_tga_gz_size, 0);
-	frames[6] = decode_tga_gz((void *) frame07_tga_gz, frame07_tga_gz_size, 0);
-	frames[7] = decode_tga_gz((void *) frame08_tga_gz, frame08_tga_gz_size, 0);
-	frames[8] = decode_tga_gz((void *) frame09_tga_gz, frame09_tga_gz_size, 0);
-	frames[9] = decode_tga_gz((void *) frame10_tga_gz, frame10_tga_gz_size, 0);
-	frames[10] = decode_tga_gz((void *) frame11_tga_gz, frame11_tga_gz_size, 0);
-	frames[11] = decode_tga_gz((void *) frame12_tga_gz, frame12_tga_gz_size, 0);
-	frames[12] = decode_tga_gz((void *) frame13_tga_gz, frame13_tga_gz_size, 0);
-	frames[13] = decode_tga_gz((void *) frame14_tga_gz, frame14_tga_gz_size, 0);
-	frames[14] = decode_tga_gz((void *) frame15_tga_gz, frame15_tga_gz_size, 0);
-	frames[15] = decode_tga_gz((void *) frame16_tga_gz, frame16_tga_gz_size, 0);
-	frames[16] = decode_tga_gz((void *) frame17_tga_gz, frame17_tga_gz_size, 0);
-	frames[17] = decode_tga_gz((void *) frame18_tga_gz, frame18_tga_gz_size, 0);
-	frames[18] = decode_tga_gz((void *) frame19_tga_gz, frame19_tga_gz_size, 0);
-	frames[19] = decode_tga_gz((void *) frame20_tga_gz, frame20_tga_gz_size, 0);
-	frames[20] = decode_tga_gz((void *) frame21_tga_gz, frame21_tga_gz_size, 0);
-	frames[21] = decode_tga_gz((void *) frame22_tga_gz, frame22_tga_gz_size, 0);
-	frames[22] = decode_tga_gz((void *) frame23_tga_gz, frame23_tga_gz_size, 0);
-	frames[23] = decode_tga_gz((void *) frame24_tga_gz, frame24_tga_gz_size, 0);
-	frames[24] = decode_tga_gz((void *) frame25_tga_gz, frame25_tga_gz_size, 0);
-	frames[25] = decode_tga_gz((void *) frame26_tga_gz, frame26_tga_gz_size, 0);
-	frames[26] = decode_tga_gz((void *) frame27_tga_gz, frame27_tga_gz_size, 0);
-	frames[27] = decode_tga_gz((void *) frame28_tga_gz, frame28_tga_gz_size, 0);
-	frames[28] = decode_tga_gz((void *) frame29_tga_gz, frame29_tga_gz_size, 0);
-	frames[29] = decode_tga_gz((void *) frame30_tga_gz, frame30_tga_gz_size, 0);
-	
-	for (unsigned int frame = 0; frame < FRAMES; frame++) {
-		if (frames[frame] == NULL) {
-			printf("Unable to decode frame %u.\n", frame);
+	for (unsigned int i = 0; i < FRAMES; i++) {
+		frames[i] = decode_tga_gz(images[i].addr, images[i].size, 0);
+		if (frames[i] == NULL) {
+			printf("Unable to decode frame %u.\n", i);
 			return false;
 		}
Index: uspace/app/bdsh/cmds/builtin_cmds.c
===================================================================
--- uspace/app/bdsh/cmds/builtin_cmds.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/bdsh/cmds/builtin_cmds.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -79,8 +79,7 @@
 		return (char *)NULL;
 
-	for(i=0; builtin_aliases[i] != NULL; i++) {
+	for(i=0; builtin_aliases[i] != NULL; i+=2) {
 		if (!str_cmp(builtin_aliases[i], command))
-			return (char *)builtin_aliases[++i];
-		i++;
+			return (char *)builtin_aliases[i+1];
 	}
 
Index: uspace/app/bdsh/cmds/mod_cmds.c
===================================================================
--- uspace/app/bdsh/cmds/mod_cmds.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/bdsh/cmds/mod_cmds.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -96,8 +96,7 @@
 		return (char *)NULL;
 
-	for(i=0; mod_aliases[i] != NULL; i++) {
+	for(i=0; mod_aliases[i] != NULL; i+=2) {
 		if (!str_cmp(mod_aliases[i], command))
-			return (char *)mod_aliases[++i];
-		i++;
+			return (char *)mod_aliases[i+1];
 	}
 
Index: uspace/app/bdsh/cmds/modules/ls/ls.c
===================================================================
--- uspace/app/bdsh/cmds/modules/ls/ls.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/bdsh/cmds/modules/ls/ls.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,4 @@
 #include <vfs/vfs.h>
 #include <str.h>
-#include <sort.h>
 
 #include "ls.h"
@@ -62,5 +61,5 @@
 static unsigned int ls_start(ls_job_t *);
 static void ls_print(struct dir_elem_t *);
-static int ls_cmp(void *, void *, void *);
+static int ls_cmp(const void *, const void *);
 static signed int ls_scan_dir(const char *, DIR *, struct dir_elem_t **);
 static unsigned int ls_recursive(const char *, DIR *);
@@ -104,12 +103,11 @@
  * @param a		Pointer to the structure of the first element.
  * @param b		Pointer to the structure of the second element.
- * @param arg		Pointer for an other and optionnal argument.
  *
  * @return		-1 if a < b, 1 otherwise.
  */
-static int ls_cmp(void *a, void *b, void *arg)
-{
-	struct dir_elem_t *da = a;
-	struct dir_elem_t *db = b;
+static int ls_cmp(const void *a, const void *b)
+{
+	struct dir_elem_t const *da = a;
+	struct dir_elem_t const *db = b;
 	
 	if ((da->s.is_directory && db->s.is_file) ||
@@ -191,10 +189,6 @@
 	}
 	
-	if (ls.sort) {
-		if (!qsort(&tosort[0], nbdirs, sizeof(struct dir_elem_t),
-		    ls_cmp, NULL)) {
-			printf("Sorting error.\n");
-		}
-	}
+	if (ls.sort)
+		qsort(&tosort[0], nbdirs, sizeof(struct dir_elem_t), ls_cmp);
 	
 	for (i = 0; i < nbdirs; i++)
Index: uspace/app/blkdump/blkdump.c
===================================================================
--- uspace/app/blkdump/blkdump.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/blkdump/blkdump.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -46,5 +46,5 @@
 #include <byteorder.h>
 #include <scsi/mmc.h>
-#include <sys/typefmt.h>
+#include <offset.h>
 #include <inttypes.h>
 #include <errno.h>
Index: uspace/app/bnchmark/bnchmark.c
===================================================================
--- uspace/app/bnchmark/bnchmark.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/bnchmark/bnchmark.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,4 @@
 #include <loc.h>
 #include <byteorder.h>
-#include <sys/typefmt.h>
 #include <inttypes.h>
 #include <errno.h>
Index: uspace/app/devctl/devctl.c
===================================================================
--- uspace/app/devctl/devctl.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/devctl/devctl.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,9 +35,9 @@
 #include <devman.h>
 #include <errno.h>
+#include <io/table.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <str_error.h>
-#include <sys/typefmt.h>
 
 #define NAME "devctl"
@@ -206,4 +206,5 @@
 	size_t ndevs;
 	size_t i;
+	table_t *table = NULL;
 	int rc;
 
@@ -211,4 +212,13 @@
 	if (rc != EOK)
 		return rc;
+
+	rc = table_create(&table);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		goto out;
+	}
+
+	table_header_row(table);
+	table_printf(table, "Driver\t" "Devs\t" "State\n");
 
 	for (i = 0; i < ndrvs; i++) {
@@ -227,11 +237,17 @@
 		sstate = drv_state_str(state);
 
-		printf("%-11s %3zu %s\n", sstate, ndevs, drv_name);
+		table_printf(table, "%s\t" "%zu\t" "%s\n", drv_name, ndevs, sstate);
 skip:
 		free(devs);
 	}
+
+	rc = table_print_out(table, stdout);
+	if (rc != EOK)
+		printf("Error printing driver table.\n");
+out:
 	free(drvs);
-
-	return EOK;
+	table_destroy(table);
+
+	return rc;
 }
 
Index: uspace/app/df/df.c
===================================================================
--- uspace/app/df/df.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/df/df.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,5 +28,5 @@
 
 /** @addtogroup df
- * @brief Df utility.
+ * @brief Print amounts of free and used disk space.
  * @{
  */
@@ -35,4 +35,6 @@
  */
 
+#include <cap.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -46,19 +48,14 @@
 #define NAME  "df"
 
-#define HEADER_TABLE 	"Filesystem     %4u-blocks           Used      Available Used%% Mounted on"
-#define HEADER_TABLE_HR "Filesystem           Size           Used      Available Used%% Mounted on"
+#define HEADER_TABLE     "Filesystem           Size           Used      Available Used%% Mounted on"
+#define HEADER_TABLE_BLK "Filesystem  Blk. Size     Total        Used   Available Used%% Mounted on"
 
 #define PERCENTAGE(x, tot) (tot ? (100ULL * (x) / (tot)) : 0)
-#define FSBK_TO_BK(x, fsbk, bk) \
-	(((fsbk) != 0 && (fsbk) < (bk)) ? \
-		(unsigned long long) ((x) / ((bk) / (fsbk))) : \
-		(unsigned long long) ((x) * ((fsbk) / (bk))))
-
-static unsigned int unit_size;
-static unsigned int human_readable;
-
-static void size_to_human_readable(char *buf, uint64_t bytes);
+
+static bool display_blocks;
+
+static int size_to_human_readable(uint64_t, size_t, char **);
 static void print_header(void);
-static void print_statfs(struct statfs *, char *, char *);
+static int print_statfs(struct statfs *, char *, char *);
 static void print_usage(void);
 
@@ -67,23 +64,17 @@
 	int optres, errflg = 0;
 	struct statfs st;
-
-	unit_size = 512;
-	human_readable = 0;
-
-	/******************************************/
-	/*   Parse command line options...        */
-	/******************************************/
-	while ((optres = getopt(argc, argv, ":uhb:")) != -1) {
+	int rc;
+
+	display_blocks = false;
+
+	/* Parse command-line options */
+	while ((optres = getopt(argc, argv, ":ubh")) != -1) {
 		switch(optres) {
-		case 'u':
+		case 'h':
 			print_usage();
 			return 0;
 
-		case 'h':
-			human_readable = 1;
-			break;
-
 		case 'b':
-			str_uint32_t(optarg, NULL, 0, 0, &unit_size);
+			display_blocks = true;
 			break;
  
@@ -123,5 +114,7 @@
 	list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
 		if (vfs_statfs_path(mtab_ent->mp, &st) == 0) {
-			print_statfs(&st, mtab_ent->fs_name, mtab_ent->mp);
+			rc = print_statfs(&st, mtab_ent->fs_name, mtab_ent->mp);
+			if (rc != EOK)
+				return 1;
 		} else {
 			fprintf(stderr, "Cannot get information for '%s' (%d).\n",
@@ -134,48 +127,53 @@
 }
 
-static void size_to_human_readable(char *buf, uint64_t bytes)
-{
-	const char *units = "BkMGTPEZY";
-	int i = 0;
-
-	while (bytes >= 1024) {
-		bytes /= 1024;
-		i++;
-	}
-
-	snprintf(buf, 6, "%4llu%c", (unsigned long long) bytes, units[i]);
+static int size_to_human_readable(uint64_t nblocks, size_t block_size, char **rptr)
+{
+	cap_spec_t cap;
+
+	cap_from_blocks(nblocks, block_size, &cap);
+	cap_simplify(&cap);
+	return cap_format(&cap, rptr);
 }
 
 static void print_header(void)
 {
-	if (human_readable)
-		printf(HEADER_TABLE_HR);
+	if (!display_blocks)
+		printf(HEADER_TABLE);
 	else
-		printf(HEADER_TABLE, unit_size);
+		printf(HEADER_TABLE_BLK);
 
 	putchar('\n');
 }
 
-static void print_statfs(struct statfs *st, char *name, char *mountpoint)
+static int print_statfs(struct statfs *st, char *name, char *mountpoint)
 {
 	uint64_t const used_blocks = st->f_blocks - st->f_bfree;
 	unsigned const perc_used = PERCENTAGE(used_blocks, st->f_blocks);
+	char *str;
+	int rc;
 
 	printf("%10s", name);
 
-	if (human_readable) {
-		char tmp[1024];
-
+	if (!display_blocks) {
 		/* Print size */
-		size_to_human_readable(tmp, st->f_blocks *  st->f_bsize);
-		printf(" %14s", tmp);
+		rc = size_to_human_readable(st->f_blocks, st->f_bsize, &str);
+		if (rc != EOK)
+			goto error;
+		printf(" %14s", str);
+		free(str);
 
 		/* Number of used blocks */
-		size_to_human_readable(tmp, used_blocks  *  st->f_bsize);
-		printf(" %14s", tmp);
+		rc = size_to_human_readable(used_blocks, st->f_bsize, &str);
+		if (rc != EOK)
+			goto error;
+		printf(" %14s", str);
+		free(str);
 
 		/* Number of available blocks */
-		size_to_human_readable(tmp, st->f_bfree *  st->f_bsize);
-		printf(" %14s", tmp);
+		rc = size_to_human_readable(st->f_bfree, st->f_bsize, &str);
+		if (rc != EOK)
+			goto error;
+		printf(" %14s", str);
+		free(str);
 
 		/* Percentage of used blocks */
@@ -185,22 +183,22 @@
 		printf(" %s\n", mountpoint);
 	} else {
-		/* Blocks / Used blocks / Available blocks / Used% / Mounted on */
-		printf(" %15llu %14llu %14llu %4u%% %s\n", 
-		    FSBK_TO_BK(st->f_blocks, st->f_bsize, unit_size),
-		    FSBK_TO_BK(used_blocks, st->f_bsize, unit_size),
-		    FSBK_TO_BK(st->f_bfree, st->f_bsize, unit_size),
-		    perc_used,
-		    mountpoint);
-	}
-
+		/* Block size / Blocks / Used blocks / Available blocks / Used% / Mounted on */
+		printf(" %10" PRIu32 " %9" PRIu64 " %11" PRIu64 " %11" PRIu64 " %4u%% %s\n", 
+		    st->f_bsize, st->f_blocks, used_blocks, st->f_bfree,
+		    perc_used, mountpoint);
+	}
+
+	return EOK;
+error:
+	printf("\nError: Out of memory.\n");
+	return ENOMEM;
 }
 
 static void print_usage(void)
 {
-	printf("syntax: %s [-u] [-h] [-b <size>] \n", NAME);
-	printf("  u : Show usage.\n");
-	printf("  h : \"Human-readable\" output.\n");
-	printf("  b : Scale block sizes by selected size.\n");
-	printf("\n");
+	printf("Syntax: %s [<options>] \n", NAME);
+	printf("Options:\n");
+	printf("  -h Print help\n");
+	printf("  -b Print exact block sizes and numbers\n");
 }
 
Index: uspace/app/download/main.c
===================================================================
--- uspace/app/download/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/download/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -57,6 +57,6 @@
 static void syntax_print(void)
 {
-	fprintf(stderr, "Usage: download <url>\n");
-	fprintf(stderr, "  This will write the data to stdout, so you may want\n");
+	fprintf(stderr, "Usage: download [-o <outfile>] <url>\n");
+	fprintf(stderr, "  Without -o, data will be written to stdout, so you may want\n");
 	fprintf(stderr, "  to redirect the output, e.g.\n");
 	fprintf(stderr, "\n");
@@ -66,18 +66,55 @@
 int main(int argc, char *argv[])
 {
-	if (argc != 2) {
+	int i;
+	char *ofname = NULL;
+	FILE *ofile = NULL;
+	size_t buf_size = 4096;
+	void *buf = NULL;
+	uri_t *uri = NULL;
+	http_t *http = NULL;
+	int rc;
+
+	if (argc < 2) {
 		syntax_print();
-		return 2;
-	}
-	
-	uri_t *uri = uri_parse(argv[1]);
+		rc = EINVAL;
+		goto error;
+	}
+	
+	i = 1;
+	
+	if (str_cmp(argv[i], "-o") == 0) {
+		++i;
+		if (argc < i + 1) {
+			syntax_print();
+			rc = EINVAL;
+			goto error;
+		}
+		
+		ofname = argv[i++];
+		ofile = fopen(ofname, "wb");
+		if (ofile == NULL) {
+			fprintf(stderr, "Error creating '%s'.\n", ofname);
+			rc = EINVAL;
+			goto error;
+		}
+	}
+	
+	if (argc != i + 1) {
+		syntax_print();
+		rc = EINVAL;
+		goto error;
+	}
+	
+	uri = uri_parse(argv[i]);
 	if (uri == NULL) {
 		fprintf(stderr, "Failed parsing URI\n");
-		return 2;
+		rc = EINVAL;
+		goto error;
 	}
 	
 	if (!uri_validate(uri)) {
 		fprintf(stderr, "The URI is invalid\n");
-		return 2;
+		rc = EINVAL;
+		goto error;
 	}
 	
@@ -86,18 +123,21 @@
 	if (str_cmp(uri->scheme, "http") != 0) {
 		fprintf(stderr, "Only http scheme is supported at the moment\n");
-		return 2;
+		rc = EINVAL;
+		goto error;
 	}
 	
 	if (uri->host == NULL) {
 		fprintf(stderr, "host not set\n");
-		return 2;
+		rc = EINVAL;
+		goto error;
 	}
 	
 	uint16_t port = 80;
 	if (uri->port != NULL) {
-		int rc = str_uint16_t(uri->port, NULL, 10, true, &port);
+		rc = str_uint16_t(uri->port, NULL, 10, true, &port);
 		if (rc != EOK) {
 			fprintf(stderr, "Invalid port number: %s\n", uri->port);
-			return 2;
+			rc = EINVAL;
+			goto error;
 		}
 	}
@@ -111,14 +151,13 @@
 		if (server_path == NULL) {
 			fprintf(stderr, "Failed allocating path\n");
-			uri_destroy(uri);
-			return 3;
-		}
-	}
-	else {
-		int rc = asprintf(&server_path, "%s?%s", path, uri->query);
+			rc = ENOMEM;
+			goto error;
+		}
+	} else {
+		rc = asprintf(&server_path, "%s?%s", path, uri->query);
 		if (rc < 0) {
 			fprintf(stderr, "Failed allocating path\n");
-			uri_destroy(uri);
-			return 3;
+			rc = ENOMEM;
+			goto error;
 		}
 	}
@@ -128,13 +167,12 @@
 	if (req == NULL) {
 		fprintf(stderr, "Failed creating request\n");
-		uri_destroy(uri);
-		return 3;
-	}
-	
-	int rc = http_headers_append(&req->headers, "Host", uri->host);
+		rc = ENOMEM;
+		goto error;
+	}
+	
+	rc = http_headers_append(&req->headers, "Host", uri->host);
 	if (rc != EOK) {
 		fprintf(stderr, "Failed setting Host header: %s\n", str_error(rc));
-		uri_destroy(uri);
-		return rc;
+		goto error;
 	}
 	
@@ -142,13 +180,12 @@
 	if (rc != EOK) {
 		fprintf(stderr, "Failed creating User-Agent header: %s\n", str_error(rc));
-		uri_destroy(uri);
-		return rc;
-	}
-	
-	http_t *http = http_create(uri->host, port);
+		goto error;
+	}
+	
+	http = http_create(uri->host, port);
 	if (http == NULL) {
-		uri_destroy(uri);
 		fprintf(stderr, "Failed creating HTTP object\n");
-		return 3;
+		rc = ENOMEM;
+		goto error;
 	}
 	
@@ -156,6 +193,6 @@
 	if (rc != EOK) {
 		fprintf(stderr, "Failed connecting: %s\n", str_error(rc));
-		uri_destroy(uri);
-		return rc;
+		rc = EIO;
+		goto error;
 	}
 	
@@ -163,6 +200,6 @@
 	if (rc != EOK) {
 		fprintf(stderr, "Failed sending request: %s\n", str_error(rc));
-		uri_destroy(uri);
-		return rc;
+		rc = EIO;
+		goto error;
 	}
 	
@@ -172,6 +209,6 @@
 	if (rc != EOK) {
 		fprintf(stderr, "Failed receiving response: %s\n", str_error(rc));
-		uri_destroy(uri);
-		return rc;
+		rc = EIO;
+		goto error;
 	}
 	
@@ -179,17 +216,15 @@
 		fprintf(stderr, "Server returned status %d %s\n", response->status,
 		    response->message);
-	}
-	else {
-		size_t buf_size = 4096;
-		void *buf = malloc(buf_size);
+	} else {
+		buf = malloc(buf_size);
 		if (buf == NULL) {
 			fprintf(stderr, "Failed allocating buffer\n)");
-			uri_destroy(uri);
-			return ENOMEM;
+			rc = ENOMEM;
+			goto error;
 		}
 		
 		int body_size;
 		while ((body_size = recv_buffer(&http->recv_buffer, buf, buf_size)) > 0) {
-			fwrite(buf, 1, body_size, stdout);
+			fwrite(buf, 1, body_size, ofile != NULL ? ofile : stdout);
 		}
 		
@@ -199,6 +234,22 @@
 	}
 	
+	free(buf);
+	http_destroy(http);
 	uri_destroy(uri);
+	if (ofile != NULL && fclose(ofile) != 0) {
+		printf("Error writing '%s'.\n", ofname);
+		return EIO;
+	}
+
 	return EOK;
+error:
+	free(buf);
+	if (http != NULL)
+		http_destroy(http);
+	if (uri != NULL)
+		uri_destroy(uri);
+	if (ofile != NULL)
+		fclose(ofile);
+	return rc;
 }
 
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/edit/edit.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,5 +48,5 @@
 #include <macros.h>
 #include <clipboard.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 #include "sheet.h"
Index: uspace/app/edit/search.h
===================================================================
--- uspace/app/edit/search.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/edit/search.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 
 #include <str.h>
-#include <sys/types.h>
+#include <offset.h>
 
 struct search;
Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/fdisk/fdisk.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
  */
 
+#include <cap.h>
 #include <errno.h>
 #include <nchoice.h>
@@ -41,4 +42,6 @@
 #include <stdlib.h>
 #include <fdisk.h>
+
+#define NO_LABEL_CAPTION "(No name)"
 
 static bool quit = false;
@@ -149,5 +152,5 @@
 	nchoice_t *choice = NULL;
 	char *svcname = NULL;
-	fdisk_cap_t cap;
+	cap_spec_t cap;
 	fdisk_dev_info_t *sdev;
 	char *scap = NULL;
@@ -198,7 +201,7 @@
 		}
 
-		fdisk_cap_simplify(&cap);
-
-		rc = fdisk_cap_format(&cap, &scap);
+		cap_simplify(&cap);
+
+		rc = cap_format(&cap, &scap);
 		if (rc != EOK) {
 			assert(rc == ENOMEM);
@@ -443,6 +446,7 @@
 	int rc;
 	fdisk_part_spec_t pspec;
-	fdisk_cap_t cap;
-	fdisk_cap_t mcap;
+	cap_spec_t cap;
+	cap_spec_t mcap;
+	vol_label_supp_t vlsupp;
 	vol_fstype_t fstype = 0;
 	tinput_t *tinput = NULL;
@@ -450,4 +454,5 @@
 	char *scap;
 	char *smcap = NULL;
+	char *label = NULL;
 
 	if (pkind == lpk_logical)
@@ -462,7 +467,7 @@
 	}
 
-	fdisk_cap_simplify(&mcap);
-
-	rc = fdisk_cap_format(&mcap, &smcap);
+	cap_simplify(&mcap);
+
+	rc = cap_format(&mcap, &smcap);
 	if (rc != EOK) {
 		rc = ENOMEM;
@@ -486,5 +491,5 @@
 			goto error;
 
-		rc = fdisk_cap_parse(scap, &cap);
+		rc = cap_parse(scap, &cap);
 		if (rc == EOK)
 			break;
@@ -502,8 +507,31 @@
 	}
 
+	fdisk_get_vollabel_support(dev, fstype, &vlsupp);
+	if (vlsupp.supported) {
+		tinput = tinput_new();
+		if (tinput == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		rc = tinput_set_prompt(tinput, "?> ");
+		if (rc != EOK)
+			goto error;
+
+		/* Ask for volume label */
+		printf("Enter volume label for new partition.\n");
+		rc = tinput_read_i(tinput, "New volume", &label);
+		if (rc != EOK)
+			goto error;
+
+	    	tinput_destroy(tinput);
+		tinput = NULL;
+	}
+
 	fdisk_pspec_init(&pspec);
 	pspec.capacity = cap;
 	pspec.pkind = pkind;
 	pspec.fstype = fstype;
+	pspec.label = label;
 
 	rc = fdisk_part_create(dev, &pspec, NULL);
@@ -513,7 +541,9 @@
 	}
 
+	free(label);
 	return EOK;
 error:
 	free(smcap);
+	free(label);
 	if (tinput != NULL)
 		tinput_destroy(tinput);
@@ -530,4 +560,5 @@
 	char *sfstype = NULL;
 	char *sdesc = NULL;
+	const char *label;
 	bool confirm;
 	void *sel;
@@ -556,7 +587,7 @@
 		}
 
-		fdisk_cap_simplify(&pinfo.capacity);
-
-		rc = fdisk_cap_format(&pinfo.capacity, &scap);
+		cap_simplify(&pinfo.capacity);
+
+		rc = cap_format(&pinfo.capacity, &scap);
 		if (rc != EOK) {
 			printf("Out of memory.\n");
@@ -577,5 +608,11 @@
 			}
 
-			rc = asprintf(&sdesc, "%s, %s, %s", scap, spkind, sfstype);
+			if (str_size(pinfo.label) > 0)
+				label = pinfo.label;
+			else
+				label = "(No name)";
+
+			rc = asprintf(&sdesc, "%s %s, %s, %s", label,
+			    scap, spkind, sfstype);
 			if (rc < 0) {
 				rc = ENOMEM;
@@ -667,6 +704,6 @@
 	fdisk_part_t *part;
 	fdisk_part_info_t pinfo;
-	fdisk_cap_t cap;
-	fdisk_cap_t mcap;
+	cap_spec_t cap;
+	cap_spec_t mcap;
 	fdisk_dev_flags_t dflags;
 	char *sltype = NULL;
@@ -677,4 +714,5 @@
 	char *svcname = NULL;
 	char *spkind;
+	const char *label;
 	int rc;
 	int npart;
@@ -701,7 +739,7 @@
 	}
 
-	fdisk_cap_simplify(&cap);
-
-	rc = fdisk_cap_format(&cap, &sdcap);
+	cap_simplify(&cap);
+
+	rc = cap_format(&cap, &sdcap);
 	if (rc != EOK) {
 		printf("Out of memory.\n");
@@ -717,5 +755,5 @@
 	fdisk_dev_get_flags(dev, &dflags);
 
-	printf("Device: %s, %s\n", sdcap, svcname);
+	printf("Device: %s (%s)\n", svcname, sdcap);
 	free(sdcap);
 	sdcap = NULL;
@@ -755,7 +793,7 @@
 		}
 
-		fdisk_cap_simplify(&pinfo.capacity);
-
-		rc = fdisk_cap_format(&pinfo.capacity, &scap);
+		cap_simplify(&pinfo.capacity);
+
+		rc = cap_format(&pinfo.capacity, &scap);
 		if (rc != EOK) {
 			printf("Out of memory.\n");
@@ -769,8 +807,13 @@
 		}
 
+		if (str_size(pinfo.label) > 0)
+			label = pinfo.label;
+		else
+			label = "(No name)";
+
 		if (linfo.ltype == lt_none)
-			printf("Entire disk: %s", scap);
+			printf("Entire disk: %s %s", label, scap);
 		else
-			printf("Partition %d: %s", npart, scap);
+			printf("Partition %d: %s %s", npart, label, scap);
 
 		if ((linfo.flags & lf_ext_supp) != 0) {
@@ -807,7 +850,7 @@
 		}
 
-		fdisk_cap_simplify(&mcap);
-
-		rc = fdisk_cap_format(&mcap, &smcap);
+		cap_simplify(&mcap);
+
+		rc = cap_format(&mcap, &smcap);
 		if (rc != EOK) {
 			rc = ENOMEM;
@@ -829,7 +872,7 @@
 		}
 
-		fdisk_cap_simplify(&mcap);
-
-		rc = fdisk_cap_format(&mcap, &smcap);
+		cap_simplify(&mcap);
+
+		rc = cap_format(&mcap, &smcap);
 		if (rc != EOK) {
 			rc = ENOMEM;
@@ -854,7 +897,7 @@
 		}
 
-		fdisk_cap_simplify(&mcap);
-
-		rc = fdisk_cap_format(&mcap, &smcap);
+		cap_simplify(&mcap);
+
+		rc = cap_format(&mcap, &smcap);
 		if (rc != EOK) {
 			rc = ENOMEM;
@@ -872,7 +915,7 @@
 		}
 
-		fdisk_cap_simplify(&mcap);
-
-		rc = fdisk_cap_format(&mcap, &smcap);
+		cap_simplify(&mcap);
+
+		rc = cap_format(&mcap, &smcap);
 		if (rc != EOK) {
 			rc = ENOMEM;
Index: uspace/app/fontviewer/fontviewer.c
===================================================================
--- uspace/app/fontviewer/fontviewer.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/fontviewer/fontviewer.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -78,5 +78,5 @@
 				points += increment;
 		
-			if ((event->key == KC_DOWN)) {
+			if (event->key == KC_DOWN) {
 				if (points <= increment) {
 					points = 1;
Index: uspace/app/gunzip/Makefile
===================================================================
--- uspace/app/gunzip/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/app/gunzip/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2017 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 = ../..
+BINARY = gunzip
+
+EXTRA_CFLAGS += -I$(LIBCOMPRESS_PREFIX)
+LIBS = $(LIBCOMPRESS_PREFIX)/libcompress.a
+
+SOURCES = \
+	gunzip.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/gunzip/gunzip.c
===================================================================
--- uspace/app/gunzip/gunzip.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/app/gunzip/gunzip.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017 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 gunzip
+ * @{
+ */
+/** @file
+ */
+
+#include <errno.h>
+#include <gzip.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+	int rc;
+	void *data, *ddata;
+	size_t size, dsize;
+	size_t nread, nwr;
+	long len;
+	FILE *f, *wf;
+
+	if (argc != 3) {
+		printf("syntax: gunzip <src.gz> <dest>\n");
+		return 1;
+	}
+
+	f = fopen(argv[1], "rb");
+	if (f == NULL) {
+		printf("Error opening '%s'\n", argv[1]);
+		return 1;
+	}
+
+	rc = fseek(f, 0, SEEK_END);
+	if (rc != 0) {
+		printf("Error determining size of '%s'\n", argv[1]);
+		fclose(f);
+		return 1;
+	}
+
+	len = ftell(f);
+	if (len < 0) {
+		printf("Error determining size of '%s'\n", argv[1]);
+		fclose(f);
+		return 1;
+	}
+
+	rc = fseek(f, 0, SEEK_SET);
+	if (rc != 0) {
+		printf ("Error rewinding '%s'\n", argv[1]);
+		fclose(f);
+		return 1;
+	}
+
+	data = malloc(len);
+	if (data == NULL) {
+		printf("Error allocating %ld bytes.\n", len);
+		fclose(f);
+		return 1;
+	}
+
+	nread = fread(data, 1, len, f);
+	if (nread != (size_t)len) {
+		printf("Error reading '%s'\n", argv[1]);
+		fclose(f);
+		return 1;
+	}
+
+	fclose(f);
+
+	size = (size_t) len;
+
+	rc = gzip_expand(data, size, &ddata, &dsize);
+	if (rc != EOK) {
+		printf("Error decompressing data.\n");
+		return 1;
+	}
+
+	wf = fopen(argv[2], "wb");
+	if (wf == NULL) {
+		printf("Error creating file '%s'\n", argv[2]);
+		return 1;
+	}
+
+	nwr = fwrite(ddata, 1, dsize, wf);
+	if (nwr != dsize) {
+		printf("Error writing '%s'\n", argv[2]);
+		fclose(wf);
+		return 1;
+	}
+
+	if (fclose(wf) != 0) {
+		printf("Error writing '%s'\n", argv[2]);
+		return 1;
+	}
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/inet/inet.c
===================================================================
--- uspace/app/inet/inet.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/inet/inet.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <inet/addr.h>
 #include <inet/inetcfg.h>
+#include <io/table.h>
 #include <loc.h>
 #include <stdio.h>
@@ -48,9 +49,13 @@
 static void print_syntax(void)
 {
-	printf("syntax:\n");
-	printf("\t" NAME " create <addr>/<width> <link-name> <addr-name>\n");
-	printf("\t" NAME " delete <link-name> <addr-name>\n");
-	printf("\t" NAME " add-sr <dest-addr>/<width> <router-addr> <route-name>\n");
-	printf("\t" NAME " del-sr <route-name>\n");
+	printf("%s: Internet configuration utility.\n", NAME);
+	printf("Syntax:\n");
+	printf("  %s list-addr\n", NAME);
+	printf("  %s create-addr <addr>/<width> <link-name> <addr-name>\n", NAME);
+	printf("  %s delete-addr <link-name> <addr-name>\n", NAME);
+	printf("  %s list-sr\n", NAME);
+	printf("  %s create-sr <dest-addr>/<width> <router-addr> <route-name>\n", NAME);
+	printf("  %s delete-sr <route-name>\n", NAME);
+	printf("  %s list-link\n", NAME);
 }
 
@@ -242,9 +247,13 @@
 	inet_addr_info_t ainfo;
 	inet_link_info_t linfo;
+	table_t *table = NULL;
 
 	size_t count;
 	size_t i;
 	int rc;
-	char *astr;
+	char *astr = NULL;
+
+	ainfo.name = NULL;
+	linfo.name = NULL;
 
 	rc = inetcfg_get_addr_list(&addr_list, &count);
@@ -254,10 +263,13 @@
 	}
 
-	printf("Configured addresses:\n");
-	if (count > 0)
-		printf("    [Addr/Width] [Link-Name] [Addr-Name] [Def-MTU]\n");
-	ainfo.name = NULL;
-	linfo.name = NULL;
-	astr = NULL;
+	rc = table_create(&table);
+	if (rc != EOK) {
+		printf("Memory allocation failed.\n");
+		goto out;
+	}
+
+	table_header_row(table);
+	table_printf(table, "Addr/Width\t" "Link-Name\t" "Addr-Name\t"
+	    "Def-MTU\n");
 
 	for (i = 0; i < count; i++) {
@@ -285,6 +297,6 @@
 		}
 
-		printf("    %s %s %s %zu\n", astr, linfo.name,
-		    ainfo.name, linfo.def_mtu);
+		table_printf(table, "%s\t" "%s\t" "%s\t" "%zu\n", astr,
+		    linfo.name, ainfo.name, linfo.def_mtu);
 
 		free(ainfo.name);
@@ -297,7 +309,15 @@
 	}
 
-	if (count == 0)
-		printf("    None\n");
+	if (count != 0) {
+		rc = table_print_out(table, stdout);
+		if (rc != EOK) {
+			printf("Error printing table.\n");
+			goto out;
+		}
+	}
+
+	rc = EOK;
 out:
+	table_destroy(table);
 	if (ainfo.name != NULL)
 		free(ainfo.name);
@@ -309,11 +329,12 @@
 	free(addr_list);
 
-	return EOK;
+	return rc;
 }
 
 static int link_list(void)
 {
-	sysarg_t *link_list;
+	sysarg_t *link_list = NULL;
 	inet_link_info_t linfo;
+	table_t *table = NULL;
 
 	size_t count;
@@ -327,7 +348,12 @@
 	}
 
-	printf("IP links:\n");
-	if (count > 0)
-		printf("    [Link-layer Address] [Link-Name] [Def-MTU]\n");
+	rc = table_create(&table);
+	if (rc != EOK) {
+		printf("Memory allocation failed.\n");
+		goto out;
+	}
+
+	table_header_row(table);
+	table_printf(table, "Link-layer Address\t" "Link-Name\t" "Def-MTU\n");
 
 	for (i = 0; i < count; i++) {
@@ -339,5 +365,6 @@
 		}
 
-		printf("    %02x:%02x:%02x:%02x:%02x:%02x %s %zu\n",
+		table_printf(table, "%02x:%02x:%02x:%02x:%02x:%02x\t"
+		    "%s\t" "%zu\n",
 		    linfo.mac_addr[0], linfo.mac_addr[1],
 		    linfo.mac_addr[2], linfo.mac_addr[3],
@@ -350,22 +377,33 @@
 	}
 
-	if (count == 0)
-		printf("    None\n");
-
+	if (count != 0) {
+		rc = table_print_out(table, stdout);
+		if (rc != EOK) {
+			printf("Error printing table.\n");
+			goto out;
+		}
+	}
+
+	rc = EOK;
+out:
+	table_destroy(table);
 	free(link_list);
 
-	return EOK;
+	return rc;
 }
 
 static int sroute_list(void)
 {
-	sysarg_t *sroute_list;
+	sysarg_t *sroute_list = NULL;
 	inet_sroute_info_t srinfo;
+	table_t *table = NULL;
 
 	size_t count;
 	size_t i;
 	int rc;
-	char *dest_str;
-	char *router_str;
+	char *dest_str = NULL;
+	char *router_str = NULL;
+
+	srinfo.name = NULL;
 
 	rc = inetcfg_get_sroute_list(&sroute_list, &count);
@@ -375,11 +413,12 @@
 	}
 
-	printf("Static routes:\n");
-	if (count > 0)
-		printf("    [Dest/Width] [Router-Addr] [Route-Name]\n");
-
-	srinfo.name = NULL;
-	dest_str = NULL;
-	router_str = NULL;
+	rc = table_create(&table);
+	if (rc != EOK) {
+		printf("Memory allocation failed.\n");
+		goto out;
+	}
+
+	table_header_row(table);
+	table_printf(table, "Dest/Width\t" "Router-Addr\t" "Route-Name\n");
 
 	for (i = 0; i < count; i++) {
@@ -406,5 +445,6 @@
 		}
 
-		printf("    %s %s %s\n", dest_str, router_str, srinfo.name);
+		table_printf(table, "%s\t" "%s\t" "%s\n", dest_str, router_str,
+		    srinfo.name);
 
 		free(srinfo.name);
@@ -417,7 +457,15 @@
 	}
 
-	if (count == 0)
-		printf("    None\n");
+	if (count != 0) {
+		rc = table_print_out(table, stdout);
+		if (rc != EOK) {
+			printf("Error printing table.\n");
+			goto out;
+		}
+	}
+
+	rc = EOK;
 out:
+	table_destroy(table);
 	if (srinfo.name != NULL)
 		free(srinfo.name);
@@ -429,5 +477,5 @@
 	free(sroute_list);
 
-	return EOK;
+	return rc;
 }
 
@@ -443,31 +491,35 @@
 	}
 
-	if (argc < 2) {
+	if (argc < 2 || str_cmp(argv[1], "-h") == 0) {
+		print_syntax();
+		return 0;
+	}
+
+	if (str_cmp(argv[1], "list-addr") == 0) {
 		rc = addr_list();
 		if (rc != EOK)
 			return 1;
+	} else if (str_cmp(argv[1], "create-addr") == 0) {
+		rc = addr_create_static(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else if (str_cmp(argv[1], "delete-addr") == 0) {
+		rc = addr_delete(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else if (str_cmp(argv[1], "list-sr") == 0) {
 		rc = sroute_list();
 		if (rc != EOK)
 			return 1;
+	} else if (str_cmp(argv[1], "create-sr") == 0) {
+		rc = sroute_create(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else if (str_cmp(argv[1], "delete-sr") == 0) {
+		rc = sroute_delete(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else if (str_cmp(argv[1], "list-link") == 0) {
 		rc = link_list();
-		if (rc != EOK)
-			return 1;
-		return 0;
-	}
-
-	if (str_cmp(argv[1], "create") == 0) {
-		rc = addr_create_static(argc - 2, argv + 2);
-		if (rc != EOK)
-			return 1;
-	} else if (str_cmp(argv[1], "delete") == 0) {
-		rc = addr_delete(argc - 2, argv + 2);
-		if (rc != EOK)
-			return 1;
-	} else if (str_cmp(argv[1], "add-sr") == 0) {
-		rc = sroute_create(argc - 2, argv + 2);
-		if (rc != EOK)
-			return 1;
-	} else if (str_cmp(argv[1], "del-sr") == 0) {
-		rc = sroute_delete(argc - 2, argv + 2);
 		if (rc != EOK)
 			return 1;
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/init/init.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -340,7 +340,5 @@
 	srv_start("/srv/apic");
 	srv_start("/srv/i8259");
-	srv_start("/srv/icp-ic");
 	srv_start("/srv/obio");
-	srv_start("/srv/cuda_adb");
 	srv_start("/srv/s3c24xx_uart");
 	srv_start("/srv/s3c24xx_ts");
Index: uspace/app/loc/loc.c
===================================================================
--- uspace/app/loc/loc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/loc/loc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,6 +38,6 @@
 #include <stdlib.h>
 #include <stdint.h>
+#include <inttypes.h>
 #include <str.h>
-#include <sys/typefmt.h>
 
 #define NAME "loc"
Index: uspace/app/mkexfat/exfat.h
===================================================================
--- uspace/app/mkexfat/exfat.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/mkexfat/exfat.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
 #define EXFAT_FILENAME_LEN	255
 #define EXFAT_NAME_PART_LEN	15
+#define EXFAT_VOLLABEL_LEN	11
 
 #define EXFAT_TYPE_UNUSED	0x00
Index: uspace/app/mkexfat/mkexfat.c
===================================================================
--- uspace/app/mkexfat/mkexfat.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/mkexfat/mkexfat.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -46,5 +46,4 @@
 #include <byteorder.h>
 #include <align.h>
-#include <sys/typefmt.h>
 #include <str.h>
 #include <getopt.h>
@@ -102,6 +101,6 @@
 	size_t   sector_size;
 	size_t   cluster_size;
+	const char *label;
 } exfat_cfg_t;
-
 
 static unsigned log2(unsigned n);
@@ -127,4 +126,5 @@
 	{"cluster-size", required_argument, 0, 'c'},
 	{"fs-size", required_argument, 0, 's'},
+	{"label", required_argument, 0, 'L' },
 };
 
@@ -133,5 +133,6 @@
 	printf("Usage: mkexfat [options] <device>\n"
 	    "-c, --cluster-size ## Specify the cluster size (Kb)\n"
-	    "-s, --fs-size ##      Specify the filesystem size (sectors)\n");
+	    "-s, --fs-size ##      Specify the filesystem size (sectors)\n"
+	    "    --label ##        Volume label\n");
 }
 
@@ -598,4 +599,5 @@
 	exfat_dentry_t *d;
 	aoff64_t rootdir_sec;
+	uint16_t wlabel[EXFAT_VOLLABEL_LEN + 1];
 	int rc;
 	uint8_t *data;
@@ -609,9 +611,22 @@
 
 	/* Initialize the volume label dentry */
-	d->type = EXFAT_TYPE_VOLLABEL;
-	str_to_utf16(d->vollabel.label, 8, "HELENOS ");
-	d->vollabel.size = 8;
-
-	d++;
+
+	if (cfg->label != NULL) {
+		memset(wlabel, 0, (EXFAT_VOLLABEL_LEN + 1) * sizeof(uint16_t));
+		rc = str_to_utf16(wlabel, EXFAT_VOLLABEL_LEN + 1, cfg->label);
+		if (rc != EOK) {
+			rc = EINVAL;
+			goto exit;
+		}
+
+		d->type = EXFAT_TYPE_VOLLABEL;
+		memcpy(d->vollabel.label, wlabel, EXFAT_VOLLABEL_LEN * 2);
+		d->vollabel.size = utf16_wsize(wlabel);
+		assert(d->vollabel.size <= EXFAT_VOLLABEL_LEN);
+
+		d++;
+	} else {
+		d->type = EXFAT_TYPE_VOLLABEL & ~EXFAT_TYPE_USED;
+	}
 
 	/* Initialize the allocation bitmap dentry */
@@ -752,7 +767,8 @@
 
 	cfg.cluster_size = 0;
+	cfg.label = NULL;
 
 	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
-		c = getopt_long(argc, argv, "hs:c:",
+		c = getopt_long(argc, argv, "hs:c:L:",
 		    long_options, &opt_ind);
 		switch (c) {
@@ -782,4 +798,7 @@
 			}
 			break;
+		case 'L':
+			cfg.label = optarg;
+			break;
 		}
 	}
Index: uspace/app/mkfat/fat_dentry.h
===================================================================
--- uspace/app/mkfat/fat_dentry.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/app/mkfat/fat_dentry.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar
+ * Copyright (c) 2011 Oleg Romanenko
+ * 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 fs
+ * @{
+ */ 
+
+#ifndef FAT_FAT_DENTRY_H_
+#define FAT_FAT_DENTRY_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <unaligned.h>
+
+#define IS_D_CHAR(ch) (isalnum(ch) || ch == '_')
+#define FAT_STOP_CHARS "*?/\\\n\t|'"
+
+#define FAT_NAME_LEN		8
+#define FAT_EXT_LEN		3
+#define FAT_VOLLABEL_LEN	11
+
+#define FAT_NAME_DOT		".       "
+#define FAT_NAME_DOT_DOT	"..      "
+#define FAT_EXT_PAD		"   "
+
+#define FAT_ATTR_RDONLY   0x01
+#define FAT_ATTR_HIDDEN   0x02
+#define FAT_ATTR_SYSTEM   0x04
+#define FAT_ATTR_VOLLABEL 0x08
+#define FAT_ATTR_SUBDIR   0x10
+#define FAT_ATTR_ARCHIVE  0x20
+#define FAT_ATTR_LFN \
+    (FAT_ATTR_RDONLY | FAT_ATTR_HIDDEN | FAT_ATTR_SYSTEM | FAT_ATTR_VOLLABEL)
+    
+#define FAT_LCASE_LOWER_NAME	0x08
+#define FAT_LCASE_LOWER_EXT	0x10
+
+#define FAT_PAD			' '
+#define FAT_LFN_PAD	0xffff
+#define FAT_SFN_CHAR '_'
+
+#define FAT_DENTRY_UNUSED	0x00
+#define FAT_DENTRY_E5_ESC	0x05
+#define FAT_DENTRY_DOT		0x2e
+#define FAT_DENTRY_ERASED	0xe5
+#define FAT_LFN_LAST		0x40
+#define FAT_LFN_ERASED		0x80
+
+#define FAT_LFN_ORDER(d) ((d)->lfn.order)
+#define FAT_IS_LFN(d) \
+    ((FAT_LFN_ORDER((d)) & FAT_LFN_LAST) == FAT_LFN_LAST)
+#define FAT_LFN_COUNT(d) \
+    (FAT_LFN_ORDER((d)) ^ FAT_LFN_LAST)
+#define FAT_LFN_PART1(d) ((d)->lfn.part1)
+#define FAT_LFN_PART2(d) ((d)->lfn.part2)
+#define FAT_LFN_PART3(d) ((d)->lfn.part3)
+#define FAT_LFN_ATTR(d) ((d)->lfn.attr)
+#define FAT_LFN_CHKSUM(d) ((d)->lfn.check_sum)
+
+#define FAT_LFN_NAME_LEN    260                           /* characters */
+#define FAT_LFN_NAME_SIZE   STR_BOUNDS(FAT_LFN_NAME_LEN)  /* bytes */
+#define FAT_LFN_MAX_COUNT   20
+#define FAT_LFN_PART1_SIZE  5
+#define FAT_LFN_PART2_SIZE  6
+#define FAT_LFN_PART3_SIZE  2
+#define FAT_LFN_ENTRY_SIZE \
+    (FAT_LFN_PART1_SIZE + FAT_LFN_PART2_SIZE + FAT_LFN_PART3_SIZE)
+
+typedef enum {
+	FAT_DENTRY_SKIP,
+	FAT_DENTRY_LAST,
+	FAT_DENTRY_FREE,
+	FAT_DENTRY_VALID,
+	FAT_DENTRY_LFN,
+	FAT_DENTRY_VOLLABEL
+} fat_dentry_clsf_t;
+
+typedef union {
+	struct {
+		uint8_t		name[8];
+		uint8_t		ext[3];
+		uint8_t		attr;
+		uint8_t		lcase;
+		uint8_t		ctime_fine;
+		uint16_t	ctime;
+		uint16_t	cdate;
+		uint16_t	adate;
+		union {
+			uint16_t	eaidx;		/* FAT12/FAT16 */
+			uint16_t	firstc_hi;	/* FAT32 */
+		} __attribute__ ((packed));
+		uint16_t	mtime;
+		uint16_t	mdate;
+		union {
+			uint16_t	firstc;		/* FAT12/FAT16 */
+			uint16_t	firstc_lo;	/* FAT32 */
+		} __attribute__ ((packed));
+		uint32_t	size;
+	} __attribute__ ((packed));
+	struct {
+		uint8_t		order;
+		uint16_t	part1[FAT_LFN_PART1_SIZE];
+		uint8_t		attr;
+		uint8_t		type;
+		uint8_t		check_sum;
+		uint16_t	part2[FAT_LFN_PART2_SIZE];
+		uint16_t	firstc_lo; /* MUST be 0 */
+		uint16_t	part3[FAT_LFN_PART3_SIZE];
+	} __attribute__ ((packed)) lfn;
+} __attribute__ ((packed)) fat_dentry_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/app/mkfat/mkfat.c
===================================================================
--- uspace/app/mkfat/mkfat.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/mkfat/mkfat.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
  */
 
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -45,10 +46,12 @@
 #include <loc.h>
 #include <byteorder.h>
-#include <sys/typefmt.h>
 #include <inttypes.h>
 #include <errno.h>
 #include "fat.h"
+#include "fat_dentry.h"
 
 #define NAME	"mkfat"
+
+#define LABEL_NONAME "NO NAME"
 
 /** Divide and round up. */
@@ -78,4 +81,5 @@
 	uint32_t total_clusters;
 	uint8_t fat_count;
+	const char *label;
 } fat_cfg_t;
 
@@ -103,4 +107,5 @@
 	cfg.root_ent_max = 128;
 	cfg.fat_type = FATAUTO;
+	cfg.label = NULL;
 
 	if (argc < 2) {
@@ -111,38 +116,59 @@
 
 	--argc; ++argv;
-	if (str_cmp(*argv, "--size") == 0) {
-		--argc; ++argv;
-		if (*argv == NULL) {
-			printf(NAME ": Error, argument missing.\n");
-			syntax_print();
-			return 1;
+
+	while (*argv[0] == '-') {
+		if (str_cmp(*argv, "--size") == 0) {
+			--argc; ++argv;
+			if (*argv == NULL) {
+				printf(NAME ": Error, argument missing.\n");
+				syntax_print();
+				return 1;
+			}
+
+			cfg.total_sectors = strtol(*argv, &endptr, 10);
+			if (*endptr != '\0') {
+				printf(NAME ": Error, invalid argument.\n");
+				syntax_print();
+				return 1;
+			}
+
+			--argc; ++argv;
 		}
 
-		cfg.total_sectors = strtol(*argv, &endptr, 10);
-		if (*endptr != '\0') {
-			printf(NAME ": Error, invalid argument.\n");
-			syntax_print();
-			return 1;
+		if (str_cmp(*argv, "--type") == 0) {
+			--argc; ++argv;
+			if (*argv == NULL) {
+				printf(NAME ": Error, argument missing.\n");
+				syntax_print();
+				return 1;
+			}
+
+			cfg.fat_type = strtol(*argv, &endptr, 10);
+			if (*endptr != '\0') {
+				printf(NAME ": Error, invalid argument.\n");
+				syntax_print();
+				return 1;
+			}
+
+			--argc; ++argv;
 		}
 
-		--argc; ++argv;
-	}
-
-	if (str_cmp(*argv, "--type") == 0) {
-		--argc; ++argv;
-		if (*argv == NULL) {
-			printf(NAME ": Error, argument missing.\n");
-			syntax_print();
-			return 1;
+		if (str_cmp(*argv, "--label") == 0) {
+			--argc; ++argv;
+			if (*argv == NULL) {
+				printf(NAME ": Error, argument missing.\n");
+				syntax_print();
+				return 1;
+			}
+
+			cfg.label = *argv;
+
+			--argc; ++argv;
 		}
 
-		cfg.fat_type = strtol(*argv, &endptr, 10);
-		if (*endptr != '\0') {
-			printf(NAME ": Error, invalid argument.\n");
-			syntax_print();
-			return 1;
+		if (str_cmp(*argv, "-") == 0) {
+			--argc; ++argv;
+			break;
 		}
-
-		--argc; ++argv;
 	}
 
@@ -195,5 +221,5 @@
 	}
 
-	printf(NAME ": Creating FAT%d filesystem on device %s.\n", cfg.fat_type, dev_path);
+	printf(NAME ": Creating FAT filesystem on device %s.\n", dev_path);
 
 	rc = fat_params_compute(&cfg);
@@ -203,4 +229,6 @@
 	}
 
+	printf(NAME ": Filesystem type FAT%d.\n", cfg.fat_type);
+
 	rc = fat_blocks_write(&cfg, service_id);
 	if (rc != EOK) {
@@ -217,5 +245,36 @@
 static void syntax_print(void)
 {
-	printf("syntax: mkfat [--size <sectors>] [--type 12|16|32] <device_name>\n");
+	printf("syntax: mkfat [<options>...] <device_name>\n");
+	printf("options:\n"
+	    "\t--size <sectors> Filesystem size, overrides device size\n"
+	    "\t--type 12|16|32  FAT type (auto-detected by default)\n"
+	    "\t--label <label>  Volume label\n");
+}
+
+static int fat_label_encode(void *dest, const char *src)
+{
+	int i;
+	const char *sp;
+	uint8_t *dp;
+
+	i = 0;
+	sp = src;
+	dp = (uint8_t *)dest;
+
+	while (*sp != '\0' && i < FAT_VOLLABEL_LEN) {
+		if (!ascii_check(*sp))
+			return EINVAL;
+		if (dp != NULL)
+			dp[i] = toupper(*sp);
+		++i; ++sp;
+	}
+
+	while (i < FAT_VOLLABEL_LEN) {
+		if (dp != NULL)
+			dp[i] = FAT_PAD;
+		++i;
+	}
+
+	return EOK;
 }
 
@@ -228,5 +287,8 @@
 {
 	uint32_t fat_bytes;
+	uint32_t non_data_sectors_lb_16;
 	uint32_t non_data_sectors_lb;
+	uint32_t rd_sectors;
+	uint32_t tot_clust_16;
 
 	/*
@@ -234,24 +296,26 @@
 	 * system. The optimum could be potentially smaller since we
 	 * do not subtract size of the FAT itself when computing the
-	 * size of the data region.
+	 * size of the data region. Also the root dir area might not
+	 * need FAT entries if we decide to make a FAT32.
 	 */
 
 	cfg->reserved_sectors = 1 + cfg->addt_res_sectors;
-	if (cfg->fat_type != FAT32) {
-		cfg->rootdir_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
-			cfg->sector_size);
-	} else
-		cfg->rootdir_sectors = 0;
-	non_data_sectors_lb = cfg->reserved_sectors + cfg->rootdir_sectors;
-
-	cfg->total_clusters = div_round_up(cfg->total_sectors - non_data_sectors_lb,
+
+	/* Only correct for FAT12/16 (FAT32 has root dir stored in clusters */
+	rd_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
+		cfg->sector_size);
+	non_data_sectors_lb_16 = cfg->reserved_sectors + rd_sectors;
+
+	/* Only correct for FAT12/16 */
+	tot_clust_16 = div_round_up(cfg->total_sectors - non_data_sectors_lb_16,
 	    cfg->sectors_per_cluster);
 
-	if (cfg->total_clusters <= FAT12_CLST_MAX) {
+	/* Now detect FAT type */
+	if (tot_clust_16 <= FAT12_CLST_MAX) {
 		if (cfg->fat_type == FATAUTO)
 			cfg->fat_type = FAT12;
 		else if (cfg->fat_type != FAT12)
 			return EINVAL;
-	} else if (cfg->total_clusters <= FAT16_CLST_MAX) {
+	} else if (tot_clust_16 <= FAT16_CLST_MAX) {
 		if (cfg->fat_type == FATAUTO)
 			cfg->fat_type = FAT16;
@@ -265,7 +329,26 @@
 	}
 
+	/* Actual root directory size, non-data sectors */
+	if (cfg->fat_type != FAT32) {
+		cfg->rootdir_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
+			cfg->sector_size);
+		non_data_sectors_lb = cfg->reserved_sectors + cfg->rootdir_sectors;
+
+	} else {
+		/* We create a single-cluster root dir */
+		cfg->rootdir_sectors = cfg->sectors_per_cluster;
+		non_data_sectors_lb = cfg->reserved_sectors;
+	}
+
+	/* Actual total number of clusters */
+	cfg->total_clusters = div_round_up(cfg->total_sectors - non_data_sectors_lb,
+	    cfg->sectors_per_cluster);
+
 	fat_bytes = div_round_up((cfg->total_clusters + 2) *
 	    FAT_CLUSTER_DOUBLE_SIZE(cfg->fat_type), 2);
 	cfg->fat_sectors = div_round_up(fat_bytes, cfg->sector_size);
+
+	if (cfg->label != NULL && fat_label_encode(NULL, cfg->label) != EOK)
+		return EINVAL;
 
 	return EOK;
@@ -281,4 +364,5 @@
 	int rc;
 	struct fat_bs bs;
+	fat_dentry_t *de;
 
 	fat_bootsec_create(cfg, &bs);
@@ -340,21 +424,24 @@
 	printf("Writing root directory.\n");
 	memset(buffer, 0, cfg->sector_size);
-	if (cfg->fat_type != FAT32) {
-		size_t idx;
-		for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
-			rc = block_write_direct(service_id, addr, 1, buffer);
-			if (rc != EOK)
-				return EIO;
-
-			++addr;
+	de = (fat_dentry_t *)buffer;
+	size_t idx;
+	for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
+
+		if (idx == 0 && cfg->label != NULL) {
+			/* Set up volume label entry */
+			(void) fat_label_encode(&de->name, cfg->label);
+			de->attr = FAT_ATTR_VOLLABEL;
+			de->mtime = 0x1234;
+			de->mdate = 0x1234;
+		} else if (idx == 1) {
+			/* Clear volume label entry */
+			memset(buffer, 0, cfg->sector_size);
 		}
-	} else {
-		for (i = 0; i < cfg->sectors_per_cluster; i++) {
-			rc = block_write_direct(service_id, addr, 1, buffer);
-			if (rc != EOK)
-				return EIO;
-
-			++addr;
-		}	
+
+		rc = block_write_direct(service_id, addr, 1, buffer);
+		if (rc != EOK)
+			return EIO;
+
+		++addr;
 	}
 
@@ -367,4 +454,14 @@
 static void fat_bootsec_create(struct fat_cfg const *cfg, struct fat_bs *bs)
 {
+	const char *bs_label;
+
+	/*
+	 * The boot sector must always contain a valid label. If there
+	 * is no label, there should be 'NO NAME'
+	 */
+	if (cfg->label != NULL)
+		bs_label = cfg->label;
+	else
+		bs_label = LABEL_NONAME;
 	memset(bs, 0, sizeof(*bs));
 
@@ -405,5 +502,5 @@
 		bs->fat32.root_cluster = 2;
 
-		memcpy(bs->fat32.label, "HELENOS_NEW", 11);
+		(void) fat_label_encode(&bs->fat32.label, bs_label);
 		memcpy(bs->fat32.type, "FAT32   ", 8);
 	} else {
@@ -413,6 +510,9 @@
 		bs->id = host2uint32_t_be(0x12345678);
 
-		memcpy(bs->label, "HELENOS_NEW", 11);
-		memcpy(bs->type, "FAT   ", 8);
+		(void) fat_label_encode(&bs->label, bs_label);
+		if (cfg->fat_type == FAT12)
+			memcpy(bs->type, "FAT12   ", 8);
+		else
+			memcpy(bs->type, "FAT16   ", 8);
 	}
 }
Index: uspace/app/mkmfs/mkmfs.c
===================================================================
--- uspace/app/mkmfs/mkmfs.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/mkmfs/mkmfs.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,4 @@
 #include <block.h>
 #include <errno.h>
-#include <sys/typefmt.h>
 #include <inttypes.h>
 #include <getopt.h>
Index: uspace/app/nic/nic.c
===================================================================
--- uspace/app/nic/nic.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/nic/nic.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -120,4 +120,5 @@
 	if (sess == NULL) {
 		printf("Error connecting to service.\n");
+		rc = EIO;
 		goto error;
 	}
@@ -209,5 +210,5 @@
 }
 
-static const char *nic_multicast_mode_str(nic_unicast_mode_t mode)
+static const char *nic_multicast_mode_str(nic_multicast_mode_t mode)
 {
 	switch (mode) {
@@ -220,5 +221,5 @@
 }
 
-static const char *nic_broadcast_mode_str(nic_unicast_mode_t mode)
+static const char *nic_broadcast_mode_str(nic_broadcast_mode_t mode)
 {
 	switch (mode) {
Index: uspace/app/pkg/Makefile
===================================================================
--- uspace/app/pkg/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/app/pkg/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2017 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 = ../..
+BINARY = pkg
+
+SOURCES = \
+	pkg.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/pkg/pkg.c
===================================================================
--- uspace/app/pkg/pkg.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/app/pkg/pkg.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2017 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 pkg
+ * @{
+ */
+/** @file Package installer
+ *
+ * Utility to simplify installation of coastline packages
+ */
+
+#include <errno.h>
+#include <macros.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str_error.h>
+#include <task.h>
+
+#define NAME "pkg"
+
+static void print_syntax(void)
+{
+	fprintf(stderr, "syntax: " NAME " install <package-name>\n");
+}
+
+static int cmd_runl(const char *path, ...)
+{
+	va_list ap;
+	const char *arg;
+	int cnt = 0;
+
+	va_start(ap, path);
+	do {
+		arg = va_arg(ap, const char *);
+		cnt++;
+	} while (arg != NULL);
+	va_end(ap);
+
+	va_start(ap, path);
+	task_id_t id;
+	task_wait_t wait;
+	int rc = task_spawn(&id, &wait, path, cnt, ap);
+	va_end(ap);
+
+	if (rc != EOK) {
+		printf("Error spawning %s (%s)\n", path, str_error(rc));
+		return rc;
+	}
+
+	if (!id) {
+		printf("Error spawning %s (invalid task ID)\n", path);
+		return EINVAL;
+	}
+
+	task_exit_t texit;
+	int retval;
+	rc = task_wait(&wait, &texit, &retval);
+	if (rc != EOK) {
+		printf("Error waiting for %s (%s)\n", path, str_error(rc));
+		return rc;
+	}
+
+	if (texit != TASK_EXIT_NORMAL) {
+		printf("Command %s unexpectedly terminated\n", path);
+		return EINVAL;
+	}
+
+	if (retval != 0) {
+		printf("Command %s returned non-zero exit code %d)\n",
+		    path, retval);
+	}
+
+	return retval;
+}
+
+
+static int pkg_install(int argc, char *argv[])
+{
+	char *pkg_name;
+	char *src_uri;
+	char *fname;
+	char *fnunpack;
+	int rc;
+
+	if (argc != 3) {
+		print_syntax();
+		return EINVAL;
+	}
+
+	pkg_name = argv[2];
+
+	rc = asprintf(&src_uri, "http://ci.helenos.org/latest/" STRING(UARCH)
+	    "/%s-for-helenos-" STRING(UARCH) ".tar.gz",
+	    pkg_name);
+	if (rc < 0) {
+		printf("Out of memory.\n");
+		return ENOMEM;
+	}
+
+	rc = asprintf(&fname, "/tmp/%s-for-helenos-" STRING(UARCH)
+	    ".tar.gz", pkg_name);
+	if (rc < 0) {
+		printf("Out of memory.\n");
+		return ENOMEM;
+	}
+
+	rc = asprintf(&fnunpack, "/tmp/%s-for-helenos-" STRING(UARCH) ".tar",
+	    pkg_name);
+	if (rc < 0) {
+		printf("Out of memory.\n");
+		return ENOMEM;
+	}
+	/*XXX error cleanup */
+
+	printf("Downloading '%s'.\n", src_uri);
+
+	rc = cmd_runl("/app/download", "/app/download", "-o", fname,
+	    src_uri, NULL);
+	if (rc != EOK) {
+		printf("Error downloading package archive.\n");
+		return rc;
+	}
+
+	printf("Extracting package\n");
+
+	rc = cmd_runl("/app/gunzip", "/app/gunzip", fname, fnunpack, NULL);
+	if (rc != EOK) {
+		printf("Error uncompressing package archive.\n");
+		return rc;
+	}
+
+	if (remove(fname) != 0) {
+		printf("Error deleting package archive.\n");
+		return rc;
+	}
+
+
+	rc = cmd_runl("/app/untar", "/app/untar", fnunpack, NULL);
+	if (rc != EOK) {
+		printf("Error extracting package archive.\n");
+		return rc;
+	}
+
+	if (remove(fnunpack) != 0) {
+		printf("Error deleting package archive.\n");
+		return rc;
+	}
+
+	printf("Package '%s' installed.\n", pkg_name);
+
+	return EOK;
+}
+
+int main(int argc, char *argv[])
+{
+	char *cmd;
+	int rc;
+
+	if (argc < 2) {
+		fprintf(stderr, "Arguments missing.\n");
+		print_syntax();
+		return 1;
+	}
+
+	cmd = argv[1];
+
+	if (str_cmp(cmd, "install") == 0) {
+		rc = pkg_install(argc, argv);
+	} else {
+		fprintf(stderr, "Unknown command.\n");
+		print_syntax();
+		return 1;
+	}
+
+	if (rc != EOK)
+		return 1;
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/sbi/src/builtin/bi_task.c
===================================================================
--- uspace/app/sbi/src/builtin/bi_task.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/sbi/src/builtin/bi_task.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -114,5 +114,5 @@
 	}
 
-	cmd[dim] = '\0';
+	cmd[dim] = NULL;
 
 	if (os_exec((char * const *)cmd) != EOK) {
Index: uspace/app/sbi/src/os/posix.c
===================================================================
--- uspace/app/sbi/src/os/posix.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/sbi/src/os/posix.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 #include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
+#include <types/common.h>
 #include <sys/wait.h>
 #include <unistd.h>
Index: uspace/app/sbi/src/run_expr.c
===================================================================
--- uspace/app/sbi/src/run_expr.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/sbi/src/run_expr.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -2886,5 +2886,5 @@
 				/* Is it static/nonstatic? */
 				var_sn = stree_symbol_has_attr(
-				    var_to_symbol(var), sac_static);
+				    var_to_symbol(var), sac_static) ? sn_static : sn_nonstatic;
 				if (var_sn == sn) {
 					/* Compute field type. XXX Memoize. */
Index: uspace/app/sysinst/sysinst.c
===================================================================
--- uspace/app/sysinst/sysinst.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/sysinst/sysinst.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <block.h>
 #include <byteorder.h>
+#include <cap.h>
 #include <errno.h>
 #include <fdisk.h>
@@ -89,5 +90,5 @@
 	fdisk_part_t *part;
 	fdisk_part_spec_t pspec;
-	fdisk_cap_t cap;
+	cap_spec_t cap;
 	service_id_t sid;
 	int rc;
@@ -171,6 +172,7 @@
 
 	printf("sysinst_fs_mount(): verify filesystem server result\n");
-	if (texit != TASK_EXIT_NORMAL || trc != 0)
-		return EIO;
+	if (texit != TASK_EXIT_NORMAL || trc != 0) {
+		printf("sysinst_fs_mount(): not successful, but could be already loaded.\n");
+	}
 
 	rc = vfs_link_path(MOUNT_POINT, KIND_DIRECTORY, NULL);
@@ -209,6 +211,7 @@
 
 	printf("sysinst_copy_boot_files(): verify filesystem server result\n");
-	if (texit != TASK_EXIT_NORMAL || trc != 0)
-		return EIO;
+	if (texit != TASK_EXIT_NORMAL || trc != 0) {
+		printf("sysinst_fs_mount(): not successful, but could be already loaded.\n");
+	}
 
 	printf("sysinst_copy_boot_files(): create CD mount point\n");
Index: uspace/app/taskdump/taskdump.c
===================================================================
--- uspace/app/taskdump/taskdump.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/taskdump/taskdump.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,4 @@
 #include <task.h>
 #include <as.h>
-#include <sys/typefmt.h>
 #include <libarch/istate.h>
 #include <macros.h>
Index: uspace/app/tester/hw/misc/virtchar1.c
===================================================================
--- uspace/app/tester/hw/misc/virtchar1.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/tester/hw/misc/virtchar1.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -60,5 +60,5 @@
 			    "have you compiled test drivers?)\n");
 		}
-		return "Failed opening devman driver device for reading";
+		return "Failed opening NULL device for reading";
 	}
 	
Index: uspace/app/testread/testread.c
===================================================================
--- uspace/app/testread/testread.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/testread/testread.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -54,8 +54,8 @@
 #include <loc.h>
 #include <byteorder.h>
-#include <sys/typefmt.h>
 #include <inttypes.h>
 #include <errno.h>
 #include <time.h>
+#include <offset.h>
 
 #define NAME	"testread"
Index: uspace/app/tetris/scores.c
===================================================================
--- uspace/app/tetris/scores.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/tetris/scores.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -65,5 +65,4 @@
 #include <vfs/vfs.h>
 #include <stdlib.h>
-#include <err.h>
 #include <time.h>
 #include "screen.h"
Index: uspace/app/tetris/screen.c
===================================================================
--- uspace/app/tetris/screen.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/tetris/screen.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -54,5 +54,4 @@
  */
 
-#include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -198,5 +197,6 @@
 		scr_end();
 	
-	errx(1, "aborting: %s", why);
+	fprintf(stderr, "aborting: %s", why);
+	abort();
 }
 
Index: uspace/app/tetris/screen.h
===================================================================
--- uspace/app/tetris/screen.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/tetris/screen.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -55,5 +55,5 @@
 #define putpad(s)  tputs(s, 1, put)
 
-#include <libarch/types.h>
+#include <types/common.h>
 #include <io/console.h>
 #include <async.h>
Index: uspace/app/tetris/tetris.c
===================================================================
--- uspace/app/tetris/tetris.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/tetris/tetris.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -56,5 +56,4 @@
 
 #include <sys/time.h>
-#include <err.h>
 #include <errno.h>
 #include <stdio.h>
@@ -289,6 +288,8 @@
 	for (i = 0; i <= 5; i++) {
 		for (j = i + 1; j <= 5; j++) {
-			if (keys[i] == keys[j])
-				errx(1, "%s", "duplicate command keys specified.");
+			if (keys[i] == keys[j]) {
+				fprintf(stderr, "duplicate command keys specified.");
+				abort();
+			}
 		}
 		
@@ -442,4 +443,5 @@
 void usage(void)
 {
+	fprintf(stderr, "%s", copyright);
 	fprintf(stderr, "usage: tetris [-ps] [-k keys]\n");
 	exit(1);
Index: uspace/app/top/top.c
===================================================================
--- uspace/app/top/top.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/top/top.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,5 +42,5 @@
 #include <sys/time.h>
 #include <errno.h>
-#include <sort.h>
+#include <gsort.h>
 #include "screen.h"
 #include "top.h"
Index: uspace/app/trace/ipc_desc.c
===================================================================
--- uspace/app/trace/ipc_desc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/trace/ipc_desc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,6 +40,4 @@
 	/* System methods */
 	{ IPC_M_PHONE_HUNGUP,     "PHONE_HUNGUP" },
-	{ IPC_M_CONNECTION_CLONE, "CONNECTION_CLONE" },
-	{ IPC_M_CLONE_ESTABLISH,  "CLONE_ESTABLISH" },
 	{ IPC_M_CONNECT_ME_TO,    "CONNECT_ME_TO" },
 	{ IPC_M_CONNECT_TO_ME,    "CONNECT_TO_ME" },
Index: uspace/app/trace/ipcp.c
===================================================================
--- uspace/app/trace/ipcp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/trace/ipcp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,6 +35,6 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <inttypes.h>
 #include <adt/hash_table.h>
-#include <sys/typefmt.h>
 #include <abi/ipc/methods.h>
 #include <macros.h>
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/trace/syscalls.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -68,6 +68,6 @@
     [SYS_IPC_EVENT_UNMASK] = { "ipc_event_unmask",	1,	V_ERRNO },
 
-    [SYS_CAP_GRANT] = { "cap_grant",			2,	V_ERRNO },
-    [SYS_CAP_REVOKE] = { "cap_revoke",			2,	V_ERRNO },
+    [SYS_PERM_GRANT] = { "perm_grant",			2,	V_ERRNO },
+    [SYS_PERM_REVOKE] = { "perm_revoke",		2,	V_ERRNO },
     [SYS_PHYSMEM_MAP] = { "physmem_map",		4,	V_ERRNO },
     [SYS_IOSPACE_ENABLE] = { "iospace_enable",		1,	V_ERRNO },
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/trace/trace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <stdint.h>
 #include <stddef.h>
+#include <inttypes.h>
 #include <fibril.h>
 #include <errno.h>
@@ -49,5 +50,4 @@
 #include <io/keycode.h>
 #include <fibril_synch.h>
-#include <sys/typefmt.h>
 #include <vfs/vfs.h>
 
Index: uspace/app/trace/trace.h
===================================================================
--- uspace/app/trace/trace.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/trace/trace.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define TRACE_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 /**
Index: uspace/app/usbinfo/usbinfo.h
===================================================================
--- uspace/app/usbinfo/usbinfo.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/usbinfo/usbinfo.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,4 @@
 #include <usb/dev/device.h>
 #include <usb/dev/dp.h>
-#include <ipc/devman.h>
 
 typedef struct {
Index: uspace/app/vlaunch/Makefile
===================================================================
--- uspace/app/vlaunch/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/vlaunch/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,16 +43,29 @@
 MATH = y
 
+IMG = image
+IMGS = $(IMG)s
+
 SOURCES = \
 	vlaunch.c \
-	images.s
+	$(IMGS).s \
+	$(IMGS)_desc.c
 
 IMAGES = \
 	gfx/helenos.tga
 
-PRE_DEPEND = images.s images.h
-EXTRA_CLEAN = images.s images.h
+PRE_DEPEND = $(IMGS).s $(IMGS).h $(IMGS)_desc.c
+EXTRA_CLEAN = $(IMGS).s $(IMGS).h $(IMGS)_desc.c $(IMGS).zip
 
 include $(USPACE_PREFIX)/Makefile.common
 
-images.s images.h: $(IMAGES)
-	$(ROOT_PATH)/tools/mkarray.py images COMPOSITOR_IMAGES "$(AS_PROLOG)" $^
+$(IMGS).s: $(IMGS).zip
+	unzip -p $< $@ > $@
+
+$(IMGS).h: $(IMGS).zip
+	unzip -p $< $@ > $@
+
+$(IMGS)_desc.c: $(IMGS).zip
+	unzip -p $< $@ > $@
+
+$(IMGS).zip: $(IMAGES)
+	$(ROOT_PATH)/tools/mkarray.py $(IMGS) $(IMG) "$(AS_PROLOG)" .data $^
Index: uspace/app/websrv/websrv.c
===================================================================
--- uspace/app/websrv/websrv.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/app/websrv/websrv.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -75,12 +75,14 @@
 static uint16_t port = DEFAULT_PORT;
 
-static char rbuf[BUFFER_SIZE];
-static size_t rbuf_out;
-static size_t rbuf_in;
-
-static char lbuf[BUFFER_SIZE + 1];
-static size_t lbuf_used;
-
-static char fbuf[BUFFER_SIZE];
+typedef struct {
+	tcp_conn_t *conn;
+
+	char rbuf[BUFFER_SIZE];
+	size_t rbuf_out;
+	size_t rbuf_in;
+
+	char lbuf[BUFFER_SIZE + 1];
+	size_t lbuf_used;
+} recv_t;
 
 static bool verbose = false;
@@ -131,15 +133,38 @@
     "</html>\r\n";
 
+
+static int recv_create(tcp_conn_t *conn, recv_t **rrecv)
+{
+	recv_t *recv;
+	
+	recv = calloc(1, sizeof(recv_t));
+	if (recv == NULL)
+		return ENOMEM;
+	
+	recv->conn = conn;
+	recv->rbuf_out = 0;
+	recv->rbuf_in = 0;
+	recv->lbuf_used = 0;
+	
+	*rrecv = recv;
+	return EOK;
+}
+
+static void recv_destroy(recv_t *recv)
+{
+	free(recv);
+}
+
 /** Receive one character (with buffering) */
-static int recv_char(tcp_conn_t *conn, char *c)
+static int recv_char(recv_t *recv, char *c)
 {
 	size_t nrecv;
 	int rc;
 	
-	if (rbuf_out == rbuf_in) {
-		rbuf_out = 0;
-		rbuf_in = 0;
-		
-		rc = tcp_conn_recv_wait(conn, rbuf, BUFFER_SIZE, &nrecv);
+	if (recv->rbuf_out == recv->rbuf_in) {
+		recv->rbuf_out = 0;
+		recv->rbuf_in = 0;
+		
+		rc = tcp_conn_recv_wait(recv->conn, recv->rbuf, BUFFER_SIZE, &nrecv);
 		if (rc != EOK) {
 			fprintf(stderr, "tcp_conn_recv() failed (%d)\n", rc);
@@ -147,20 +172,20 @@
 		}
 		
-		rbuf_in = nrecv;
-	}
-	
-	*c = rbuf[rbuf_out++];
+		recv->rbuf_in = nrecv;
+	}
+	
+	*c = recv->rbuf[recv->rbuf_out++];
 	return EOK;
 }
 
 /** Receive one line with length limit */
-static int recv_line(tcp_conn_t *conn)
-{
-	char *bp = lbuf;
+static int recv_line(recv_t *recv, char **rbuf)
+{
+	char *bp = recv->lbuf;
 	char c = '\0';
 	
-	while (bp < lbuf + BUFFER_SIZE) {
+	while (bp < recv->lbuf + BUFFER_SIZE) {
 		char prev = c;
-		int rc = recv_char(conn, &c);
+		int rc = recv_char(recv, &c);
 		
 		if (rc != EOK)
@@ -172,10 +197,11 @@
 	}
 	
-	lbuf_used = bp - lbuf;
+	recv->lbuf_used = bp - recv->lbuf;
 	*bp = '\0';
 	
-	if (bp == lbuf + BUFFER_SIZE)
+	if (bp == recv->lbuf + BUFFER_SIZE)
 		return ELIMIT;
 	
+	*rbuf = recv->lbuf;
 	return EOK;
 }
@@ -218,24 +244,36 @@
 static int uri_get(const char *uri, tcp_conn_t *conn)
 {
+	char *fbuf = NULL;
+	char *fname = NULL;
+	int rc;
+	int fd = -1;
+	
+	fbuf = calloc(BUFFER_SIZE, 1);
+	if (fbuf == NULL) {
+		rc = ENOMEM;
+		goto out;
+	}
+	
 	if (str_cmp(uri, "/") == 0)
 		uri = "/index.html";
 	
-	char *fname;
-	int rc = asprintf(&fname, "%s%s", WEB_ROOT, uri);
-	if (rc < 0)
-		return ENOMEM;
-	
-	int fd = vfs_lookup_open(fname, WALK_REGULAR, MODE_READ);
+	rc = asprintf(&fname, "%s%s", WEB_ROOT, uri);
+	if (rc < 0) {
+		rc = ENOMEM;
+		goto out;
+	}
+	
+	fd = vfs_lookup_open(fname, WALK_REGULAR, MODE_READ);
 	if (fd < 0) {
 		rc = send_response(conn, msg_not_found);
-		free(fname);
-		return rc;
+		goto out;
 	}
 	
 	free(fname);
+	fname = NULL;
 	
 	rc = send_response(conn, msg_ok);
 	if (rc != EOK)
-		return rc;
+		goto out;
 	
 	aoff64_t pos = 0;
@@ -246,6 +284,6 @@
 		
 		if (nr < 0) {
-			vfs_put(fd);
-			return EIO;
+			rc = EIO;
+			goto out;
 		}
 		
@@ -253,17 +291,22 @@
 		if (rc != EOK) {
 			fprintf(stderr, "tcp_conn_send() failed\n");
-			vfs_put(fd);
-			return rc;
+			goto out;
 		}
 	}
 	
-	vfs_put(fd);
-	
-	return EOK;
-}
-
-static int req_process(tcp_conn_t *conn)
-{
-	int rc = recv_line(conn);
+	rc = EOK;
+out:
+	if (fd >= 0)
+		vfs_put(fd);
+	free(fname);
+	free(fbuf);
+	return rc;
+}
+
+static int req_process(tcp_conn_t *conn, recv_t *recv)
+{
+	char *reqline = NULL;
+
+	int rc = recv_line(recv, &reqline);
 	if (rc != EOK) {
 		fprintf(stderr, "recv_line() failed\n");
@@ -272,15 +315,15 @@
 	
 	if (verbose)
-		fprintf(stderr, "Request: %s", lbuf);
-	
-	if (str_lcmp(lbuf, "GET ", 4) != 0) {
+		fprintf(stderr, "Request: %s", reqline);
+	
+	if (str_lcmp(reqline, "GET ", 4) != 0) {
 		rc = send_response(conn, msg_not_implemented);
 		return rc;
 	}
 	
-	char *uri = lbuf + 4;
+	char *uri = reqline + 4;
 	char *end_uri = str_chr(uri, ' ');
 	if (end_uri == NULL) {
-		end_uri = lbuf + lbuf_used - 2;
+		end_uri = reqline + str_size(reqline) - 2;
 		assert(*end_uri == '\r');
 	}
@@ -300,5 +343,5 @@
 static void usage(void)
 {
-	printf("Skeletal server\n"
+	printf("Simple web server\n"
 	    "\n"
 	    "Usage: " NAME " [options]\n"
@@ -363,23 +406,36 @@
 {
 	int rc;
+	recv_t *recv = NULL;
 	
 	if (verbose)
 		fprintf(stderr, "New connection, waiting for request\n");
 	
-	rbuf_out = 0;
-	rbuf_in = 0;
-	
-	rc = req_process(conn);
+	rc = recv_create(conn, &recv);
+	if (rc != EOK) {
+		fprintf(stderr, "Out of memory.\n");
+		goto error;
+	}
+	
+	rc = req_process(conn, recv);
 	if (rc != EOK) {
 		fprintf(stderr, "Error processing request (%s)\n",
 		    str_error(rc));
-		return;
-	}
-
+		goto error;
+	}
+	
 	rc = tcp_conn_send_fin(conn);
 	if (rc != EOK) {
 		fprintf(stderr, "Error sending FIN.\n");
-		return;
-	}
+		goto error;
+	}
+
+	recv_destroy(recv);
+	return;
+error:
+	rc = tcp_conn_reset(conn);
+	if (rc != EOK)
+		fprintf(stderr, "Error resetting connection.\n");
+	
+	recv_destroy(recv);
 }
 
Index: uspace/dist/src/c/demos/tetris/screen.h
===================================================================
--- uspace/dist/src/c/demos/tetris/screen.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/dist/src/c/demos/tetris/screen.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -55,5 +55,5 @@
 #define putpad(s)  tputs(s, 1, put)
 
-#include <libarch/types.h>
+#include <types/common.h>
 #include <io/console.h>
 #include <async.h>
Index: uspace/dist/src/c/demos/top/top.c
===================================================================
--- uspace/dist/src/c/demos/top/top.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/dist/src/c/demos/top/top.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,5 +42,5 @@
 #include <sys/time.h>
 #include <errno.h>
-#include <sort.h>
+#include <gsort.h>
 #include "screen.h"
 #include "top.h"
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,6 +36,6 @@
 #include <bitops.h>
 #include <ddi.h>
+#include <device/hw_res.h>
 #include <device/hw_res_parsed.h>
-#include <irc.h>
 #include <stdio.h>
 #include <errno.h>
@@ -175,5 +175,5 @@
 
 	ddf_msg(LVL_NOTE, "create parent sess");
-	hda->parent_sess = ddf_dev_parent_sess_create(dev);
+	hda->parent_sess = ddf_dev_parent_sess_get(dev);
 	if (hda->parent_sess == NULL) {
 		ddf_msg(LVL_ERROR, "Failed connecting parent driver.\n");
@@ -257,5 +257,5 @@
 	ddf_msg(LVL_NOTE, "range0.base=%zu", hdaudio_irq_pio_ranges[0].base);
 
-	rc = irc_enable_interrupt(res.irqs.irqs[0]);
+	rc = hw_res_enable_interrupt(hda->parent_sess, res.irqs.irqs[0]);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enabling interrupt. (%d)", rc);
@@ -263,7 +263,8 @@
 	}
 
-	rc = register_interrupt_handler(dev, res.irqs.irqs[0],
+	int irq_cap = register_interrupt_handler(dev, res.irqs.irqs[0],
 	    hdaudio_interrupt, &irq_code);
-	if (rc != EOK) {
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		ddf_msg(LVL_ERROR, "Failed registering interrupt handler. (%d)",
 		    rc);
Index: uspace/drv/audio/sb16/dsp.c
===================================================================
--- uspace/drv/audio/sb16/dsp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/audio/sb16/dsp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,6 +35,6 @@
 #include <as.h>
 #include <stdbool.h>
+#include <ddf/driver.h>
 #include <ddi.h>
-#include <devman.h>
 #include <device/hw_res.h>
 #include <libarch/ddi.h>
@@ -75,5 +75,5 @@
 		[DSP_NO_BUFFER] = "NO BUFFER",
 	};
-	if (state < ARRAY_SIZE(state_names))
+	if ((size_t)state < ARRAY_SIZE(state_names))
 		return state_names[state];
 	return "UNKNOWN";
@@ -144,7 +144,9 @@
 {
 	dsp_write(dsp, SET_SAMPLING_RATE_OUTPUT);
-	dsp_write(dsp, rate >> 8);
-	dsp_write(dsp, rate & 0xff);
-	ddf_log_verbose("Sampling rate: %hhx:%hhx.", rate >> 8, rate & 0xff);
+	uint8_t rate_lo = rate & 0xff;
+	uint8_t rate_hi = rate >> 8;
+	dsp_write(dsp, rate_hi);
+	dsp_write(dsp, rate_lo);
+	ddf_log_verbose("Sampling rate: %hhx:%hhx.", rate_hi, rate_lo);
 }
 
@@ -159,13 +161,9 @@
 static inline int setup_dma(sb_dsp_t *dsp, uintptr_t pa, size_t size)
 {
-	async_sess_t *sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(dsp->sb_dev), IPC_FLAG_BLOCKING);
-
-	const int ret = hw_res_dma_channel_setup(sess,
+	async_sess_t *sess = ddf_dev_parent_sess_get(dsp->sb_dev);
+
+	return hw_res_dma_channel_setup(sess,
 	    dsp->dma16_channel, pa, size,
 	    DMA_MODE_READ | DMA_MODE_AUTO | DMA_MODE_ON_DEMAND);
-
-	async_hangup(sess);
-	return ret;
 }
 
@@ -202,9 +200,4 @@
 	
 	return ret;
-}
-
-static inline size_t sample_count(pcm_sample_format_t format, size_t byte_count)
-{
-	return byte_count / pcm_sample_format_size(format);
 }
 
@@ -307,10 +300,8 @@
 
 	assert(dsp->buffer.data);
-	async_sess_t *sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(dsp->sb_dev), IPC_FLAG_BLOCKING);
+	async_sess_t *sess = ddf_dev_parent_sess_get(dsp->sb_dev);
 
 	// TODO: Assumes DMA 16
 	const int remain = hw_res_dma_channel_remain(sess, dsp->dma16_channel);
-	async_hangup(sess);
 	if (remain >= 0) {
 		*pos = dsp->buffer.size - remain;
Index: uspace/drv/audio/sb16/main.c
===================================================================
--- uspace/drv/audio/sb16/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/audio/sb16/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,4 @@
 #include <ddf/log.h>
 #include <device/hw_res_parsed.h>
-#include <devman.h>
 #include <assert.h>
 #include <stdio.h>
@@ -51,5 +50,5 @@
 static int sb_get_res(ddf_dev_t *device, addr_range_t **pp_sb_regs,
     addr_range_t **pp_mpu_regs, int *irq, int *dma8, int *dma16);
-static int sb_enable_interrupts(ddf_dev_t *device);
+static int sb_enable_interrupt(ddf_dev_t *device, int irq);
 
 static driver_ops_t sb_driver_ops = {
@@ -94,4 +93,5 @@
 	irq_cmd_t irq_cmds[irq_cmd_count];
 	irq_pio_range_t irq_ranges[1];
+	int irq_cap;
 
 	sb16_t *soft_state = ddf_dev_data_alloc(device, sizeof(sb16_t));
@@ -123,6 +123,8 @@
 	};
 
-	rc = register_interrupt_handler(device, irq, irq_handler, &irq_code);
-	if (rc != EOK) {
+	irq_cap = register_interrupt_handler(device, irq, irq_handler,
+	    &irq_code);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		ddf_log_error("Failed to register irq handler: %s.",
 		    str_error(rc));
@@ -132,5 +134,5 @@
 	handler_regd = true;
 
-	rc = sb_enable_interrupts(device);
+	rc = sb_enable_interrupt(device, irq);
 	if (rc != EOK) {
 		ddf_log_error("Failed to enable interrupts: %s.",
@@ -168,5 +170,5 @@
 error:
 	if (handler_regd)
-		unregister_interrupt_handler(device, irq);
+		unregister_interrupt_handler(device, irq_cap);
 	return rc;
 }
@@ -177,7 +179,6 @@
 	assert(device);
 
-	async_sess_t *parent_sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
-	if (!parent_sess)
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
+	if (parent_sess == NULL)
 		return ENOMEM;
 
@@ -185,5 +186,4 @@
 	hw_res_list_parsed_init(&hw_res);
 	const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
-	async_hangup(parent_sess);
 	if (ret != EOK) {
 		return ret;
@@ -242,15 +242,11 @@
 }
 
-int sb_enable_interrupts(ddf_dev_t *device)
-{
-	async_sess_t *parent_sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
-	if (!parent_sess)
+static int sb_enable_interrupt(ddf_dev_t *device, int irq)
+{
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
+	if (parent_sess == NULL)
 		return ENOMEM;
 
-	bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-
-	return enabled ? EOK : EIO;
+	return hw_res_enable_interrupt(parent_sess, irq);
 }
 
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/block/ahci/ahci.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,7 @@
 #include <ddf/interrupt.h>
 #include <ddf/log.h>
+#include <device/hw_res.h>
 #include <device/hw_res_parsed.h>
 #include <pci_dev_iface.h>
-#include <irc.h>
 #include <ahci_iface.h>
 #include "ahci.h"
@@ -1140,5 +1140,5 @@
 	
 	/* Connect to parent device */
-	ahci->parent_sess = ddf_dev_parent_sess_create(dev);
+	ahci->parent_sess = ddf_dev_parent_sess_get(dev);
 	if (ahci->parent_sess == NULL)
 		return NULL;
@@ -1185,12 +1185,13 @@
 	ct.ranges = ahci_ranges;
 	
-	int rc = register_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0],
-	    ahci_interrupt, &ct);
-	if (rc != EOK) {
+	int irq_cap = register_interrupt_handler(dev,
+	    hw_res_parsed.irqs.irqs[0], ahci_interrupt, &ct);
+	if (irq_cap < 0) {
 		ddf_msg(LVL_ERROR, "Failed registering interrupt handler.");
 		goto error_register_interrupt_handler;
 	}
 	
-	rc = irc_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
+	int rc = hw_res_enable_interrupt(ahci->parent_sess,
+	    hw_res_parsed.irqs.irqs[0]);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enable interupt.");
@@ -1202,5 +1203,5 @@
 	
 error_enable_interrupt:
-	unregister_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0]);
+	unregister_interrupt_handler(dev, irq_cap);
 	
 error_register_interrupt_handler:
Index: uspace/drv/block/ahci/ahci.h
===================================================================
--- uspace/drv/block/ahci/ahci.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/block/ahci/ahci.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,5 +35,4 @@
 
 #include <async.h>
-#include <devman.h>
 #include <ddf/interrupt.h>
 #include <stdio.h>
@@ -92,7 +91,4 @@
 	ahci_port_is_t event_pxis;
 	
-	/** Block device service id. */
-	service_id_t service_id;
-	
 	/** Number of device data blocks. */
 	uint64_t blocks;
Index: uspace/drv/block/ata_bd/main.c
===================================================================
--- uspace/drv/block/ata_bd/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/block/ata_bd/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -68,5 +68,5 @@
 	int rc;
 
-	parent_sess = ddf_dev_parent_sess_create(dev);
+	parent_sess = ddf_dev_parent_sess_get(dev);
 	if (parent_sess == NULL)
 		return ENOMEM;
Index: uspace/drv/block/ddisk/ddisk.c
===================================================================
--- uspace/drv/block/ddisk/ddisk.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/block/ddisk/ddisk.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -112,4 +112,6 @@
 	ddisk_regs_t *ddisk_regs;
 
+	int irq_cap;
+
 	bd_srvs_t bds;
 } ddisk_t;
@@ -286,5 +288,5 @@
 	int rc;
 
-	parent_sess = ddf_dev_parent_sess_create(dev);
+	parent_sess = ddf_dev_parent_sess_get(dev);
 	if (parent_sess == NULL)
 		return ENOMEM;
@@ -447,4 +449,6 @@
 	ddisk->bds.sarg = ddisk;
 
+	ddisk->irq_cap = -1;
+
 	/*
 	 * Enable access to ddisk's PIO registers.
@@ -499,7 +503,8 @@
 	ddisk_irq_commands[0].addr = (void *) &res_phys->status;
 	ddisk_irq_commands[3].addr = (void *) &res_phys->command;
-	rc = register_interrupt_handler(dev, ddisk->ddisk_res.irq,
+	ddisk->irq_cap = register_interrupt_handler(dev, ddisk->ddisk_res.irq,
 	    ddisk_irq_handler, &ddisk_irq_code);
-	if (rc != EOK) {
+	if (ddisk->irq_cap < 0) {
+		rc = ddisk->irq_cap;
 		ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
 		goto error;
@@ -541,5 +546,5 @@
 	}
 
-	unregister_interrupt_handler(ddisk->dev, ddisk->ddisk_res.irq);
+	unregister_interrupt_handler(ddisk->dev, ddisk->irq_cap);
 	
 	rc = pio_disable(ddisk->ddisk_regs, sizeof(ddisk_regs_t));
Index: uspace/drv/bus/adb/cuda_adb/Makefile
===================================================================
--- uspace/drv/bus/adb/cuda_adb/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/bus/adb/cuda_adb/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -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 = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = cuda_adb
+
+SOURCES = \
+	cuda_adb.c \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/bus/adb/cuda_adb/cuda_adb.c
===================================================================
--- uspace/drv/bus/adb/cuda_adb/cuda_adb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/bus/adb/cuda_adb/cuda_adb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,506 @@
+/*
+ * 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 <assert.h>
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ddi.h>
+#include <errno.h>
+#include <ipc/adb.h>
+#include <libarch/ddi.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <sysinfo.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cuda_adb.h"
+#include "cuda_hw.h"
+
+#define NAME  "cuda_adb"
+
+static void cuda_dev_connection(ipc_callid_t, ipc_call_t *, void *);
+static int cuda_init(cuda_t *);
+static void cuda_irq_handler(ipc_callid_t, ipc_call_t *, void *);
+
+static void cuda_irq_listen(cuda_t *);
+static void cuda_irq_receive(cuda_t *);
+static void cuda_irq_rcv_end(cuda_t *, void *, size_t *);
+static void cuda_irq_send_start(cuda_t *);
+static void cuda_irq_send(cuda_t *);
+
+static void cuda_packet_handle(cuda_t *, uint8_t *, size_t);
+static void cuda_send_start(cuda_t *);
+static void cuda_autopoll_set(cuda_t *, bool);
+
+static void adb_packet_handle(cuda_t *, uint8_t *, size_t, bool);
+
+static irq_pio_range_t cuda_ranges[] = {
+	{
+		.base = 0,
+		.size = sizeof(cuda_regs_t)
+	}
+};
+
+static irq_cmd_t cuda_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = NULL,
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_AND,
+		.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_ranges) / sizeof(irq_pio_range_t),
+	cuda_ranges,
+	sizeof(cuda_cmds) / sizeof(irq_cmd_t),
+	cuda_cmds
+};
+
+static int cuda_dev_create(cuda_t *cuda, const char *name, adb_dev_t **rdev)
+{
+	adb_dev_t *dev = NULL;
+	ddf_fun_t *fun;
+	int rc;
+
+	fun = ddf_fun_create(cuda->dev, fun_exposed, name);
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Failed creating function '%s'.", name);
+		rc = ENOMEM;
+		goto error;
+	}
+
+	dev = ddf_fun_data_alloc(fun, sizeof(adb_dev_t));
+	if (dev == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating memory for '%s'.", name);
+		rc = ENOMEM;
+		goto error;
+	}
+
+	dev->fun = fun;
+	list_append(&dev->lcuda, &cuda->devs);
+
+	ddf_fun_set_conn_handler(fun, cuda_dev_connection);
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function '%s'.", name);
+		goto error;
+	}
+
+	*rdev = dev;
+	return EOK;
+error:
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	return rc;
+}
+
+int cuda_add(cuda_t *cuda, cuda_res_t *res)
+{
+	adb_dev_t *kbd = NULL;
+	adb_dev_t *mouse = NULL;
+	int rc;
+
+	cuda->phys_base = res->base;
+
+	rc = cuda_dev_create(cuda, "kbd", &kbd);
+	if (rc != EOK)
+		goto error;
+
+	rc = cuda_dev_create(cuda, "mouse", &mouse);
+	if (rc != EOK)
+		goto error;
+
+	cuda->addr_dev[2] = kbd;
+	cuda->addr_dev[8] = kbd;
+
+	cuda->addr_dev[9] = mouse;
+
+	rc = cuda_init(cuda);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed initializing CUDA hardware.");
+		return rc;
+	}
+
+	return EOK;
+error:
+	return rc;
+}
+
+int cuda_remove(cuda_t *cuda)
+{
+	return ENOTSUP;
+}
+
+int cuda_gone(cuda_t *cuda)
+{
+	return ENOTSUP;
+}
+
+/** Device connection handler */
+static void cuda_dev_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	adb_dev_t *dev = (adb_dev_t *) ddf_fun_data_get((ddf_fun_t *) arg);
+	ipc_callid_t callid;
+	ipc_call_t call;
+	sysarg_t method;
+
+	/* Answer the IPC_M_CONNECT_ME_TO call. */
+	async_answer_0(iid, EOK);
+
+	while (true) {
+		callid = async_get_call(&call);
+		method = IPC_GET_IMETHOD(call);
+
+		if (!method) {
+			/* The other side has hung up. */
+			async_answer_0(callid, EOK);
+			return;
+		}
+
+		async_sess_t *sess =
+		    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
+		if (sess != NULL) {
+			dev->client_sess = sess;
+			async_answer_0(callid, EOK);
+		} else {
+			async_answer_0(callid, EINVAL);
+		}
+	}
+}
+
+static int cuda_init(cuda_t *cuda)
+{
+	int rc;
+
+	void *vaddr;
+	rc = pio_enable((void *) cuda->phys_base, sizeof(cuda_regs_t),
+	    &vaddr);
+	if (rc != EOK)
+		return rc;
+
+	cuda->regs = vaddr;
+	cuda->xstate = cx_listen;
+	cuda->bidx = 0;
+	cuda->snd_bytes = 0;
+
+	fibril_mutex_initialize(&cuda->dev_lock);
+
+	/* Disable all interrupts from CUDA. */
+	pio_write_8(&cuda->regs->ier, IER_CLR | ALL_INT);
+
+	cuda_irq_code.ranges[0].base = (uintptr_t) cuda->phys_base;
+	cuda_irq_code.cmds[0].addr = (void *) &((cuda_regs_t *)
+	    cuda->phys_base)->ifr;
+	async_irq_subscribe(10, cuda_irq_handler, cuda, &cuda_irq_code);
+
+	/* Enable SR interrupt. */
+	pio_write_8(&cuda->regs->ier, TIP | TREQ);
+	pio_write_8(&cuda->regs->ier, IER_SET | SR_INT);
+
+	/* Enable ADB autopolling. */
+	cuda_autopoll_set(cuda, true);
+
+	return EOK;
+}
+
+static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg)
+{
+	uint8_t rbuf[CUDA_RCV_BUF_SIZE];
+	cuda_t *cuda = (cuda_t *)arg;
+	size_t len;
+	bool handle;
+
+	handle = false;
+	len = 0;
+
+	fibril_mutex_lock(&cuda->dev_lock);
+
+	switch (cuda->xstate) {
+	case cx_listen:
+		cuda_irq_listen(cuda);
+		break;
+	case cx_receive:
+		cuda_irq_receive(cuda);
+		break;
+	case cx_rcv_end:
+		cuda_irq_rcv_end(cuda, rbuf, &len);
+		handle = true;
+		break;
+	case cx_send_start:
+		cuda_irq_send_start(cuda);
+		break;
+	case cx_send:
+		cuda_irq_send(cuda);
+		break;
+	}
+
+	/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
+	pio_write_8(&cuda->regs->ifr, SR_INT);
+
+	fibril_mutex_unlock(&cuda->dev_lock);
+
+	/* Handle an incoming packet. */
+	if (handle)
+		cuda_packet_handle(cuda, rbuf, len);
+}
+
+/** Interrupt in listen state.
+ *
+ * Start packet reception.
+ *
+ * @param cuda CUDA instance
+ */
+static void cuda_irq_listen(cuda_t *cuda)
+{
+	uint8_t b = pio_read_8(&cuda->regs->b);
+
+	if ((b & TREQ) != 0) {
+		ddf_msg(LVL_WARN, "cuda_irq_listen: no TREQ?!");
+		return;
+	}
+
+	pio_write_8(&cuda->regs->b, b & ~TIP);
+	cuda->xstate = cx_receive;
+}
+
+/** Interrupt in receive state.
+ *
+ * Receive next byte of packet.
+ *
+ * @param cuda CUDA instance
+ */
+static void cuda_irq_receive(cuda_t *cuda)
+{
+	uint8_t data = pio_read_8(&cuda->regs->sr);
+	if (cuda->bidx < CUDA_RCV_BUF_SIZE)
+		cuda->rcv_buf[cuda->bidx++] = data;
+
+	uint8_t b = pio_read_8(&cuda->regs->b);
+
+	if ((b & TREQ) == 0) {
+		pio_write_8(&cuda->regs->b, b ^ TACK);
+	} else {
+		pio_write_8(&cuda->regs->b, b | TACK | TIP);
+		cuda->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.
+ *
+ * @param cuda CUDA instance
+ * @param buf Buffer for storing received packet
+ * @param len Place to store length of received packet
+ */
+static void cuda_irq_rcv_end(cuda_t *cuda, void *buf, size_t *len)
+{
+	uint8_t b = pio_read_8(&cuda->regs->b);
+
+	if ((b & TREQ) == 0) {
+		cuda->xstate = cx_receive;
+		pio_write_8(&cuda->regs->b, b & ~TIP);
+	} else {
+		cuda->xstate = cx_listen;
+		cuda_send_start(cuda);
+	}
+
+	memcpy(buf, cuda->rcv_buf, cuda->bidx);
+	*len = cuda->bidx;
+	cuda->bidx = 0;
+}
+
+/** Interrupt in send_start state.
+ *
+ * Process result of sending first byte (and send second on success).
+ *
+ * @param cuda CUDA instance
+ */
+static void cuda_irq_send_start(cuda_t *cuda)
+{
+	uint8_t b;
+
+	b = pio_read_8(&cuda->regs->b);
+
+	if ((b & TREQ) == 0) {
+		/* Collision */
+		pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) &
+		    ~SR_OUT);
+		pio_read_8(&cuda->regs->sr);
+		pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) |
+		    TIP | TACK);
+		cuda->xstate = cx_listen;
+		return;
+	}
+
+	pio_write_8(&cuda->regs->sr, cuda->snd_buf[1]);
+	pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) ^ TACK);
+	cuda->bidx = 2;
+
+	cuda->xstate = cx_send;
+}
+
+/** Interrupt in send state.
+ *
+ * Send next byte or terminate transmission.
+ *
+ * @param cuda CUDA instance
+ */
+static void cuda_irq_send(cuda_t *cuda)
+{
+	if (cuda->bidx < cuda->snd_bytes) {
+		/* Send next byte. */
+		pio_write_8(&cuda->regs->sr,
+		    cuda->snd_buf[cuda->bidx++]);
+		pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) ^ TACK);
+		return;
+	}
+
+	/* End transfer. */
+	cuda->snd_bytes = 0;
+	cuda->bidx = 0;
+
+	pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) & ~SR_OUT);
+	pio_read_8(&cuda->regs->sr);
+	pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) | TACK | TIP);
+
+	cuda->xstate = cx_listen;
+	/* TODO: Match reply with request. */
+}
+
+static void cuda_packet_handle(cuda_t *cuda, uint8_t *data, size_t len)
+{
+	if (data[0] != PT_ADB)
+		return;
+	if (len < 2)
+		return;
+
+	adb_packet_handle(cuda, data + 2, len - 2, (data[1] & 0x40) != 0);
+}
+
+static void adb_packet_handle(cuda_t *cuda, uint8_t *data, size_t size,
+    bool autopoll)
+{
+	uint8_t dev_addr;
+	uint8_t reg_no;
+	uint16_t reg_val;
+	adb_dev_t *dev;
+	unsigned i;
+
+	dev_addr = data[0] >> 4;
+	reg_no = data[0] & 0x03;
+
+	if (size != 3) {
+		ddf_msg(LVL_WARN, "Unrecognized packet, size=%zu", size);
+		for (i = 0; i < size; ++i) {
+			ddf_msg(LVL_WARN, "  0x%02x", data[i]);
+		}
+		return;
+	}
+
+	if (reg_no != 0) {
+		ddf_msg(LVL_WARN, "Unrecognized packet, size=%zu", size);
+		for (i = 0; i < size; ++i) {
+			ddf_msg(LVL_WARN, "  0x%02x", data[i]);
+		}
+		return;
+	}
+
+	reg_val = ((uint16_t) data[1] << 8) | (uint16_t) data[2];
+
+	ddf_msg(LVL_DEBUG, "Received ADB packet for device address %d",
+	    dev_addr);
+	dev = cuda->addr_dev[dev_addr];
+	if (dev == NULL)
+		return;
+
+	async_exch_t *exch = async_exchange_begin(dev->client_sess);
+	async_msg_1(exch, ADB_REG_NOTIF, reg_val);
+	async_exchange_end(exch);
+}
+
+static void cuda_autopoll_set(cuda_t *cuda, bool enable)
+{
+	cuda->snd_buf[0] = PT_CUDA;
+	cuda->snd_buf[1] = CPT_AUTOPOLL;
+	cuda->snd_buf[2] = enable ? 0x01 : 0x00;
+	cuda->snd_bytes = 3;
+	cuda->bidx = 0;
+
+	cuda_send_start(cuda);
+}
+
+static void cuda_send_start(cuda_t *cuda)
+{
+	assert(cuda->xstate == cx_listen);
+
+	if (cuda->snd_bytes == 0)
+		return;
+
+	/* Check for incoming data. */
+	if ((pio_read_8(&cuda->regs->b) & TREQ) == 0)
+		return;
+
+	pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) | SR_OUT);
+	pio_write_8(&cuda->regs->sr, cuda->snd_buf[0]);
+	pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) & ~TIP);
+
+	cuda->xstate = cx_send_start;
+}
+
+/** @}
+ */
Index: uspace/drv/bus/adb/cuda_adb/cuda_adb.h
===================================================================
--- uspace/drv/bus/adb/cuda_adb/cuda_adb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/bus/adb/cuda_adb/cuda_adb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,96 @@
+/*
+ * 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 <adt/list.h>
+#include <async.h>
+#include <ddf/driver.h>
+#include <fibril_synch.h>
+#include <loc.h>
+#include <stdint.h>
+#include "cuda_hw.h"
+
+enum {
+	CUDA_RCV_BUF_SIZE = 5
+};
+
+enum cuda_xfer_state {
+	cx_listen,
+	cx_receive,
+	cx_rcv_end,
+	cx_send_start,
+	cx_send
+};
+
+typedef struct {
+	uintptr_t base;
+	int irq;
+} cuda_res_t;
+
+/** ADB bus device */
+typedef struct {
+	ddf_fun_t *fun;
+	async_sess_t *client_sess;
+	link_t lcuda;
+	struct cuda *cuda;
+} adb_dev_t;
+
+/** CUDA ADB bus */
+typedef struct cude {
+	struct cuda_regs *regs;
+	uintptr_t phys_base;
+	ddf_dev_t *dev;
+
+	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;
+
+	list_t devs;
+	adb_dev_t *addr_dev[ADB_MAX_ADDR];
+} cuda_t;
+
+extern int cuda_add(cuda_t *, cuda_res_t *);
+extern int cuda_remove(cuda_t *);
+extern int cuda_gone(cuda_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/bus/adb/cuda_adb/cuda_adb.ma
===================================================================
--- uspace/drv/bus/adb/cuda_adb/cuda_adb.ma	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/bus/adb/cuda_adb/cuda_adb.ma	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,1 @@
+10 cuda_adb
Index: uspace/drv/bus/adb/cuda_adb/cuda_hw.h
===================================================================
--- uspace/drv/bus/adb/cuda_adb/cuda_hw.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/bus/adb/cuda_adb/cuda_hw.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,130 @@
+/*
+ * 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_HW_H_
+#define CUDA_HW_H_
+
+#include <stdint.h>
+
+typedef struct cuda_regs {
+	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_regs_t;
+
+/** 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
+};
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/bus/adb/cuda_adb/main.c
===================================================================
--- uspace/drv/bus/adb/cuda_adb/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/bus/adb/cuda_adb/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2017 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
+ */
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "cuda_adb.h"
+
+#define NAME  "cuda_adb"
+
+static int cuda_dev_add(ddf_dev_t *dev);
+static int cuda_dev_remove(ddf_dev_t *dev);
+static int cuda_dev_gone(ddf_dev_t *dev);
+static int cuda_fun_online(ddf_fun_t *fun);
+static int cuda_fun_offline(ddf_fun_t *fun);
+
+static driver_ops_t driver_ops = {
+	.dev_add = cuda_dev_add,
+	.dev_remove = cuda_dev_remove,
+	.dev_gone = cuda_dev_gone,
+	.fun_online = cuda_fun_online,
+	.fun_offline = cuda_fun_offline
+};
+
+static driver_t cuda_adb_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+static int cuda_get_res(ddf_dev_t *dev, cuda_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	int rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.io_ranges.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->base = RNGABS(hw_res.io_ranges.ranges[0]);
+
+	if (hw_res.irqs.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->irq = hw_res.irqs.irqs[0];
+
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static int cuda_dev_add(ddf_dev_t *dev)
+{
+	cuda_t *cuda;
+	cuda_res_t cuda_res;
+	int rc;
+
+        ddf_msg(LVL_DEBUG, "cuda_dev_add(%p)", dev);
+	cuda = ddf_dev_data_alloc(dev, sizeof(cuda_t));
+	if (cuda == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		return ENOMEM;
+	}
+
+	cuda->dev = dev;
+	list_initialize(&cuda->devs);
+
+	rc = cuda_get_res(dev, &cuda_res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.\n");
+		return EIO;
+	}
+
+	return cuda_add(cuda, &cuda_res);
+}
+
+static int cuda_dev_remove(ddf_dev_t *dev)
+{
+        cuda_t *cuda = (cuda_t *)ddf_dev_data_get(dev);
+
+        ddf_msg(LVL_DEBUG, "cuda_dev_remove(%p)", dev);
+
+        return cuda_remove(cuda);
+}
+
+static int cuda_dev_gone(ddf_dev_t *dev)
+{
+        cuda_t *cuda = (cuda_t *)ddf_dev_data_get(dev);
+
+        ddf_msg(LVL_DEBUG, "cuda_dev_gone(%p)", dev);
+
+        return cuda_gone(cuda);
+}
+
+static int cuda_fun_online(ddf_fun_t *fun)
+{
+        ddf_msg(LVL_DEBUG, "cuda_fun_online()");
+        return ddf_fun_online(fun);
+}
+
+static int cuda_fun_offline(ddf_fun_t *fun)
+{
+        ddf_msg(LVL_DEBUG, "cuda_fun_offline()");
+        return ddf_fun_offline(fun);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": VIA-CUDA Apple Desktop Bus driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&cuda_adb_driver);
+}
+
+/** @}
+ */
Index: uspace/drv/bus/isa/i8237.c
===================================================================
--- uspace/drv/bus/isa/i8237.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/isa/i8237.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -371,5 +371,5 @@
 	
 	/* 16 bit transfers are a bit special */
-	ddf_msg(LVL_DEBUG, "Unspoiled address %#" PRIx32 " (size %" PRIu16 ")",
+	ddf_msg(LVL_DEBUG, "Unspoiled address %#" PRIx32 " (size %" PRIu32 ")",
 	    pa, size);
 	if (is_dma16(channel)) {
@@ -388,5 +388,5 @@
 	
 	ddf_msg(LVL_DEBUG, "Setting channel %u to address %#" PRIx32 " "
-	    "(size %" PRIu16 "), mode %hhx.", channel, pa, size, mode);
+	    "(size %" PRIu32 "), mode %hhx.", channel, pa, size, mode);
 	
 	/* Mask DMA request */
Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/isa/isa.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -115,24 +115,47 @@
 }
 
-static bool isa_fun_enable_interrupt(ddf_fun_t *fnode)
-{
-	/* This is an old ugly way, copied from pci driver */
-	assert(fnode);
+static bool isa_fun_owns_interrupt(isa_fun_t *fun, int irq)
+{
+	const hw_resource_list_t *res = &fun->hw_resources;
+
+	/* Check that specified irq really belongs to the function */
+	for (size_t i = 0; i < res->count; ++i) {
+		if (res->resources[i].type == INTERRUPT &&
+		    res->resources[i].res.interrupt.irq == irq) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int isa_fun_enable_interrupt(ddf_fun_t *fnode, int irq)
+{
 	isa_fun_t *fun = isa_fun(fnode);
-	assert(fun);
-
-	const hw_resource_list_t *res = &fun->hw_resources;
-	assert(res);
-	for (size_t i = 0; i < res->count; ++i) {
-		if (res->resources[i].type == INTERRUPT) {
-			int rc = irc_enable_interrupt(
-			    res->resources[i].res.interrupt.irq);
-
-			if (rc != EOK)
-				return false;
-		}
-	}
-
-	return true;
+
+	if (!isa_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_enable_interrupt(irq);
+}
+
+static int isa_fun_disable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	isa_fun_t *fun = isa_fun(fnode);
+
+	if (!isa_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_disable_interrupt(irq);
+}
+
+static int isa_fun_clear_interrupt(ddf_fun_t *fnode, int irq)
+{
+	isa_fun_t *fun = isa_fun(fnode);
+
+	if (!isa_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_clear_interrupt(irq);
 }
 
@@ -185,4 +208,6 @@
 	.get_resource_list = isa_fun_get_resources,
 	.enable_interrupt = isa_fun_enable_interrupt,
+	.disable_interrupt = isa_fun_disable_interrupt,
+	.clear_interrupt = isa_fun_clear_interrupt,
 	.dma_channel_setup = isa_fun_setup_dma,
 	.dma_channel_remain = isa_fun_remain_dma,
@@ -643,5 +668,5 @@
 	list_initialize(&isa->functions);
 
-	sess = ddf_dev_parent_sess_create(dev);
+	sess = ddf_dev_parent_sess_get(dev);
 	if (sess == NULL) {
 		ddf_msg(LVL_ERROR, "isa_dev_add failed to connect to the "
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -99,23 +99,47 @@
 }
 
-static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
-{
-	/* This is an old ugly way */
-	assert(fnode);
-	pci_fun_t *dev_data = pci_fun(fnode);
-	
-	size_t i = 0;
-	hw_resource_list_t *res = &dev_data->hw_resources;
-	for (; i < res->count; i++) {
-		if (res->resources[i].type == INTERRUPT) {
-			int rc = irc_enable_interrupt(
-			    res->resources[i].res.interrupt.irq);
-			
-			if (rc != EOK)
-				return false;
+static int pciintel_fun_owns_interrupt(pci_fun_t *fun, int irq)
+{
+	size_t i;
+	hw_resource_list_t *res = &fun->hw_resources;
+	
+	for (i = 0; i < res->count; i++) {
+		if (res->resources[i].type == INTERRUPT &&
+		    res->resources[i].res.interrupt.irq == irq) {
+			return true;
 		}
 	}
 	
-	return true;
+	return false;
+}
+
+static int pciintel_enable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	pci_fun_t *fun = pci_fun(fnode);
+	
+	if (!pciintel_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_enable_interrupt(irq);
+}
+
+static int pciintel_disable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	pci_fun_t *fun = pci_fun(fnode);
+	
+	if (!pciintel_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_disable_interrupt(irq);
+}
+
+static int pciintel_clear_interrupt(ddf_fun_t *fnode, int irq)
+{
+	pci_fun_t *fun = pci_fun(fnode);
+	
+	if (!pciintel_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_clear_interrupt(irq);
 }
 
@@ -187,4 +211,6 @@
 	.get_resource_list = &pciintel_get_resources,
 	.enable_interrupt = &pciintel_enable_interrupt,
+	.disable_interrupt = &pciintel_disable_interrupt,
+	.clear_interrupt = &pciintel_clear_interrupt,
 };
 
@@ -683,5 +709,5 @@
 	bus->dnode = dnode;
 	
-	sess = ddf_dev_parent_sess_create(dnode);
+	sess = ddf_dev_parent_sess_get(dnode);
 	if (sess == NULL) {
 		ddf_msg(LVL_ERROR, "pci_dev_add failed to connect to the "
Index: uspace/drv/bus/usb/ehci/res.c
===================================================================
--- uspace/drv/bus/usb/ehci/res.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/usb/ehci/res.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #include <str_error.h>
 #include <assert.h>
-#include <devman.h>
+#include <ddf/driver.h>
 #include <ddi.h>
 #include <usb/debug.h>
@@ -176,7 +176,6 @@
 	assert(device);
 
-	async_sess_t *parent_sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
-	if (!parent_sess)
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
+	if (parent_sess == NULL)
 		return ENOMEM;
 
Index: uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -78,5 +78,5 @@
 
 	/* Allow less data on input. */
-	if (dir == USB_DIRECTION_IN) {
+	if (direction == USB_DIRECTION_IN) {
 		OHCI_MEM32_SET(instance->status, TD_STATUS_ROUND_FLAG);
 	}
Index: uspace/drv/bus/usb/ohci/ohci_rh.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_rh.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/usb/ohci/ohci_rh.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -361,5 +361,5 @@
 	case USB_HUB_FEATURE_C_PORT_RESET:        /*20*/
 		usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, "
-		    "C_SUSPEND, C_OC or C_RESET on port %"PRIu16".\n", port);
+		    "C_SUSPEND, C_OC or C_RESET on port %u.\n", port);
 		/* Bit offsets correspond to the feature number */
 		OHCI_WR(hub->registers->rh_port_status[port],
@@ -410,5 +410,5 @@
 	case USB_HUB_FEATURE_PORT_RESET:   /*4*/
 		usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET "
-		    "on port %"PRIu16".\n", port);
+		    "on port %u.\n", port);
 		/* Bit offsets correspond to the feature number */
 		OHCI_WR(hub->registers->rh_port_status[port], 1 << feature);
Index: uspace/drv/bus/usb/uhci/main.c
===================================================================
--- uspace/drv/bus/usb/uhci/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/usb/uhci/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #include <assert.h>
 #include <ddf/driver.h>
-#include <devman.h>
 #include <errno.h>
 #include <io/log.h>
@@ -123,15 +122,11 @@
 	assert(device);
 
-	async_sess_t *parent_sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
-	if (!parent_sess)
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
+	if (parent_sess == NULL)
 		return ENOMEM;
 
 	/* See UHCI design guide page 45 for these values.
 	 * Write all WC bits in USB legacy register */
-	const int rc = pci_config_space_write_16(parent_sess, 0xc0, 0xaf00);
-
-	async_hangup(parent_sess);
-	return rc;
+	return pci_config_space_write_16(parent_sess, 0xc0, 0xaf00);
 }
 
Index: uspace/drv/bus/usb/usbhub/status.h
===================================================================
--- uspace/drv/bus/usb/usbhub/status.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/usb/usbhub/status.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,6 +35,4 @@
 #define	HUB_STATUS_H
 
-#include <stdbool.h>
-#include <stdint.h>
 #include <usb/dev/request.h>
 
Index: uspace/drv/bus/usb/usbhub/usbhub.h
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/usb/usbhub/usbhub.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,4 @@
 #define DRV_USBHUB_USBHUB_H
 
-#include <ipc/devman.h>
 #include <ddf/driver.h>
 
@@ -72,5 +71,5 @@
 	/** Condition variable for pending_ops_count. */
 	fibril_condvar_t pending_ops_cv;
-	/** Pointer to devman usbhub function. */
+	/** Pointer to usbhub function. */
 	ddf_fun_t *hub_fun;
 	/** Status indicator */
Index: uspace/drv/bus/usb/usbmid/explore.c
===================================================================
--- uspace/drv/bus/usb/usbmid/explore.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/bus/usb/usbmid/explore.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -132,5 +132,5 @@
  *
  * @param dev Device to be explored.
- * @return Whether to accept this device from devman.
+ * @return Whether to accept this device.
  */
 int usbmid_explore_device(usb_device_t *dev)
Index: uspace/drv/char/atkbd/atkbd.c
===================================================================
--- uspace/drv/char/atkbd/atkbd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/atkbd/atkbd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -366,5 +366,5 @@
 	
 	kbd->client_sess = NULL;
-	kbd->parent_sess = ddf_dev_parent_sess_create(dev);
+	kbd->parent_sess = ddf_dev_parent_sess_get(dev);
 	
 	if (!kbd->parent_sess) {
Index: uspace/drv/char/atkbd/main.c
===================================================================
--- uspace/drv/char/atkbd/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/atkbd/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
  */
 
-#include <libarch/inttypes.h>
+#include <inttypes.h>
 #include <ddf/driver.h>
 #include <device/hw_res_parsed.h>
Index: uspace/drv/char/i8042/i8042.c
===================================================================
--- uspace/drv/char/i8042/i8042.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/i8042/i8042.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -269,7 +269,8 @@
 	};
 	
-	rc = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
-	    &irq_code);
-	if (rc != EOK) {
+	const int irq_kbd_cap = register_interrupt_handler(ddf_dev, irq_kbd,
+	    i8042_irq_handler, &irq_code);
+	if (irq_kbd_cap < 0) {
+		rc = irq_kbd_cap;
 		ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.",
 		    ddf_dev_get_name(ddf_dev));
@@ -277,7 +278,8 @@
 	}
 	
-	rc = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
-	    &irq_code);
-	if (rc != EOK) {
+	const int irq_mouse_cap = register_interrupt_handler(ddf_dev, irq_mouse,
+	    i8042_irq_handler, &irq_code);
+	if (irq_mouse_cap < 0) {
+		rc = irq_mouse_cap;
 		ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.",
 		    ddf_dev_get_name(ddf_dev));
@@ -289,7 +291,15 @@
 	assert(parent_sess != NULL);
 	
-	const bool enabled = hw_res_enable_interrupt(parent_sess);
-	if (!enabled) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to enable interrupts: %s.",
+	rc = hw_res_enable_interrupt(parent_sess, irq_kbd);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to enable keyboard interrupt: %s.",
+		    ddf_dev_get_name(ddf_dev));
+		rc = EIO;
+		goto error;
+	}
+
+	rc = hw_res_enable_interrupt(parent_sess, irq_mouse);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to enable mouse interrupt: %s.",
 		    ddf_dev_get_name(ddf_dev));
 		rc = EIO;
Index: uspace/drv/char/i8042/main.c
===================================================================
--- uspace/drv/char/i8042/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/i8042/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,5 +35,5 @@
  */
 
-#include <libarch/inttypes.h>
+#include <inttypes.h>
 #include <libarch/config.h>
 #include <ddf/driver.h>
@@ -60,5 +60,5 @@
 	assert(dev);
 	
-	async_sess_t *parent_sess = ddf_dev_parent_sess_create(dev);
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(dev);
 	if (parent_sess == NULL)
 		return ENOMEM;
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/ns8250/ns8250.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -55,5 +55,4 @@
 #include <ops/char_dev.h>
 
-#include <irc.h>
 #include <device/hw_res.h>
 #include <ipc/serial_ctl.h>
@@ -154,4 +153,6 @@
 	/** DDF function node */
 	ddf_fun_t *fun;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/** I/O registers **/
 	ns8250_regs_t *regs;
@@ -160,4 +161,6 @@
 	/** The irq assigned to this device. */
 	int irq;
+	/** IRQ capability handle */
+	int irq_cap;
 	/** The base i/o address of the devices registers. */
 	uintptr_t io_addr;
@@ -380,5 +383,4 @@
 static int ns8250_dev_initialize(ns8250_t *ns)
 {
-	async_sess_t *parent_sess;
 	int ret = EOK;
 	
@@ -388,15 +390,6 @@
 	memset(&hw_resources, 0, sizeof(hw_resource_list_t));
 	
-	/* Connect to the parent's driver. */
-	parent_sess = ddf_dev_parent_sess_create(ns->dev);
-	if (parent_sess == NULL) {
-		ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
-		    "device %s.", ddf_dev_get_name(ns->dev));
-		ret = ENOENT;
-		goto failed;
-	}
-	
 	/* Get hw resources. */
-	ret = hw_res_get_resource_list(parent_sess, &hw_resources);
+	ret = hw_res_get_resource_list(ns->parent_sess, &hw_resources);
 	if (ret != EOK) {
 		ddf_msg(LVL_ERROR, "Failed to get HW resources for device "
@@ -485,5 +478,5 @@
 {
 	/* Enable interrupt using IRC service. */
-	int rc = irc_enable_interrupt(ns->irq);
+	int rc = hw_res_enable_interrupt(ns->parent_sess, ns->irq);
 	if (rc != EOK)
 		return EIO;
@@ -778,5 +771,5 @@
 	
 	ns8250_read_from_device(ns);
-	irc_disable_interrupt(ns->irq);
+	hw_res_clear_interrupt(ns->parent_sess, ns->irq);
 }
 
@@ -797,5 +790,5 @@
 static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns)
 {
-	return unregister_interrupt_handler(ns->dev, ns->irq);
+	return unregister_interrupt_handler(ns->dev, ns->irq_cap);
 }
 
@@ -828,4 +821,12 @@
 	ns->dev = dev;
 	
+	ns->parent_sess = ddf_dev_parent_sess_get(ns->dev);
+	if (ns->parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
+		    "device %s.", ddf_dev_get_name(ns->dev));
+		rc = EIO;
+		goto fail;
+	}
+	
 	rc = ns8250_dev_initialize(ns);
 	if (rc != EOK)
@@ -849,5 +850,6 @@
 	
 	/* Register interrupt handler. */
-	if (ns8250_register_interrupt_handler(ns) != EOK) {
+	ns->irq_cap = ns8250_register_interrupt_handler(ns);
+	if (ns->irq_cap < 0) {
 		ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
 		rc = EADDRNOTAVAIL;
Index: uspace/drv/char/pl050/pl050.c
===================================================================
--- uspace/drv/char/pl050/pl050.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/pl050/pl050.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,7 +38,7 @@
 #include <ddf/interrupt.h>
 #include <ddf/log.h>
+#include <device/hw_res.h>
 #include <device/hw_res_parsed.h>
 #include <io/chardev_srv.h>
-#include <irc.h>
 
 #include "pl050_hw.h"
@@ -167,5 +167,5 @@
 	pl050->buf_rp = pl050->buf_wp = 0;
 
-	pl050->parent_sess = ddf_dev_parent_sess_create(pl050->dev);
+	pl050->parent_sess = ddf_dev_parent_sess_get(pl050->dev);
 	if (pl050->parent_sess == NULL) {
 		ddf_msg(LVL_ERROR, "Failed connecitng parent driver.");
@@ -212,7 +212,8 @@
 	pl050->regs = regs;
 
-	rc = register_interrupt_handler(pl050->dev, res.irqs.irqs[0],
-	    pl050_interrupt, &pl050_irq_code);
-	if (rc != EOK) {
+	const int irq_cap = register_interrupt_handler(pl050->dev,
+	    res.irqs.irqs[0], pl050_interrupt, &pl050_irq_code);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		ddf_msg(LVL_ERROR, "Failed registering interrupt handler. (%d)",
 		    rc);
@@ -220,5 +221,5 @@
 	}
 
-	rc = irc_enable_interrupt(res.irqs.irqs[0]);
+	rc = hw_res_enable_interrupt(pl050->parent_sess, res.irqs.irqs[0]);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enabling interrupt. (%d)", rc);
Index: uspace/drv/char/ps2mouse/main.c
===================================================================
--- uspace/drv/char/ps2mouse/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/ps2mouse/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
  */
 
-#include <libarch/inttypes.h>
+#include <inttypes.h>
 #include <ddf/driver.h>
 #include <device/hw_res_parsed.h>
Index: uspace/drv/char/ps2mouse/ps2mouse.c
===================================================================
--- uspace/drv/char/ps2mouse/ps2mouse.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/ps2mouse/ps2mouse.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -116,5 +116,5 @@
 {
 	mouse->client_sess = NULL;
-	mouse->parent_sess = ddf_dev_parent_sess_create(dev);
+	mouse->parent_sess = ddf_dev_parent_sess_get(dev);
 	if (!mouse->parent_sess)
 		return ENOMEM;
Index: uspace/drv/char/xtkbd/main.c
===================================================================
--- uspace/drv/char/xtkbd/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/xtkbd/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
  */
 
-#include <libarch/inttypes.h>
+#include <inttypes.h>
 #include <ddf/driver.h>
 #include <device/hw_res_parsed.h>
Index: uspace/drv/char/xtkbd/xtkbd.c
===================================================================
--- uspace/drv/char/xtkbd/xtkbd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/char/xtkbd/xtkbd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -417,5 +417,5 @@
 	
 	kbd->client_sess = NULL;
-	kbd->parent_sess = ddf_dev_parent_sess_create(dev);
+	kbd->parent_sess = ddf_dev_parent_sess_get(dev);
 	
 	if (!kbd->parent_sess) {
Index: uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c
===================================================================
--- uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -267,5 +267,5 @@
 	amdm37x_dispc_t *dispc = vis->dev_ctx;
 	const visual_t visual = mode.cell_visual.pixel_visual;
-	assert(visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
+	assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
 	const unsigned bpp = pixel2visual_table[visual].bpp;
 	pixel2visual_t p2v = pixel2visual_table[visual].func;
Index: uspace/drv/fb/amdm37x_dispc/main.c
===================================================================
--- uspace/drv/fb/amdm37x_dispc/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/fb/amdm37x_dispc/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -91,5 +91,5 @@
 	}
 
-	/* Report to devman */
+	/* Bind function */
 	ret = ddf_fun_bind(fun);
 	if (ret != EOK) {
Index: uspace/drv/fb/kfb/port.c
===================================================================
--- uspace/drv/fb/kfb/port.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/fb/kfb/port.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -66,4 +66,5 @@
 
 typedef struct {
+	sysarg_t paddr;
 	sysarg_t width;
 	sysarg_t height;
@@ -85,71 +86,24 @@
 static vslmode_list_element_t pixel_mode;
 
-static pixel_t color_table[16] = {
-	[COLOR_BLACK]       = 0x000000,
-	[COLOR_BLUE]        = 0x0000f0,
-	[COLOR_GREEN]       = 0x00f000,
-	[COLOR_CYAN]        = 0x00f0f0,
-	[COLOR_RED]         = 0xf00000,
-	[COLOR_MAGENTA]     = 0xf000f0,
-	[COLOR_YELLOW]      = 0xf0f000,
-	[COLOR_WHITE]       = 0xf0f0f0,
-
-	[COLOR_BLACK + 8]   = 0x000000,
-	[COLOR_BLUE + 8]    = 0x0000ff,
-	[COLOR_GREEN + 8]   = 0x00ff00,
-	[COLOR_CYAN + 8]    = 0x00ffff,
-	[COLOR_RED + 8]     = 0xff0000,
-	[COLOR_MAGENTA + 8] = 0xff00ff,
-	[COLOR_YELLOW + 8]  = 0xffff00,
-	[COLOR_WHITE + 8]   = 0xffffff,
-};
-
-static inline void attrs_rgb(char_attrs_t attrs, pixel_t *bgcolor, pixel_t *fgcolor)
-{
-	switch (attrs.type) {
-	case CHAR_ATTR_STYLE:
-		switch (attrs.val.style) {
-		case STYLE_NORMAL:
-			*bgcolor = color_table[COLOR_WHITE];
-			*fgcolor = color_table[COLOR_BLACK];
-			break;
-		case STYLE_EMPHASIS:
-			*bgcolor = color_table[COLOR_WHITE];
-			*fgcolor = color_table[COLOR_RED];
-			break;
-		case STYLE_INVERTED:
-			*bgcolor = color_table[COLOR_BLACK];
-			*fgcolor = color_table[COLOR_WHITE];
-			break;
-		case STYLE_SELECTED:
-			*bgcolor = color_table[COLOR_RED];
-			*fgcolor = color_table[COLOR_WHITE];
-			break;
-		}
-		break;
-	case CHAR_ATTR_INDEX:
-		*bgcolor = color_table[(attrs.val.index.bgcolor & 7) |
-		    ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
-		*fgcolor = color_table[(attrs.val.index.fgcolor & 7) |
-		    ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
-		break;
-	case CHAR_ATTR_RGB:
-		*bgcolor = attrs.val.rgb.bgcolor;
-		*fgcolor = attrs.val.rgb.fgcolor;
-		break;
-	}
-}
-
 static int kfb_claim(visualizer_t *vs)
 {
-	return EOK;
+	return physmem_map(kfb.paddr + kfb.offset,
+	    ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
+	    AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
 }
 
 static int kfb_yield(visualizer_t *vs)
 {
+	int rc;
+
 	if (vs->mode_set) {
 		vs->ops.handle_damage = NULL;
 	}
 
+	rc = physmem_unmap(kfb.addr);
+	if (rc != EOK)
+		return rc;
+
+	kfb.addr = NULL;
 	return EOK;
 }
@@ -211,7 +165,14 @@
 {
 	visualizer_t *vsl;
+	int rc;
 
 	vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
 	graph_visualizer_connection(vsl, iid, icall, NULL);
+
+	if (kfb.addr != NULL) {
+		rc = physmem_unmap(kfb.addr);
+		if (rc == EOK)
+			kfb.addr = NULL;
+	}
 }
 
@@ -266,4 +227,5 @@
 	kfb.width = width;
 	kfb.height = height;
+	kfb.paddr = paddr;
 	kfb.offset = offset;
 	kfb.scanline = scanline;
@@ -343,10 +305,4 @@
 	kfb.size = scanline * height;
 	kfb.addr = AS_AREA_ANY;
-	
-	rc = physmem_map(paddr + offset,
-	    ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
-	    AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
-	if (rc != EOK)
-		return rc;
 	
 	ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0");
Index: uspace/drv/intctl/icp-ic/Makefile
===================================================================
--- uspace/drv/intctl/icp-ic/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/intctl/icp-ic/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2014 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 = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = icp-ic
+
+SOURCES = \
+	icp-ic.c \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/intctl/icp-ic/icp-ic.c
===================================================================
--- uspace/drv/intctl/icp-ic/icp-ic.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/intctl/icp-ic/icp-ic.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2014 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 icp-ic
+ * @{
+ */
+
+/**
+ * @file icp-ic.c
+ * @brief IntegratorCP interrupt controller driver
+ */
+
+#include <async.h>
+#include <bitops.h>
+#include <ddi.h>
+#include <ddf/log.h>
+#include <errno.h>
+#include <ipc/irc.h>
+#include <loc.h>
+#include <stdint.h>
+
+#include "icp-ic.h"
+#include "icp-ic_hw.h"
+
+enum {
+	icpic_max_irq = 32
+};
+
+static int icpic_enable_irq(icpic_t *icpic, sysarg_t irq)
+{
+	if (irq > icpic_max_irq)
+		return EINVAL;
+
+	ddf_msg(LVL_NOTE, "Enable IRQ %zu", irq);
+
+	pio_write_32(&icpic->regs->irq_enableset, BIT_V(uint32_t, irq));
+	return EOK;
+}
+
+/** Client connection handler.
+ *
+ * @param iid   Hash of the request that opened the connection.
+ * @param icall Call data of the request that opened the connection.
+ * @param arg	Local argument.
+ */
+static void icpic_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	icpic_t *icpic;
+
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	async_answer_0(iid, EOK);
+
+	icpic = (icpic_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
+
+	while (true) {
+		callid = async_get_call(&call);
+
+		if (!IPC_GET_IMETHOD(call)) {
+			/* The other side has hung up. */
+			async_answer_0(callid, EOK);
+			return;
+		}
+
+		switch (IPC_GET_IMETHOD(call)) {
+		case IRC_ENABLE_INTERRUPT:
+			async_answer_0(callid,
+			    icpic_enable_irq(icpic, IPC_GET_ARG1(call)));
+			break;
+		case IRC_DISABLE_INTERRUPT:
+			/* XXX TODO */
+			async_answer_0(callid, EOK);
+			break;
+		case IRC_CLEAR_INTERRUPT:
+			/* Noop */
+			async_answer_0(callid, EOK);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+			break;
+		}
+	}
+}
+
+/** Add icp-ic device. */
+int icpic_add(icpic_t *icpic, icpic_res_t *res)
+{
+	ddf_fun_t *fun_a = NULL;
+	void *regs;
+	int rc;
+
+	rc = pio_enable((void *)res->base, sizeof(icpic_regs_t), &regs);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error enabling PIO");
+		goto error;
+	}
+
+	icpic->regs = (icpic_regs_t *)regs;
+
+	fun_a = ddf_fun_create(icpic->dev, fun_exposed, "a");
+	if (fun_a == NULL) {
+		ddf_msg(LVL_ERROR, "Failed creating function 'a'.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	ddf_fun_set_conn_handler(fun_a, icpic_connection);
+
+	rc = ddf_fun_bind(fun_a);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function 'a'. (%d)", rc);
+		goto error;
+	}
+
+	rc = ddf_fun_add_to_category(fun_a, "irc");
+	if (rc != EOK)
+		goto error;
+
+	return EOK;
+error:
+	if (fun_a != NULL)
+		ddf_fun_destroy(fun_a);
+	return rc;
+}
+
+/** Remove icp-ic device */
+int icpic_remove(icpic_t *icpic)
+{
+	return ENOTSUP;
+}
+
+/** icp-ic device gone */
+int icpic_gone(icpic_t *icpic)
+{
+	return ENOTSUP;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/intctl/icp-ic/icp-ic.h
===================================================================
--- uspace/drv/intctl/icp-ic/icp-ic.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/intctl/icp-ic/icp-ic.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 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 ICP_IC_H_
+#define ICP_IC_H
+
+#include <ddf/driver.h>
+#include <loc.h>
+#include <stdint.h>
+
+#include "icp-ic_hw.h"
+
+typedef struct {
+	uintptr_t base;
+} icpic_res_t;
+
+/** IntegratorCP Interrupt Controller */
+typedef struct {
+	icpic_regs_t *regs;
+	uintptr_t phys_base;
+	ddf_dev_t *dev;
+} icpic_t;
+
+extern int icpic_add(icpic_t *, icpic_res_t *);
+extern int icpic_remove(icpic_t *);
+extern int icpic_gone(icpic_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/intctl/icp-ic/icp-ic.ma
===================================================================
--- uspace/drv/intctl/icp-ic/icp-ic.ma	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/intctl/icp-ic/icp-ic.ma	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,1 @@
+10 integratorcp/intctl
Index: uspace/drv/intctl/icp-ic/icp-ic_hw.h
===================================================================
--- uspace/drv/intctl/icp-ic/icp-ic_hw.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/intctl/icp-ic/icp-ic_hw.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 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 pl050
+ * @{
+ */
+/** @file ARM PrimeCell PS2 Keyboard/Mouse Interface (PL050) registers
+ */
+
+#ifndef ICP_IC_HW_H
+#define ICP_IC_HW_H
+
+#include <ddi.h>
+
+typedef struct {
+	ioport32_t irq_status;
+	ioport32_t irq_rawstat;
+	ioport32_t irq_enableset;
+	ioport32_t irq_enableclr;
+	ioport32_t int_softset;
+	ioport32_t int_softclr;
+	ioport32_t fiq_status;
+	ioport32_t fiq_rawstat;
+	ioport32_t fiq_enableset;
+	ioport32_t fiq_enableclr;
+} icpic_regs_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/intctl/icp-ic/main.c
===================================================================
--- uspace/drv/intctl/icp-ic/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/drv/intctl/icp-ic/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2017 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 IntegratorCP Interrupt Controller driver
+ */
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "icp-ic.h"
+
+#define NAME  "icp-ic"
+
+static int icpic_dev_add(ddf_dev_t *dev);
+static int icpic_dev_remove(ddf_dev_t *dev);
+static int icpic_dev_gone(ddf_dev_t *dev);
+static int icpic_fun_online(ddf_fun_t *fun);
+static int icpic_fun_offline(ddf_fun_t *fun);
+
+static driver_ops_t driver_ops = {
+	.dev_add = icpic_dev_add,
+	.dev_remove = icpic_dev_remove,
+	.dev_gone = icpic_dev_gone,
+	.fun_online = icpic_fun_online,
+	.fun_offline = icpic_fun_offline
+};
+
+static driver_t icpic_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+static int icpic_get_res(ddf_dev_t *dev, icpic_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	int rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.mem_ranges.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->base = RNGABS(hw_res.mem_ranges.ranges[0]);
+
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static int icpic_dev_add(ddf_dev_t *dev)
+{
+	icpic_t *icpic;
+	icpic_res_t icpic_res;
+	int rc;
+
+        ddf_msg(LVL_DEBUG, "icpic_dev_add(%p)", dev);
+	icpic = ddf_dev_data_alloc(dev, sizeof(icpic_t));
+	if (icpic == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		return ENOMEM;
+	}
+
+	icpic->dev = dev;
+
+	rc = icpic_get_res(dev, &icpic_res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.\n");
+		return EIO;
+	}
+
+	return icpic_add(icpic, &icpic_res);
+}
+
+static int icpic_dev_remove(ddf_dev_t *dev)
+{
+        icpic_t *icpic = (icpic_t *)ddf_dev_data_get(dev);
+
+        ddf_msg(LVL_DEBUG, "icpic_dev_remove(%p)", dev);
+
+        return icpic_remove(icpic);
+}
+
+static int icpic_dev_gone(ddf_dev_t *dev)
+{
+        icpic_t *icpic = (icpic_t *)ddf_dev_data_get(dev);
+
+        ddf_msg(LVL_DEBUG, "icpic_dev_gone(%p)", dev);
+
+        return icpic_gone(icpic);
+}
+
+static int icpic_fun_online(ddf_fun_t *fun)
+{
+        ddf_msg(LVL_DEBUG, "icpic_fun_online()");
+        return ddf_fun_online(fun);
+}
+
+static int icpic_fun_offline(ddf_fun_t *fun)
+{
+        ddf_msg(LVL_DEBUG, "icpic_fun_offline()");
+        return ddf_fun_offline(fun);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": IntegratorCP Interrupt Controller driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&icpic_driver);
+}
+
+/** @}
+ */
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/nic/e1k/e1k.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,9 +40,9 @@
 #include <thread.h>
 #include <byteorder.h>
-#include <irc.h>
 #include <as.h>
 #include <ddi.h>
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
+#include <device/hw_res.h>
 #include <device/hw_res_parsed.h>
 #include <pci_dev_iface.h>
@@ -116,4 +116,8 @@
 /** E1000 device data */
 typedef struct {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/** Device configuration */
 	e1000_info_t info;
@@ -365,13 +369,16 @@
 	if (ctrl & CTRL_SLU) {
 		ctrl &= ~(CTRL_SLU);
+		E1000_REG_WRITE(e1000, E1000_CTRL, ctrl);
 		fibril_mutex_unlock(&e1000->ctrl_lock);
+		
 		thread_usleep(10);
+		
 		fibril_mutex_lock(&e1000->ctrl_lock);
+		ctrl = E1000_REG_READ(e1000, E1000_CTRL);
 		ctrl |= CTRL_SLU;
+		E1000_REG_WRITE(e1000, E1000_CTRL, ctrl);
 	}
 	
 	fibril_mutex_unlock(&e1000->ctrl_lock);
-	
-	e1000_link_restart(e1000);
 }
 
@@ -1253,5 +1260,5 @@
  * @param nic Driver data
  *
- * @return EOK if the handler was registered
+ * @return IRQ capability handle if the handler was registered
  * @return Negative error code otherwise
  *
@@ -1268,9 +1275,9 @@
 	e1000_irq_code.cmds[2].addr = e1000->reg_base_phys + E1000_IMC;
 	
-	int rc = register_interrupt_handler(nic_get_ddf_dev(nic),
-	    e1000->irq, e1000_interrupt_handler, &e1000_irq_code);
+	int cap = register_interrupt_handler(nic_get_ddf_dev(nic), e1000->irq,
+	    e1000_interrupt_handler, &e1000_irq_code);
 	
 	fibril_mutex_unlock(&irq_reg_mutex);
-	return rc;
+	return cap;
 }
 
@@ -1754,5 +1761,5 @@
 	e1000_enable_interrupts(e1000);
 	
-	int rc = irc_enable_interrupt(e1000->irq);
+	int rc = hw_res_enable_interrupt(e1000->parent_sess, e1000->irq);
 	if (rc != EOK) {
 		e1000_disable_interrupts(e1000);
@@ -1799,5 +1806,5 @@
 	e1000_disable_rx(e1000);
 	
-	irc_disable_interrupt(e1000->irq);
+	hw_res_disable_interrupt(e1000->parent_sess, e1000->irq);
 	e1000_disable_interrupts(e1000);
 	
@@ -1881,4 +1888,5 @@
 	
 	memset(e1000, 0, sizeof(e1000_t));
+	e1000->dev = dev;
 	
 	nic_set_specific(nic, e1000);
@@ -1995,4 +2003,10 @@
 		ddf_msg(LVL_ERROR, "Unable to allocate device softstate");
 		return ENOMEM;
+	}
+	
+	e1000->parent_sess = ddf_dev_parent_sess_get(dev);
+	if (e1000->parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Failed connecting parent device.");
+		return EIO;
 	}
 	
@@ -2116,5 +2130,4 @@
 {
 	ddf_fun_t *fun;
-	assert(dev);
 	
 	/* Initialize device structure for E1000 */
@@ -2152,7 +2165,9 @@
 	ddf_fun_set_ops(fun, &e1000_dev_ops);
 	
-	rc = e1000_register_int_handler(nic);
-	if (rc != EOK)
+	int irq_cap = e1000_register_int_handler(nic);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		goto err_fun_create;
+	}
 	
 	rc = e1000_initialize_rx_structure(nic);
@@ -2189,5 +2204,5 @@
 	e1000_uninitialize_rx_structure(nic);
 err_irq:
-	unregister_interrupt_handler(dev, DRIVER_DATA_DEV(dev)->irq);
+	unregister_interrupt_handler(dev, irq_cap);
 err_fun_create:
 	ddf_fun_destroy(fun);
Index: uspace/drv/nic/ne2k/dp8390.h
===================================================================
--- uspace/drv/nic/ne2k/dp8390.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/nic/ne2k/dp8390.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -50,4 +50,6 @@
 #define __NET_NETIF_DP8390_H__
 
+#include <async.h>
+#include <ddf/driver.h>
 #include <fibril_synch.h>
 #include <nic.h>
@@ -223,4 +225,8 @@
 
 typedef struct {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/* Device configuration */
 	void *base_port; /**< Port assigned from ISA configuration **/
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,5 @@
 #include <stdio.h>
 #include <errno.h>
-#include <irc.h>
+#include <device/hw_res.h>
 #include <stdlib.h>
 #include <str_error.h>
@@ -160,7 +160,7 @@
 	}
 
-	int rc = register_interrupt_handler(nic_get_ddf_dev(nic_data),
+	int irq_cap = register_interrupt_handler(nic_get_ddf_dev(nic_data),
 		ne2k->irq, ne2k_interrupt_handler, &ne2k->code);
-	return rc;
+	return irq_cap;
 }
 
@@ -228,6 +228,6 @@
 	ne2k->probed = true;
 	
-	rc = ne2k_register_interrupt(nic_data);
-	if (rc != EOK)
+	int irq_cap = ne2k_register_interrupt(nic_data);
+	if (irq_cap < 0)
 		return EINVAL;
 	
@@ -256,5 +256,5 @@
 			return rc;
 
-		rc = irc_enable_interrupt(ne2k->irq);
+		rc = hw_res_enable_interrupt(ne2k->parent_sess, ne2k->irq);
 		if (rc != EOK) {
 			ne2k_down(ne2k);
@@ -269,5 +269,5 @@
 	ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data);
 
-	(void) irc_disable_interrupt(ne2k->irq);
+	(void) hw_res_disable_interrupt(ne2k->parent_sess, ne2k->irq);
 	ne2k->receive_configuration = RCR_AB | RCR_AM;
 	ne2k_down(ne2k);
@@ -384,4 +384,11 @@
 	}
 	
+	ne2k->dev = dev;
+	ne2k->parent_sess = ddf_dev_parent_sess_get(dev);
+	if (ne2k->parent_sess == NULL) {
+		ne2k_dev_cleanup(dev);
+		return ENOMEM;
+	}
+	
 	int rc = ne2k_dev_init(nic_data);
 	if (rc != EOK) {
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/nic/rtl8139/driver.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,8 +36,8 @@
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
+#include <device/hw_res.h>
 #include <io/log.h>
 #include <nic.h>
 #include <pci_dev_iface.h>
-#include <irc.h>
 #include <stdio.h>
 #include <str.h>
@@ -125,17 +125,9 @@
 
 
-/** Disable interrupts on controller
+/** Set interrupts on controller
  *
  *  @param rtl8139  The card private structure
  */
-inline static void rtl8139_hw_int_disable(rtl8139_t *rtl8139)
-{
-	pio_write_16(rtl8139->io_port + IMR, 0x0);
-}
-/** Enable interrupts on controller
- *
- *  @param rtl8139  The card private structure
- */
-inline static void rtl8139_hw_int_enable(rtl8139_t *rtl8139)
+inline static void rtl8139_hw_int_set(rtl8139_t *rtl8139)
 {
 	pio_write_16(rtl8139->io_port + IMR, rtl8139->int_mask);
@@ -274,18 +266,4 @@
 }
 
-/**  Provide OR in the 32bit register (set selected bits to 1)
- *
- *   @param rtl8139     The rtl8139 structure
- *   @param reg_offset  Register offset in the device IO space
- *   @param bits_add    The value to or
- */
-inline static void rtl8139_hw_reg_add_32(rtl8139_t * rtl8139, size_t reg_offset,
-    uint32_t bits_add)
-{
-	uint32_t value = pio_read_32(rtl8139->io_port + reg_offset);
-	value |= bits_add;
-	pio_write_32(rtl8139->io_port + reg_offset, value);
-}
-
 /**  Unset selected bits in 8bit register
  *
@@ -301,19 +279,4 @@
 	pio_write_8(rtl8139->io_port + reg_offset, value);
 }
-
-/**  Unset selected bits in 32bit register
- *
- *   @param rtl8139     The rtl8139 structure
- *   @param reg_offset  Register offset in the device IO space
- *   @param bits_add    The mask of bits to remove
- */
-inline static void rtl8139_hw_reg_rem_32(rtl8139_t * rtl8139, size_t reg_offset,
-    uint32_t bits_add)
-{
-	uint32_t value = pio_read_32(rtl8139->io_port + reg_offset);
-	value &= ~bits_add;
-	pio_write_32(rtl8139->io_port + reg_offset, value);
-}
-
 
 static int rtl8139_set_addr(ddf_fun_t *fun, const nic_address_t *);
@@ -871,5 +834,5 @@
 
 	/* Turn the interrupts on again */
-	rtl8139_hw_int_enable(rtl8139);
+	rtl8139_hw_int_set(rtl8139);
 };
 
@@ -881,5 +844,6 @@
  *  @param nic_data  The driver data
  *
- *  @return EOK if the handler was registered, negative error code otherwise
+ *  @return IRQ capability handle if the handler was registered.
+ *  @return Negative error code otherwise.
  */
 inline static int rtl8139_register_int_handler(nic_t *nic_data)
@@ -894,10 +858,10 @@
 	rtl8139_irq_code.cmds[2].addr = rtl8139->io_addr + ISR;
 	rtl8139_irq_code.cmds[3].addr = rtl8139->io_addr + IMR;
-	int rc = register_interrupt_handler(nic_get_ddf_dev(nic_data),
+	int cap = register_interrupt_handler(nic_get_ddf_dev(nic_data),
 	    rtl8139->irq, rtl8139_interrupt_handler, &rtl8139_irq_code);
 
 	RTL8139_IRQ_STRUCT_UNLOCK();
 
-	return rc;
+	return cap;
 }
 
@@ -954,7 +918,7 @@
 
 	rtl8139->int_mask = RTL_DEFAULT_INTERRUPTS;
-	rtl8139_hw_int_enable(rtl8139);
-
-	int rc = irc_enable_interrupt(rtl8139->irq);
+	rtl8139_hw_int_set(rtl8139);
+
+	int rc = hw_res_enable_interrupt(rtl8139->parent_sess, rtl8139->irq);
 	if (rc != EOK) {
 		rtl8139_on_stopped(nic_data);
@@ -1012,5 +976,5 @@
 		return NULL;
 
-	rtl8139_t *rtl8139 = malloc(sizeof(rtl8139_t));
+	rtl8139_t *rtl8139 = calloc(1, sizeof(rtl8139_t));
 	if (!rtl8139) {
 		nic_unbind_and_destroy(dev);
@@ -1018,5 +982,5 @@
 	}
 
-	memset(rtl8139, 0, sizeof(rtl8139_t));
+	rtl8139->dev = dev;
 
 	rtl8139->nic_data = nic_data;
@@ -1202,4 +1166,9 @@
 
 	ddf_msg(LVL_DEBUG, "rtl8139: dev_data created");
+	rtl8139->parent_sess = ddf_dev_parent_sess_get(dev);
+	if (rtl8139->parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Error connecting parent device.");
+		return EIO;
+	}
 
 	/* Obtain and fill hardware resources info and connect to parent */
@@ -1294,5 +1263,4 @@
 	ddf_fun_t *fun;
 
-	assert(dev);
 	ddf_msg(LVL_NOTE, "RTL8139_dev_add %s (handle = %zu)",
 	    ddf_dev_get_name(dev), ddf_dev_get_handle(dev));
@@ -1321,7 +1289,9 @@
 
 	/* Register interrupt handler */
-	rc = rtl8139_register_int_handler(nic_data);
-	if (rc != EOK)
+	int irq_cap = rtl8139_register_int_handler(nic_data);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		goto err_pio;
+	}
 
 	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
@@ -1355,5 +1325,5 @@
 	ddf_fun_destroy(fun);
 err_srv:
-	unregister_interrupt_handler(dev, rtl8139->irq);
+	unregister_interrupt_handler(dev, irq_cap);
 err_pio:
 	// rtl8139_pio_disable(dev);
@@ -2117,5 +2087,5 @@
 		/* Disable timer interrupts while working with timer-related data */
 		rtl8139->int_mask = 0;
-		rtl8139_hw_int_enable(rtl8139);
+		rtl8139_hw_int_set(rtl8139);
 
 		rtl8139->poll_timer = new_timer;
@@ -2140,5 +2110,5 @@
 	}
 
-	rtl8139_hw_int_enable(rtl8139);
+	rtl8139_hw_int_set(rtl8139);
 
 	fibril_mutex_unlock(&rtl8139->rx_lock);
Index: uspace/drv/nic/rtl8139/driver.h
===================================================================
--- uspace/drv/nic/rtl8139/driver.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/nic/rtl8139/driver.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -87,4 +87,8 @@
 /** RTL8139 device data */
 typedef struct rtl8139_data {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/** I/O address of the device */
 	void *io_addr;
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/nic/rtl8169/driver.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,4 @@
 #include <align.h>
 #include <byteorder.h>
-#include <irc.h>
 #include <libarch/barrier.h>
 
@@ -38,9 +37,10 @@
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
+#include <device/hw_res.h>
+#include <device/hw_res_parsed.h>
 #include <io/log.h>
 #include <nic.h>
 #include <pci_dev_iface.h>
 
-#include <ipc/irc.h>
 #include <sysinfo.h>
 #include <ipc/ns.h>
@@ -371,8 +371,8 @@
 	rtl8169_irq_code.cmds[2].addr = rtl8169->regs + ISR;
 	rtl8169_irq_code.cmds[3].addr = rtl8169->regs + IMR;
-	int rc = register_interrupt_handler(nic_get_ddf_dev(nic_data),
+	int irq_cap = register_interrupt_handler(nic_get_ddf_dev(nic_data),
 	    rtl8169->irq, rtl8169_irq_handler, &rtl8169_irq_code);
 
-	return rc;
+	return irq_cap;
 }
 
@@ -396,12 +396,17 @@
 	rtl8169_t *rtl8169 = nic_get_specific(nic_data);
 
+	rtl8169->dev = dev;
+	rtl8169->parent_sess = ddf_dev_parent_sess_get(dev);
+	if (rtl8169->parent_sess == NULL)
+		return EIO;
+
 	/* Get PCI VID & PID */
-	rc = pci_config_space_read_16(ddf_dev_parent_sess_get(dev),
-	    PCI_VENDOR_ID, &rtl8169->pci_vid);
+	rc = pci_config_space_read_16(rtl8169->parent_sess, PCI_VENDOR_ID,
+	    &rtl8169->pci_vid);
 	if (rc != EOK)
 		return rc;
 
-	rc = pci_config_space_read_16(ddf_dev_parent_sess_get(dev),
-	    PCI_DEVICE_ID, &rtl8169->pci_pid);
+	rc = pci_config_space_read_16(rtl8169->parent_sess, PCI_DEVICE_ID,
+	    &rtl8169->pci_pid);
 	if (rc != EOK)
 		return rc;
@@ -426,9 +431,9 @@
 		goto err_pio;
 
-	rc = rtl8169_register_int_handler(nic_data);
-	if (rc != EOK) {
+	int irq_cap = rtl8169_register_int_handler(nic_data);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		ddf_msg(LVL_ERROR, "Failed to register IRQ handler (%d)", rc);
 		goto err_irq;
-
 	}
 
@@ -469,6 +474,6 @@
 err_srv:
 	/* XXX Disconnect from services */
+	unregister_interrupt_handler(dev, irq_cap);
 err_irq:
-	//unregister_interrupt_handler(dev, rtl8169->irq);
 err_pio:
 err_destroy:
@@ -745,5 +750,6 @@
 
 	pio_write_16(rtl8169->regs + IMR, 0xffff);
-	irc_enable_interrupt(rtl8169->irq);
+	/* XXX Check return value */
+	hw_res_enable_interrupt(rtl8169->parent_sess, rtl8169->irq);
 
 	return EOK;
Index: uspace/drv/nic/rtl8169/driver.h
===================================================================
--- uspace/drv/nic/rtl8169/driver.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/nic/rtl8169/driver.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -49,4 +49,8 @@
 /** RTL8139 device data */
 typedef struct rtl8169_data {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/** I/O address of the device */
 	void *regs_phys;
Index: uspace/drv/platform/amdm37x/main.c
===================================================================
--- uspace/drv/platform/amdm37x/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/platform/amdm37x/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -150,5 +150,5 @@
 
 static hw_resource_list_t *amdm37x_get_resources(ddf_fun_t *fnode);
-static bool amdm37x_enable_interrupt(ddf_fun_t *fun);
+static int amdm37x_enable_interrupt(ddf_fun_t *fun, int);
 
 static hw_res_ops_t fun_hw_res_ops = {
@@ -265,5 +265,5 @@
 }
 
-static bool amdm37x_enable_interrupt(ddf_fun_t *fun)
+static int amdm37x_enable_interrupt(ddf_fun_t *fun, int irq)
 {
 	//TODO: Implement
Index: uspace/drv/platform/icp/icp.c
===================================================================
--- uspace/drv/platform/icp/icp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/platform/icp/icp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 #include <stdio.h>
 #include <errno.h>
+#include <irc.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -53,5 +54,6 @@
 	icp_kbd_irq = 3,
 	icp_mouse_base = 0x19000000,
-	icp_mouse_irq = 4
+	icp_mouse_irq = 4,
+	icp_ic_base = 0x14000000
 };
 
@@ -107,4 +109,16 @@
 };
 
+static hw_resource_t icp_ic_res[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = icp_ic_base,
+			.size = 40,
+			.relative = false,
+			.endianness = LITTLE_ENDIAN
+		}
+	}
+};
+
 static pio_window_t icp_pio_window = {
 	.mem = {
@@ -128,4 +142,11 @@
 };
 
+static icp_fun_t icp_ic_fun_proto = {
+	.hw_resources = {
+		sizeof(icp_ic_res) / sizeof(icp_ic_res[0]),
+		icp_ic_res
+	},
+};
+
 /** Obtain function soft-state from DDF function node */
 static icp_fun_t *icp_fun(ddf_fun_t *fnode)
@@ -142,8 +163,47 @@
 }
 
-static bool icp_enable_interrupt(ddf_fun_t *fun)
-{
-	/* TODO */
+static bool icp_fun_owns_interrupt(icp_fun_t *fun, int irq)
+{
+	const hw_resource_list_t *res = &fun->hw_resources;
+
+	/* Check that specified irq really belongs to the function */
+	for (size_t i = 0; i < res->count; ++i) {
+		if (res->resources[i].type == INTERRUPT &&
+		    res->resources[i].res.interrupt.irq == irq) {
+			return true;
+		}
+	}
+
 	return false;
+}
+
+static int icp_fun_enable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	icp_fun_t *fun = icp_fun(fnode);
+
+	if (!icp_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_enable_interrupt(irq);
+}
+
+static int icp_fun_disable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	icp_fun_t *fun = icp_fun(fnode);
+
+	if (!icp_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_disable_interrupt(irq);
+}
+
+static int icp_fun_clear_interrupt(ddf_fun_t *fnode, int irq)
+{
+	icp_fun_t *fun = icp_fun(fnode);
+
+	if (!icp_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_clear_interrupt(irq);
 }
 
@@ -155,5 +215,7 @@
 static hw_res_ops_t icp_hw_res_ops = {
 	.get_resource_list = &icp_get_resources,
-	.enable_interrupt = &icp_enable_interrupt,
+	.enable_interrupt = &icp_fun_enable_interrupt,
+	.disable_interrupt = &icp_fun_disable_interrupt,
+	.clear_interrupt = &icp_fun_clear_interrupt
 };
 
@@ -225,4 +287,9 @@
 		return rc;
 
+	rc = icp_add_fun(dev, "intctl", "integratorcp/intctl",
+	    &icp_ic_fun_proto);
+	if (rc != EOK)
+		return rc;
+
 	return EOK;
 }
Index: uspace/drv/platform/mac/mac.c
===================================================================
--- uspace/drv/platform/mac/mac.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/platform/mac/mac.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2011 Martin Decky
+ * Copyright (c) 2017 Jiri Svoboda
  * All rights reserved.
  *
@@ -40,5 +41,7 @@
 #include <errno.h>
 #include <ops/hw_res.h>
+#include <ops/pio_window.h>
 #include <stdio.h>
+#include <sysinfo.h>
 
 #define NAME  "mac"
@@ -46,5 +49,37 @@
 typedef struct {
 	hw_resource_list_t hw_resources;
+	pio_window_t pio_window;
 } mac_fun_t;
+
+static hw_resource_t adb_res[] = {
+	{
+		.type = IO_RANGE,
+		.res.io_range = {
+			.address = 0,
+			.size = 0x2000,
+			.relative = true,
+			.endianness = BIG_ENDIAN
+		}
+	},
+	{
+		.type = INTERRUPT,
+		.res.interrupt = {
+			.irq = 0 /* patched at run time */
+		}
+	},
+};
+
+static mac_fun_t adb_data = {
+	.hw_resources = {
+		sizeof(adb_res) / sizeof(adb_res[0]),
+		adb_res
+	},
+	.pio_window = {
+		.io = {
+			.base = 0, /* patched at run time */
+			.size = 0x2000
+		}
+	}
+};
 
 static hw_resource_t pci_conf_regs[] = {
@@ -79,7 +114,13 @@
 
 /** Obtain function soft-state from DDF function node */
-static mac_fun_t *mac_fun(ddf_fun_t *fnode)
-{
-	return ddf_fun_data_get(fnode);
+static mac_fun_t *mac_fun(ddf_fun_t *ddf_fun)
+{
+	return ddf_fun_data_get(ddf_fun);
+}
+
+static pio_window_t *mac_get_pio_window(ddf_fun_t *ddf_fun)
+{
+	mac_fun_t *fun = mac_fun(ddf_fun);
+	return &fun->pio_window;
 }
 
@@ -88,4 +129,5 @@
 {
 	ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
+	printf("mac: Adding new function '%s'.\n", name);
 	
 	ddf_fun_t *fnode = NULL;
@@ -114,4 +156,5 @@
 	}
 	
+	printf("mac: Added new function '%s' (str=%s).\n", name, str_match_id);
 	return true;
 	
@@ -135,13 +178,31 @@
 static int mac_dev_add(ddf_dev_t *dev)
 {
+	int rc;
+	uintptr_t cuda_physical;
+	sysarg_t cuda_inr;
 #if 0
 	/* Register functions */
-	if (!mac_add_fun(dev, "pci0", "intel_pci", &pci_data))
-		ddf_msg(LVL_ERROR, "Failed to add functions for Mac platform.");
+	if (!mac_add_fun(dev, "pci0", "intel_pci", &pci_data)) {
+		ddf_msg(LVL_ERROR, "Failed to add PCI function for Mac platform.");
+		return EIO;
+	}
 #else
 	(void)pci_data;
-	(void)mac_add_fun;
 #endif
-	
+	rc = sysinfo_get_value("cuda.address.physical", &cuda_physical);
+	if (rc != EOK)
+		return EIO;
+	rc = sysinfo_get_value("cuda.inr", &cuda_inr);
+	if (rc != EOK)
+		return EIO;
+
+	adb_data.pio_window.io.base = cuda_physical;
+	adb_res[1].res.interrupt.irq = cuda_inr;
+
+	if (!mac_add_fun(dev, "adb", "cuda_adb", &adb_data)) {
+		ddf_msg(LVL_ERROR, "Failed to add ADB function for Mac platform.");
+		return EIO;
+	}
+
 	return EOK;
 }
@@ -166,5 +227,5 @@
 }
 
-static bool mac_enable_interrupt(ddf_fun_t *fun)
+static int mac_enable_interrupt(ddf_fun_t *fun, int irq)
 {
 	/* TODO */
@@ -172,4 +233,8 @@
 	return false;
 }
+
+static pio_window_ops_t fun_pio_window_ops = {
+        .get_pio_window = &mac_get_pio_window
+};
 
 static hw_res_ops_t fun_hw_res_ops = {
@@ -183,4 +248,5 @@
 	ddf_log_init(NAME);
 	mac_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
+	mac_fun_ops.interfaces[PIO_WINDOW_DEV_IFACE] = &fun_pio_window_ops;
 	return ddf_driver_main(&mac_driver);
 }
Index: uspace/drv/platform/malta/malta.c
===================================================================
--- uspace/drv/platform/malta/malta.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/platform/malta/malta.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -143,5 +143,5 @@
 }
 
-static bool malta_enable_interrupt(ddf_fun_t *fun)
+static int malta_enable_interrupt(ddf_fun_t *fun, int irq)
 {
 	/* TODO */
Index: uspace/drv/platform/msim/msim.c
===================================================================
--- uspace/drv/platform/msim/msim.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/platform/msim/msim.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -121,5 +121,5 @@
 }
 
-static bool msim_enable_interrupt(ddf_fun_t *fun)
+static int msim_enable_interrupt(ddf_fun_t *fun, int irq)
 {
 	/* Nothing to do. */
Index: uspace/drv/platform/pc/pc.c
===================================================================
--- uspace/drv/platform/pc/pc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/platform/pc/pc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -125,5 +125,5 @@
 }
 
-static bool pc_enable_interrupt(ddf_fun_t *fun)
+static int pc_enable_interrupt(ddf_fun_t *fun, int irq)
 {
 	/* TODO */
Index: uspace/drv/platform/sun4u/sun4u.c
===================================================================
--- uspace/drv/platform/sun4u/sun4u.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/platform/sun4u/sun4u.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -130,5 +130,5 @@
 }
 
-static bool sun4u_enable_interrupt(ddf_fun_t *fun)
+static int sun4u_enable_interrupt(ddf_fun_t *fun, int irq)
 {
 	/* TODO */
Index: uspace/drv/test/test1/test1.c
===================================================================
--- uspace/drv/test/test1/test1.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/test/test1/test1.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -135,5 +135,5 @@
  * /virtual/test1/clone/child
  *
- * and devman shall not deadlock.
+ * and the DDF shall not deadlock.
  *
  *
Index: uspace/drv/time/cmos-rtc/cmos-rtc.c
===================================================================
--- uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -213,6 +213,6 @@
 	/* Connect to the parent's driver */
 
-	parent_sess = ddf_dev_parent_sess_create(rtc->dev);
-	if (!parent_sess) {
+	parent_sess = ddf_dev_parent_sess_get(rtc->dev);
+	if (parent_sess == NULL) {
 		ddf_msg(LVL_ERROR, "Failed to connect to parent driver\
 		    of device %s.", ddf_dev_get_name(rtc->dev));
Index: uspace/lib/bithenge/include/bithenge/blob.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/blob.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/bithenge/include/bithenge/blob.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #define BITHENGE_BLOB_H_
 
-#include <sys/types.h>
+#include <offset.h>
 #include <errno.h>
 #include "tree.h"
Index: uspace/lib/block/block.c
===================================================================
--- uspace/lib/block/block.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/block/block.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -51,6 +51,7 @@
 #include <malloc.h>
 #include <stdio.h>
-#include <sys/typefmt.h>
 #include <stacktrace.h>
+#include <offset.h>
+#include <inttypes.h>
 #include "block.h"
 
Index: uspace/lib/block/block.h
===================================================================
--- uspace/lib/block/block.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/block/block.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #define LIBBLOCK_LIBBLOCK_H_
 
-#include <sys/types.h>
+#include <offset.h>
 #include <async.h>
 #include <fibril_synch.h>
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -63,4 +63,5 @@
 	generic/bd.c \
 	generic/bd_srv.c \
+	generic/perm.c \
 	generic/cap.c \
 	generic/clipboard.c \
@@ -81,4 +82,5 @@
 	generic/event.c \
 	generic/errno.c \
+	generic/gsort.c \
 	generic/loc.c \
 	generic/mem.c \
@@ -124,4 +126,5 @@
 	generic/io/con_srv.c \
 	generic/io/console.c \
+	generic/io/table.c \
 	generic/io/visualizer.c \
 	generic/io/window.c \
@@ -158,8 +161,8 @@
 	generic/stacktrace.c \
 	generic/arg_parse.c \
-	generic/sort.c \
 	generic/stats.c \
 	generic/assert.c \
 	generic/pio_trace.c \
+	generic/qsort.c \
 	generic/uuid.c \
 	generic/vbd.c \
@@ -179,6 +182,9 @@
 
 TEST_SOURCES = \
+	test/fibril/timer.c \
 	test/main.c \
+	test/io/table.c \
 	test/odict.c \
+	test/qsort.c \
 	test/sprintf.c \
 	test/str.c
@@ -188,5 +194,5 @@
 %.h: %.ag
 	$(AUTOGEN) probe $< >$<.probe.c
-	$(CC) $(DEFS) $(CFLAGS) -S -o $<.probe.s $<.probe.c
+	$(CC_AUTOGEN) $(DEFS) $(CFLAGS) -S -o $<.probe.s $<.probe.c
 	$(AUTOGEN) generate $< <$<.probe.s >$@   
 
Index: uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_abs32le_ELF_LINUX_H_
-#define LBIC_abs32le_ELF_LINUX_H_
+#define LIBC_abs32le_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/abs32le/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_abs32le_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define FADDR(fptr)  ((uintptr_t) (fptr))
Index: uspace/lib/c/arch/abs32le/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/abs32le/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_abs32le_INTTYPES_H_
 
+#define PRIdPTR  PRId32  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu32  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx32  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/abs32le/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/abs32le/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint32_t size_t;
+typedef int32_t ssize_t;
 typedef int32_t ptrdiff_t;
 
Index: uspace/lib/c/arch/abs32le/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/syscall.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/abs32le/include/libarch/syscall.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 
 #include <abi/syscall.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define __syscall0  __syscall
Index: uspace/lib/c/arch/abs32le/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/abs32le/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,6 +48,4 @@
 typedef int32_t native_t;
 
-typedef int32_t ssize_t;
-
 typedef uint32_t atomic_count_t;
 typedef int32_t atomic_signed_t;
Index: uspace/lib/c/arch/amd64/Makefile.common
===================================================================
--- uspace/lib/c/arch/amd64/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/amd64/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,6 +27,11 @@
 #
 
-GCC_CFLAGS += -mno-tls-direct-seg-refs -fno-omit-frame-pointer
-CLANG_CFLAGS += -fno-omit-frame-pointer
+COMMON_CFLAGS += -fno-omit-frame-pointer
+
+# XXX: clang doesn't support this flag, but the optimization is OS-specific,
+#      so it isn't used for amd64-unknown-elf target.
+GCC_CFLAGS += -mno-tls-direct-seg-refs
+
+LFLAGS += --gc-sections
 
 ENDIANESS = LE
Index: uspace/lib/c/arch/amd64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/amd64/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_amd64_ELF_LINUX_H_
-#define LBIC_amd64_ELF_LINUX_H_
+#define LIBC_amd64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/amd64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/amd64/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_amd64_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define FADDR(fptr)		((uintptr_t) (fptr))
Index: uspace/lib/c/arch/amd64/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/amd64/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_amd64_INTTYPES_H_
 
+#define PRIdPTR  PRId64  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu64  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx64  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId64  /**< Format for native_t. */
 #define PRIun  PRIu64  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/amd64/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/amd64/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint64_t size_t;
+typedef int64_t ssize_t;
 typedef int64_t ptrdiff_t;
 
Index: uspace/lib/c/arch/amd64/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/amd64/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,6 +48,4 @@
 typedef int64_t native_t;
 
-typedef int64_t ssize_t;
-
 typedef uint64_t atomic_count_t;
 typedef int64_t atomic_signed_t;
Index: uspace/lib/c/arch/arm32/Makefile.common
===================================================================
--- uspace/lib/c/arch/arm32/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/arm32/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,8 +28,11 @@
 #
 
-GCC_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH))
+COMMON_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame \
+	-march=$(subst _,-,$(PROCESSOR_ARCH))
+
+LFLAGS += --gc-sections
 
 ifeq ($(CONFIG_FPU),y)
-	GCC_CFLAGS += -mfloat-abi=hard
+	COMMON_CFLAGS += -mfloat-abi=hard
 else
 	BASE_LIBS += $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
Index: uspace/lib/c/arch/arm32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/arm32/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_arm32_ELF_LINUX_H_
-#define LBIC_arm32_ELF_LINUX_H_
+#define LIBC_arm32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/arm32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/arm32/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 #define LIBC_arm32_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 /** Calculate absolute address of function referenced by fptr pointer.
Index: uspace/lib/c/arch/arm32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/fibril.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/arm32/include/libarch/fibril.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 #define LIBC_arm32_FIBRIL_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 #include <align.h>
 #include <thread.h>
Index: uspace/lib/c/arch/arm32/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/arm32/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_arm32_INTTYPES_H_
 
+#define PRIdPTR  PRId32  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu32  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx32  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/arm32/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/arm32/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint32_t size_t;
+typedef int32_t ssize_t;
 typedef int32_t ptrdiff_t;
 
Index: uspace/lib/c/arch/arm32/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/arm32/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -49,6 +49,4 @@
 typedef int32_t native_t;
 
-typedef int32_t ssize_t;
-
 typedef uint32_t atomic_count_t;
 typedef int32_t atomic_signed_t;
Index: uspace/lib/c/arch/ia32/Makefile.common
===================================================================
--- uspace/lib/c/arch/ia32/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,10 +28,11 @@
 
 ifeq ($(PROCESSOR),i486)
-	GCC_CFLAGS += -march=i486 -mno-tls-direct-seg-refs -fno-omit-frame-pointer
+	COMMON_CFLAGS += -march=i486
 else
-	GCC_CFLAGS += -march=pentium -mno-tls-direct-seg-refs -fno-omit-frame-pointer
+	COMMON_CFLAGS += -march=pentium
 endif
 
-CLANG_CFLAGS += -fno-omit-frame-pointer
+COMMON_CFLAGS += -mno-tls-direct-seg-refs -fno-omit-frame-pointer
+LFLAGS += --gc-sections
 
 ENDIANESS = LE
Index: uspace/lib/c/arch/ia32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_ia32_ELF_LINUX_H_
-#define LBIC_ia32_ELF_LINUX_H_
+#define LIBC_ia32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ia32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_ia32_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define FADDR(fptr)  ((uintptr_t) (fptr))
Index: uspace/lib/c/arch/ia32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/fibril.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/include/libarch/fibril.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_ia32_FIBRIL_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 #include <libarch/fibril_context.h>
 
Index: uspace/lib/c/arch/ia32/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_ia32_INTTYPES_H_
 
+#define PRIdPTR  PRId32  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu32  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx32  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/ia32/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint32_t size_t;
+typedef int32_t ssize_t;
 typedef int32_t ptrdiff_t;
 
Index: uspace/lib/c/arch/ia32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/syscall.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/include/libarch/syscall.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 
 #include <abi/syscall.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define __syscall0  __syscall_fast_func
Index: uspace/lib/c/arch/ia32/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,7 +48,4 @@
 typedef int32_t native_t;
 
-typedef int32_t ssize_t;
-typedef uint32_t size_t;
-
 typedef uint32_t atomic_count_t;
 typedef int32_t atomic_signed_t;
Index: uspace/lib/c/arch/ia32/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/ia32/src/rtld/reloc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia32/src/rtld/reloc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <inttypes.h>
 
 #include <libarch/rtld/elf_dyn.h>
@@ -79,5 +80,5 @@
 	str_tab = m->dyn.str_tab;
 
-	DPRINTF("address: 0x%x, entries: %d\n", (uintptr_t)rt, rt_entries);
+	DPRINTF("address: 0x%" PRIxPTR ", entries: %zd\n", (uintptr_t)rt, rt_entries);
 	
 	for (i = 0; i < rt_entries; ++i) {
Index: uspace/lib/c/arch/ia64/Makefile.common
===================================================================
--- uspace/lib/c/arch/ia64/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia64/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,5 +27,5 @@
 #
 
-GCC_CFLAGS += -fno-unwind-tables
+COMMON_CFLAGS += -fno-unwind-tables
 
 ENDIANESS = LE
Index: uspace/lib/c/arch/ia64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia64/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_ia64_ELF_LINUX_H_
-#define LBIC_ia64_ELF_LINUX_H_
+#define LIBC_ia64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ia64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia64/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_ia64_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 /**
Index: uspace/lib/c/arch/ia64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/fibril.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia64/include/libarch/fibril.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #include <align.h>
 #include <libarch/stack.h>
-#include <libarch/types.h>
+#include <types/common.h>
 #include <libarch/fibril_context.h>
 
Index: uspace/lib/c/arch/ia64/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia64/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_ia64_INTTYPES_H_
 
+#define PRIdPTR  PRId64  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu64  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx64  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId64  /**< Format for native_t. */
 #define PRIun  PRIu64  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/ia64/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia64/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint64_t size_t;
+typedef int64_t ssize_t;
 typedef int64_t ptrdiff_t;
 
Index: uspace/lib/c/arch/ia64/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ia64/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,6 +48,4 @@
 typedef int64_t native_t;
 
-typedef int64_t ssize_t;
-
 typedef uint64_t atomic_count_t;
 typedef int64_t atomic_signed_t;
Index: uspace/lib/c/arch/mips32/Makefile.common
===================================================================
--- uspace/lib/c/arch/mips32/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/mips32/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,7 +27,8 @@
 #
 
-GCC_CFLAGS += -msoft-float -mabi=32
+COMMON_CFLAGS += -msoft-float -mabi=32
 BASE_LIBS += $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
 AS_PROLOG = .module softfloat;.abicalls;
+LFLAGS += --gc-sections
 
 ENDIANESS = LE
@@ -37,9 +38,9 @@
 
 ifeq ($(MACHINE),msim)
-	GCC_CFLAGS += -march=r4000 
+	COMMON_CFLAGS += -march=r4000
 endif
 
 ifeq ($(MACHINE),lmalta)
-	GCC_CFLAGS += -march=4kc
+	COMMON_CFLAGS += -march=4kc
 endif
 
Index: uspace/lib/c/arch/mips32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/mips32/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_mips32_ELF_LINUX_H_
-#define LBIC_mips32_ELF_LINUX_H_
+#define LIBC_mips32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/mips32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/mips32/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_mips32_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define FADDR(fptr)  ((uintptr_t) (fptr))
Index: uspace/lib/c/arch/mips32/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/mips32/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_mips32_INTTYPES_H_
 
+#define PRIdPTR  PRId32  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu32  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx32  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/mips32/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/mips32/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint32_t size_t;
+typedef int32_t ssize_t;
 typedef int32_t ptrdiff_t;
 
Index: uspace/lib/c/arch/mips32/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/mips32/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -49,6 +49,4 @@
 typedef int32_t native_t;
 
-typedef int32_t ssize_t;
-
 typedef uint32_t atomic_count_t;
 typedef int32_t atomic_signed_t;
Index: uspace/lib/c/arch/mips32eb/Makefile.common
===================================================================
--- uspace/lib/c/arch/mips32eb/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/mips32eb/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,7 +27,8 @@
 #
 
-GCC_CFLAGS += -msoft-float -mabi=32
+COMMON_CFLAGS += -msoft-float -mabi=32
 BASE_LIBS += $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
 AS_PROLOG = .module softfloat;.abicalls;
+LFLAGS += --gc-sections
 
 ENDIANESS = BE
@@ -37,5 +38,5 @@
 
 ifeq ($(MACHINE),bmalta)
-	GCC_CFLAGS += -march=4kc
+	COMMON_CFLAGS += -march=4kc
 endif
 
Index: uspace/lib/c/arch/ppc32/Makefile.common
===================================================================
--- uspace/lib/c/arch/ppc32/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ppc32/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,14 +27,14 @@
 #
 
-
 ifeq ($(CONFIG_FPU),y)
-FLOATS=hard
+	FLOATS=hard
 else
-FLOATS=soft
+	FLOATS=soft
 endif
 
-GCC_CFLAGS += -mcpu=powerpc -m$(FLOATS)-float -m32
+COMMON_CFLAGS += -mcpu=powerpc -m$(FLOATS)-float -m32
 BASE_LIBS += $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
 AFLAGS += -a32
+LFLAGS += --gc-sections
 
 ENDIANESS = BE
Index: uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_ppc32_ELF_LINUX_H_
-#define LBIC_ppc32_ELF_LINUX_H_
+#define LIBC_ppc32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ppc32/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_ppc32_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define FADDR(fptr)		((uintptr_t) (fptr))
Index: uspace/lib/c/arch/ppc32/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ppc32/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_ppc32_INTTYPES_H_
 
+#define PRIdPTR  PRId32  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu32  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx32  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId32  /**< Format for native_t. */
 #define PRIun  PRIu32  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/ppc32/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ppc32/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint32_t size_t;
+typedef int32_t ssize_t;
 typedef int32_t ptrdiff_t;
 
Index: uspace/lib/c/arch/ppc32/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/ppc32/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,6 +48,4 @@
 typedef int32_t native_t;
 
-typedef int32_t ssize_t;
-
 typedef uint32_t atomic_count_t;
 typedef int32_t atomic_signed_t;
Index: uspace/lib/c/arch/riscv64/Makefile.common
===================================================================
--- uspace/lib/c/arch/riscv64/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/arch/riscv64/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2005 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+BASE_LIBS += $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
+
+ENDIANESS = LE
+
+BFD_NAME = elf64-littleriscv
+BFD_ARCH = riscv
Index: uspace/lib/c/arch/riscv64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/config.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/arch/riscv64/include/libarch/config.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcamd64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_riscv64_CONFIG_H_
+#define LIBC_riscv64_CONFIG_H_
+
+#define PAGE_WIDTH  12
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_riscv64_ELF_LINUX_H_
-#define LBIC_riscv64_ELF_LINUX_H_
+#define LIBC_riscv64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_riscv64_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define FADDR(fptr)  ((uintptr_t) (fptr))
Index: uspace/lib/c/arch/riscv64/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_riscv64_INTTYPES_H_
 
+#define PRIdPTR  PRId64  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu64  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx64  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId64  /**< Format for native_t. */
 #define PRIun  PRIu64  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/riscv64/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint64_t size_t;
+typedef int64_t ssize_t;
 typedef int64_t ptrdiff_t;
 
Index: uspace/lib/c/arch/riscv64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/syscall.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/include/libarch/syscall.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,7 @@
 #define LIBC_riscv64_SYSCALL_H_
 
+#include <stdint.h>
 #include <abi/syscall.h>
+#include <types/common.h>
 
 #define __syscall0  __syscall
Index: uspace/lib/c/arch/riscv64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/tls.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/include/libarch/tls.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -51,5 +51,5 @@
 static inline tcb_t *__tcb_get(void)
 {
-	return NULL;
+	return (void *) 0;
 }
 
Index: uspace/lib/c/arch/riscv64/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,6 +48,4 @@
 typedef int64_t native_t;
 
-typedef int64_t ssize_t;
-
 typedef uint64_t atomic_count_t;
 typedef int64_t atomic_signed_t;
Index: uspace/lib/c/arch/riscv64/src/entry.c
===================================================================
--- uspace/lib/c/arch/riscv64/src/entry.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/src/entry.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,5 +35,5 @@
 void __entry(void)
 {
-	__main(NULL);
+	__main((void *) 0);
 }
 
Index: uspace/lib/c/arch/riscv64/src/stacktrace.c
===================================================================
--- uspace/lib/c/arch/riscv64/src/stacktrace.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/src/stacktrace.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -55,10 +55,10 @@
 uintptr_t stacktrace_fp_get(void)
 {
-	return (uintptr_t) NULL;
+	return 0;
 }
 
 uintptr_t stacktrace_pc_get(void)
 {
-	return (uintptr_t) NULL;
+	return 0;
 }
 
Index: uspace/lib/c/arch/riscv64/src/thread_entry.c
===================================================================
--- uspace/lib/c/arch/riscv64/src/thread_entry.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/riscv64/src/thread_entry.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -30,9 +30,10 @@
  */
 
+#include <types/common.h>
 #include "../../../generic/private/thread.h"
 
 void __thread_entry(void)
 {
-	__thread_main(NULL);
+	__thread_main((void *) 0);
 }
 
Index: uspace/lib/c/arch/sparc64/Makefile.common
===================================================================
--- uspace/lib/c/arch/sparc64/Makefile.common	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/sparc64/Makefile.common	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,12 +28,12 @@
 
 ifeq ($(PROCESSOR),sun4v)
-GCC_CFLAGS += -mcpu=niagara -mno-vis
+COMMON_CFLAGS += -mcpu=niagara -mno-vis
 else
-GCC_CFLAGS += -mcpu=ultrasparc
+COMMON_CFLAGS += -mcpu=ultrasparc
 endif
 
-GCC_CFLAGS += -m64 -mcmodel=medlow
+COMMON_CFLAGS += -m64 -mcmodel=medlow
 
-LFLAGS += -no-check-sections
+LFLAGS += -no-check-sections --gc-sections
 
 ENDIANESS = BE
Index: uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,5 @@
 
 #ifndef LIBC_sparc64_ELF_LINUX_H_
-#define LBIC_sparc64_ELF_LINUX_H_
+#define LIBC_sparc64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/faddr.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/sparc64/include/libarch/faddr.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_sparc64_FADDR_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define FADDR(fptr)		((uintptr_t) (fptr))
Index: uspace/lib/c/arch/sparc64/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/inttypes.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/sparc64/include/libarch/inttypes.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,8 @@
 #define LIBC_sparc64_INTTYPES_H_
 
+#define PRIdPTR  PRId64  /**< Format for intptr_t. */
+#define PRIuPTR  PRIu64  /**< Format for uintptr_t. */
+#define PRIxPTR  PRIx64  /**< Format for hexadecimal uintptr_t. */
+
 #define PRIdn  PRId64  /**< Format for native_t. */
 #define PRIun  PRIu64  /**< Format for sysarg_t. */
Index: uspace/lib/c/arch/sparc64/include/libarch/stddef.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/sparc64/include/libarch/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 
 typedef uint64_t size_t;
+typedef int64_t ssize_t;
 typedef int64_t ptrdiff_t;
 
Index: uspace/lib/c/arch/sparc64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/syscall.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/sparc64/include/libarch/syscall.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #include <stdint.h>
 #include <abi/syscall.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define __syscall0	__syscall
Index: uspace/lib/c/arch/sparc64/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/arch/sparc64/include/libarch/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,6 +48,4 @@
 typedef int64_t native_t;
 
-typedef int64_t ssize_t;
-
 typedef uint64_t atomic_count_t;
 typedef int64_t atomic_signed_t;
Index: uspace/lib/c/generic/adt/hash_table.c
===================================================================
--- uspace/lib/c/generic/adt/hash_table.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/adt/hash_table.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -190,5 +190,4 @@
  *
  * @param h    Hash table.
- * @param key  Array of all keys necessary to compute hash index.
  * @param item Item to be inserted into the hash table.
  */
@@ -210,5 +209,4 @@
  *
  * @param h    Hash table.
- * @param key  Array of all keys necessary to compute hash index.
  * @param item Item to be inserted into the hash table.
  * 
Index: uspace/lib/c/generic/adt/list.c
===================================================================
--- uspace/lib/c/generic/adt/list.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/adt/list.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -69,24 +69,26 @@
 }
 
-/** Concatenate two lists
+/** Moves items of one list into another after the specified item.
  *
- * Concatenate lists @a list1 and @a list2, producing a single
- * list @a list1 containing items from both (in @a list1, @a list2
- * order) and empty list @a list2.
+ * Inserts all items of @a list after item at @a pos in another list.
+ * Both lists may be empty.
  *
- * @param list1		First list and concatenated output
- * @param list2 	Second list and empty output.
- *
+ * @param list Source list to move after pos. Empty afterwards.
+ * @param pos Source items will be placed after this item.
  */
-void list_concat(list_t *list1, list_t *list2)
+void list_splice(list_t *list, link_t *pos)
 {
-	if (list_empty(list2))
+	if (list_empty(list)) 
 		return;
-
-	list2->head.next->prev = list1->head.prev;
-	list2->head.prev->next = &list1->head;
-	list1->head.prev->next = list2->head.next;
-	list1->head.prev = list2->head.prev;
-	list_initialize(list2);
+	
+	/* Attach list to destination. */
+	list->head.next->prev = pos;
+	list->head.prev->next = pos->next;
+	
+	/* Link destination list to the added list. */
+	pos->next->prev = list->head.prev;
+	pos->next = list->head.next;
+	
+	list_initialize(list);
 }
 
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/async.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -106,4 +106,5 @@
 #include <fibril.h>
 #include <adt/hash_table.h>
+#include <adt/hash.h>
 #include <adt/list.h>
 #include <assert.h>
@@ -587,7 +588,17 @@
 };
 
-/** Compute hash into the connection hash table based on the source phone hash.
- *
- * @param key Pointer to source phone hash.
+typedef struct {
+	task_id_t task_id;
+	sysarg_t phone_hash;
+} conn_key_t;
+
+/** Compute hash into the connection hash table
+ *
+ * The hash is based on the source task ID and the source phone hash. The task
+ * ID is included in the hash because a phone hash alone might not be unique
+ * while we still track connections for killed tasks due to kernel's recycling
+ * of phone structures.
+ *
+ * @param key Pointer to the connection key structure.
  *
  * @return Index into the connection hash table.
@@ -596,6 +607,11 @@
 static size_t conn_key_hash(void *key)
 {
-	sysarg_t in_phone_hash = *(sysarg_t *) key;
-	return in_phone_hash;
+	conn_key_t *ck = (conn_key_t *) key;
+
+	size_t hash = 0;
+	hash = hash_combine(hash, LOWER32(ck->task_id));
+	hash = hash_combine(hash, UPPER32(ck->task_id));
+	hash = hash_combine(hash, ck->phone_hash);
+	return hash;
 }
 
@@ -603,12 +619,16 @@
 {
 	connection_t *conn = hash_table_get_inst(item, connection_t, link);
-	return conn_key_hash(&conn->in_phone_hash);
+	return conn_key_hash(&(conn_key_t){
+		.task_id = conn->in_task_id,
+		.phone_hash = conn->in_phone_hash
+	});
 }
 
 static bool conn_key_equal(void *key, const ht_link_t *item)
 {
-	sysarg_t in_phone_hash = *(sysarg_t *) key;
+	conn_key_t *ck = (conn_key_t *) key;
 	connection_t *conn = hash_table_get_inst(item, connection_t, link);
-	return (in_phone_hash == conn->in_phone_hash);
+	return ((ck->task_id == conn->in_task_id) &&
+	    (ck->phone_hash == conn->in_phone_hash));
 }
 
@@ -716,5 +736,8 @@
 	 */
 	futex_down(&async_futex);
-	hash_table_remove(&conn_hash_table, &fibril_connection->in_phone_hash);
+	hash_table_remove(&conn_hash_table, &(conn_key_t){
+		.task_id = fibril_connection->in_task_id,
+		.phone_hash = fibril_connection->in_phone_hash
+	});
 	futex_up(&async_futex);
 	
@@ -951,5 +974,8 @@
 	futex_down(&async_futex);
 	
-	ht_link_t *link = hash_table_find(&conn_hash_table, &call->in_phone_hash);
+	ht_link_t *link = hash_table_find(&conn_hash_table, &(conn_key_t){
+		.task_id = call->in_task_id,
+		.phone_hash = call->in_phone_hash
+	});
 	if (!link) {
 		futex_up(&async_futex);
@@ -1022,14 +1048,14 @@
  *
  * @param inr     IRQ number.
- * @param devno   Device number of the device generating inr.
  * @param handler Notification handler.
  * @param data    Notification handler client data.
  * @param ucode   Top-half pseudocode handler.
  *
- * @return Zero on success or a negative error code.
- *
- */
-int async_irq_subscribe(int inr, int devno,
-    async_notification_handler_t handler, void *data, const irq_code_t *ucode)
+ * @return IRQ capability handle on success.
+ * @return Negative error code.
+ *
+ */
+int async_irq_subscribe(int inr, async_notification_handler_t handler,
+    void *data, const irq_code_t *ucode)
 {
 	notification_t *notification =
@@ -1051,21 +1077,20 @@
 	futex_up(&async_futex);
 	
-	return ipc_irq_subscribe(inr, devno, imethod, ucode);
+	return ipc_irq_subscribe(inr, imethod, ucode);
 }
 
 /** Unsubscribe from IRQ notification.
  *
- * @param inr     IRQ number.
- * @param devno   Device number of the device generating inr.
+ * @param cap     IRQ capability handle. 
  *
  * @return Zero on success or a negative error code.
  *
  */
-int async_irq_unsubscribe(int inr, int devno)
+int async_irq_unsubscribe(int cap)
 {
 	// TODO: Remove entry from hash table
 	//       to avoid memory leak
 	
-	return ipc_irq_unsubscribe(inr, devno);
+	return ipc_irq_unsubscribe(cap);
 }
 
@@ -1358,14 +1383,4 @@
 		async_new_connection(call->in_task_id, in_phone_hash, callid,
 		    call, handler, data);
-		return;
-	}
-	
-	/* Cloned connection */
-	if (IPC_GET_IMETHOD(*call) == IPC_M_CLONE_ESTABLISH) {
-		// TODO: Currently ignores ports altogether
-		
-		/* Open new connection with fibril, etc. */
-		async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
-		    callid, call, fallback_port_handler, fallback_port_data);
 		return;
 	}
@@ -2085,76 +2100,4 @@
 	
 	return EOK;
-}
-
-/** Wrapper for making IPC_M_CLONE_ESTABLISH calls using the async framework.
- *
- * Ask for a cloned connection to some service.
- *
- * @param mgmt Exchange management style.
- * @param exch Exchange for sending the message.
- *
- * @return New session on success or NULL on error.
- *
- */
-async_sess_t *async_clone_establish(exch_mgmt_t mgmt, async_exch_t *exch)
-{
-	if (exch == NULL) {
-		errno = ENOENT;
-		return NULL;
-	}
-	
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
-	if (sess == NULL) {
-		errno = ENOMEM;
-		return NULL;
-	}
-	
-	ipc_call_t result;
-	
-	amsg_t *msg = amsg_create();
-	if (!msg) {
-		free(sess);
-		errno = ENOMEM;
-		return NULL;
-	}
-	
-	msg->dataptr = &result;
-	msg->wdata.active = true;
-	
-	ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg,
-	    reply_received);
-	
-	sysarg_t rc;
-	async_wait_for((aid_t) msg, &rc);
-	
-	if (rc != EOK) {
-		errno = rc;
-		free(sess);
-		return NULL;
-	}
-	
-	int phone = (int) IPC_GET_ARG5(result);
-	
-	if (phone < 0) {
-		errno = phone;
-		free(sess);
-		return NULL;
-	}
-	
-	sess->iface = 0;
-	sess->mgmt = mgmt;
-	sess->phone = phone;
-	sess->arg1 = 0;
-	sess->arg2 = 0;
-	sess->arg3 = 0;
-	
-	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-	
-	list_initialize(&sess->exch_list);
-	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
-	
-	return sess;
 }
 
@@ -3127,64 +3070,4 @@
 }
 
-/** Wrapper for sending an exchange over different exchange for cloning
- *
- * @param exch       Exchange to be used for sending.
- * @param clone_exch Exchange to be cloned.
- *
- */
-int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)
-{
-	return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);
-}
-
-/** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.
- *
- * If the current call is IPC_M_CONNECTION_CLONE then a new
- * async session is created for the accepted phone.
- *
- * @param mgmt Exchange management style.
- *
- * @return New async session or NULL on failure.
- *
- */
-async_sess_t *async_clone_receive(exch_mgmt_t mgmt)
-{
-	/* Accept the phone */
-	ipc_call_t call;
-	ipc_callid_t callid = async_get_call(&call);
-	int phone = (int) IPC_GET_ARG1(call);
-	
-	if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
-	    (phone < 0)) {
-		async_answer_0(callid, EINVAL);
-		return NULL;
-	}
-	
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
-	if (sess == NULL) {
-		async_answer_0(callid, ENOMEM);
-		return NULL;
-	}
-	
-	sess->iface = 0;
-	sess->mgmt = mgmt;
-	sess->phone = phone;
-	sess->arg1 = 0;
-	sess->arg2 = 0;
-	sess->arg3 = 0;
-	
-	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-	
-	list_initialize(&sess->exch_list);
-	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
-	
-	/* Acknowledge the cloned phone */
-	async_answer_0(callid, EOK);
-	
-	return sess;
-}
-
 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
  *
Index: uspace/lib/c/generic/bd.c
===================================================================
--- uspace/lib/c/generic/bd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/bd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,5 @@
 #include <macros.h>
 #include <stdlib.h>
-#include <sys/types.h>
+#include <offset.h>
 
 static void bd_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
Index: uspace/lib/c/generic/cap.c
===================================================================
--- uspace/lib/c/generic/cap.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/cap.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2015 Jiri Svoboda
  * All rights reserved.
  *
@@ -31,51 +31,254 @@
  */
 /**
- * @file  cap.c
- * @brief Functions to grant/revoke capabilities to/from a task.
+ * @file Storage capacity specification.
  */
 
 #include <cap.h>
-#include <task.h>
-#include <libc.h>
-#include <libarch/types.h>
-
-/** Grant capabilities to a task.
- *
- * @param id   Destination task ID.
- * @param caps Capabilities to grant.
- *
- * @return Zero on success or a value from @ref errno.h on failure.
- *
- */
-int cap_grant(task_id_t id, unsigned int caps)
-{
-#ifdef __32_BITS__
-	sysarg64_t arg = (sysarg64_t) id;
-	return __SYSCALL2(SYS_CAP_GRANT, (sysarg_t) &arg, (sysarg_t) caps);
-#endif
-	
-#ifdef __64_BITS__
-	return __SYSCALL2(SYS_CAP_GRANT, (sysarg_t) id, (sysarg_t) caps);
-#endif
-}
-
-/** Revoke capabilities from a task.
- *
- * @param id   Destination task ID.
- * @param caps Capabilities to revoke.
- *
- * @return Zero on success or a value from @ref errno.h on failure.
- *
- */
-int cap_revoke(task_id_t id, unsigned int caps)
-{
-#ifdef __32_BITS__
-	sysarg64_t arg = (sysarg64_t) id;
-	return __SYSCALL2(SYS_CAP_REVOKE, (sysarg_t) &arg, (sysarg_t) caps);
-#endif
-	
-#ifdef __64_BITS__
-	return __SYSCALL2(SYS_CAP_REVOKE, (sysarg_t) id, (sysarg_t) caps);
-#endif
+#include <errno.h>
+#include <imath.h>
+#include <stdio.h>
+#include <str.h>
+
+/** Simplified capacity parameters */
+enum {
+	/** Simplified capacity maximum integer digits */
+	scap_max_idig = 3,
+	/** Simplified capacity maximum significant digits */
+	scap_max_sdig = 4
+};
+
+static const char *cu_str[] = {
+	[cu_byte] = "B",
+	[cu_kbyte] = "kB",
+	[cu_mbyte] = "MB",
+	[cu_gbyte] = "GB",
+	[cu_tbyte] = "TB",
+	[cu_pbyte] = "PB",
+	[cu_ebyte] = "EB",
+	[cu_zbyte] = "ZB",
+	[cu_ybyte] = "YB"
+};
+
+void cap_from_blocks(uint64_t nblocks, size_t block_size, cap_spec_t *cap)
+{
+	uint64_t tsize;
+
+	tsize = nblocks * block_size;
+	cap->m = tsize;
+	cap->dp = 0;
+	cap->cunit = cu_byte;
+}
+
+/** Convert capacity to blocks.
+ *
+ * If the value of bytes is not integer, it is properly rounded. If the number
+ * of bytes is not divisible by the number of blocks, it is rounded
+ * up to an integer number of blocks.
+ *
+ * A capacity value entails precision, i.e. it corresponds to a range
+ * of values. @a cvsel selects the value to return. @c cv_nom gives
+ * the nominal (middle) value, @c cv_min gives the minimum value
+ * and @c cv_max gives the maximum value.
+ */
+int cap_to_blocks(cap_spec_t *cap, cap_vsel_t cvsel, size_t block_size,
+    uint64_t *rblocks)
+{
+	int exp;
+	uint64_t bytes;
+	uint64_t f;
+	uint64_t adj;
+	uint64_t blocks;
+	uint64_t rem;
+	int rc;
+
+	exp = cap->cunit * 3 - cap->dp;
+	if (exp < 0) {
+		rc = ipow10_u64(-exp, &f);
+		if (rc != EOK)
+			return ERANGE;
+		bytes = (cap->m + (f / 2)) / f;
+		if (bytes * f - (f / 2) != cap->m)
+			return ERANGE;
+	} else {
+		rc = ipow10_u64(exp, &f);
+		if (rc != EOK)
+			return ERANGE;
+
+		adj = 0;
+		switch (cvsel) {
+		case cv_nom:
+			adj = 0;
+			break;
+		case cv_min:
+			adj = -(f / 2);
+			break;
+		case cv_max:
+			adj = f / 2 - 1;
+			break;
+		}
+
+		bytes = cap->m * f + adj;
+		if ((bytes - adj) / f != cap->m)
+			return ERANGE;
+	}
+
+	rem = bytes % block_size;
+	if ((bytes + rem) < bytes)
+		return ERANGE;
+
+	blocks = (bytes + rem) / block_size;
+
+	*rblocks = blocks;
+	return EOK;
+}
+
+/** Simplify and round capacity to a human-friendly form.
+ *
+ * Change unit and round the number so that we have at most three integer
+ * digits and at most two fractional digits, e.g abc.xy <unit>.
+ */
+void cap_simplify(cap_spec_t *cap)
+{
+	uint64_t div;
+	uint64_t maxv;
+	unsigned sdig;
+	unsigned rdig;
+	int rc;
+
+	/* Change units so that we have at most @c scap_max_idig integer digits */
+	rc = ipow10_u64(scap_max_idig, &maxv);
+	assert(rc == EOK);
+
+	rc = ipow10_u64(cap->dp, &div);
+	assert(rc == EOK);
+
+	while (cap->m / div >= maxv) {
+		++cap->cunit;
+		cap->dp += 3;
+		div = div * 1000;
+	}
+
+	/* Round the number so that we have at most @c scap_max_sdig significant digits */
+	sdig = 1 + ilog10_u64(cap->m); /* number of significant digits */
+	if (sdig > scap_max_sdig) {
+		/* Number of digits to remove */
+		rdig = sdig - scap_max_sdig;
+		if (rdig > cap->dp)
+			rdig = cap->dp;
+
+		rc = ipow10_u64(rdig, &div);
+		assert(rc == EOK);
+
+		cap->m = (cap->m + (div / 2)) / div;
+		cap->dp -= rdig;
+	}
+}
+
+int cap_format(cap_spec_t *cap, char **rstr)
+{
+	int rc;
+	const char *sunit;
+	uint64_t ipart;
+	uint64_t fpart;
+	uint64_t div;
+
+	sunit = NULL;
+
+	assert(cap->cunit < CU_LIMIT);
+
+	rc = ipow10_u64(cap->dp, &div);
+	if (rc != EOK)
+		return rc;
+
+	ipart = cap->m / div;
+	fpart = cap->m % div;
+
+	sunit = cu_str[cap->cunit];
+	if (cap->dp > 0) {
+		rc = asprintf(rstr, "%" PRIu64 ".%0*" PRIu64 " %s", ipart,
+		    (int)cap->dp, fpart, sunit);
+	} else {
+		rc = asprintf(rstr, "%" PRIu64 " %s", ipart, sunit);
+	}
+	if (rc < 0)
+		return ENOMEM;
+
+	return EOK;
+}
+
+static int cap_digit_val(char c, int *val)
+{
+	switch (c) {
+	case '0': *val = 0; break;
+	case '1': *val = 1; break;
+	case '2': *val = 2; break;
+	case '3': *val = 3; break;
+	case '4': *val = 4; break;
+	case '5': *val = 5; break;
+	case '6': *val = 6; break;
+	case '7': *val = 7; break;
+	case '8': *val = 8; break;
+	case '9': *val = 9; break;
+	default:
+		return EINVAL;
+	}
+
+	return EOK;
+}
+
+int cap_parse(const char *str, cap_spec_t *cap)
+{
+	const char *eptr;
+	const char *p;
+	int d;
+	int dp;
+	unsigned long m;
+	int i;
+
+	m = 0;
+
+	eptr = str;
+	while (cap_digit_val(*eptr, &d) == EOK) {
+		m = m * 10 + d;
+		++eptr;
+	}
+
+	if (*eptr == '.') {
+		++eptr;
+		dp = 0;
+		while (cap_digit_val(*eptr, &d) == EOK) {
+			m = m * 10 + d;
+			++dp;
+			++eptr;
+		}
+	} else {
+		dp = 0;
+	}
+
+	while (*eptr == ' ')
+		++eptr;
+
+	if (*eptr == '\0') {
+		cap->cunit = cu_byte;
+	} else {
+		for (i = 0; i < CU_LIMIT; i++) {
+			if (str_lcasecmp(eptr, cu_str[i],
+			    str_length(cu_str[i])) == 0) {
+				p = eptr + str_size(cu_str[i]);
+				while (*p == ' ')
+					++p;
+				if (*p == '\0')
+					goto found;
+			}
+		}
+
+		return EINVAL;
+found:
+		cap->cunit = i;
+	}
+
+	cap->m = m;
+	cap->dp = dp;
+	return EOK;
 }
 
Index: uspace/lib/c/generic/clipboard.c
===================================================================
--- uspace/lib/c/generic/clipboard.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/clipboard.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,13 +38,13 @@
  */
 
+#include <async.h>
 #include <clipboard.h>
-#include <ns.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <ipc/clipboard.h>
 #include <ipc/services.h>
-#include <ipc/clipboard.h>
-#include <fibril_synch.h>
-#include <async.h>
+#include <loc.h>
+#include <malloc.h>
 #include <str.h>
-#include <errno.h>
-#include <malloc.h>
 
 static FIBRIL_MUTEX_INITIALIZE(clip_mutex);
@@ -58,9 +58,18 @@
 static async_exch_t *clip_exchange_begin(void)
 {
+	service_id_t sid;
+	int rc;
+	
 	fibril_mutex_lock(&clip_mutex);
 	
-	while (clip_sess == NULL)
-		clip_sess = service_connect_blocking(SERVICE_CLIPBOARD,
-		    INTERFACE_CLIPBOARD, 0);
+	while (clip_sess == NULL) {
+		rc = loc_service_get_id(SERVICE_NAME_CLIPBOARD, &sid,
+		    IPC_FLAG_BLOCKING);
+		if (rc != EOK)
+			continue;
+		
+		clip_sess = loc_service_connect(sid, INTERFACE_CLIPBOARD,
+		    IPC_FLAG_BLOCKING);
+	}
 	
 	fibril_mutex_unlock(&clip_mutex);
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/ddi.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -51,17 +51,7 @@
 
 
-/** Return unique device number.
- *
- * @return New unique device number.
- *
- */
-int device_assign_devno(void)
-{
-	return __SYSCALL0(SYS_DEVICE_ASSIGN_DEVNO);
-}
-
 /** Map a piece of physical memory to task.
  *
- * Caller of this function must have the CAP_MEM_MANAGER capability.
+ * Caller of this function must have the PERM_MEM_MANAGER permission.
  *
  * @param phys  Physical address of the starting frame.
@@ -74,5 +64,5 @@
  *
  * @return EOK on success.
- * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability.
+ * @return EPERM if the caller lacks the PERM_MEM_MANAGER permission.
  * @return ENOMEM if there was some problem in creating
  *         the address space area.
@@ -87,10 +77,10 @@
 /** Unmap a piece of physical memory to task.
  *
- * Caller of this function must have the CAP_MEM_MANAGER capability.
+ * Caller of this function must have the PERM_MEM_MANAGER permission.
  *
  * @param virt Virtual address from the phys-mapped region.
  *
  * @return EOK on success.
- * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability.
+ * @return EPERM if the caller lacks the PERM_MEM_MANAGER permission.
  *
  */
@@ -106,5 +96,5 @@
  * make it safe for DMA transferts.
  *
- * Caller of this function must have the CAP_MEM_MANAGER capability.
+ * Caller of this function must have the PERM_MEM_MANAGER permission.
  *
  * @param virt      Virtual address of the memory to be locked.
@@ -115,5 +105,5 @@
  *
  * @return EOK on success.
- * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability.
+ * @return EPERM if the caller lacks the PERM_MEM_MANAGER permission.
  * @return ENOMEM if there was some problem in creating
  *         the address space area.
@@ -130,5 +120,5 @@
 /** Map a piece of physical memory suitable for DMA transfers.
  *
- * Caller of this function must have the CAP_MEM_MANAGER capability.
+ * Caller of this function must have the PERM_MEM_MANAGER permission.
  *
  * @param size       Number of bytes to map.
@@ -143,5 +133,5 @@
  *
  * @return EOK on success.
- * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability.
+ * @return EPERM if the caller lacks the PERM_MEM_MANAGER permission.
  * @return ENOMEM if there was some problem in creating
  *         the address space area.
@@ -171,5 +161,5 @@
 /** Enable I/O space range to task.
  *
- * Caller of this function must have the IO_MEM_MANAGER capability.
+ * Caller of this function must have the PERM_IO_MANAGER permission.
  *
  * @param id     Task ID.
@@ -178,5 +168,5 @@
  *
  * @return EOK on success
- * @return EPERM if the caller lacks the CAP_IO_MANAGER capability
+ * @return EPERM if the caller lacks the PERM_IO_MANAGER permission
  * @return ENOENT if there is no task with specified ID
  * @return ENOMEM if there was some problem in allocating memory.
@@ -196,5 +186,5 @@
 /** Disable I/O space range to task.
  *
- * Caller of this function must have the IO_MEM_MANAGER capability.
+ * Caller of this function must have the PERM_IO_MANAGER permission.
  *
  * @param id     Task ID.
@@ -203,5 +193,5 @@
  *
  * @return EOK on success
- * @return EPERM if the caller lacks the CAP_IO_MANAGER capability
+ * @return EPERM if the caller lacks the PERM_IO_MANAGER permission
  * @return ENOENT if there is no task with specified ID
  *
Index: uspace/lib/c/generic/device/hw_res.c
===================================================================
--- uspace/lib/c/generic/device/hw_res.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/device/hw_res.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -75,13 +75,35 @@
 }
 
-bool hw_res_enable_interrupt(async_sess_t *sess)
+int hw_res_enable_interrupt(async_sess_t *sess, int irq)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
 	
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
-	    HW_RES_ENABLE_INTERRUPT);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_ENABLE_INTERRUPT, irq);
 	async_exchange_end(exch);
 	
-	return (rc == EOK);
+	return rc;
+}
+
+int hw_res_disable_interrupt(async_sess_t *sess, int irq)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_DISABLE_INTERRUPT, irq);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+int hw_res_clear_interrupt(async_sess_t *sess, int irq)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_CLEAR_INTERRUPT, irq);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/devman.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,5 +45,4 @@
 #include <errno.h>
 #include <malloc.h>
-#include <stdbool.h>
 
 static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex);
Index: uspace/lib/c/generic/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/fibril_synch.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/fibril_synch.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -629,4 +629,40 @@
 }
 
+/** Delay fibril execution for the specified number of microseconds
+ *
+ * @param usec Number of microseconds to sleep
+ */
+void fibril_usleep(useconds_t usec)
+{
+	fibril_condvar_t cv;
+	fibril_mutex_t lock;
+
+	fibril_condvar_initialize(&cv);
+	fibril_mutex_initialize(&lock);
+	fibril_mutex_lock(&lock);
+	fibril_condvar_wait_timeout(&cv, &lock, usec);
+	fibril_mutex_unlock(&lock);
+}
+
+/** Delay fibril execution for the specified number of seconds
+ *
+ * @param sec Number of seconds to sleep
+ */
+void fibril_sleep(unsigned int sec)
+{
+	/*
+	 * Sleep in 1000 second steps to support
+	 * full argument range
+	 */
+
+	while (sec > 0) {
+		unsigned int period = (sec > 1000) ? 1000 : sec;
+
+		fibril_usleep(period * 1000000);
+		sec -= period;
+	}
+}
+
+
 /** @}
  */
Index: uspace/lib/c/generic/getopt.c
===================================================================
--- uspace/lib/c/generic/getopt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/getopt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,7 +34,7 @@
 #include <assert.h>
 #include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
-#include <err.h>
 #include <errno.h>
 #include <getopt.h>
Index: uspace/lib/c/generic/gsort.c
===================================================================
--- uspace/lib/c/generic/gsort.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/generic/gsort.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2005 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 libc
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Sorting functions.
+ *
+ * This files contains functions implementing several sorting
+ * algorithms (e.g. quick sort and gnome sort).
+ *
+ */
+
+#include <gsort.h>
+#include <mem.h>
+#include <malloc.h>
+
+/** Immediate buffer size.
+ *
+ * For small buffer sizes avoid doing malloc()
+ * and use the stack.
+ *
+ */
+#define IBUF_SIZE  32
+
+/** Array accessor.
+ *
+ */
+#define INDEX(buf, i, elem_size)  ((buf) + (i) * (elem_size))
+
+/** Gnome sort
+ *
+ * Apply generic gnome sort algorithm on supplied data,
+ * using pre-allocated buffer.
+ *
+ * @param data      Pointer to data to be sorted.
+ * @param cnt       Number of elements to be sorted.
+ * @param elem_size Size of one element.
+ * @param cmp       Comparator function.
+ * @param arg       3rd argument passed to cmp.
+ * @param slot      Pointer to scratch memory buffer
+ *                  elem_size bytes long.
+ *
+ */
+static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
+    void *arg, void *slot)
+{
+	size_t i = 0;
+	
+	while (i < cnt) {
+		if ((i != 0) &&
+		    (cmp(INDEX(data, i, elem_size),
+		    INDEX(data, i - 1, elem_size), arg) == -1)) {
+			memcpy(slot, INDEX(data, i, elem_size), elem_size);
+			memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
+			    elem_size);
+			memcpy(INDEX(data, i - 1, elem_size), slot, elem_size);
+			i--;
+		} else
+			i++;
+	}
+}
+
+/** Gnome sort wrapper
+ *
+ * This is only a wrapper that takes care of memory
+ * allocations for storing the slot element for generic
+ * gnome sort algorithm.
+ *
+ * @param data      Pointer to data to be sorted.
+ * @param cnt       Number of elements to be sorted.
+ * @param elem_size Size of one element.
+ * @param cmp       Comparator function.
+ * @param arg       3rd argument passed to cmp.
+ *
+ * @return True if sorting succeeded.
+ *
+ */
+bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
+{
+	uint8_t ibuf_slot[IBUF_SIZE];
+	void *slot;
+	
+	if (elem_size > IBUF_SIZE) {
+		slot = (void *) malloc(elem_size);
+		if (!slot)
+			return false;
+	} else
+		slot = (void *) ibuf_slot;
+	
+	_gsort(data, cnt, elem_size, cmp, arg, slot);
+	
+	if (elem_size > IBUF_SIZE)
+		free(slot);
+	
+	return true;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/inet/udp.c
===================================================================
--- uspace/lib/c/generic/inet/udp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/inet/udp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -227,4 +227,20 @@
 }
 
+/** Set UDP association sending messages with no local address
+ *
+ * @param assoc Association
+ * @param flags Flags
+ */
+int udp_assoc_set_nolocal(udp_assoc_t *assoc)
+{
+	async_exch_t *exch;
+
+	exch = async_exchange_begin(assoc->udp->sess);
+	sysarg_t rc = async_req_1_0(exch, UDP_ASSOC_SET_NOLOCAL, assoc->id);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
 /** Send message via UDP association.
  *
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/io/io.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -793,5 +793,5 @@
 }
 
-int fseek(FILE *stream, off64_t offset, int whence)
+int fseek(FILE *stream, long offset, int whence)
 {
 	int rc;
@@ -831,8 +831,8 @@
 }
 
-off64_t ftell(FILE *stream)
+long ftell(FILE *stream)
 {
 	/* The native position is too large for the C99-ish interface. */
-	if (stream->pos - stream->ungetc_chars > INT64_MAX)
+	if (stream->pos - stream->ungetc_chars > LONG_MAX)
 		return EOF;
 
Index: uspace/lib/c/generic/io/table.c
===================================================================
--- uspace/lib/c/generic/io/table.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/generic/io/table.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,565 @@
+/*
+ * Copyright (c) 2017 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
+ * @brief Tabulate text
+ */
+
+#include <errno.h>
+#include <io/table.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static table_column_t *table_column_first(table_t *);
+static table_column_t *table_column_next(table_column_t *);
+
+/** Add a new row at the end of the table.
+ *
+ * @param table Table
+ * @param rrow Place to store pointer to new row or @c NULL
+ *
+ * @return EOK on success, ENOMEM if out of memory
+ */
+static int table_add_row(table_t *table, table_row_t **rrow)
+{
+	table_row_t *row;
+
+	row = calloc(1, sizeof(table_row_t));
+	if (row == NULL)
+		return ENOMEM;
+
+	row->table = table;
+	list_initialize(&row->cells);
+	list_append(&row->ltable, &table->rows);
+
+	if (rrow != NULL)
+		*rrow = row;
+	return EOK;
+}
+
+/** Add a new cell at the end of the row.
+ *
+ * @param row Row
+ * @param rcell Place to store pointer to new cell or @c NULL
+ * @return EOK on success, ENOMEM if out of memory
+ */
+static int table_row_add_cell(table_row_t *row, table_cell_t **rcell)
+{
+	table_cell_t *cell;
+
+	cell = calloc(1, sizeof(table_cell_t));
+	if (cell == NULL)
+		return ENOMEM;
+
+	cell->text = NULL;
+
+	cell->row = row;
+	list_append(&cell->lrow, &row->cells);
+
+	if (rcell != NULL)
+		*rcell = cell;
+	return EOK;
+}
+
+/** Add a new column at the right side of the table.
+ *
+ * @param table Table
+ * @param rcolumn Place to store pointer to new column or @c NULL
+ *
+ * @return EOK on success, ENOMEM if out of memory
+ */
+static int table_add_column(table_t *table, table_column_t **rcolumn)
+{
+	table_column_t *column;
+
+	column = calloc(1, sizeof(table_column_t));
+	if (column == NULL)
+		return ENOMEM;
+
+	column->table = table;
+	column->width = 0;
+	list_append(&column->ltable, &table->columns);
+
+	if (rcolumn != NULL)
+		*rcolumn = column;
+	return EOK;
+}
+
+/** Start writing next table cell.
+ *
+ * @param table Table
+ * @return EOK on success, ENOMEM if out of memory
+ */
+static int table_write_next_cell(table_t *table)
+{
+	int rc;
+
+	rc = table_row_add_cell(table->wrow, &table->wcell);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		return rc;
+	}
+
+	if (list_count(&table->wrow->cells) == 1) {
+		/* First column */
+		table->wcolumn = table_column_first(table);
+	} else {
+		/* Next column */
+		table->wcolumn = table_column_next(table->wcolumn);
+	}
+
+	if (table->wcolumn == NULL) {
+		rc = table_add_column(table, &table->wcolumn);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			return rc;
+		}
+	}
+
+	return EOK;
+}
+
+/** Start writing next table row.
+ *
+ * @param table Table
+ * @return EOK on success, ENOMEM if out of memory
+ */
+static int table_write_next_row(table_t *table)
+{
+	int rc;
+
+	rc = table_add_row(table, &table->wrow);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		return rc;
+	}
+
+	table->wcell = NULL;
+	return EOK;
+}
+
+/** Get first table row.
+ *
+ * @param table Table
+ * @return First table row or @c NULL if none
+ */
+static table_row_t *table_row_first(table_t *table)
+{
+	link_t *link;
+
+	link = list_first(&table->rows);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, table_row_t, ltable);
+}
+
+/** Get next table row.
+ *
+ * @param cur Current row
+ * @return Next table row or @c NULL if none
+ */
+static table_row_t *table_row_next(table_row_t *cur)
+{
+	link_t *link;
+
+	link = list_next(&cur->ltable, &cur->table->rows);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, table_row_t, ltable);
+}
+
+/** Get first cell in table row.
+ *
+ * @param row Table row
+ * @return First cell in row or @c NULL if none
+ */
+static table_cell_t *table_row_cell_first(table_row_t *row)
+{
+	link_t *link;
+
+	link = list_first(&row->cells);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, table_cell_t, lrow);
+}
+
+/** Get next cell in table row.
+ *
+ * @param cur Current cell
+ * @return Next cell in table row or @c NULL if none
+ */
+static table_cell_t *table_row_cell_next(table_cell_t *cur)
+{
+	link_t *link;
+
+	link = list_next(&cur->lrow, &cur->row->cells);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, table_cell_t, lrow);
+}
+
+/** Get first table column.
+ *
+ * @param table Table
+ * @return First table column or @c NULL if none
+ */
+static table_column_t *table_column_first(table_t *table)
+{
+	link_t *link;
+
+	link = list_first(&table->columns);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, table_column_t, ltable);
+}
+
+/** Get next table column.
+ *
+ * @param cur Current column
+ * @return Next table column or @c NULL if none
+ */
+static table_column_t *table_column_next(table_column_t *cur)
+{
+	link_t *link;
+
+	link = list_next(&cur->ltable, &cur->table->columns);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, table_column_t, ltable);
+}
+
+/** Append to cell text.
+ *
+ * @param cell Cell
+ * @param str Text to append
+ * @param len Max number of bytes to read from str
+ * @return EOK on success, ENOMEM if out of memory
+ */
+static int table_cell_extend(table_cell_t *cell, const char *str, size_t len)
+{
+	char *cstr;
+	int rc;
+
+	if (cell->text == NULL) {
+		cell->text = str_ndup(str, len);
+		if (cell->text == NULL)
+			return ENOMEM;
+	} else {
+		rc = asprintf(&cstr, "%s%.*s", cell->text, (int)len, str);
+		if (rc < 0)
+			return ENOMEM;
+
+		free(cell->text);
+		cell->text = cstr;
+	}
+
+	return EOK;
+}
+
+/** Create table.
+ *
+ * @para, rtable Place to store pointer to new table.
+ * @return EOK on success, ENOMEM if out of memory
+ */
+int table_create(table_t **rtable)
+{
+	table_t *table;
+	int rc;
+
+	table = calloc(1, sizeof(table_t));
+	if (table == NULL)
+		return ENOMEM;
+
+	table->error = EOK;
+	list_initialize(&table->rows);
+	list_initialize(&table->columns);
+
+	rc = table_add_row(table, &table->wrow);
+	if (rc != EOK)
+		goto error;
+
+	rc = table_row_add_cell(table->wrow, &table->wcell);
+	if (rc != EOK)
+		goto error;
+
+	rc = table_add_column(table, &table->wcolumn);
+	if (rc != EOK)
+		goto error;
+
+	*rtable = table;
+	return EOK;
+error:
+	table_destroy(table);
+	return rc;
+}
+
+/** Destroy table.
+ *
+ * @param table Table
+ */
+void table_destroy(table_t *table)
+{
+	table_row_t *row;
+	table_cell_t *cell;
+	table_column_t *column;
+
+	if (table == NULL)
+		return;
+
+	row = table_row_first(table);
+	while (row != NULL) {
+		cell = table_row_cell_first(row);
+		while (cell != NULL) {
+			list_remove(&cell->lrow);
+			free(cell->text);
+			free(cell);
+			cell = table_row_cell_first(row);
+		}
+
+		list_remove(&row->ltable);
+		free(row);
+
+		row = table_row_first(table);
+	}
+
+	column = table_column_first(table);
+	while (column != NULL) {
+		list_remove(&column->ltable);
+		free(column);
+
+		column = table_column_first(table);
+	}
+
+	free(table);
+}
+
+/** Print out table contents to a file stream.
+ *
+ * @param table Table
+ * @param f File where to write the output
+ *
+ * @return EOK on success, EIO on I/O error
+ */
+int table_print_out(table_t *table, FILE *f)
+{
+	table_row_t *row;
+	table_cell_t *cell;
+	table_column_t *column;
+	bool firstc;
+	bool firstr;
+	size_t spacing;
+	size_t i;
+	int rc;
+
+	if (table->error != EOK)
+		return table->error;
+
+	row = table_row_first(table);
+	firstr = true;
+	while (row != NULL) {
+		cell = table_row_cell_first(row);
+		if (cell == NULL)
+			break;
+
+		column = table_column_first(table);
+		firstc = true;
+
+		while (cell != NULL && cell->text != NULL) {
+			spacing = firstc ? table->metrics.margin_left : 1;
+			for (i = 0; i < spacing; i++) {
+				rc = fprintf(f, " ");
+				if (rc < 0)
+					return EIO;
+			}
+
+			rc = fprintf(f, "%*s", -(int)column->width, cell->text);
+			if (rc < 0)
+				return EIO;
+
+			cell = table_row_cell_next(cell);
+			column = table_column_next(column);
+			firstc = false;
+		}
+		rc = fprintf(f, "\n");
+		if (rc < 0)
+			return EIO;
+
+		if (firstr && table->header_row) {
+			/* Display header separator */
+			column = table_column_first(table);
+			firstc = true;
+			while (column != NULL) {
+				spacing = firstc ? table->metrics.margin_left : 1;
+				for (i = 0; i < spacing; i++) {
+					rc = fprintf(f, " ");
+					if (rc < 0)
+						return EIO;
+				}
+
+				for (i = 0; i < column->width; i++) {
+					rc = fprintf(f, "=");
+					if (rc < 0)
+						return EIO;
+				}
+
+				column = table_column_next(column);
+				firstc = false;
+			}
+
+			rc = fprintf(f, "\n");
+			if (rc < 0)
+				return EIO;
+		}
+
+		row = table_row_next(row);
+		firstr = false;
+	}
+	return EOK;
+}
+
+/** Start a header row.
+ *
+ * @param table Table
+ */
+void table_header_row(table_t *table)
+{
+	assert(list_count(&table->rows) == 1);
+	assert(!table->header_row);
+	table->header_row = true;
+}
+
+/** Insert text into table cell(s).
+ *
+ * Appends text to the current cell. A tab character starts a new cell.
+ * A newline character starts a new row.
+ *
+ * @param table Table
+ * @param fmt Format string
+ * @return EOK on success, ENOMEM if out of memory
+ */
+int table_printf(table_t *table, const char *fmt, ...)
+{
+	va_list args;
+	int rc;
+	char *str;
+	char *sp, *ep;
+	size_t width;
+
+	if (table->error != EOK)
+		return table->error;
+
+	va_start(args, fmt);
+	rc = vasprintf(&str, fmt, args);
+	va_end(args);
+
+	if (rc < 0) {
+		table->error = ENOMEM;
+		return table->error;
+	}
+
+	sp = str;
+	while (*sp != '\0' && table->error == EOK) {
+		ep = sp;
+		while (*ep != '\0' && *ep != '\t' && *ep != '\n')
+			++ep;
+
+		if (table->wcell == NULL) {
+			rc = table_write_next_cell(table);
+			if (rc != EOK) {
+				assert(rc == ENOMEM);
+				goto out;
+			}
+		}
+
+		rc = table_cell_extend(table->wcell, sp, ep - sp);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			table->error = ENOMEM;
+			goto out;
+		}
+
+		/* Update column width */
+		width = str_width(table->wcell->text);
+		if (width > table->wcolumn->width)
+			table->wcolumn->width = width;
+
+		if (*ep == '\t')
+			rc = table_write_next_cell(table);
+		else if (*ep == '\n')
+			rc = table_write_next_row(table);
+		else
+			break;
+
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			table->error = ENOMEM;
+			goto out;
+		}
+
+		sp = ep + 1;
+	}
+
+	rc = table->error;
+out:
+	free(str);
+	return rc;
+}
+
+/** Return table error code.
+ *
+ * @param table Table
+ * @return EOK if no error indicated, non-zero error code otherwise
+ */
+int table_get_error(table_t *table)
+{
+	return table->error;
+}
+
+/** Set left table margin.
+ *
+ * @param table Table
+ * @param mleft Left margin
+ */
+void table_set_margin_left(table_t *table, size_t mleft)
+{
+	table->metrics.margin_left = mleft;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/io/visualizer.c
===================================================================
--- uspace/lib/c/generic/io/visualizer.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/io/visualizer.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,4 +33,5 @@
  */
 
+#include <assert.h>
 #include <errno.h>
 #include <as.h>
@@ -175,9 +176,8 @@
 	sysarg_t x_offset, sysarg_t y_offset)
 {
-#ifdef __32_BITS__
+	assert(x_offset <= UINT16_MAX);
+	assert(y_offset <= UINT16_MAX);
+
 	sysarg_t offsets = ((x_offset << 16) | (y_offset & 0x0000ffff));
-#else
-	sysarg_t offsets = ((x_offset << 32) | (y_offset & 0xffffffff));
-#endif
 
 	async_exch_t *exch = async_exchange_begin(sess);
Index: uspace/lib/c/generic/irc.c
===================================================================
--- uspace/lib/c/generic/irc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/irc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,8 +35,10 @@
 #include <assert.h>
 #include <errno.h>
+#include <fibril_synch.h>
 #include <ipc/irc.h>
 #include <ipc/services.h>
 #include <irc.h>
-#include <ns.h>
+#include <loc.h>
+#include <stdlib.h>
 #include <sysinfo.h>
 
@@ -49,7 +51,31 @@
 static int irc_init(void)
 {
+	category_id_t irc_cat;
+	service_id_t *svcs;
+	size_t count;
+	int rc;
+
 	assert(irc_sess == NULL);
+	rc = loc_category_get_id("irc", &irc_cat, IPC_FLAG_BLOCKING);
+	if (rc != EOK)
+		return EIO;
 
-	irc_sess = service_connect_blocking(SERVICE_IRC, INTERFACE_IRC, 0);
+	while (true) {
+		rc = loc_category_get_svcs(irc_cat, &svcs, &count);
+		if (rc != EOK)
+			return EIO;
+
+		if (count > 0)
+			break;
+
+		free(svcs);
+
+		// XXX This is just a temporary hack
+		fibril_usleep(500 * 1000);
+	}
+
+	irc_sess = loc_service_connect(svcs[0], INTERFACE_IRC,
+	    IPC_FLAG_BLOCKING);
+	free(svcs);
 
 	if (irc_sess == NULL)
@@ -60,4 +86,6 @@
 
 /** Enable interrupt.
+ *
+ * Allow interrupt delivery.
  *
  * @param irq	IRQ number
@@ -80,10 +108,35 @@
 }
 
-
 /** Disable interrupt.
+ *
+ * Disallow interrupt delivery.
  *
  * @param irq	IRQ number
  */
 int irc_disable_interrupt(int irq)
+{
+	int rc;
+
+	if (irc_sess == NULL) {
+		rc = irc_init();
+		if (rc != EOK)
+			return rc;
+	}
+
+	async_exch_t *exch = async_exchange_begin(irc_sess);
+	rc = async_req_1_0(exch, IRC_DISABLE_INTERRUPT, irq);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+/** Clear interrupt.
+ *
+ * Clear/acknowledge interrupt in interrupt controller so that
+ * another interrupt can be delivered.
+ *
+ * @param irq	IRQ number
+ */
+int irc_clear_interrupt(int irq)
 {
 	int rc;
Index: uspace/lib/c/generic/irq.c
===================================================================
--- uspace/lib/c/generic/irq.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/irq.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -55,32 +55,29 @@
  *
  * @param inr    IRQ number.
- * @param devno  Device number of the device generating inr.
  * @param method Use this method for notifying me.
  * @param ucode  Top-half pseudocode handler.
+ *
+ * @return IRQ capability handle returned by the kernel.
+ * @return Error code returned by the kernel.
+ *
+ */
+int ipc_irq_subscribe(int inr, sysarg_t method, const irq_code_t *ucode)
+{
+	if (ucode == NULL)
+		ucode = &default_ucode;
+	
+	return __SYSCALL3(SYS_IPC_IRQ_SUBSCRIBE, inr, method, (sysarg_t) ucode);
+}
+
+/** Unsubscribe from IRQ notification.
+ *
+ * @param cap   IRQ capability handle.
  *
  * @return Value returned by the kernel.
  *
  */
-int ipc_irq_subscribe(int inr, int devno, sysarg_t method,
-    const irq_code_t *ucode)
+int ipc_irq_unsubscribe(int cap)
 {
-	if (ucode == NULL)
-		ucode = &default_ucode;
-	
-	return __SYSCALL4(SYS_IPC_IRQ_SUBSCRIBE, inr, devno, method,
-	    (sysarg_t) ucode);
-}
-
-/** Unsubscribe from IRQ notification.
- *
- * @param inr   IRQ number.
- * @param devno Device number of the device generating inr.
- *
- * @return Value returned by the kernel.
- *
- */
-int ipc_irq_unsubscribe(int inr, int devno)
-{
-	return __SYSCALL2(SYS_IPC_IRQ_UNSUBSCRIBE, inr, devno);
+	return __SYSCALL1(SYS_IPC_IRQ_UNSUBSCRIBE, cap);
 }
 
Index: uspace/lib/c/generic/ns.c
===================================================================
--- uspace/lib/c/generic/ns.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/ns.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,25 +40,49 @@
 #include "private/ns.h"
 
+/*
+ * XXX ns does not know about session_ns, so we create an extra session for
+ * actual communicaton
+ */
+static async_sess_t *sess_ns = NULL;
+
 int service_register(service_t service)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	sysarg_t retval;
+	ipc_call_t answer;
+	
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
+		return EIO;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t req = async_send_1(exch, NS_REGISTER, service, &answer);
 	int rc = async_connect_to_me(exch, 0, service, 0);
+	
 	async_exchange_end(exch);
 	
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+	
+	async_wait_for(req, &retval);
 	return rc;
 }
 
-
 async_sess_t *service_connect(service_t service, iface_t iface, sysarg_t arg3)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
-	if (!exch)
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
 		return NULL;
 	
-	async_sess_t *sess =
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (exch == NULL)
+		return NULL;
+	
+	async_sess_t *csess =
 	    async_connect_me_to_iface(exch, iface, service, arg3);
 	async_exchange_end(exch);
 	
-	if (!sess)
+	if (csess == NULL)
 		return NULL;
 	
@@ -68,7 +92,7 @@
 	 * first argument for non-initial connections.
 	 */
-	async_sess_args_set(sess, iface, arg3, 0);
+	async_sess_args_set(csess, iface, arg3, 0);
 	
-	return sess;
+	return csess;
 }
 
@@ -76,10 +100,14 @@
     sysarg_t arg3)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
-	async_sess_t *sess =
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
+		return NULL;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_sess_t *csess =
 	    async_connect_me_to_blocking_iface(exch, iface, service, arg3);
 	async_exchange_end(exch);
 	
-	if (!sess)
+	if (csess == NULL)
 		return NULL;
 	
@@ -89,7 +117,7 @@
 	 * first argument for non-initial connections.
 	 */
-	async_sess_args_set(sess, iface, arg3, 0);
+	async_sess_args_set(csess, iface, arg3, 0);
 	
-	return sess;
+	return csess;
 }
 
@@ -97,5 +125,9 @@
 int ns_ping(void)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
+		return EIO;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
 	int rc = async_req_0_0(exch, NS_PING);
 	async_exchange_end(exch);
@@ -106,5 +138,10 @@
 int ns_intro(task_id_t id)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_exch_t *exch;
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
+		return EIO;
+	
+	exch = async_exchange_begin(sess);
 	int rc = async_req_2_0(exch, NS_ID_INTRO, LOWER32(id), UPPER32(id));
 	async_exchange_end(exch);
@@ -113,4 +150,19 @@
 }
 
+async_sess_t *ns_session_get(void)
+{
+	async_exch_t *exch;
+	
+	if (sess_ns == NULL) {
+		exch = async_exchange_begin(session_ns);
+		sess_ns = async_connect_me_to_iface(exch, 0, 0, 0);
+		async_exchange_end(exch);
+		if (sess_ns == NULL)
+			return NULL;
+	}
+	
+	return sess_ns;
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/perm.c
===================================================================
--- uspace/lib/c/generic/perm.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/generic/perm.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/**
+ * @file  perm.c
+ * @brief Functions to grant/revoke permissions to/from a task.
+ */
+
+#include <perm.h>
+#include <task.h>
+#include <libc.h>
+#include <types/common.h>
+
+/** Grant permissions to a task.
+ *
+ * @param id    Destination task ID.
+ * @param perms Permissions to grant.
+ *
+ * @return Zero on success or a value from @ref errno.h on failure.
+ *
+ */
+int perm_grant(task_id_t id, unsigned int perms)
+{
+#ifdef __32_BITS__
+	sysarg64_t arg = (sysarg64_t) id;
+	return __SYSCALL2(SYS_PERM_GRANT, (sysarg_t) &arg, (sysarg_t) perms);
+#endif
+	
+#ifdef __64_BITS__
+	return __SYSCALL2(SYS_PERM_GRANT, (sysarg_t) id, (sysarg_t) perms);
+#endif
+}
+
+/** Revoke permissions from a task.
+ *
+ * @param id    Destination task ID.
+ * @param perms Permissions to revoke.
+ *
+ * @return Zero on success or a value from @ref errno.h on failure.
+ *
+ */
+int perm_revoke(task_id_t id, unsigned int perms)
+{
+#ifdef __32_BITS__
+	sysarg64_t arg = (sysarg64_t) id;
+	return __SYSCALL2(SYS_PERM_REVOKE, (sysarg_t) &arg, (sysarg_t) perms);
+#endif
+	
+#ifdef __64_BITS__
+	return __SYSCALL2(SYS_PERM_REVOKE, (sysarg_t) id, (sysarg_t) perms);
+#endif
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/qsort.c
===================================================================
--- uspace/lib/c/generic/qsort.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/generic/qsort.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2017 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
+ * @brief Quicksort.
+ */
+
+#include <qsort.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/** Quicksort spec */
+typedef struct {
+	void *base;
+	size_t nmemb;
+	size_t size;
+	int (*compar)(const void *, const void *, void *);
+	void *arg;
+} qs_spec_t;
+
+/** Comparison function wrapper.
+ *
+ * Performs qsort_r comparison using qsort comparison function
+ *
+ * @param a First element
+ * @param b Second element
+ * @param arg qsort comparison function
+ */
+static int compar_wrap(const void *a, const void *b, void *arg)
+{
+	int (*compar)(const void *, const void *) =
+	    (int (*)(const void *, const void *))arg;
+
+	return compar(a, b);
+}
+
+/** Determine if one element is less-than another element.
+ *
+ * @param qs Quicksort spec
+ * @param i First element index
+ * @param j Second element index
+ */
+static bool elem_lt(qs_spec_t *qs, size_t i, size_t j)
+{
+	const void *a;
+	const void *b;
+	int r;
+
+	a = qs->base + i * qs->size;
+	b = qs->base + j * qs->size;
+
+	r = qs->compar(a, b, qs->arg);
+
+	return r < 0;
+}
+
+/** Swap two elements.
+ *
+ * @param qs Quicksort spec
+ * @param i First element index
+ * @param j Second element index
+ */
+static void elem_swap(qs_spec_t *qs, size_t i, size_t j)
+{
+	char *a;
+	char *b;
+	char t;
+	size_t k;
+
+	a = qs->base + i * qs->size;
+	b = qs->base + j * qs->size;
+
+	for (k = 0; k < qs->size; k++) {
+		t = a[k];
+		a[k] = b[k];
+		b[k] = t;
+	}
+}
+
+/** Partition a range of indices.
+ *
+ * @param qs Quicksort spec
+ * @param lo Lower bound (inclusive)
+ * @param hi Upper bound (inclusive)
+ * @return Pivot index
+ */
+static size_t partition(qs_spec_t *qs, size_t lo, size_t hi)
+{
+	size_t pivot;
+	size_t i, j;
+
+	pivot = lo + (hi - lo) / 2;
+	i = lo;
+	j = hi;
+	while (true) {
+		while (elem_lt(qs, i, pivot))
+			++i;
+		while (elem_lt(qs, pivot, j))
+			--j;
+
+		if (i >= j)
+			return j;
+
+		elem_swap(qs, i, j);
+
+		/* Need to follow pivot movement */
+		if (i == pivot)
+			pivot = j;
+		else if (j == pivot)
+			pivot = i;
+
+		i++;
+		j--;
+	}
+}
+
+/** Sort a range of indices.
+ *
+ * @param qs Quicksort spec
+ * @param lo Lower bound (inclusive)
+ * @param hi Upper bound (inclusive)
+ */
+static void quicksort(qs_spec_t *qs, size_t lo, size_t hi)
+{
+	size_t p;
+
+	if (lo < hi) {
+		p = partition(qs, lo, hi);
+		quicksort(qs, lo, p);
+		quicksort(qs, p + 1, hi);
+	}
+}
+
+/** Quicksort.
+ *
+ * @param base Array to sort
+ * @param nmemb Number of array members
+ * @param size Size of member in bytes
+ * @param compar Comparison function
+ */
+void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *,
+    const void *))
+{
+	qs_spec_t qs;
+
+	if (nmemb == 0)
+		return;
+
+	qs.base = base;
+	qs.nmemb = nmemb;
+	qs.size = size;
+	qs.compar = compar_wrap;
+	qs.arg = compar;
+
+	quicksort(&qs, 0, nmemb - 1);
+}
+
+/** Quicksort with extra argument to comparison function.
+ *
+ * @param base Array to sort
+ * @param nmemb Number of array members
+ * @param size Size of member in bytes
+ * @param compar Comparison function
+ * @param arg Argument to comparison function
+ */
+void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *,
+    const void *, void *), void *arg)
+{
+	qs_spec_t qs;
+
+	if (nmemb == 0)
+		return;
+
+	qs.base = base;
+	qs.nmemb = nmemb;
+	qs.size = size;
+	qs.compar = compar;
+	qs.arg = arg;
+
+	quicksort(&qs, 0, nmemb - 1);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/rtld/dynamic.c
===================================================================
--- uspace/lib/c/generic/rtld/dynamic.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/rtld/dynamic.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 
 #include <stdio.h>
+#include <inttypes.h>
 
 #include <rtld/elf_dyn.h>
@@ -105,13 +106,13 @@
 	info->dynamic = dyn_ptr;
 
-	DPRINTF("str_tab=0x%x, soname_idx=0x%x, soname=0x%x\n",
+	DPRINTF("str_tab=0x%" PRIxPTR ", soname_idx=0x%x, soname=0x%" PRIxPTR "\n",
 		(uintptr_t)info->soname, soname_idx, (uintptr_t)info->soname);
 	DPRINTF("soname='%s'\n", info->soname);
 	DPRINTF("rpath='%s'\n", info->rpath);
-	DPRINTF("hash=0x%x\n", (uintptr_t)info->hash);
-	DPRINTF("dt_rela=0x%x\n", (uintptr_t)info->rela);
-	DPRINTF("dt_rela_sz=0x%x\n", (uintptr_t)info->rela_sz);
-	DPRINTF("dt_rel=0x%x\n", (uintptr_t)info->rel);
-	DPRINTF("dt_rel_sz=0x%x\n", (uintptr_t)info->rel_sz);
+	DPRINTF("hash=0x%" PRIxPTR "\n", (uintptr_t)info->hash);
+	DPRINTF("dt_rela=0x%" PRIxPTR "\n", (uintptr_t)info->rela);
+	DPRINTF("dt_rela_sz=0x%" PRIxPTR "\n", (uintptr_t)info->rela_sz);
+	DPRINTF("dt_rel=0x%" PRIxPTR "\n", (uintptr_t)info->rel);
+	DPRINTF("dt_rel_sz=0x%" PRIxPTR "\n", (uintptr_t)info->rel_sz);
 
 	/*
Index: uspace/lib/c/generic/rtld/module.c
===================================================================
--- uspace/lib/c/generic/rtld/module.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/rtld/module.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -192,5 +192,5 @@
 
 	DPRINTF("filename:'%s'\n", name_buf);
-	DPRINTF("load '%s' at 0x%x\n", name_buf, m->bias);
+	DPRINTF("load '%s' at 0x%zx\n", name_buf, m->bias);
 
 	rc = elf_load_file_name(name_buf, m->bias, ELDF_RW, &info);
Index: pace/lib/c/generic/sort.c
===================================================================
--- uspace/lib/c/generic/sort.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,223 +1,0 @@
-/*
- * Copyright (c) 2005 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 libc
- * @{
- */
-
-/**
- * @file
- * @brief Sorting functions.
- *
- * This files contains functions implementing several sorting
- * algorithms (e.g. quick sort and gnome sort).
- *
- */
-
-#include <sort.h>
-#include <mem.h>
-#include <malloc.h>
-
-/** Immediate buffer size.
- *
- * For small buffer sizes avoid doing malloc()
- * and use the stack.
- *
- */
-#define IBUF_SIZE  32
-
-/** Array accessor.
- *
- */
-#define INDEX(buf, i, elem_size)  ((buf) + (i) * (elem_size))
-
-/** Gnome sort
- *
- * Apply generic gnome sort algorithm on supplied data,
- * using pre-allocated buffer.
- *
- * @param data      Pointer to data to be sorted.
- * @param cnt       Number of elements to be sorted.
- * @param elem_size Size of one element.
- * @param cmp       Comparator function.
- * @param arg       3rd argument passed to cmp.
- * @param slot      Pointer to scratch memory buffer
- *                  elem_size bytes long.
- *
- */
-static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
-    void *arg, void *slot)
-{
-	size_t i = 0;
-	
-	while (i < cnt) {
-		if ((i != 0) &&
-		    (cmp(INDEX(data, i, elem_size),
-		    INDEX(data, i - 1, elem_size), arg) == -1)) {
-			memcpy(slot, INDEX(data, i, elem_size), elem_size);
-			memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
-			    elem_size);
-			memcpy(INDEX(data, i - 1, elem_size), slot, elem_size);
-			i--;
-		} else
-			i++;
-	}
-}
-
-/** Quicksort
- *
- * Apply generic quicksort algorithm on supplied data,
- * using pre-allocated buffers.
- *
- * @param data      Pointer to data to be sorted.
- * @param cnt       Number of elements to be sorted.
- * @param elem_size Size of one element.
- * @param cmp       Comparator function.
- * @param arg       3rd argument passed to cmp.
- * @param slot      Pointer to scratch memory buffer
- *                  elem_size bytes long.
- * @param pivot     Pointer to scratch memory buffer
- *                  elem_size bytes long.
- *
- */
-static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
-    void *arg, void *slot, void *pivot)
-{
-	if (cnt > 4) {
-		size_t i = 0;
-		size_t j = cnt - 1;
-		
-		memcpy(pivot, data, elem_size);
-		
-		while (true) {
-			while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))
-				i++;
-			
-			while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
-				j--;
-			
-			if (i < j) {
-				memcpy(slot, INDEX(data, i, elem_size), elem_size);
-				memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size),
-				    elem_size);
-				memcpy(INDEX(data, j, elem_size), slot, elem_size);
-			} else
-				break;
-		}
-		
-		_qsort(data, j + 1, elem_size, cmp, arg, slot, pivot);
-		_qsort(INDEX(data, j + 1, elem_size), cnt - j - 1, elem_size,
-		    cmp, arg, slot, pivot);
-	} else
-		_gsort(data, cnt, elem_size, cmp, arg, slot);
-}
-
-/** Gnome sort wrapper
- *
- * This is only a wrapper that takes care of memory
- * allocations for storing the slot element for generic
- * gnome sort algorithm.
- *
- * @param data      Pointer to data to be sorted.
- * @param cnt       Number of elements to be sorted.
- * @param elem_size Size of one element.
- * @param cmp       Comparator function.
- * @param arg       3rd argument passed to cmp.
- *
- * @return True if sorting succeeded.
- *
- */
-bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
-{
-	uint8_t ibuf_slot[IBUF_SIZE];
-	void *slot;
-	
-	if (elem_size > IBUF_SIZE) {
-		slot = (void *) malloc(elem_size);
-		if (!slot)
-			return false;
-	} else
-		slot = (void *) ibuf_slot;
-	
-	_gsort(data, cnt, elem_size, cmp, arg, slot);
-	
-	if (elem_size > IBUF_SIZE)
-		free(slot);
-	
-	return true;
-}
-
-/** Quicksort wrapper
- *
- * This is only a wrapper that takes care of memory
- * allocations for storing the pivot and temporary elements
- * for generic quicksort algorithm.
- *
- * @param data      Pointer to data to be sorted.
- * @param cnt       Number of elements to be sorted.
- * @param elem_size Size of one element.
- * @param cmp       Comparator function.
- * @param arg       3rd argument passed to cmp.
- *
- * @return True if sorting succeeded.
- *
- */
-bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
-{
-	uint8_t ibuf_slot[IBUF_SIZE];
-	uint8_t ibuf_pivot[IBUF_SIZE];
-	void *slot;
-	void *pivot;
-	
-	if (elem_size > IBUF_SIZE) {
-		slot = (void *) malloc(elem_size);
-		if (!slot)
-			return false;
-		
-		pivot = (void *) malloc(elem_size);
-		if (!pivot) {
-			free(slot);
-			return false;
-		}
-	} else {
-		slot = (void *) ibuf_slot;
-		pivot = (void *) ibuf_pivot;
-	}
-	
-	_qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
-	
-	if (elem_size > IBUF_SIZE) {
-		free(pivot);
-		free(slot);
-	}
-	
-	return true;
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/str.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -995,4 +995,24 @@
 	dest[idx] = '\0';
 	return rc;
+}
+
+/** Get size of UTF-16 string.
+ *
+ * Get the number of words which are used by the UTF-16 string @a ustr
+ * (excluding the NULL-terminator).
+ *
+ * @param ustr UTF-16 string to consider.
+ *
+ * @return Number of words used by the UTF-16 string
+ *
+ */
+size_t utf16_wsize(const uint16_t *ustr)
+{
+	size_t wsize = 0;
+
+	while (*ustr++ != 0)
+		wsize++;
+
+	return wsize;
 }
 
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/task.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,4 +44,5 @@
 #include <async.h>
 #include <errno.h>
+#include <ns.h>
 #include <malloc.h>
 #include <libc.h>
@@ -324,5 +325,9 @@
 int task_setup_wait(task_id_t id, task_wait_t *wait)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_sess_t *sess_ns = ns_session_get();
+	if (sess_ns == NULL)
+		return EIO;
+
+	async_exch_t *exch = async_exchange_begin(sess_ns);
 	wait->aid = async_send_2(exch, NS_TASK_WAIT, LOWER32(id), UPPER32(id),
 	    &wait->result);
@@ -401,5 +406,9 @@
 int task_retval(int val)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_sess_t *sess_ns = ns_session_get();
+	if (sess_ns == NULL)
+		return EIO;
+
+	async_exch_t *exch = async_exchange_begin(sess_ns);
 	int rc = (int) async_req_1_0(exch, NS_RETVAL, val);
 	async_exchange_end(exch);
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/generic/vol.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 #include <loc.h>
 #include <stdlib.h>
+#include <str.h>
 #include <vol.h>
 
@@ -251,13 +252,48 @@
 }
 
+/** Get volume label support. */
+int vol_part_get_lsupp(vol_t *vol, vol_fstype_t fstype,
+    vol_label_supp_t *vlsupp)
+{
+	async_exch_t *exch;
+	sysarg_t retval;
+	ipc_call_t answer;
+
+	exch = async_exchange_begin(vol->sess);
+	aid_t req = async_send_1(exch, VOL_PART_LSUPP, fstype, &answer);
+	int rc = async_data_read_start(exch, vlsupp, sizeof(vol_label_supp_t));
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return EIO;
+	}
+
+	async_wait_for(req, &retval);
+	if (retval != EOK)
+		return EIO;
+
+	return EOK;
+}
+
 /** Create file system. */
-int vol_part_mkfs(vol_t *vol, service_id_t sid, vol_fstype_t fstype)
-{
-	async_exch_t *exch;
-	int retval;
-
-	exch = async_exchange_begin(vol->sess);
-	retval = async_req_2_0(exch, VOL_PART_MKFS, sid, fstype);
-	async_exchange_end(exch);
+int vol_part_mkfs(vol_t *vol, service_id_t sid, vol_fstype_t fstype,
+    const char *label)
+{
+	async_exch_t *exch;
+	ipc_call_t answer;
+	sysarg_t retval;
+
+	exch = async_exchange_begin(vol->sess);
+	aid_t req = async_send_2(exch, VOL_PART_MKFS, sid, fstype, &answer);
+	retval = async_data_write_start(exch, label, str_size(label));
+	async_exchange_end(exch);
+
+	if (retval != EOK) {
+		async_forget(req);
+		return retval;
+	}
+
+	async_wait_for(req, &retval);
 
 	if (retval != EOK)
Index: uspace/lib/c/include/adt/hash.h
===================================================================
--- uspace/lib/c/include/adt/hash.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/adt/hash.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 
 #include <stdint.h>
+#include <types/common.h>
 
 /** Produces a uniform hash affecting all output bits from the skewed input. */
Index: uspace/lib/c/include/adt/list.h
===================================================================
--- uspace/lib/c/include/adt/list.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/adt/list.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,4 +40,5 @@
 #include <stdbool.h>
 #include <stddef.h>
+#include <trace.h>
 
 /** Doubly linked list link. */
@@ -51,4 +52,8 @@
 	link_t head;  /**< List head. Does not have any data. */
 } list_t;
+
+extern bool list_member(const link_t *, const list_t *);
+extern void list_splice(list_t *, link_t *);
+extern unsigned long list_count(const list_t *);
 
 /** Declare and initialize statically allocated list.
@@ -88,13 +93,13 @@
 #define list_foreach(list, member, itype, iterator) \
 	for (itype *iterator = NULL; iterator == NULL; iterator = (itype *) 1) \
-	    for (link_t *_link = (list).head.next; \
-	    iterator = list_get_instance(_link, itype, member), \
-	    _link != &(list).head; _link = _link->next)
+		for (link_t *_link = (list).head.next; \
+		    iterator = list_get_instance(_link, itype, member), \
+		    _link != &(list).head; _link = _link->next)
 
 #define list_foreach_rev(list, member, itype, iterator) \
 	for (itype *iterator = NULL; iterator == NULL; iterator = (itype *) 1) \
-	    for (link_t *_link = (list).head.prev; \
-	    iterator = list_get_instance(_link, itype, member), \
-	    _link != &(list).head; _link = _link->prev)
+		for (link_t *_link = (list).head.prev; \
+		    iterator = list_get_instance(_link, itype, member), \
+		    _link != &(list).head; _link = _link->prev)
 
 /** Unlike list_foreach(), allows removing items while traversing a list.
@@ -125,7 +130,7 @@
 #define list_foreach_safe(list, iterator, next_iter) \
 	for (link_t *iterator = (list).head.next, \
-		*next_iter = iterator->next; \
-		iterator != &(list).head; \
-		iterator = next_iter, next_iter = iterator->next)
+	    *next_iter = iterator->next; \
+	    iterator != &(list).head; \
+	    iterator = next_iter, next_iter = iterator->next)
 
 #define assert_link_not_used(link) \
@@ -145,5 +150,5 @@
  *
  */
-static inline void link_initialize(link_t *link)
+NO_TRACE static inline void link_initialize(link_t *link)
 {
 	link->prev = NULL;
@@ -158,5 +163,5 @@
  *
  */
-static inline void list_initialize(list_t *list)
+NO_TRACE static inline void list_initialize(list_t *list)
 {
 	list->head.prev = &list->head;
@@ -194,5 +199,5 @@
  *
  */
-static inline void list_prepend(link_t *link, list_t *list)
+NO_TRACE static inline void list_prepend(link_t *link, list_t *list)
 {
 	list_insert_after(link, &list->head);
@@ -207,5 +212,5 @@
  *
  */
-static inline void list_append(link_t *link, list_t *list)
+NO_TRACE static inline void list_append(link_t *link, list_t *list)
 {
 	list_insert_before(link, &list->head);
@@ -220,5 +225,5 @@
  *
  */
-static inline void list_remove(link_t *link)
+NO_TRACE static inline void list_remove(link_t *link)
 {
 	if ((link->prev != NULL) && (link->next != NULL)) {
@@ -237,5 +242,5 @@
  *
  */
-static inline bool list_empty(const list_t *list)
+NO_TRACE static inline bool list_empty(const list_t *list)
 {
 	return (list->head.next == &list->head);
@@ -274,5 +279,4 @@
  *
  * @return Next item or NULL if @a link is the last item.
- *
  */
 static inline link_t *list_next(const link_t *link, const list_t *list)
@@ -287,5 +291,4 @@
  *
  * @return Previous item or NULL if @a link is the first item.
- *
  */
 static inline link_t *list_prev(const link_t *link, const list_t *list)
@@ -307,5 +310,5 @@
  *
  */
-static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
+NO_TRACE static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
 {
 	part1->prev->next = part2;
@@ -328,5 +331,5 @@
  *
  */
-static inline void headless_list_split(link_t *part1, link_t *part2)
+NO_TRACE static inline void headless_list_split(link_t *part1, link_t *part2)
 {
 	headless_list_split_or_concat(part1, part2);
@@ -343,7 +346,22 @@
  *
  */
-static inline void headless_list_concat(link_t *part1, link_t *part2)
+NO_TRACE static inline void headless_list_concat(link_t *part1, link_t *part2)
 {
 	headless_list_split_or_concat(part1, part2);
+}
+
+/** Concatenate two lists
+ *
+ * Concatenate lists @a list1 and @a list2, producing a single
+ * list @a list1 containing items from both (in @a list1, @a list2
+ * order) and empty list @a list2.
+ *
+ * @param list1		First list and concatenated output
+ * @param list2 	Second list and empty output.
+ *
+ */
+NO_TRACE static inline void list_concat(list_t *list1, list_t *list2)
+{
+	list_splice(list2, list1->head.prev);
 }
 
@@ -396,8 +414,4 @@
 }
 
-extern bool list_member(const link_t *, const list_t *);
-extern void list_concat(list_t *, list_t *);
-extern unsigned long list_count(const list_t *);
-
 #endif
 
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/as.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_AS_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 #include <stddef.h>
 #include <stdint.h>
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/async.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -166,7 +166,7 @@
     sysarg_t, async_port_handler_t, void *, port_id_t *);
 
-extern int async_irq_subscribe(int, int, async_notification_handler_t, void *,
+extern int async_irq_subscribe(int, async_notification_handler_t, void *,
     const irq_code_t *);
-extern int async_irq_unsubscribe(int, int);
+extern int async_irq_unsubscribe(int);
 
 extern int async_event_subscribe(event_type_t, async_notification_handler_t,
@@ -343,5 +343,4 @@
     sysarg_t *, sysarg_t *);
 
-extern async_sess_t *async_clone_establish(exch_mgmt_t, async_exch_t *);
 extern async_sess_t *async_connect_me_to(exch_mgmt_t, async_exch_t *, sysarg_t,
     sysarg_t, sysarg_t);
@@ -472,6 +471,4 @@
     sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
-extern int async_exchange_clone(async_exch_t *, async_exch_t *);
-extern async_sess_t *async_clone_receive(exch_mgmt_t);
 extern async_sess_t *async_callback_receive(exch_mgmt_t);
 extern async_sess_t *async_callback_receive_start(exch_mgmt_t, ipc_call_t *);
Index: uspace/lib/c/include/atomicdflt.h
===================================================================
--- uspace/lib/c/include/atomicdflt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/atomicdflt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,5 @@
 #endif
 
-#include <stdint.h>
+#include <types/common.h>
 #include <stdbool.h>
 
Index: uspace/lib/c/include/bd.h
===================================================================
--- uspace/lib/c/include/bd.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/bd.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 
 #include <async.h>
-#include <sys/types.h>
+#include <offset.h>
 
 typedef struct {
Index: uspace/lib/c/include/bd_srv.h
===================================================================
--- uspace/lib/c/include/bd_srv.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/bd_srv.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,5 @@
 #include <fibril_synch.h>
 #include <stdbool.h>
-#include <sys/types.h>
+#include <offset.h>
 
 typedef struct bd_ops bd_ops_t;
Index: uspace/lib/c/include/cap.h
===================================================================
--- uspace/lib/c/include/cap.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/cap.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2015 Jiri Svoboda
  * All rights reserved.
  *
@@ -30,14 +30,69 @@
  * @{
  */
-/** @file
+/**
+ * @file Storage capacity specification.
  */
 
-#ifndef LIB_CAP_H_
-#define LIB_CAP_H_
+#ifndef LIBC_CAP_H_
+#define LIBC_CAP_H_
 
-#include <task.h>
+#include <adt/list.h>
+#include <loc.h>
+#include <stdint.h>
+#include <types/label.h>
+#include <types/vol.h>
+#include <vbd.h>
 
-extern int cap_grant(task_id_t id, unsigned int caps);
-extern int cap_revoke(task_id_t id, unsigned int caps);
+/** Capacity unit */
+typedef enum {
+	cu_byte = 0,
+	cu_kbyte,
+	cu_mbyte,
+	cu_gbyte,
+	cu_tbyte,
+	cu_pbyte,
+	cu_ebyte,
+	cu_zbyte,
+	cu_ybyte
+} cap_unit_t;
+
+/** Which of values within the precision of the capacity */
+typedef enum {
+	/** The nominal (middling) value */
+	cv_nom,
+	/** The minimum value */
+	cv_min,
+	/** The maximum value */
+	cv_max
+} cap_vsel_t;
+
+#define CU_LIMIT (cu_ybyte + 1)
+
+/** Storage capacity.
+ *
+ * Storage capacity represents both value and precision.
+ * It is a decimal floating point value combined with a decimal
+ * capacity unit. There is an integer mantisa @c m which in combination
+ * with the number of decimal positions @c dp gives a decimal floating-point
+ * number. E.g. for m = 1025 and dp = 2 the number is 10.25. If the unit
+ * cunit = cu_kbyte, the capacity is 10.25 kByte, i.e. 10 250 bytes.
+ *
+ * Note that 1.000 kByte is equivalent to 1000 Byte, but 1 kByte is less
+ * precise.
+ */
+typedef struct {
+	/** Mantisa */
+	uint64_t m;
+	/** Decimal positions */
+	unsigned dp;
+	/** Capacity unit */
+	cap_unit_t cunit;
+} cap_spec_t;
+
+extern int cap_format(cap_spec_t *, char **);
+extern int cap_parse(const char *, cap_spec_t *);
+extern void cap_simplify(cap_spec_t *);
+extern void cap_from_blocks(uint64_t, size_t, cap_spec_t *);
+extern int cap_to_blocks(cap_spec_t *, cap_vsel_t, size_t, uint64_t *);
 
 #endif
Index: uspace/lib/c/include/corecfg.h
===================================================================
--- uspace/lib/c/include/corecfg.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/corecfg.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_INETCFG_H_
-#define LIBC_INET_INETCFG_H_
+#ifndef LIBC_CORECFG_H_
+#define LIBC_CORECFG_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/device/hw_res.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -52,4 +52,6 @@
 	HW_RES_GET_RESOURCE_LIST = 0,
 	HW_RES_ENABLE_INTERRUPT,
+	HW_RES_DISABLE_INTERRUPT,
+	HW_RES_CLEAR_INTERRUPT,
 	HW_RES_DMA_CHANNEL_SETUP,
 	HW_RES_DMA_CHANNEL_REMAIN,
@@ -115,5 +117,7 @@
 
 extern int hw_res_get_resource_list(async_sess_t *, hw_resource_list_t *);
-extern bool hw_res_enable_interrupt(async_sess_t *);
+extern int hw_res_enable_interrupt(async_sess_t *, int);
+extern int hw_res_disable_interrupt(async_sess_t *, int);
+extern int hw_res_clear_interrupt(async_sess_t *, int);
 
 extern int hw_res_dma_channel_setup(async_sess_t *, unsigned int, uint32_t,
Index: uspace/lib/c/include/dirent.h
===================================================================
--- uspace/lib/c/include/dirent.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/dirent.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #define NAME_MAX  256
 
-#include <sys/types.h>
+#include <offset.h>
 
 struct dirent {
Index: uspace/lib/c/include/elf/elf.h
===================================================================
--- uspace/lib/c/include/elf/elf.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/elf/elf.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 
 #include <stdint.h>
-#include <libarch/types.h>
+#include <types/common.h>
 #include <abi/elf.h>
 #include <libarch/elf.h>
Index: pace/lib/c/include/err.h
===================================================================
--- uspace/lib/c/include/err.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,49 +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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_ERR_H_
-#define LIBC_ERR_H_
-
-#include <stdio.h>
-
-#define errx(status, fmt, ...) \
-	do { \
-		printf((fmt), ##__VA_ARGS__); \
-		exit(status); \
-	} while (0)
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/fibril.h
===================================================================
--- uspace/lib/c/include/fibril.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/fibril.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
 
 #include <libarch/fibril.h>
+#include <types/common.h>
 #include <adt/list.h>
 #include <libarch/tls.h>
Index: uspace/lib/c/include/fibril_synch.h
===================================================================
--- uspace/lib/c/include/fibril_synch.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/fibril_synch.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -173,4 +173,6 @@
 extern fibril_timer_state_t fibril_timer_clear(fibril_timer_t *);
 extern fibril_timer_state_t fibril_timer_clear_locked(fibril_timer_t *);
+extern void fibril_usleep(useconds_t);
+extern void fibril_sleep(unsigned int);
 
 #endif
Index: uspace/lib/c/include/fourcc.h
===================================================================
--- uspace/lib/c/include/fourcc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/include/fourcc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_FOURCC_H_
+#define LIBC_FOURCC_H_
+
+#include <stdint.h>
+
+typedef uint32_t fourcc_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/gsort.h
===================================================================
--- uspace/lib/c/include/gsort.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/include/gsort.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2005 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_SORT_H_
+#define LIBC_SORT_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+
+typedef int (* sort_cmp_t)(void *, void *, void *);
+
+extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/inet/dhcp.h
===================================================================
--- uspace/lib/c/include/inet/dhcp.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/inet/dhcp.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define LIBC_INET_DHCP_H_
 
+#include <types/common.h>
 
 extern int dhcp_init(void);
Index: uspace/lib/c/include/inet/udp.h
===================================================================
--- uspace/lib/c/include/inet/udp.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/inet/udp.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -95,4 +95,5 @@
 extern int udp_assoc_create(udp_t *, inet_ep2_t *, udp_cb_t *, void *,
     udp_assoc_t **);
+extern int udp_assoc_set_nolocal(udp_assoc_t *);
 extern void udp_assoc_destroy(udp_assoc_t *);
 extern int udp_assoc_send_msg(udp_assoc_t *, inet_ep_t *, void *, size_t);
Index: uspace/lib/c/include/io/chardev.h
===================================================================
--- uspace/lib/c/include/io/chardev.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/io/chardev.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,5 @@
 #define LIBC_IO_CHARDEV_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 #include <async.h>
 
Index: uspace/lib/c/include/io/chargrid.h
===================================================================
--- uspace/lib/c/include/io/chargrid.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/io/chargrid.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,6 +37,7 @@
 #define LIBC_IO_CHARGRID_H_
 
+#include <io/charfield.h>
+#include <types/common.h>
 #include <stddef.h>
-#include <io/charfield.h>
 
 typedef enum {
Index: uspace/lib/c/include/io/log.h
===================================================================
--- uspace/lib/c/include/io/log.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/io/log.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #include <inttypes.h>
 #include <io/verify.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 #include <abi/log.h>
Index: uspace/lib/c/include/io/pixelmap.h
===================================================================
--- uspace/lib/c/include/io/pixelmap.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/io/pixelmap.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,6 @@
 #define LIBC_IO_PIXELMAP_H_
 
+#include <types/common.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <io/pixel.h>
Index: uspace/lib/c/include/io/pos_event.h
===================================================================
--- uspace/lib/c/include/io/pos_event.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/io/pos_event.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
 #define LIBC_IO_POS_EVENT_H_
 
+#include <types/common.h>
 
 typedef enum {
Index: uspace/lib/c/include/io/table.h
===================================================================
--- uspace/lib/c/include/io/table.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/include/io/table.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017 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_IO_TABLE_H_
+#define LIBC_IO_TABLE_H_
+
+#include <adt/list.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+
+/** Table metrics */
+typedef struct {
+	/** Space to the left of the table */
+	size_t margin_left;
+} table_metrics_t;
+
+/** Table cell */
+typedef struct {
+	/** Containing row */
+	struct table_row *row;
+	/** Link to table_row_t.cells */
+	link_t lrow;
+	/** Cell text */
+	char *text;
+} table_cell_t;
+
+/** Table row */
+typedef struct table_row {
+	/** Containing table */
+	struct table *table;
+	/** Link to table_t.rows */
+	link_t ltable;
+	/** Cells of this row */
+	list_t cells;
+} table_row_t;
+
+/** Table column */
+typedef struct {
+	/** Containing table */
+	struct table *table;
+	/** Link to table_t.columns */
+	link_t ltable;
+	/** Column width */
+	size_t width;
+} table_column_t;
+
+/** Table */
+typedef struct table {
+	/** @c true if the first row is a header row */
+	bool header_row;
+	/** Encountered error while writing to table */
+	int error;
+	/** Table rows */
+	list_t rows; /* of table_row_t */
+	/** Table columns */
+	list_t columns; /* of table_column_t */
+	/** Current row */
+	table_row_t *wrow;
+	/** Current cell */
+	table_cell_t *wcell;
+	/** Current column */
+	table_column_t *wcolumn;
+	/** Table metrics */
+	table_metrics_t metrics;
+} table_t;
+
+extern int table_create(table_t **);
+extern void table_destroy(table_t *);
+extern int table_print_out(table_t *, FILE *);
+extern void table_header_row(table_t *);
+extern int table_printf(table_t *, const char *, ...);
+extern int table_get_error(table_t *);
+extern void table_set_margin_left(table_t *, size_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,5 @@
 
 #include <malloc.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 typedef enum {
Index: uspace/lib/c/include/ipc/event.h
===================================================================
--- uspace/lib/c/include/ipc/event.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ipc/event.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 
 #include <abi/ipc/event.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 extern int ipc_event_subscribe(event_type_t, sysarg_t);
Index: uspace/lib/c/include/ipc/irc.h
===================================================================
--- uspace/lib/c/include/ipc/irc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ipc/irc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,4 +40,5 @@
 typedef enum {
 	IRC_ENABLE_INTERRUPT = IPC_FIRST_USER_METHOD,
+	IRC_DISABLE_INTERRUPT,
 	IRC_CLEAR_INTERRUPT
 } irc_request_t;
Index: uspace/lib/c/include/ipc/irq.h
===================================================================
--- uspace/lib/c/include/ipc/irq.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ipc/irq.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,9 +36,9 @@
 #define LIBC_IPC_IRQ_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 #include <abi/ddi/irq.h>
 
-extern int ipc_irq_subscribe(int, int, sysarg_t, const irq_code_t *);
-extern int ipc_irq_unsubscribe(int, int);
+extern int ipc_irq_subscribe(int, sysarg_t, const irq_code_t *);
+extern int ipc_irq_unsubscribe(int);
 
 #endif
Index: uspace/lib/c/include/ipc/ns.h
===================================================================
--- uspace/lib/c/include/ipc/ns.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ipc/ns.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,4 +40,5 @@
 typedef enum {
 	NS_PING = IPC_FIRST_USER_METHOD,
+	NS_REGISTER,
 	NS_TASK_WAIT,
 	NS_ID_INTRO,
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ipc/services.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -47,8 +47,7 @@
 	SERVICE_LOGGER     = FOURCC('l', 'o', 'g', 'g'),
 	SERVICE_DEVMAN     = FOURCC('d', 'e', 'v', 'n'),
-	SERVICE_IRC        = FOURCC('i', 'r', 'c', ' '),
-	SERVICE_CLIPBOARD  = FOURCC('c', 'l', 'i', 'p'),
 } service_t;
 
+#define SERVICE_NAME_CLIPBOARD "clipboard"
 #define SERVICE_NAME_CORECFG  "corecfg"
 #define SERVICE_NAME_DHCP     "net/dhcp"
Index: uspace/lib/c/include/ipc/udp.h
===================================================================
--- uspace/lib/c/include/ipc/udp.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ipc/udp.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,4 +42,5 @@
 	UDP_ASSOC_CREATE,
 	UDP_ASSOC_DESTROY,
+	UDP_ASSOC_SET_NOLOCAL,
 	UDP_ASSOC_SEND_MSG,
 	UDP_RMSG_INFO,
Index: uspace/lib/c/include/ipc/vol.h
===================================================================
--- uspace/lib/c/include/ipc/vol.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ipc/vol.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,6 @@
 #include <ipc/common.h>
 
+#define VOL_LABEL_MAXLEN 63
+
 typedef enum {
 	VOL_GET_PARTS = IPC_FIRST_USER_METHOD,
@@ -41,5 +43,6 @@
 	VOL_PART_INFO,
 	VOL_PART_EMPTY,
-	VOL_PART_MKFS
+	VOL_PART_LSUPP,
+	VOL_PART_MKFS,
 } vol_request_t;
 
Index: uspace/lib/c/include/irc.h
===================================================================
--- uspace/lib/c/include/irc.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/irc.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 extern int irc_enable_interrupt(int);
 extern int irc_disable_interrupt(int);
+extern int irc_clear_interrupt(int);
 
 #endif
Index: uspace/lib/c/include/ns.h
===================================================================
--- uspace/lib/c/include/ns.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/ns.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -46,4 +46,5 @@
 extern int ns_ping(void);
 extern int ns_intro(task_id_t);
+extern async_sess_t *ns_session_get(void);
 
 #endif
Index: uspace/lib/c/include/offset.h
===================================================================
--- uspace/lib/c/include/offset.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/include/offset.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_OFFSET_H_
+#define LIBC_OFFSET_H_
+
+#include <stdint.h>
+
+/* off64_t */
+#define OFF64_MIN  INT64_MIN
+#define OFF64_MAX  INT64_MAX
+
+/* aoff64_t */
+#define AOFF64_MIN  UINT64_MIN
+#define AOFF64_MAX  UINT64_MAX
+
+/* off64_t, aoff64_t */
+#define PRIdOFF64 PRId64
+#define PRIuOFF64 PRIu64
+#define PRIxOFF64 PRIx64
+#define PRIXOFF64 PRIX64
+
+/** Relative offset */
+typedef int64_t off64_t;
+
+/** Absolute offset */
+typedef uint64_t aoff64_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/perm.h
===================================================================
--- uspace/lib/c/include/perm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/include/perm.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIB_PERM_H_
+#define LIB_PERM_H_
+
+#include <task.h>
+
+extern int perm_grant(task_id_t, unsigned int);
+extern int perm_revoke(task_id_t, unsigned int);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/qsort.h
===================================================================
--- uspace/lib/c/include/qsort.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/include/qsort.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 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_QSORT_H_
+#define LIBC_QSORT_H_
+
+#include <stddef.h>
+
+extern void qsort(void *, size_t, size_t, int (*)(const void *,
+    const void *));
+extern void qsort_r(void *, size_t, size_t, int (*)(const void *,
+    const void *, void *), void *);
+
+#endif
+
+/** @}
+ */
Index: pace/lib/c/include/rwlock.h
===================================================================
--- uspace/lib/c/include/rwlock.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2008 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 libc
- * @{
- */
-/**
- * @file
- * @brief	This file contains rwlock API and provides its fake
- *		implementation based on futexes.
- */
-
-#ifndef LIBC_RWLOCK_H_
-#define LIBC_RWLOCK_H_
-
-#include <atomic.h>
-#include <futex.h>
-
-typedef atomic_t rwlock_t;
-
-#define RWLOCK_INITIALIZE(rwlock)	\
-    rwlock_t rwlock = FUTEX_INITIALIZER
-
-#define rwlock_initialize(rwlock)	futex_initialize((rwlock), 1)
-#define rwlock_read_lock(rwlock)	futex_lock((rwlock))
-#define rwlock_write_lock(rwlock)	futex_lock((rwlock))
-#define rwlock_read_unlock(rwlock)	futex_unlock((rwlock))
-#define rwlock_write_unlock(rwlock)	futex_unlock((rwlock))
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/sort.h
===================================================================
--- uspace/lib/c/include/sort.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2005 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_SORT_H_
-#define LIBC_SORT_H_
-
-#include <stddef.h>
-#include <stdbool.h>
-
-typedef int (* sort_cmp_t)(void *, void *, void *);
-
-extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *);
-extern bool qsort(void *, size_t, size_t, sort_cmp_t, void *);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/stack.h
===================================================================
--- uspace/lib/c/include/stack.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/stack.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #define LIBC_STACK_H_
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 extern size_t stack_size_get(void);
Index: uspace/lib/c/include/stdbool.h
===================================================================
--- uspace/lib/c/include/stdbool.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/stdbool.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define LIBC_BOOL_H_
 
-#include <libarch/types.h>
 #include <abi/bool.h>
 
Index: uspace/lib/c/include/stddef.h
===================================================================
--- uspace/lib/c/include/stddef.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/stddef.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,5 +42,6 @@
 #endif
 
-#define offsetof(type,member) ((size_t) &(((type *) 0)->member))
+#define offsetof(type, member) \
+	((size_t) &(((type *) 0)->member))
 
 #endif
Index: uspace/lib/c/include/stdint.h
===================================================================
--- uspace/lib/c/include/stdint.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/stdint.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -62,12 +62,4 @@
 #include <libarch/stdint.h>
 
-/* off64_t */
-#define OFF64_MIN  INT64_MIN
-#define OFF64_MAX  INT64_MAX
-
-/* aoff64_t */
-#define AOFF64_MIN  UINT64_MIN
-#define AOFF64_MAX  UINT64_MAX
-
 #endif
 
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/stdio.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,4 @@
 #define LIBC_STDIO_H_
 
-#include <sys/types.h>
 #include <stdarg.h>
 #include <str.h>
@@ -140,7 +139,7 @@
 extern size_t fwrite(const void *, size_t, size_t, FILE *);
 
-extern int fseek(FILE *, off64_t, int);
+extern int fseek(FILE *, long, int);
 extern void rewind(FILE *);
-extern off64_t ftell(FILE *);
+extern long ftell(FILE *);
 extern int feof(FILE *);
 extern int fileno(FILE *);
Index: uspace/lib/c/include/stdlib.h
===================================================================
--- uspace/lib/c/include/stdlib.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/stdlib.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,5 @@
 
 #include <malloc.h>
+#include <qsort.h>
 #include <stacktrace.h>
 
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/str.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -99,4 +99,5 @@
 extern int utf16_to_str(char *dest, size_t size, const uint16_t *src);
 extern int str_to_utf16(uint16_t *dest, size_t dlen, const char *src);
+extern size_t utf16_wsize(const uint16_t *ustr);
 
 extern char *str_chr(const char *str, wchar_t ch);
Index: pace/lib/c/include/sys/typefmt.h
===================================================================
--- uspace/lib/c/include/sys/typefmt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,50 +1,0 @@
-/*
- * 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>
-
-/* off64_t, aoff64_t */
-#define PRIdOFF64 PRId64
-#define PRIuOFF64 PRIu64
-#define PRIxOFF64 PRIx64
-#define PRIXOFF64 PRIX64
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/sys/types.h
===================================================================
--- uspace/lib/c/include/sys/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,59 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_SYS_TYPES_H_
-#define LIBC_SYS_TYPES_H_
-
-#include <libarch/types.h>
-
-/** Relative offset */
-typedef int64_t off64_t;
-
-/** Absolute offset */
-typedef uint64_t aoff64_t;
-
-typedef uint32_t fourcc_t;
-
-typedef int16_t unaligned_int16_t __attribute__ ((aligned(1)));
-typedef int32_t unaligned_int32_t __attribute__ ((aligned(1)));
-typedef int64_t unaligned_int64_t __attribute__ ((aligned(1)));
-
-typedef uint16_t unaligned_uint16_t __attribute__ ((aligned(1)));
-typedef uint32_t unaligned_uint32_t __attribute__ ((aligned(1)));
-typedef uint64_t unaligned_uint64_t __attribute__ ((aligned(1)));
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/syscall.h
===================================================================
--- uspace/lib/c/include/syscall.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/syscall.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,5 +45,5 @@
 
 #include <abi/syscall.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 #define __syscall0  __syscall
Index: uspace/lib/c/include/sysinfo.h
===================================================================
--- uspace/lib/c/include/sysinfo.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/sysinfo.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #define LIBC_SYSINFO_H_
 
+#include <types/common.h>
 #include <stddef.h>
 #include <stdbool.h>
Index: uspace/lib/c/include/types/common.h
===================================================================
--- uspace/lib/c/include/types/common.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/include/types/common.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 Jiri Zarevucky
+ * 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_TYPES_COMMON_H_
+#define LIBC_TYPES_COMMON_H_
+
+#include <libarch/types.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/types/label.h
===================================================================
--- uspace/lib/c/include/types/label.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/types/label.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -124,4 +124,6 @@
 } label_pcnt_t;
 
+#define LPC_LIMIT (lpc_minix + 1)
+
 #endif
 
Index: uspace/lib/c/include/types/vol.h
===================================================================
--- uspace/lib/c/include/types/vol.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/types/vol.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,4 +37,6 @@
 
 #include <async.h>
+#include <ipc/vol.h>
+#include <stdbool.h>
 
 typedef enum {
@@ -71,5 +73,13 @@
 	/** Filesystem type */
 	vol_fstype_t fstype;
+	/** Volume label */
+	char label[VOL_LABEL_MAXLEN + 1];
 } vol_part_info_t;
+
+/** Volume label support */
+typedef struct {
+	/** Volume labels are supported */
+	bool supported;
+} vol_label_supp_t;
 
 #endif
Index: uspace/lib/c/include/unaligned.h
===================================================================
--- uspace/lib/c/include/unaligned.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/include/unaligned.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_UNALIGNED_H_
+#define LIBC_UNALIGNED_H_
+
+#include <stdint.h>
+
+typedef int16_t unaligned_int16_t __attribute__ ((aligned(1)));
+typedef int32_t unaligned_int32_t __attribute__ ((aligned(1)));
+typedef int64_t unaligned_int64_t __attribute__ ((aligned(1)));
+
+typedef uint16_t unaligned_uint16_t __attribute__ ((aligned(1)));
+typedef uint32_t unaligned_uint32_t __attribute__ ((aligned(1)));
+typedef uint64_t unaligned_uint64_t __attribute__ ((aligned(1)));
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/vbd.h
===================================================================
--- uspace/lib/c/include/vbd.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/vbd.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #include <loc.h>
 #include <types/label.h>
-#include <sys/types.h>
+#include <offset.h>
 
 /** VBD service */
Index: uspace/lib/c/include/vfs/vfs.h
===================================================================
--- uspace/lib/c/include/vfs/vfs.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/vfs/vfs.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,4 +43,5 @@
 #include <stdio.h>
 #include <async.h>
+#include <offset.h>
 
 #define MAX_OPEN_FILES	128
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/include/vol.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -48,5 +48,6 @@
 extern int vol_part_info(vol_t *, service_id_t, vol_part_info_t *);
 extern int vol_part_empty(vol_t *, service_id_t);
-extern int vol_part_mkfs(vol_t *, service_id_t, vol_fstype_t);
+extern int vol_part_get_lsupp(vol_t *, vol_fstype_t, vol_label_supp_t *);
+extern int vol_part_mkfs(vol_t *, service_id_t, vol_fstype_t, const char *);
 
 #endif
Index: uspace/lib/c/test/fibril/timer.c
===================================================================
--- uspace/lib/c/test/fibril/timer.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/test/fibril/timer.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <fibril_synch.h>
+#include <pcut/pcut.h>
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(fibril_timer);
+
+static void test_timeout_fn(void *arg)
+{
+	int *i;
+
+	i = (int *)arg;
+	++*i;
+}
+
+PCUT_TEST(create_destroy)
+{
+	fibril_timer_t *t;
+
+	t = fibril_timer_create(NULL);
+	PCUT_ASSERT_NOT_NULL(t);
+	fibril_timer_destroy(t);
+}
+
+PCUT_TEST(create_destroy_user_lock)
+{
+	fibril_mutex_t lock;
+	fibril_timer_t *t;
+
+	fibril_mutex_initialize(&lock);
+	t = fibril_timer_create(&lock);
+	PCUT_ASSERT_NOT_NULL(t);
+	fibril_timer_destroy(t);
+}
+
+PCUT_TEST(set_clear_locked)
+{
+	fibril_mutex_t lock;
+	fibril_timer_t *t;
+	fibril_timer_state_t fts;
+	int cnt;
+
+	fibril_mutex_initialize(&lock);
+	t = fibril_timer_create(&lock);
+	PCUT_ASSERT_NOT_NULL(t);
+
+	fibril_mutex_lock(&lock);
+	cnt = 0;
+
+	fibril_timer_set_locked(t, 100 * 1000 * 1000, test_timeout_fn, &cnt);
+	fibril_usleep(1000);
+	fts = fibril_timer_clear_locked(t);
+	PCUT_ASSERT_INT_EQUALS(fts_active, fts);
+
+	PCUT_ASSERT_INT_EQUALS(0, cnt);
+	fibril_mutex_unlock(&lock);
+
+	fibril_timer_destroy(t);
+}
+
+PCUT_TEST(set_clear_not_locked)
+{
+	fibril_mutex_t lock;
+	fibril_timer_t *t;
+	fibril_timer_state_t fts;
+	int cnt;
+
+	fibril_mutex_initialize(&lock);
+	t = fibril_timer_create(&lock);
+	PCUT_ASSERT_NOT_NULL(t);
+
+	cnt = 0;
+	fibril_timer_set(t, 100 * 1000 * 1000, test_timeout_fn, &cnt);
+	fibril_usleep(1000);
+	fts = fibril_timer_clear(t);
+	PCUT_ASSERT_INT_EQUALS(fts_active, fts);
+
+	PCUT_ASSERT_INT_EQUALS(0, cnt);
+
+	fibril_timer_destroy(t);
+}
+
+PCUT_TEST(fire)
+{
+	fibril_mutex_t lock;
+	fibril_timer_t *t;
+	fibril_timer_state_t fts;
+	int cnt;
+
+	fibril_mutex_initialize(&lock);
+	t = fibril_timer_create(&lock);
+	PCUT_ASSERT_NOT_NULL(t);
+
+	fibril_mutex_lock(&lock);
+	cnt = 0;
+
+	fibril_timer_set_locked(t, 100, test_timeout_fn, &cnt);
+	fibril_mutex_unlock(&lock);
+
+	fibril_usleep(1000);
+
+	fibril_mutex_lock(&lock);
+	fts = fibril_timer_clear_locked(t);
+	PCUT_ASSERT_INT_EQUALS(fts_fired, fts);
+
+	PCUT_ASSERT_INT_EQUALS(1, cnt);
+	fibril_mutex_unlock(&lock);
+
+	fibril_timer_destroy(t);
+}
+
+PCUT_EXPORT(fibril_timer);
Index: uspace/lib/c/test/io/table.c
===================================================================
--- uspace/lib/c/test/io/table.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/test/io/table.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <io/table.h>
+#include <pcut/pcut.h>
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(table);
+
+PCUT_TEST(smoke) {
+	table_t *table;
+	int rc;
+
+	rc = table_create(&table);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	table_header_row(table);
+	rc = table_printf(table, "A\t" "B\t" "C\t" "D\n");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	rc = table_printf(table, "1\t" "2\t" "3\t" "4\n");
+	rc = table_printf(table, "i\t" "ii\t" "iii\t" "iv\n");
+	table_destroy(table);
+}
+
+PCUT_EXPORT(table);
Index: uspace/lib/c/test/main.c
===================================================================
--- uspace/lib/c/test/main.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/test/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -32,7 +32,10 @@
 PCUT_INIT
 
+PCUT_IMPORT(fibril_timer);
 PCUT_IMPORT(odict);
+PCUT_IMPORT(qsort);
 PCUT_IMPORT(sprintf);
 PCUT_IMPORT(str);
+PCUT_IMPORT(table);
 
 PCUT_MAIN()
Index: uspace/lib/c/test/odict.c
===================================================================
--- uspace/lib/c/test/odict.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/c/test/odict.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -272,5 +272,4 @@
 
 		v = seq_next(v);
-		++i;
 	}
 }
Index: uspace/lib/c/test/qsort.c
===================================================================
--- uspace/lib/c/test/qsort.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/c/test/qsort.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <pcut/pcut.h>
+#include <qsort.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+enum {
+	/** Length of test number sequences */
+	test_seq_len = 5
+};
+
+/** Test compare function.
+ *
+ * @param a First key
+ * @param b Second key
+ * @return <0, 0, >0 if @a a is less than, equal or greater than @a b
+ */
+static int test_cmp(const void *a, const void *b)
+{
+	int *ia = (int *)a;
+	int *ib = (int *)b;
+
+	return *ia - *ib;
+}
+
+static void bubble_sort(int *seq, size_t nmemb)
+{
+	size_t i;
+	size_t j;
+	int t;
+
+	for (i = 0; i < nmemb - 1; i++)
+		for (j = 0; j < nmemb - 1; j++) {
+			if (seq[j] > seq[j + 1]) {
+				t = seq[j];
+				seq[j] = seq[j + 1];
+				seq[j + 1] = t;
+			}
+		}
+}
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(qsort);
+
+/** Test sorting already sorted increasing sequence */
+PCUT_TEST(incr_seq)
+{
+	int *seq;
+	int i;
+
+	seq = calloc(test_seq_len, sizeof(int));
+	PCUT_ASSERT_NOT_NULL(seq);
+
+	for (i = 0; i < test_seq_len; i++)
+		seq[i] = i;
+
+	qsort(seq, test_seq_len, sizeof(int), test_cmp);
+
+	for (i = 0; i < test_seq_len; i++) {
+		PCUT_ASSERT_INT_EQUALS(i, seq[i]);
+	}
+
+	free(seq);
+}
+
+/** Test sorting reverse-sorted decreasing sequence. */
+PCUT_TEST(decr_seq)
+{
+	int *seq;
+	int i;
+
+	seq = calloc(test_seq_len, sizeof(int));
+	PCUT_ASSERT_NOT_NULL(seq);
+
+	for (i = 0; i < test_seq_len; i++)
+		seq[i] = test_seq_len - 1 - i;
+
+	qsort(seq, test_seq_len, sizeof(int), test_cmp);
+
+	for (i = 0; i < test_seq_len; i++) {
+		PCUT_ASSERT_INT_EQUALS(i, seq[i]);
+	}
+
+	free(seq);
+}
+
+/** Test sorting reverse-sorted decreasing sequence where each member repeats twice. */
+PCUT_TEST(decr2_seq)
+{
+	int *seq;
+	int i;
+
+	seq = calloc(test_seq_len, sizeof(int));
+	PCUT_ASSERT_NOT_NULL(seq);
+
+	for (i = 0; i < test_seq_len; i++) {
+		seq[i] = (test_seq_len - 1 - i) / 2;
+	}
+
+	qsort(seq, test_seq_len, sizeof(int), test_cmp);
+
+	for (i = 0; i < test_seq_len; i++) {
+		PCUT_ASSERT_INT_EQUALS(i / 2, seq[i]);
+	}
+
+	free(seq);
+}
+
+/** Generate pseudorandom sequence. */
+static int seq_next(int cur)
+{
+	return (cur * 1951) % 1000000;
+}
+
+/** Test sorting pseudorandom sequence. */
+PCUT_TEST(pseudorandom_seq)
+{
+	int *seq, *seq2;
+	int i;
+	int v;
+
+	seq = calloc(test_seq_len, sizeof(int));
+	PCUT_ASSERT_NOT_NULL(seq);
+
+	seq2 = calloc(test_seq_len, sizeof(int));
+	PCUT_ASSERT_NOT_NULL(seq);
+
+	v = 1;
+	for (i = 0; i < test_seq_len; i++) {
+		seq[i] = v;
+		seq2[i] = v;
+		v = seq_next(v);
+	}
+
+	qsort(seq, test_seq_len, sizeof(int), test_cmp);
+	bubble_sort(seq2, test_seq_len);
+
+	for (i = 0; i < test_seq_len; i++) {
+		PCUT_ASSERT_INT_EQUALS(seq2[i], seq[i]);
+	}
+
+	free(seq);
+	free(seq2);
+}
+
+PCUT_EXPORT(qsort);
Index: uspace/lib/clui/tinput.c
===================================================================
--- uspace/lib/clui/tinput.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/clui/tinput.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,5 +27,4 @@
  */
 
-#include <sort.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -583,5 +582,5 @@
 
 /** Compare two entries in array of completions. */
-static int compl_cmp(void *va, void *vb, void *arg)
+static int compl_cmp(const void *va, const void *vb)
 {
 	const char *a = *(const char **) va;
@@ -741,5 +740,5 @@
 			/* No common prefix. Sort and display all entries. */
 
-			qsort(compl, cnum, sizeof(char *), compl_cmp, NULL);
+			qsort(compl, cnum, sizeof(char *), compl_cmp);
 
 			tinput_jump_after(ti);
Index: uspace/lib/draw/codec/webp.c
===================================================================
--- uspace/lib/draw/codec/webp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/draw/codec/webp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,5 @@
 #include <stdbool.h>
 #include <pixconv.h>
-#include <sys/types.h>
+#include <fourcc.h>
 #include <stdint.h>
 #include <abi/fourcc.h>
Index: uspace/lib/draw/font/pcf.c
===================================================================
--- uspace/lib/draw/font/pcf.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/draw/font/pcf.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,4 +41,5 @@
 #include <stdio.h>
 #include <align.h>
+#include <offset.h>
 
 #include "pcf.h"
Index: uspace/lib/draw/path.c
===================================================================
--- uspace/lib/draw/path.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/draw/path.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,5 +35,4 @@
 
 #include <assert.h>
-#include <stdbool.h>
 #include <malloc.h>
 
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/drv/generic/driver.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -599,29 +599,16 @@
 }
 
-/** Create session with the parent function.
- *
- * The session will be automatically closed when @a dev is destroyed.
- *
- * @param dev Device
- *
- * @return New session or NULL if session could not be created
- *
- */
-async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *dev)
-{
-	assert(dev->parent_sess == NULL);
-	dev->parent_sess = devman_parent_device_connect(dev->handle,
-	    IPC_FLAG_BLOCKING);
-
-	return dev->parent_sess;
-}
-
 /** Return existing session with the parent function.
  *
  * @param dev	Device
- * @return	Existing session or NULL if there is no session
+ * @return	Session with parent function or NULL upon failure
  */
 async_sess_t *ddf_dev_parent_sess_get(ddf_dev_t *dev)
 {
+	if (dev->parent_sess == NULL) {
+		dev->parent_sess = devman_parent_device_connect(dev->handle,
+		    IPC_FLAG_BLOCKING);
+	}
+
 	return dev->parent_sess;
 }
@@ -943,11 +930,15 @@
 	int rc = async_create_port(INTERFACE_DDF_DRIVER, driver_connection_driver,
 	    NULL, &port);
-	if (rc != EOK)
+	if (rc != EOK) {
+		printf("Error: Failed to create driver port.\n");
 		return rc;
+	}
 	
 	rc = async_create_port(INTERFACE_DDF_DEVMAN, driver_connection_devman,
 	    NULL, &port);
-	if (rc != EOK)
+	if (rc != EOK) {
+		printf("Error: Failed to create devman port.\n");
 		return rc;
+	}
 	
 	async_set_fallback_port_handler(driver_connection_client, NULL);
@@ -964,6 +955,8 @@
 	/* Return success from the task since server has started. */
 	rc = task_retval(0);
-	if (rc != EOK)
+	if (rc != EOK) {
+		printf("Error: Failed returning task value.\n");
 		return rc;
+	}
 	
 	async_manager();
Index: uspace/lib/drv/generic/interrupt.c
===================================================================
--- uspace/lib/drv/generic/interrupt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/drv/generic/interrupt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,13 +44,13 @@
 
 int register_interrupt_handler(ddf_dev_t *dev, int irq,
-    interrupt_handler_t *handler, const irq_code_t *pseudocode)
+    interrupt_handler_t *handler, const irq_code_t *irq_code)
 {
-	return async_irq_subscribe(irq, dev->handle,
-	    (async_notification_handler_t) handler, dev, pseudocode);
+	return async_irq_subscribe(irq, (async_notification_handler_t) handler,
+	    dev, irq_code);
 }
 
-int unregister_interrupt_handler(ddf_dev_t *dev, int irq)
+int unregister_interrupt_handler(ddf_dev_t *dev, int cap)
 {
-	return async_irq_unsubscribe(irq, dev->handle);
+	return async_irq_unsubscribe(cap);
 }
 
Index: uspace/lib/drv/generic/remote_hw_res.c
===================================================================
--- uspace/lib/drv/generic/remote_hw_res.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/drv/generic/remote_hw_res.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,4 +45,8 @@
 static void remote_hw_res_enable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
+static void remote_hw_res_disable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
+    ipc_call_t *);
+static void remote_hw_res_clear_interrupt(ddf_fun_t *, void *, ipc_callid_t,
+    ipc_call_t *);
 static void remote_hw_res_dma_channel_setup(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
@@ -53,4 +57,6 @@
 	[HW_RES_GET_RESOURCE_LIST] = &remote_hw_res_get_resource_list,
 	[HW_RES_ENABLE_INTERRUPT] = &remote_hw_res_enable_interrupt,
+	[HW_RES_DISABLE_INTERRUPT] = &remote_hw_res_disable_interrupt,
+	[HW_RES_CLEAR_INTERRUPT] = &remote_hw_res_clear_interrupt,
 	[HW_RES_DMA_CHANNEL_SETUP] = &remote_hw_res_dma_channel_setup,
 	[HW_RES_DMA_CHANNEL_REMAIN] = &remote_hw_res_dma_channel_remain,
@@ -67,10 +73,42 @@
 	hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
 	
-	if (hw_res_ops->enable_interrupt == NULL)
+	if (hw_res_ops->enable_interrupt == NULL) {
 		async_answer_0(callid, ENOTSUP);
-	else if (hw_res_ops->enable_interrupt(fun))
-		async_answer_0(callid, EOK);
-	else
-		async_answer_0(callid, EREFUSED);
+		return;
+	}
+	
+	const int irq = DEV_IPC_GET_ARG1(*call);
+	const int ret = hw_res_ops->enable_interrupt(fun, irq);
+	async_answer_0(callid, ret);
+}
+
+static void remote_hw_res_disable_interrupt(ddf_fun_t *fun, void *ops,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
+	
+	if (hw_res_ops->disable_interrupt == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	
+	const int irq = DEV_IPC_GET_ARG1(*call);
+	const int ret = hw_res_ops->disable_interrupt(fun, irq);
+	async_answer_0(callid, ret);
+}
+
+static void remote_hw_res_clear_interrupt(ddf_fun_t *fun, void *ops,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
+	
+	if (hw_res_ops->clear_interrupt == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	
+	const int irq = DEV_IPC_GET_ARG1(*call);
+	const int ret = hw_res_ops->enable_interrupt(fun, irq);
+	async_answer_0(callid, ret);
 }
 
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/drv/include/ddf/driver.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -117,5 +117,4 @@
 extern devman_handle_t ddf_dev_get_handle(ddf_dev_t *);
 extern const char *ddf_dev_get_name(ddf_dev_t *);
-extern async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *);
 extern async_sess_t *ddf_dev_parent_sess_get(ddf_dev_t *);
 extern ddf_fun_t *ddf_fun_create(ddf_dev_t *, fun_type_t, const char *);
Index: uspace/lib/drv/include/ddf/interrupt.h
===================================================================
--- uspace/lib/drv/include/ddf/interrupt.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/drv/include/ddf/interrupt.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,5 @@
 
 #include <libarch/common.h>
-#include <libarch/types.h>
+#include <types/common.h>
 #include <abi/ddi/irq.h>
 #include <adt/list.h>
Index: uspace/lib/drv/include/ops/hw_res.h
===================================================================
--- uspace/lib/drv/include/ops/hw_res.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/drv/include/ops/hw_res.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,7 @@
 typedef struct {
 	hw_resource_list_t *(*get_resource_list)(ddf_fun_t *);
-	bool (*enable_interrupt)(ddf_fun_t *);
+	int (*enable_interrupt)(ddf_fun_t *, int);
+	int (*disable_interrupt)(ddf_fun_t *, int);
+	int (*clear_interrupt)(ddf_fun_t *, int);
 	int (*dma_channel_setup)(ddf_fun_t *, unsigned, uint32_t, uint32_t, uint8_t);
 	int (*dma_channel_remain)(ddf_fun_t *, unsigned, size_t *);
Index: uspace/lib/ext4/src/directory_index.c
===================================================================
--- uspace/lib/ext4/src/directory_index.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/ext4/src/directory_index.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,4 @@
 #include <errno.h>
 #include <mem.h>
-#include <sort.h>
 #include <stdlib.h>
 #include <str.h>
@@ -668,5 +667,4 @@
  * @param arg1  First entry
  * @param arg2  Second entry
- * @param dummy Unused parameter, can be NULL
  *
  * @return Classic compare result
@@ -674,8 +672,9 @@
  *
  */
-static int ext4_directory_dx_entry_comparator(void *arg1, void *arg2, void *dummy)
-{
-	ext4_dx_sort_entry_t *entry1 = arg1;
-	ext4_dx_sort_entry_t *entry2 = arg2;
+static int ext4_directory_dx_entry_comparator(const void *arg1,
+    const void *arg2)
+{
+	ext4_dx_sort_entry_t const *entry1 = arg1;
+	ext4_dx_sort_entry_t const *entry2 = arg2;
 	
 	if (entry1->hash == entry2->hash)
@@ -793,5 +792,5 @@
 	/* Sort all entries */
 	qsort(sort_array, idx, sizeof(ext4_dx_sort_entry_t),
-	    ext4_directory_dx_entry_comparator, NULL);
+	    ext4_directory_dx_entry_comparator);
 	
 	/* Allocate new block for store the second part of entries */
Index: uspace/lib/fdisk/Makefile
===================================================================
--- uspace/lib/fdisk/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/fdisk/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -33,5 +33,4 @@
 
 SOURCES = \
-	src/cap.c \
 	src/fdisk.c
 
Index: uspace/lib/fdisk/include/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/fdisk.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/fdisk/include/fdisk.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 #include <loc.h>
 #include <types/fdisk.h>
+#include <types/vol.h>
 
 extern int fdisk_create(fdisk_t **);
@@ -48,5 +49,5 @@
 extern int fdisk_dev_info_get_svcname(fdisk_dev_info_t *, char **);
 extern void fdisk_dev_info_get_svcid(fdisk_dev_info_t *, service_id_t *);
-extern int fdisk_dev_info_capacity(fdisk_dev_info_t *, fdisk_cap_t *);
+extern int fdisk_dev_info_capacity(fdisk_dev_info_t *, cap_spec_t *);
 
 extern int fdisk_dev_open(fdisk_t *, service_id_t, fdisk_dev_t **);
@@ -55,5 +56,5 @@
 extern void fdisk_dev_get_flags(fdisk_dev_t *, fdisk_dev_flags_t *);
 extern int fdisk_dev_get_svcname(fdisk_dev_t *, char **);
-extern int fdisk_dev_capacity(fdisk_dev_t *, fdisk_cap_t *);
+extern int fdisk_dev_capacity(fdisk_dev_t *, cap_spec_t *);
 
 extern int fdisk_label_get_info(fdisk_dev_t *, fdisk_label_info_t *);
@@ -64,6 +65,6 @@
 extern fdisk_part_t *fdisk_part_next(fdisk_part_t *);
 extern int fdisk_part_get_info(fdisk_part_t *, fdisk_part_info_t *);
-extern int fdisk_part_get_max_avail(fdisk_dev_t *, fdisk_spc_t, fdisk_cap_t *);
-extern int fdisk_part_get_tot_avail(fdisk_dev_t *, fdisk_spc_t, fdisk_cap_t *);
+extern int fdisk_part_get_max_avail(fdisk_dev_t *, fdisk_spc_t, cap_spec_t *);
+extern int fdisk_part_get_tot_avail(fdisk_dev_t *, fdisk_spc_t, cap_spec_t *);
 extern int fdisk_part_create(fdisk_dev_t *, fdisk_part_spec_t *,
     fdisk_part_t **);
@@ -71,13 +72,10 @@
 extern void fdisk_pspec_init(fdisk_part_spec_t *);
 
-extern int fdisk_cap_format(fdisk_cap_t *, char **);
-extern int fdisk_cap_parse(const char *, fdisk_cap_t *);
-extern void fdisk_cap_simplify(fdisk_cap_t *);
-extern void fdisk_cap_from_blocks(uint64_t, size_t, fdisk_cap_t *);
-extern int fdisk_cap_to_blocks(fdisk_cap_t *, fdisk_cvsel_t, size_t, uint64_t *);
-
 extern int fdisk_ltype_format(label_type_t, char **);
 extern int fdisk_fstype_format(vol_fstype_t, char **);
 extern int fdisk_pkind_format(label_pkind_t, char **);
+
+extern int fdisk_get_vollabel_support(fdisk_dev_t *, vol_fstype_t,
+    vol_label_supp_t *);
 
 #endif
Index: uspace/lib/fdisk/include/types/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/types/fdisk.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/fdisk/include/types/fdisk.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 
 #include <adt/list.h>
+#include <cap.h>
 #include <loc.h>
 #include <stdint.h>
@@ -43,28 +44,4 @@
 #include <types/vol.h>
 #include <vbd.h>
-#include <vol.h>
-
-/** Capacity unit */
-typedef enum {
-	cu_byte = 0,
-	cu_kbyte,
-	cu_mbyte,
-	cu_gbyte,
-	cu_tbyte,
-	cu_pbyte,
-	cu_ebyte,
-	cu_zbyte,
-	cu_ybyte
-} fdisk_cunit_t;
-
-/** Which of values within the precision of the capacity */
-typedef enum {
-	/** The nominal (middling) value */
-	fcv_nom,
-	/** The minimum value */
-	fcv_min,
-	/** The maximum value */
-	fcv_max
-} fdisk_cvsel_t;
 
 typedef enum {
@@ -86,25 +63,4 @@
 
 #define CU_LIMIT (cu_ybyte + 1)
-
-/** Partition capacity.
- *
- * Partition capacity represents both value and precision.
- * It is a decimal floating point value combined with a decimal
- * capacity unit. There is an integer mantisa @c m which in combination
- * with the number of decimal positions @c dp gives a decimal floating-point
- * number. E.g. for m = 1025 and dp = 2 the number is 10.25. If the unit
- * cunit = cu_kbyte, the capacity is 10.25 kByte, i.e. 10 250 bytes.
- *
- * Note that 1.000 kByte is equivalent to 1000 Byte, but 1 kByte is less
- * precise.
- */
-typedef struct {
-	/** Mantisa */
-	uint64_t m;
-	/** Decimal positions */
-	unsigned dp;
-	/** Capacity unit */
-	fdisk_cunit_t cunit;
-} fdisk_cap_t;
 
 /** List of devices available for managing by fdisk */
@@ -170,5 +126,5 @@
 	link_t llog_ba;
 	/** Capacity */
-	fdisk_cap_t capacity;
+	cap_spec_t capacity;
 	/** Partition kind */
 	label_pkind_t pkind;
@@ -187,4 +143,6 @@
 	/** Service ID */
 	service_id_t svc_id;
+	/** Volume label */
+	char *label;
 } fdisk_part_t;
 
@@ -192,9 +150,11 @@
 typedef struct {
 	/** Desired capacity */
-	fdisk_cap_t capacity;
+	cap_spec_t capacity;
 	/** Partition kind */
 	label_pkind_t pkind;
 	/** File system type */
 	vol_fstype_t fstype;
+	/** Volume label */
+	char *label;
 } fdisk_part_spec_t;
 
@@ -202,5 +162,5 @@
 typedef struct {
 	/** Capacity */
-	fdisk_cap_t capacity;
+	cap_spec_t capacity;
 	/** Partition kind */
 	label_pkind_t pkind;
@@ -209,4 +169,6 @@
 	/** File system type */
 	vol_fstype_t fstype;
+	/** Volume label */
+	char *label;
 } fdisk_part_info_t;
 
Index: pace/lib/fdisk/src/cap.c
===================================================================
--- uspace/lib/fdisk/src/cap.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,288 +1,0 @@
-/*
- * Copyright (c) 2015 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 libfdisk
- * @{
- */
-/**
- * @file Disk management library.
- */
-
-#include <errno.h>
-#include <fdisk.h>
-#include <imath.h>
-#include <stdio.h>
-#include <str.h>
-
-/** Simplified capacity parameters */
-enum {
-	/** Simplified capacity maximum integer digits */
-	scap_max_idig = 3,
-	/** Simplified capacity maximum significant digits */
-	scap_max_sdig = 4
-};
-
-static const char *cu_str[] = {
-	[cu_byte] = "B",
-	[cu_kbyte] = "kB",
-	[cu_mbyte] = "MB",
-	[cu_gbyte] = "GB",
-	[cu_tbyte] = "TB",
-	[cu_pbyte] = "PB",
-	[cu_ebyte] = "EB",
-	[cu_zbyte] = "ZB",
-	[cu_ybyte] = "YB"
-};
-
-void fdisk_cap_from_blocks(uint64_t nblocks, size_t block_size,
-    fdisk_cap_t *cap)
-{
-	uint64_t tsize;
-
-	tsize = nblocks * block_size;
-	cap->m = tsize;
-	cap->dp = 0;
-	cap->cunit = cu_byte;
-}
-
-/** Convert capacity to blocks.
- *
- * If the value of bytes is not integer, it is properly rounded. If the number
- * of bytes is not divisible by the number of blocks, it is rounded
- * up to an integer number of blocks.
- *
- * A capacity value entails precision, i.e. it corresponds to a range
- * of values. @a cvsel selects the value to return. @c fcv_nom gives
- * the nominal (middle) value, @c fcv_min gives the minimum value
- * and @c fcv_max gives the maximum value.
- */
-int fdisk_cap_to_blocks(fdisk_cap_t *cap, fdisk_cvsel_t cvsel,
-    size_t block_size, uint64_t *rblocks)
-{
-	int exp;
-	uint64_t bytes;
-	uint64_t f;
-	uint64_t adj;
-	uint64_t blocks;
-	uint64_t rem;
-	int rc;
-
-	exp = cap->cunit * 3 - cap->dp;
-	if (exp < 0) {
-		rc = ipow10_u64(-exp, &f);
-		if (rc != EOK)
-			return ERANGE;
-		bytes = (cap->m + (f / 2)) / f;
-		if (bytes * f - (f / 2) != cap->m)
-			return ERANGE;
-	} else {
-		rc = ipow10_u64(exp, &f);
-		if (rc != EOK)
-			return ERANGE;
-
-		adj = 0;
-		switch (cvsel) {
-		case fcv_nom:
-			adj = 0;
-			break;
-		case fcv_min:
-			adj = -(f / 2);
-			break;
-		case fcv_max:
-			adj = f / 2 - 1;
-			break;
-		}
-
-		bytes = cap->m * f + adj;
-		if ((bytes - adj) / f != cap->m)
-			return ERANGE;
-	}
-
-	rem = bytes % block_size;
-	if ((bytes + rem) < bytes)
-		return ERANGE;
-
-	blocks = (bytes + rem) / block_size;
-
-	*rblocks = blocks;
-	return EOK;
-}
-
-/** Simplify and round capacity to a human-friendly form.
- *
- * Change unit and round the number so that we have at most three integer
- * digits and at most two fractional digits, e.g abc.xy <unit>.
- */
-void fdisk_cap_simplify(fdisk_cap_t *cap)
-{
-	uint64_t div;
-	uint64_t maxv;
-	unsigned sdig;
-	unsigned rdig;
-	int rc;
-
-	/* Change units so that we have at most @c scap_max_idig integer digits */
-	rc = ipow10_u64(scap_max_idig, &maxv);
-	assert(rc == EOK);
-
-	rc = ipow10_u64(cap->dp, &div);
-	assert(rc == EOK);
-
-	while (cap->m / div >= maxv) {
-		++cap->cunit;
-		cap->dp += 3;
-		div = div * 1000;
-	}
-
-	/* Round the number so that we have at most @c scap_max_sdig significant digits */
-	sdig = 1 + ilog10_u64(cap->m); /* number of significant digits */
-	if (sdig > scap_max_sdig) {
-		/* Number of digits to remove */
-		rdig = sdig - scap_max_sdig;
-		if (rdig > cap->dp)
-			rdig = cap->dp;
-
-		rc = ipow10_u64(rdig, &div);
-		assert(rc == EOK);
-
-		cap->m = (cap->m + (div / 2)) / div;
-		cap->dp -= rdig;
-	}
-}
-
-int fdisk_cap_format(fdisk_cap_t *cap, char **rstr)
-{
-	int rc;
-	const char *sunit;
-	uint64_t ipart;
-	uint64_t fpart;
-	uint64_t div;
-
-	sunit = NULL;
-
-	if (cap->cunit < 0 || cap->cunit >= CU_LIMIT)
-		assert(false);
-
-	rc = ipow10_u64(cap->dp, &div);
-	if (rc != EOK)
-		return rc;
-
-	ipart = cap->m / div;
-	fpart = cap->m % div;
-
-	sunit = cu_str[cap->cunit];
-	if (cap->dp > 0) {
-		rc = asprintf(rstr, "%" PRIu64 ".%0*" PRIu64 " %s", ipart,
-		    (int)cap->dp, fpart, sunit);
-	} else {
-		rc = asprintf(rstr, "%" PRIu64 " %s", ipart, sunit);
-	}
-	if (rc < 0)
-		return ENOMEM;
-
-	return EOK;
-}
-
-static int fdisk_digit_val(char c, int *val)
-{
-	switch (c) {
-	case '0': *val = 0; break;
-	case '1': *val = 1; break;
-	case '2': *val = 2; break;
-	case '3': *val = 3; break;
-	case '4': *val = 4; break;
-	case '5': *val = 5; break;
-	case '6': *val = 6; break;
-	case '7': *val = 7; break;
-	case '8': *val = 8; break;
-	case '9': *val = 9; break;
-	default:
-		return EINVAL;
-	}
-
-	return EOK;
-}
-
-int fdisk_cap_parse(const char *str, fdisk_cap_t *cap)
-{
-	const char *eptr;
-	const char *p;
-	int d;
-	int dp;
-	unsigned long m;
-	int i;
-
-	m = 0;
-
-	eptr = str;
-	while (fdisk_digit_val(*eptr, &d) == EOK) {
-		m = m * 10 + d;
-		++eptr;
-	}
-
-	if (*eptr == '.') {
-		++eptr;
-		dp = 0;
-		while (fdisk_digit_val(*eptr, &d) == EOK) {
-			m = m * 10 + d;
-			++dp;
-			++eptr;
-		}
-	} else {
-		dp = 0;
-	}
-
-	while (*eptr == ' ')
-		++eptr;
-
-	if (*eptr == '\0') {
-		cap->cunit = cu_byte;
-	} else {
-		for (i = 0; i < CU_LIMIT; i++) {
-			if (str_lcasecmp(eptr, cu_str[i],
-			    str_length(cu_str[i])) == 0) {
-				p = eptr + str_size(cu_str[i]);
-				while (*p == ' ')
-					++p;
-				if (*p == '\0')
-					goto found;
-			}
-		}
-
-		return EINVAL;
-found:
-		cap->cunit = i;
-	}
-
-	cap->m = m;
-	cap->dp = dp;
-	return EOK;
-}
-
-/** @}
- */
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/fdisk/src/fdisk.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,4 +35,5 @@
 
 #include <adt/list.h>
+#include <cap.h>
 #include <errno.h>
 #include <fdisk.h>
@@ -218,5 +219,5 @@
 }
 
-int fdisk_dev_info_capacity(fdisk_dev_info_t *info, fdisk_cap_t *cap)
+int fdisk_dev_info_capacity(fdisk_dev_info_t *info, cap_spec_t *cap)
 {
 	vbd_disk_info_t vinfo;
@@ -227,5 +228,5 @@
 		return EIO;
 
-	fdisk_cap_from_blocks(vinfo.nblocks, vinfo.block_size, cap);
+	cap_from_blocks(vinfo.nblocks, vinfo.block_size, cap);
 	return EOK;
 }
@@ -269,4 +270,5 @@
 		part->pcnt = vpinfo.pcnt;
 		part->fstype = vpinfo.fstype;
+		part->label = str_dup(vpinfo.label);
 	}
 
@@ -293,5 +295,5 @@
 		dev->ext_part = part;
 
-	fdisk_cap_from_blocks(part->nblocks, dev->dinfo.block_size,
+	cap_from_blocks(part->nblocks, dev->dinfo.block_size,
 	    &part->capacity);
 	part->part_id = partid;
@@ -301,4 +303,6 @@
 	return EOK;
 error:
+	if (part != NULL)
+		free(part->label);
 	free(part);
 	return rc;
@@ -315,4 +319,6 @@
 	if (link_used(&part->llog_ba))
 		list_remove(&part->llog_ba);
+
+	free(part->label);
 	free(part);
 }
@@ -530,7 +536,7 @@
 }
 
-int fdisk_dev_capacity(fdisk_dev_t *dev, fdisk_cap_t *cap)
-{
-	fdisk_cap_from_blocks(dev->dinfo.nblocks, dev->dinfo.block_size, cap);
+int fdisk_dev_capacity(fdisk_dev_t *dev, cap_spec_t *cap)
+{
+	cap_from_blocks(dev->dinfo.nblocks, dev->dinfo.block_size, cap);
 	return EOK;
 }
@@ -667,9 +673,10 @@
 	info->fstype = part->fstype;
 	info->pkind = part->pkind;
+	info->label = part->label;
 	return EOK;
 }
 
 /** Get size of largest free block. */
-int fdisk_part_get_max_avail(fdisk_dev_t *dev, fdisk_spc_t spc, fdisk_cap_t *cap)
+int fdisk_part_get_max_avail(fdisk_dev_t *dev, fdisk_spc_t spc, cap_spec_t *cap)
 {
 	int rc;
@@ -690,5 +697,5 @@
 	}
 
-	fdisk_cap_from_blocks(nb, dev->dinfo.block_size, cap);
+	cap_from_blocks(nb, dev->dinfo.block_size, cap);
 	return EOK;
 }
@@ -696,5 +703,5 @@
 /** Get total free space capacity. */
 int fdisk_part_get_tot_avail(fdisk_dev_t *dev, fdisk_spc_t spc,
-    fdisk_cap_t *cap)
+    cap_spec_t *cap)
 {
 	fdisk_free_range_t fr;
@@ -718,5 +725,5 @@
 	} while (fdisk_free_range_next(&fr));
 
-	fdisk_cap_from_blocks(totb, dev->dinfo.block_size, cap);
+	cap_from_blocks(totb, dev->dinfo.block_size, cap);
 	return EOK;
 }
@@ -725,34 +732,54 @@
     fdisk_part_t **rpart)
 {
-	fdisk_part_t *part;
+	fdisk_part_t *part = NULL;
 	vbd_part_spec_t vpspec;
-	vbd_part_id_t partid;
-	int rc;
+	vbd_part_id_t partid = 0;
+	vol_part_info_t vpinfo;
+	const char *label;
+	int rc;
+
+	label = pspec->label != NULL ? pspec->label : "";
 
 	rc = fdisk_part_spec_prepare(dev, pspec, &vpspec);
-	if (rc != EOK)
-		return EIO;
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
 
 	rc = vbd_part_create(dev->fdisk->vbd, dev->sid, &vpspec, &partid);
-	if (rc != EOK)
-		return EIO;
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
 
 	rc = fdisk_part_add(dev, partid, &part);
 	if (rc != EOK) {
-		/* Try rolling back */
-		(void) vbd_part_delete(dev->fdisk->vbd, partid);
-		return EIO;
+		rc = EIO;
+		goto error;
 	}
 
 	if (part->svc_id != 0) {
-		rc = vol_part_mkfs(dev->fdisk->vol, part->svc_id, pspec->fstype);
+		rc = vol_part_mkfs(dev->fdisk->vol, part->svc_id, pspec->fstype,
+		    label);
 		if (rc != EOK && rc != ENOTSUP) {
-			fdisk_part_remove(part);
-			(void) vbd_part_delete(dev->fdisk->vbd, partid);
-			return EIO;
-		}
-
-		part->pcnt = vpc_fs;
-		part->fstype = pspec->fstype;
+			rc = EIO;
+			goto error;
+		}
+
+		/* Get the real label value */
+		rc = vol_part_info(dev->fdisk->vol, part->svc_id, &vpinfo);
+		if (rc != EOK) {
+			rc = EIO;
+			goto error;
+		}
+
+		part->pcnt = vpinfo.pcnt;
+		part->fstype = vpinfo.fstype;
+		part->label = str_dup(vpinfo.label);
+
+		if (part->label == NULL) {
+			rc = EIO;
+			goto error;
+		}
 	}
 
@@ -760,4 +787,11 @@
 		*rpart = part;
 	return EOK;
+error:
+	/* Try rolling back */
+	if (part != NULL)
+		fdisk_part_remove(part);
+	if (partid != 0)
+		(void) vbd_part_delete(dev->fdisk->vbd, partid);
+	return rc;
 }
 
@@ -962,15 +996,15 @@
 	int rc;
 
-	rc = fdisk_cap_to_blocks(&pspec->capacity, fcv_nom, dev->dinfo.block_size,
+	rc = cap_to_blocks(&pspec->capacity, cv_nom, dev->dinfo.block_size,
 	    &nom_blocks);
 	if (rc != EOK)
 		return rc;
 
-	rc = fdisk_cap_to_blocks(&pspec->capacity, fcv_min, dev->dinfo.block_size,
+	rc = cap_to_blocks(&pspec->capacity, cv_min, dev->dinfo.block_size,
 	    &min_blocks);
 	if (rc != EOK)
 		return rc;
 
-	rc = fdisk_cap_to_blocks(&pspec->capacity, fcv_max, dev->dinfo.block_size,
+	rc = cap_to_blocks(&pspec->capacity, cv_max, dev->dinfo.block_size,
 	    &max_blocks);
 	if (rc != EOK)
@@ -981,5 +1015,5 @@
 	max_blocks = fdisk_ba_align_up(dev, max_blocks);
 
-	pcnt = -1;
+	pcnt = LPC_LIMIT;
 
 	switch (pspec->fstype) {
@@ -1000,5 +1034,5 @@
 	}
 
-	if (pcnt < 0)
+	if (pcnt == LPC_LIMIT)
 		return EINVAL;
 
@@ -1188,4 +1222,11 @@
 }
 
+/** Get volume label support. */
+int fdisk_get_vollabel_support(fdisk_dev_t *dev, vol_fstype_t fstype,
+    vol_label_supp_t *vlsupp)
+{
+	return vol_part_get_lsupp(dev->fdisk->vol, fstype, vlsupp);
+}
+
 /** @}
  */
Index: uspace/lib/fs/libfs.h
===================================================================
--- uspace/lib/fs/libfs.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/fs/libfs.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 
 #include <ipc/vfs.h>
-#include <sys/types.h>
+#include <offset.h>
 #include <async.h>
 #include <loc.h>
Index: uspace/lib/graph/graph.c
===================================================================
--- uspace/lib/graph/graph.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/graph/graph.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -469,11 +469,6 @@
 static void vs_update_damaged_region(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
 {
-#ifdef __32_BITS__
 	sysarg_t x_offset = (IPC_GET_ARG5(*icall) >> 16);
 	sysarg_t y_offset = (IPC_GET_ARG5(*icall) & 0x0000ffff);
-#else
-	sysarg_t x_offset = (IPC_GET_ARG5(*icall) >> 32);
-	sysarg_t y_offset = (IPC_GET_ARG5(*icall) & 0xffffffff);
-#endif
 	
 	int rc = vs->ops.handle_damage(vs,
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/gui/window.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -677,4 +677,24 @@
 }
 
+int window_set_caption(window_t *win, const char *caption)
+{
+	char *cap;
+	
+	if (caption == NULL) {
+		win->caption = NULL;
+	} else {
+		cap = str_dup(caption);
+		if (cap == NULL)
+			return ENOMEM;
+		free(win->caption);
+		win->caption = cap;
+	}
+	
+	win->is_focused = false;
+	handle_refresh(win);
+	
+	return EOK;
+}
+
 void window_refresh(window_t *win)
 {
Index: uspace/lib/gui/window.h
===================================================================
--- uspace/lib/gui/window.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/gui/window.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -77,4 +77,7 @@
     window_placement_flags_t);
 
+/** Change window caption. */
+extern int window_set_caption(window_t *, const char *);
+
 /**
  * Post refresh event into event loop. Widget tree is traversed and all widgets
Index: uspace/lib/hound/include/hound/client.h
===================================================================
--- uspace/lib/hound/include/hound/client.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/hound/include/hound/client.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,4 @@
 
 #include <async.h>
-#include <stdbool.h>
 #include <pcm/format.h>
 #include <hound/protocol.h>
Index: uspace/lib/hound/src/client.c
===================================================================
--- uspace/lib/hound/src/client.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/hound/src/client.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,5 @@
 #include <stdlib.h>
 #include <stdio.h>
-#include <libarch/types.h>
+#include <types/common.h>
 #include <task.h>
 
@@ -48,5 +48,5 @@
 
 /** Stream structure */
-typedef struct hound_stream {
+struct hound_stream {
 	/** link in context's list */
 	link_t link;
@@ -59,5 +59,5 @@
 	/** Stream flags */
 	int flags;
-} hound_stream_t;
+};
 
 /**
@@ -72,5 +72,5 @@
 
 /** Hound client context structure */
-typedef struct hound_context {
+struct hound_context {
 	/** Audio session */
 	hound_sess_t *session;
@@ -89,5 +89,5 @@
 	/** Assigned context id */
 	hound_context_id_t id;
-} hound_context_t;
+};
 
 /**
Index: uspace/lib/hound/src/protocol.c
===================================================================
--- uspace/lib/hound/src/protocol.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/hound/src/protocol.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,5 @@
 #include <stdlib.h>
 #include <stdio.h>
-#include <libarch/types.h>
+#include <types/common.h>
 
 #include "protocol.h"
Index: uspace/lib/http/include/http/receive-buffer.h
===================================================================
--- uspace/lib/http/include/http/receive-buffer.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/http/include/http/receive-buffer.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 
 #include <adt/list.h>
+#include <stddef.h>
 
 /** Receive data.
Index: uspace/lib/http/src/http.c
===================================================================
--- uspace/lib/http/src/http.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/http/src/http.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -121,5 +121,8 @@
 	
 	tcp_conn_destroy(http->conn);
+	http->conn = NULL;
 	tcp_destroy(http->tcp);
+	http->tcp = NULL;
+	
 	return EOK;
 }
@@ -127,4 +130,5 @@
 void http_destroy(http_t *http)
 {
+	(void) http_close(http);
 	recv_buffer_fini(&http->recv_buffer);
 	free(http);
Index: uspace/lib/label/Makefile
===================================================================
--- uspace/lib/label/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/label/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -28,5 +28,5 @@
 
 USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude -I$(LIBBLOCK_PREFIX)
+EXTRA_CFLAGS = -Iinclude
 
 LIBRARY = liblabel
@@ -34,7 +34,12 @@
 SOURCES = \
 	src/dummy.c \
+	src/empty.c \
 	src/mbr.c \
 	src/gpt.c \
 	src/label.c
 
+TEST_SOURCES = \
+	test/main.c \
+	test/label.c
+
 include $(USPACE_PREFIX)/Makefile.common
Index: pace/lib/label/include/label.h
===================================================================
--- uspace/lib/label/include/label.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * Copyright (c) 2015 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 liblabel
- * @{
- */
-/**
- * @file Disk label library.
- */
-
-#ifndef LIBLABEL_LABEL_H_
-#define LIBLABEL_LABEL_H_
-
-#include <loc.h>
-#include <types/label.h>
-#include <types/liblabel.h>
-
-extern int label_open(service_id_t, label_t **);
-extern int label_create(service_id_t, label_type_t, label_t **);
-extern void label_close(label_t *);
-extern int label_destroy(label_t *);
-extern int label_get_info(label_t *, label_info_t *);
-
-extern label_part_t *label_part_first(label_t *);
-extern label_part_t *label_part_next(label_part_t *);
-extern void label_part_get_info(label_part_t *, label_part_info_t *);
-
-extern int label_part_create(label_t *, label_part_spec_t *,
-    label_part_t **);
-extern int label_part_destroy(label_part_t *);
-extern void label_pspec_init(label_part_spec_t *);
-extern int label_suggest_ptype(label_t *, label_pcnt_t, label_ptype_t *);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/label/include/label/empty.h
===================================================================
--- uspace/lib/label/include/label/empty.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/label/include/label/empty.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 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 liblabel
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef LABEL_EMPTY_H_
+#define LABEL_EMPTY_H_
+
+#include <loc.h>
+#include <types/liblabel.h>
+
+extern int label_bd_is_empty(label_bd_t *, bool *);
+extern int label_bd_empty(label_bd_t *);
+extern int label_part_empty(label_part_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/label/include/label/label.h
===================================================================
--- uspace/lib/label/include/label/label.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/label/include/label/label.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015 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 liblabel
+ * @{
+ */
+/**
+ * @file Disk label library.
+ */
+
+#ifndef LIBLABEL_LABEL_H_
+#define LIBLABEL_LABEL_H_
+
+#include <types/label.h>
+#include <types/liblabel.h>
+
+extern int label_open(label_bd_t *, label_t **);
+extern int label_create(label_bd_t *, label_type_t, label_t **);
+extern void label_close(label_t *);
+extern int label_destroy(label_t *);
+extern int label_get_info(label_t *, label_info_t *);
+
+extern label_part_t *label_part_first(label_t *);
+extern label_part_t *label_part_next(label_part_t *);
+extern void label_part_get_info(label_part_t *, label_part_info_t *);
+
+extern int label_part_create(label_t *, label_part_spec_t *,
+    label_part_t **);
+extern int label_part_destroy(label_part_t *);
+extern void label_pspec_init(label_part_spec_t *);
+extern int label_suggest_ptype(label_t *, label_pcnt_t, label_ptype_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/label/include/std/fat.h
===================================================================
--- uspace/lib/label/include/std/fat.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/label/include/std/fat.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2008 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 fs
+ * @{
+ */
+
+#ifndef FAT_FAT_H_
+#define FAT_FAT_H_
+
+#include <stdint.h>
+
+#define BS_BLOCK		0
+#define BS_SIZE			512
+#define DIRENT_SIZE		32
+
+#define FAT12_CLST_MAX    4085
+#define FAT16_CLST_MAX    65525
+
+#define FATAUTO	0
+#define FAT12	12
+#define FAT16	16
+#define FAT32	32
+
+#define FAT_CLUSTER_DOUBLE_SIZE(a) ((a) / 4)
+
+typedef struct fat_bs {
+	uint8_t		ji[3];		/**< Jump instruction. */
+	uint8_t		oem_name[8];
+	/* BIOS Parameter Block */
+	uint16_t	bps;		/**< Bytes per sector. */
+	uint8_t		spc;		/**< Sectors per cluster. */
+	uint16_t	rscnt;		/**< Reserved sector count. */
+	uint8_t		fatcnt;		/**< Number of FATs. */
+	uint16_t	root_ent_max;	/**< Maximum number of root directory
+					     entries. */
+	uint16_t	totsec16;	/**< Total sectors. 16-bit version. */
+	uint8_t		mdesc;		/**< Media descriptor. */
+	uint16_t	sec_per_fat;	/**< Sectors per FAT12/FAT16. */
+	uint16_t	sec_per_track;	/**< Sectors per track. */
+	uint16_t	headcnt;	/**< Number of heads. */
+	uint32_t	hidden_sec;	/**< Hidden sectors. */
+	uint32_t	totsec32;	/**< Total sectors. 32-bit version. */
+
+	union {
+		struct {
+			/* FAT12/FAT16 only: Extended BIOS Parameter Block */
+			/** Physical drive number. */
+			uint8_t		pdn;
+			uint8_t		reserved;
+			/** Extended boot signature. */
+			uint8_t		ebs;
+			/** Serial number. */
+			uint32_t	id;
+			/** Volume label. */
+			uint8_t		label[11];
+			/** FAT type. */
+			uint8_t		type[8];
+			/** Boot code. */
+			uint8_t		boot_code[448];
+			/** Boot sector signature. */
+			uint16_t	signature;
+		} __attribute__ ((packed));
+		struct {
+			/* FAT32 only */
+			/** Sectors per FAT. */
+			uint32_t	sectors_per_fat;
+			/** FAT flags. */
+			uint16_t	flags;
+			/** Version. */
+			uint16_t	version;
+			/** Cluster number of root directory. */
+			uint32_t	root_cluster;
+			/** Sector number of file system information sector. */
+			uint16_t	fsinfo_sec;
+			/** Sector number of boot sector copy. */
+			uint16_t	bscopy_sec;
+			uint8_t		reserved1[12];
+			/** Physical drive number. */
+			uint8_t		pdn;
+			uint8_t		reserved2;
+			/** Extended boot signature. */
+			uint8_t		ebs;
+			/** Serial number. */
+			uint32_t	id;
+			/** Volume label. */
+			uint8_t		label[11];
+			/** FAT type. */
+			uint8_t		type[8];
+			/** Boot code. */
+			uint8_t		boot_code[420];
+			/** Signature. */
+			uint16_t	signature;
+		} __attribute__ ((packed)) fat32;
+	};
+} __attribute__ ((packed)) fat_bs_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/label/include/types/liblabel.h
===================================================================
--- uspace/lib/label/include/types/liblabel.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/label/include/types/liblabel.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,5 +39,6 @@
 #include <adt/list.h>
 #include <types/label.h>
-#include <sys/types.h>
+#include <offset.h>
+#include <stddef.h>
 #include <vol.h>
 #include <uuid.h>
@@ -48,9 +49,11 @@
 typedef struct label_part_info label_part_info_t;
 typedef struct label_part_spec label_part_spec_t;
+typedef struct label_bd label_bd_t;
+typedef struct label_bd_ops label_bd_ops_t;
 
 /** Ops for individual label type */
 typedef struct {
-	int (*open)(service_id_t, label_t **);
-	int (*create)(service_id_t, label_t **);
+	int (*open)(label_bd_t *, label_t **);
+	int (*create)(label_bd_t *, label_t **);
 	void (*close)(label_t *);
 	int (*destroy)(label_t *);
@@ -138,4 +141,24 @@
 } label_mbr_t;
 
+/** Block device operations */
+struct label_bd_ops {
+	/** Get block size */
+	int (*get_bsize)(void *, size_t *);
+	/** Get number of blocks */
+	int (*get_nblocks)(void *, aoff64_t *);
+	/** Read blocks */
+	int (*read)(void *, aoff64_t, size_t, void *);
+	/** Write blocks */
+	int (*write)(void *, aoff64_t, size_t, const void *);
+};
+
+/** Block device */
+struct label_bd {
+	/** Ops structure */
+	label_bd_ops_t *ops;
+	/** Argument */
+	void *arg;
+};
+
 /** Label instance */
 struct label {
@@ -144,6 +167,6 @@
 	/** Label type */
 	label_type_t ltype;
-	/** Block device service ID */
-	service_id_t svc_id;
+	/** Block device */
+	label_bd_t bd;
 	/** Partitions */
 	list_t parts; /* of label_part_t */
Index: uspace/lib/label/src/dummy.c
===================================================================
--- uspace/lib/label/src/dummy.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/label/src/dummy.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,4 @@
  */
 
-#include <block.h>
 #include <errno.h>
 #include <mem.h>
@@ -41,6 +40,6 @@
 #include "dummy.h"
 
-static int dummy_open(service_id_t, label_t **);
-static int dummy_create(service_id_t, label_t **);
+static int dummy_open(label_bd_t *, label_t **);
+static int dummy_create(label_bd_t *, label_t **);
 static void dummy_close(label_t *);
 static int dummy_destroy(label_t *);
@@ -67,5 +66,5 @@
 };
 
-static int dummy_open(service_id_t sid, label_t **rlabel)
+static int dummy_open(label_bd_t *bd, label_t **rlabel)
 {
 	label_t *label = NULL;
@@ -76,5 +75,5 @@
 	int rc;
 
-	rc = block_get_bsize(sid, &bsize);
+	rc = bd->ops->get_bsize(bd->arg, &bsize);
 	if (rc != EOK) {
 		rc = EIO;
@@ -82,5 +81,5 @@
 	}
 
-	rc = block_get_nblocks(sid, &nblocks);
+	rc = bd->ops->get_nblocks(bd->arg, &nblocks);
 	if (rc != EOK) {
 		rc = EIO;
@@ -101,5 +100,5 @@
 	label->ops = &dummy_label_ops;
 	label->ltype = lt_none;
-	label->svc_id = sid;
+	label->bd = *bd;
 	label->ablock0 = ba_min;
 	label->anblocks = ba_max - ba_min + 1;
@@ -129,5 +128,5 @@
 }
 
-static int dummy_create(service_id_t sid, label_t **rlabel)
+static int dummy_create(label_bd_t *bd, label_t **rlabel)
 {
 	return ENOTSUP;
Index: uspace/lib/label/src/empty.c
===================================================================
--- uspace/lib/label/src/empty.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/label/src/empty.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2015 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 liblabel
+ * @{
+ */
+/**
+ * @file Empty partition handling
+ * @brief
+ */
+
+#include <errno.h>
+#include <io/log.h>
+#include <label/empty.h>
+#include <loc.h>
+#include <stdlib.h>
+
+/*
+ * The partition will be considered empty if at least a minimum number of
+ * bytes *and* blocks (whichever is larger) at the beginning and end of
+ * the partition is zero.
+ */
+enum {
+	min_empty_bytes = 16384,
+	/*
+	 * First block in ISO 9660 that cannot be empty is the first
+	 * volume descriptor at LBA 16
+	 */
+	min_empty_blocks = 17
+};
+
+static bool mem_is_zero(void *buf, size_t size)
+{
+	uint8_t *bp;
+	size_t i;
+
+	bp = (uint8_t *)buf;
+	for (i = 0; i < size; i++) {
+		if (bp[i] != 0)
+			return false;
+	}
+
+	return true;
+}
+
+/** Calculate number of blocks to check.
+ *
+ * Will store to @a *ncb the number of blocks that should be checked
+ * at the beginning and end of device each.
+ *
+ * @param nblocks Total number of blocks on block device
+ * @param block_size Block size
+ * @param ncb Place to store number of blocks to check.
+ */
+static void calc_num_check_blocks(aoff64_t nblocks, size_t block_size,
+    aoff64_t *ncb)
+{
+	aoff64_t n;
+
+	/* Check first 16 kiB / 16 blocks, whichever is more */
+	n = (min_empty_bytes + block_size - 1) / block_size;
+	if (n < min_empty_blocks)
+		n = min_empty_blocks;
+	/*
+	 * Limit to half of the device so we do not process the same blocks
+	 * twice
+	 */
+	if (n > (nblocks + 1) / 2)
+		n = (nblocks + 1) / 2;
+
+	*ncb = n;
+}
+
+int label_bd_is_empty(label_bd_t *bd, bool *rempty)
+{
+	int rc;
+	void *buf = NULL;
+	aoff64_t nblocks;
+	aoff64_t n;
+	aoff64_t i;
+	size_t block_size;
+	bool empty;
+
+	rc = bd->ops->get_bsize(bd->arg, &block_size);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "block size.");
+		rc = EIO;
+		goto error;
+	}
+
+	rc = bd->ops->get_nblocks(bd->arg, &nblocks);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "number of blocks.");
+		rc = EIO;
+		goto error;
+	}
+
+	calc_num_check_blocks(nblocks, block_size, &n);
+
+	buf = calloc(block_size, 1);
+	if (buf == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	empty = true;
+
+	for (i = 0; i < n; i++) {
+		rc = bd->ops->read(bd->arg, i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+
+		if (!mem_is_zero(buf, block_size)) {
+			empty = false;
+			goto done;
+		}
+	}
+
+	for (i = 0; i < n; i++) {
+		rc = bd->ops->read(bd->arg, nblocks - n + i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+
+		if (!mem_is_zero(buf, block_size)) {
+			empty = false;
+			goto done;
+		}
+	}
+
+done:
+	free(buf);
+	*rempty = empty;
+	return EOK;
+error:
+	if (buf != NULL)
+		free(buf);
+	return rc;
+}
+
+int label_bd_empty(label_bd_t *bd)
+{
+	int rc;
+	void *buf = NULL;
+	aoff64_t nblocks;
+	aoff64_t n;
+	aoff64_t i;
+	size_t block_size;
+
+	rc = bd->ops->get_bsize(bd->arg, &block_size);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "block size.");
+		rc = EIO;
+		goto error;
+	}
+
+	rc = bd->ops->get_nblocks(bd->arg, &nblocks);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "number of blocks.");
+		rc = EIO;
+		goto error;
+	}
+
+	calc_num_check_blocks(nblocks, block_size, &n);
+
+	buf = calloc(block_size, 1);
+	if (buf == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	for (i = 0; i < n; i++) {
+		rc = bd->ops->write(bd->arg, i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+	}
+
+	for (i = 0; i < n; i++) {
+		rc = bd->ops->write(bd->arg, nblocks - n + i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+	}
+
+	free(buf);
+	return EOK;
+error:
+	if (buf != NULL)
+		free(buf);
+	return rc;
+}
+
+int label_part_empty(label_part_t *part)
+{
+	int rc;
+	void *buf = NULL;
+	aoff64_t block0;
+	aoff64_t nblocks;
+	aoff64_t n;
+	aoff64_t i;
+	size_t block_size;
+	label_bd_t *bd;
+
+	bd = &part->label->bd;
+
+	block_size = part->label->block_size;
+	block0 = part->block0;
+	nblocks = part->nblocks;
+
+	calc_num_check_blocks(nblocks, block_size, &n);
+
+	buf = calloc(block_size, 1);
+	if (buf == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	for (i = 0; i < n; i++) {
+		rc = bd->ops->write(bd->arg, block0 + i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+	}
+
+	for (i = 0; i < n; i++) {
+		rc = bd->ops->write(bd->arg, block0 + nblocks - n + i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+	}
+
+	free(buf);
+	return EOK;
+error:
+	if (buf != NULL)
+		free(buf);
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/lib/label/src/gpt.c
===================================================================
--- uspace/lib/label/src/gpt.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/label/src/gpt.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,5 +35,4 @@
 
 #include <adt/checksum.h>
-#include <block.h>
 #include <byteorder.h>
 #include <errno.h>
@@ -47,6 +46,6 @@
 #include "gpt.h"
 
-static int gpt_open(service_id_t, label_t **);
-static int gpt_create(service_id_t, label_t **);
+static int gpt_open(label_bd_t *, label_t **);
+static int gpt_create(label_bd_t *, label_t **);
 static void gpt_close(label_t *);
 static int gpt_destroy(label_t *);
@@ -71,6 +70,6 @@
 static int gpt_hdr_get_crc(gpt_header_t *, size_t, uint32_t *);
 
-static int gpt_pmbr_create(service_id_t, size_t, uint64_t);
-static int gpt_pmbr_destroy(service_id_t, size_t);
+static int gpt_pmbr_create(label_bd_t *, size_t, uint64_t);
+static int gpt_pmbr_destroy(label_bd_t *, size_t);
 
 const uint8_t efi_signature[8] = {
@@ -93,5 +92,5 @@
 };
 
-static int gpt_open(service_id_t sid, label_t **rlabel)
+static int gpt_open(label_bd_t *bd, label_t **rlabel)
 {
 	label_t *label = NULL;
@@ -100,4 +99,5 @@
 	uint8_t *etable[2];
 	size_t bsize;
+	aoff64_t nblocks;
 	uint32_t num_entries;
 	uint32_t esize;
@@ -118,5 +118,11 @@
 	etable[1] = NULL;
 
-	rc = block_get_bsize(sid, &bsize);
+	rc = bd->ops->get_bsize(bd->arg, &bsize);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	rc = bd->ops->get_nblocks(bd->arg, &nblocks);
 	if (rc != EOK) {
 		rc = EIO;
@@ -141,5 +147,5 @@
 	}
 
-	rc = block_read_direct(sid, gpt_hdr_ba, 1, gpt_hdr[0]);
+	rc = bd->ops->read(bd->arg, gpt_hdr_ba, 1, gpt_hdr[0]);
 	if (rc != EOK) {
 		rc = EIO;
@@ -149,5 +155,10 @@
 	h1ba = uint64_t_le2host(gpt_hdr[0]->alternate_lba);
 
-	rc = block_read_direct(sid, h1ba, 1, gpt_hdr[1]);
+	if (h1ba >= nblocks) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	rc = bd->ops->read(bd->arg, h1ba, 1, gpt_hdr[1]);
 	if (rc != EOK) {
 		rc = EIO;
@@ -277,5 +288,5 @@
 		}
 
-		rc = block_read_direct(sid, ptba[j], pt_blocks / 2, etable[j]);
+		rc = bd->ops->read(bd->arg, ptba[j], pt_blocks / 2, etable[j]);
 		if (rc != EOK) {
 			rc = EIO;
@@ -308,5 +319,5 @@
 	label->ops = &gpt_label_ops;
 	label->ltype = lt_gpt;
-	label->svc_id = sid;
+	label->bd = *bd;
 	label->ablock0 = ba_min;
 	label->anblocks = ba_max - ba_min + 1;
@@ -334,5 +345,5 @@
 }
 
-static int gpt_create(service_id_t sid, label_t **rlabel)
+static int gpt_create(label_bd_t *bd, label_t **rlabel)
 {
 	label_t *label = NULL;
@@ -353,5 +364,5 @@
 	int rc;
 
-	rc = block_get_bsize(sid, &bsize);
+	rc = bd->ops->get_bsize(bd->arg, &bsize);
 	if (rc != EOK) {
 		rc = EIO;
@@ -364,5 +375,5 @@
 	}
 
-	rc = block_get_nblocks(sid, &nblocks);
+	rc = bd->ops->get_nblocks(bd->arg, &nblocks);
 	if (rc != EOK) {
 		rc = EIO;
@@ -380,5 +391,5 @@
 	}
 
-	rc = gpt_pmbr_create(sid, bsize, nblocks);
+	rc = gpt_pmbr_create(bd, bsize, nblocks);
 	if (rc != EOK) {
 		rc = EIO;
@@ -405,5 +416,5 @@
 		}
 
-		rc = block_write_direct(sid, ptba[i], pt_blocks, etable);
+		rc = bd->ops->write(bd->arg, ptba[i], pt_blocks, etable);
 		if (rc != EOK) {
 			rc = EIO;
@@ -440,5 +451,5 @@
 		gpt_hdr_compute_crc(gpt_hdr, sizeof(gpt_header_t));
 
-		rc = block_write_direct(sid, hdr_ba[i], 1, gpt_hdr);
+		rc = bd->ops->write(bd->arg, hdr_ba[i], 1, gpt_hdr);
 		if (rc != EOK) {
 			rc = EIO;
@@ -460,5 +471,5 @@
 	label->ops = &gpt_label_ops;
 	label->ltype = lt_gpt;
-	label->svc_id = sid;
+	label->bd = *bd;
 	label->ablock0 = ba_min;
 	label->anblocks = ba_max - ba_min + 1;
@@ -520,5 +531,5 @@
 		}
 
-		rc = block_write_direct(label->svc_id, label->lt.gpt.hdr_ba[i],
+		rc = label->bd.ops->write(label->bd.arg, label->lt.gpt.hdr_ba[i],
 		    1, gpt_hdr);
 		if (rc != EOK) {
@@ -537,5 +548,5 @@
 		}
 
-		rc = block_write_direct(label->svc_id,
+		rc = label->bd.ops->write(label->bd.arg,
 		    label->lt.gpt.ptable_ba[i], label->lt.gpt.pt_blocks,
 		    etable);
@@ -549,5 +560,5 @@
 	}
 
-	rc = gpt_pmbr_destroy(label->svc_id, label->block_size);
+	rc = gpt_pmbr_destroy(&label->bd, label->block_size);
 	if (rc != EOK)
 		goto error;
@@ -871,5 +882,5 @@
 		nblocks = label->lt.gpt.pt_blocks;
 
-		rc = block_read_direct(label->svc_id, ba, nblocks, buf);
+		rc = label->bd.ops->read(label->bd.arg, ba, nblocks, buf);
 		if (rc != EOK) {
 			rc = EIO;
@@ -888,5 +899,5 @@
 		*e = *pte;
 
-		rc = block_write_direct(label->svc_id, ba, nblocks, buf);
+		rc = label->bd.ops->write(label->bd.arg, ba, nblocks, buf);
 		if (rc != EOK) {
 			rc = EIO;
@@ -923,5 +934,5 @@
 
 	for (i = 0; i < 2; i++) {
-		rc = block_read_direct(label->svc_id,
+		rc = label->bd.ops->read(label->bd.arg,
 		    label->lt.gpt.hdr_ba[i], 1, gpt_hdr);
 		if (rc != EOK) {
@@ -933,5 +944,5 @@
 		gpt_hdr_compute_crc(gpt_hdr, label->lt.gpt.hdr_size);
 
-		rc = block_write_direct(label->svc_id,
+		rc = label->bd.ops->write(label->bd.arg,
 		    label->lt.gpt.hdr_ba[i], 1, gpt_hdr);
 		if (rc != EOK) {
@@ -940,7 +951,7 @@
 		}
 	}
-	
+
 	rc = EOK;
-	
+
 exit:
 	free(gpt_hdr);
@@ -974,5 +985,5 @@
 
 /** Create GPT Protective MBR */
-static int gpt_pmbr_create(service_id_t sid, size_t bsize, uint64_t nblocks)
+static int gpt_pmbr_create(label_bd_t *bd, size_t bsize, uint64_t nblocks)
 {
 	mbr_br_block_t *pmbr = NULL;
@@ -998,5 +1009,5 @@
 	pmbr->signature = host2uint16_t_le(mbr_br_signature);
 
-	rc = block_write_direct(sid, mbr_ba, 1, pmbr);
+	rc = bd->ops->write(bd->arg, mbr_ba, 1, pmbr);
 	if (rc != EOK) {
 		rc = EIO;
@@ -1012,5 +1023,5 @@
 
 /** Destroy GPT Protective MBR */
-static int gpt_pmbr_destroy(service_id_t sid, size_t bsize)
+static int gpt_pmbr_destroy(label_bd_t *bd, size_t bsize)
 {
 	mbr_br_block_t *pmbr = NULL;
@@ -1023,5 +1034,5 @@
 	}
 
-	rc = block_write_direct(sid, mbr_ba, 1, pmbr);
+	rc = bd->ops->write(bd->arg, mbr_ba, 1, pmbr);
 	if (rc != EOK) {
 		rc = EIO;
Index: uspace/lib/label/src/label.c
===================================================================
--- uspace/lib/label/src/label.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/label/src/label.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,5 @@
 #include <adt/list.h>
 #include <errno.h>
-#include <label.h>
+#include <label/label.h>
 #include <mem.h>
 #include <stdlib.h>
@@ -51,5 +51,5 @@
 };
 
-int label_open(service_id_t sid, label_t **rlabel)
+int label_open(label_bd_t *bd, label_t **rlabel)
 {
 	label_ops_t **ops;
@@ -58,5 +58,5 @@
 	ops = &probe_list[0];
 	while (ops[0] != NULL) {
-		rc = ops[0]->open(sid, rlabel);
+		rc = ops[0]->open(bd, rlabel);
 		if (rc == EOK)
 			return EOK;
@@ -67,5 +67,5 @@
 }
 
-int label_create(service_id_t sid, label_type_t ltype, label_t **rlabel)
+int label_create(label_bd_t *bd, label_type_t ltype, label_t **rlabel)
 {
 	label_ops_t *ops = NULL;
@@ -85,5 +85,5 @@
 		return ENOTSUP;
 
-	return ops->create(sid, rlabel);
+	return ops->create(bd, rlabel);
 }
 
Index: uspace/lib/label/src/mbr.c
===================================================================
--- uspace/lib/label/src/mbr.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/label/src/mbr.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,5 +34,4 @@
  */
 
-#include <block.h>
 #include <byteorder.h>
 #include <errno.h>
@@ -40,10 +39,11 @@
 #include <stdlib.h>
 
+#include "std/fat.h"
 #include "std/mbr.h"
 #include "mbr.h"
 
-static int mbr_open(service_id_t, label_t **);
+static int mbr_open(label_bd_t *, label_t **);
 static int mbr_open_ext(label_t *);
-static int mbr_create(service_id_t, label_t **);
+static int mbr_create(label_bd_t *, label_t **);
 static void mbr_close(label_t *);
 static int mbr_destroy(label_t *);
@@ -86,8 +86,9 @@
 };
 
-static int mbr_open(service_id_t sid, label_t **rlabel)
+static int mbr_open(label_bd_t *bd, label_t **rlabel)
 {
 	label_t *label = NULL;
 	mbr_br_block_t *mbr = NULL;
+	fat_bs_t *bs;
 	mbr_pte_t *eptr;
 	uint16_t sgn;
@@ -97,11 +98,11 @@
 	int rc;
 
-	rc = block_get_bsize(sid, &bsize);
-	if (rc != EOK) {
-		rc = EIO;
-		goto error;
-	}
-
-	rc = block_get_nblocks(sid, &nblocks);
+	rc = bd->ops->get_bsize(bd->arg, &bsize);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	rc = bd->ops->get_nblocks(bd->arg, &nblocks);
 	if (rc != EOK) {
 		rc = EIO;
@@ -125,5 +126,7 @@
 	}
 
-	rc = block_read_direct(sid, mbr_ba, 1, mbr);
+	bs = (fat_bs_t *)mbr;
+
+	rc = bd->ops->read(bd->arg, mbr_ba, 1, mbr);
 	if (rc != EOK) {
 		rc = EIO;
@@ -146,4 +149,21 @@
 	}
 
+	/*
+	 * We can't really tell whether this is an MBR. Make sure
+	 * this is not actually the BR of a 12/16-bit FAT file system
+	 */
+	if (bs->type[0] == 'F' && bs->type[1] == 'A' && bs->type[2] == 'T') {
+		rc = EIO;
+		goto error;
+	}
+
+	/*
+	 * Or a 32-bit FAT file system
+	 */
+	if (bs->fat32.type[0] == 'F' && bs->fat32.type[1] == 'A' &&
+	    bs->fat32.type[2] == 'T') {
+		rc = EIO;
+		goto error;
+	}
 
 	label->ext_part = NULL;
@@ -160,5 +180,5 @@
 	label->ops = &mbr_label_ops;
 	label->ltype = lt_mbr;
-	label->svc_id = sid;
+	label->bd = *bd;
 	label->block_size = bsize;
 	label->ablock0 = mbr_ablock0;
@@ -219,5 +239,5 @@
 	while (true) {
 		/* Read EBR */
-		rc = block_read_direct(label->svc_id, ebr_b0, 1, ebr);
+		rc = label->bd.ops->read(label->bd.arg, ebr_b0, 1, ebr);
 		if (rc != EOK) {
 			rc = EIO;
@@ -280,5 +300,5 @@
 }
 
-static int mbr_create(service_id_t sid, label_t **rlabel)
+static int mbr_create(label_bd_t *bd, label_t **rlabel)
 {
 	label_t *label = NULL;
@@ -289,11 +309,11 @@
 	int rc;
 
-	rc = block_get_bsize(sid, &bsize);
-	if (rc != EOK) {
-		rc = EIO;
-		goto error;
-	}
-
-	rc = block_get_nblocks(sid, &nblocks);
+	rc = bd->ops->get_bsize(bd->arg, &bsize);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	rc = bd->ops->get_nblocks(bd->arg, &nblocks);
 	if (rc != EOK) {
 		rc = EIO;
@@ -321,5 +341,5 @@
 	mbr->signature = host2uint16_t_le(mbr_br_signature);
 
-	rc = block_write_direct(sid, mbr_ba, 1, mbr);
+	rc = bd->ops->write(bd->arg, mbr_ba, 1, mbr);
 	if (rc != EOK) {
 		rc = EIO;
@@ -333,5 +353,5 @@
 	label->ltype = lt_mbr;
 	label->block_size = bsize;
-	label->svc_id = sid;
+	label->bd = *bd;
 	label->ablock0 = mbr_ablock0;
 	label->anblocks = nblocks - mbr_ablock0;
@@ -387,5 +407,5 @@
 	}
 
-	rc = block_write_direct(label->svc_id, mbr_ba, 1, mbr);
+	rc = label->bd.ops->write(label->bd.arg, mbr_ba, 1, mbr);
 	if (rc != EOK) {
 		rc = EIO;
@@ -998,5 +1018,5 @@
 		return ENOMEM;
 
-	rc = block_read_direct(label->svc_id, mbr_ba, 1, br);
+	rc = label->bd.ops->read(label->bd.arg, mbr_ba, 1, br);
 	if (rc != EOK) {
 		rc = EIO;
@@ -1006,5 +1026,5 @@
 	br->pte[index] = *pte;
 
-	rc = block_write_direct(label->svc_id, mbr_ba, 1, br);
+	rc = label->bd.ops->write(label->bd.arg, mbr_ba, 1, br);
 	if (rc != EOK) {
 		rc = EIO;
@@ -1066,5 +1086,5 @@
 	br->signature = host2uint16_t_le(mbr_br_signature);
 
-	rc = block_write_direct(label->svc_id, ba, 1, br);
+	rc = label->bd.ops->write(label->bd.arg, ba, 1, br);
 	if (rc != EOK) {
 		rc = EIO;
@@ -1091,5 +1111,5 @@
 	ba = part->block0 - part->hdr_blocks;
 
-	rc = block_write_direct(label->svc_id, ba, 1, br);
+	rc = label->bd.ops->write(label->bd.arg, ba, 1, br);
 	if (rc != EOK) {
 		rc = EIO;
@@ -1118,5 +1138,5 @@
 		return ENOMEM;
 
-	rc = block_read_direct(label->svc_id, ba, 1, br);
+	rc = label->bd.ops->read(label->bd.arg, ba, 1, br);
 	if (rc != EOK) {
 		rc = EIO;
@@ -1133,5 +1153,5 @@
 	mbr_log_part_to_ptes(part, NULL, &br->pte[mbr_ebr_pte_next]);
 
-	rc = block_write_direct(label->svc_id, ba, 1, br);
+	rc = label->bd.ops->write(label->bd.arg, ba, 1, br);
 	if (rc != EOK) {
 		rc = EIO;
Index: uspace/lib/label/test/label.c
===================================================================
--- uspace/lib/label/test/label.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/label/test/label.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <label/label.h>
+#include <mem.h>
+#include <pcut/pcut.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(label);
+
+static int label_test_get_bsize(void *, size_t *);
+static int label_test_get_nblocks(void *, aoff64_t *);
+static int label_test_read(void *, aoff64_t, size_t, void *);
+static int label_test_write(void *, aoff64_t, size_t, const void *);
+
+label_bd_ops_t label_test_ops = {
+	.get_bsize = label_test_get_bsize,
+	.get_nblocks = label_test_get_nblocks,
+	.read = label_test_read,
+	.write = label_test_write
+};
+
+/** Pretended block device for testing */
+typedef struct {
+	char *data;
+	size_t bsize;
+	aoff64_t nblocks;
+} test_bd_t;
+
+enum {
+	test_block_size = 512,
+	test_nblocks = 1024
+};
+
+/** Create pretended block device.
+ *
+ * @param bsize Block size
+ * @param nblocks Number of blocks
+ * @param rbd Place to store pointer to new pretended block device
+ */
+static int test_bd_create(size_t bsize, aoff64_t nblocks, test_bd_t **rbd)
+{
+	test_bd_t *bd;
+
+	bd = calloc(1, sizeof(test_bd_t));
+	if (bd == NULL)
+		return ENOMEM;
+
+	bd->data = calloc(bsize, nblocks);
+	if (bd->data == NULL) {
+		free(bd);
+		return ENOMEM;
+	}
+
+	bd->bsize = bsize;
+	bd->nblocks = nblocks;
+	*rbd = bd;
+
+	return EOK;
+}
+
+/** Destroy pretended block device.
+ *
+ * @param bd Pretended block device
+ */
+static void test_bd_destroy(test_bd_t *bd)
+{
+	free(bd->data);
+	free(bd);
+}
+
+/** Get block size wrapper for liblabel */
+static int label_test_get_bsize(void *arg, size_t *bsize)
+{
+	test_bd_t *bd = (test_bd_t *)arg;
+
+	*bsize = bd->bsize;
+	return EOK;
+}
+
+/** Get number of blocks wrapper for liblabel */
+static int label_test_get_nblocks(void *arg, aoff64_t *nblocks)
+{
+	test_bd_t *bd = (test_bd_t *)arg;
+
+	*nblocks = bd->nblocks;
+	return EOK;
+}
+
+/** Read blocks wrapper for liblabel */
+static int label_test_read(void *arg, aoff64_t ba, size_t cnt, void *buf)
+{
+	test_bd_t *bd = (test_bd_t *)arg;
+
+	if (ba >= bd->nblocks)
+		return EINVAL;
+
+	memcpy(buf, bd->data + ba * bd->bsize, bd->bsize);
+	return EOK;
+}
+
+/** Write blocks wrapper for liblabel */
+static int label_test_write(void *arg, aoff64_t ba, size_t cnt, const void *data)
+{
+	test_bd_t *bd = (test_bd_t *)arg;
+
+	if (ba >= bd->nblocks)
+		return EINVAL;
+
+	memcpy(bd->data + ba * bd->bsize, data, bd->bsize);
+	return EOK;
+}
+
+PCUT_TEST(open_empty) {
+	label_t *label;
+	label_bd_t lbd;
+	label_info_t linfo;
+	label_part_t *part;
+	test_bd_t *bd = NULL;
+	int rc;
+
+	rc = test_bd_create(test_block_size, test_nblocks, &bd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	lbd.ops = &label_test_ops;
+	lbd.arg = (void *)bd;
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(lt_none, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(0, linfo.flags);
+
+	/* There should be exactly one pseudo partition */
+	part = label_part_first(label);
+	PCUT_ASSERT_NOT_NULL(part);
+
+	part = label_part_next(part);
+	PCUT_ASSERT_NULL(part);
+
+	label_close(label);
+
+	test_bd_destroy(bd);
+}
+
+PCUT_TEST(create_destroy_mbr) {
+	label_t *label;
+	label_bd_t lbd;
+	label_info_t linfo;
+	label_part_t *part;
+	test_bd_t *bd = NULL;
+	int rc;
+
+	rc = test_bd_create(test_block_size, test_nblocks, &bd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	lbd.ops = &label_test_ops;
+	lbd.arg = (void *)bd;
+
+	rc = label_create(&lbd, lt_mbr, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(lt_mbr, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(lf_ext_supp | lf_can_create_pri |
+	    lf_can_create_ext, linfo.flags);
+
+	/* There should be no partitions */
+	part = label_part_first(label);
+	PCUT_ASSERT_NULL(part);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Everything should still be the same */
+	PCUT_ASSERT_INT_EQUALS(lt_mbr, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(lf_ext_supp | lf_can_create_pri |
+	    lf_can_create_ext, linfo.flags);
+
+	rc = label_destroy(label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* There should be no label now */
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(lt_none, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(0, linfo.flags);
+
+	label_close(label);
+
+	test_bd_destroy(bd);
+}
+
+PCUT_TEST(create_destroy_gpt) {
+	label_t *label;
+	label_bd_t lbd;
+	label_info_t linfo;
+	label_part_t *part;
+	test_bd_t *bd = NULL;
+	int rc;
+
+	rc = test_bd_create(test_block_size, test_nblocks, &bd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	lbd.ops = &label_test_ops;
+	lbd.arg = (void *)bd;
+
+	rc = label_create(&lbd, lt_gpt, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(lt_gpt, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(lf_can_create_pri | lf_ptype_uuid, linfo.flags);
+
+	/* There should be no partitions */
+	part = label_part_first(label);
+	PCUT_ASSERT_NULL(part);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Everything should still be the same */
+	PCUT_ASSERT_INT_EQUALS(lt_gpt, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(lf_can_create_pri | lf_ptype_uuid, linfo.flags);
+
+	rc = label_destroy(label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* There should be no label now */
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(lt_none, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(0, linfo.flags);
+
+	label_close(label);
+
+	test_bd_destroy(bd);
+}
+
+PCUT_TEST(mbr_primary_part) {
+	label_t *label;
+	label_bd_t lbd;
+	label_info_t linfo;
+	label_part_t *part;
+	label_part_spec_t pspec;
+	label_part_info_t pinfo;
+	label_ptype_t ptype;
+	test_bd_t *bd = NULL;
+	int rc;
+
+	rc = test_bd_create(test_block_size, test_nblocks, &bd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	lbd.ops = &label_test_ops;
+	lbd.arg = (void *)bd;
+
+	rc = label_create(&lbd, lt_mbr, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* There should be no partitions */
+	part = label_part_first(label);
+	PCUT_ASSERT_NULL(part);
+
+	rc = label_suggest_ptype(label, lpc_ext4, &ptype);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	memset(&pspec, 0, sizeof(pspec));
+	pspec.index = 1;
+	pspec.block0 = linfo.ablock0;
+	pspec.nblocks = linfo.anblocks;
+	pspec.hdr_blocks = 0;
+	pspec.pkind = lpk_primary;
+	pspec.ptype = ptype;
+
+	rc = label_part_create(label, &pspec, &part);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	label_part_get_info(part, &pinfo);
+	PCUT_ASSERT_INT_EQUALS(1, pinfo.index);
+	PCUT_ASSERT_INT_EQUALS(lpk_primary, pinfo.pkind);
+	PCUT_ASSERT_INT_EQUALS(linfo.ablock0, pinfo.block0);
+	PCUT_ASSERT_INT_EQUALS(linfo.anblocks, pinfo.nblocks);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(lt_mbr, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(lf_ext_supp | lf_can_create_pri |
+	    lf_can_create_ext | lf_can_delete_part, linfo.flags);
+
+	part = label_part_first(label);
+	PCUT_ASSERT_NOT_NULL(part);
+	PCUT_ASSERT_NULL(label_part_next(part));
+
+	label_part_get_info(part, &pinfo);
+	PCUT_ASSERT_INT_EQUALS(1, pinfo.index);
+	PCUT_ASSERT_INT_EQUALS(lpk_primary, pinfo.pkind);
+	PCUT_ASSERT_INT_EQUALS(linfo.ablock0, pinfo.block0);
+	PCUT_ASSERT_INT_EQUALS(linfo.anblocks, pinfo.nblocks);
+
+	/* Destroy the partition */
+	rc = label_part_destroy(part);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* There should be no partitions */
+	part = label_part_first(label);
+	PCUT_ASSERT_NULL(part);
+
+	label_close(label);
+
+	test_bd_destroy(bd);
+}
+
+PCUT_TEST(mbr_logical_part) {
+	label_t *label;
+	label_bd_t lbd;
+	label_info_t linfo;
+	label_part_t *part, *lpart, *epart;
+	label_part_spec_t pspec;
+	label_ptype_t ptype;
+	label_part_info_t pinfo, lpinfo, epinfo;
+	test_bd_t *bd = NULL;
+	int rc;
+
+	rc = test_bd_create(test_block_size, test_nblocks, &bd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	lbd.ops = &label_test_ops;
+	lbd.arg = (void *)bd;
+
+	rc = label_create(&lbd, lt_mbr, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* There should be no partitions */
+	part = label_part_first(label);
+	PCUT_ASSERT_NULL(part);
+
+	memset(&pspec, 0, sizeof(pspec));
+	pspec.index = 1;
+	pspec.block0 = linfo.ablock0;
+	pspec.nblocks = linfo.anblocks;
+	pspec.hdr_blocks = 0;
+	pspec.pkind = lpk_extended;
+
+	rc = label_part_create(label, &pspec, &epart);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	label_part_get_info(epart, &epinfo);
+	PCUT_ASSERT_INT_EQUALS(1, epinfo.index);
+	PCUT_ASSERT_INT_EQUALS(lpk_extended, epinfo.pkind);
+	PCUT_ASSERT_INT_EQUALS(linfo.ablock0, epinfo.block0);
+	PCUT_ASSERT_INT_EQUALS(linfo.anblocks, epinfo.nblocks);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(lt_mbr, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(lf_ext_supp | lf_can_create_pri |
+	    lf_can_create_log | lf_can_delete_part, linfo.flags);
+
+	epart = label_part_first(label);
+	PCUT_ASSERT_NOT_NULL(epart);
+	PCUT_ASSERT_NULL(label_part_next(epart));
+
+	label_part_get_info(epart, &epinfo);
+	PCUT_ASSERT_INT_EQUALS(1, epinfo.index);
+	PCUT_ASSERT_INT_EQUALS(lpk_extended, epinfo.pkind);
+	PCUT_ASSERT_INT_EQUALS(linfo.ablock0, epinfo.block0);
+	PCUT_ASSERT_INT_EQUALS(linfo.anblocks, epinfo.nblocks);
+
+	/* Create logical partition */
+	rc = label_suggest_ptype(label, lpc_ext4, &ptype);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	memset(&pspec, 0, sizeof(pspec));
+	pspec.index = 0;
+	pspec.block0 = epinfo.block0 + 1;
+	pspec.nblocks = epinfo.nblocks - 1;
+	pspec.hdr_blocks = 1;
+	pspec.pkind = lpk_logical;
+	pspec.ptype = ptype;
+
+	rc = label_part_create(label, &pspec, &lpart);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	label_part_get_info(lpart, &lpinfo);
+	PCUT_ASSERT_INT_EQUALS(5, lpinfo.index);
+	PCUT_ASSERT_INT_EQUALS(lpk_logical, lpinfo.pkind);
+	PCUT_ASSERT_INT_EQUALS(epinfo.block0 + 1, lpinfo.block0);
+	PCUT_ASSERT_INT_EQUALS(epinfo.nblocks - 1, lpinfo.nblocks);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Find the extended and the logical partition */
+
+	epart = NULL;
+	lpart = NULL;
+
+	part = label_part_first(label);
+	while (part != NULL) {
+		label_part_get_info(part, &pinfo);
+		if (pinfo.pkind == lpk_extended) {
+			epart = part;
+		} else {
+			PCUT_ASSERT_INT_EQUALS(lpk_logical, pinfo.pkind);
+			lpart = part;
+		}
+
+		part = label_part_next(part);
+	}
+
+	PCUT_ASSERT_NOT_NULL(epart);
+	PCUT_ASSERT_NOT_NULL(lpart);
+
+	/* Destroy the logical partition */
+	rc = label_part_destroy(lpart);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Destroy the extended partition */
+	rc = label_part_destroy(epart);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* There should be no partitions */
+	part = label_part_first(label);
+	PCUT_ASSERT_NULL(part);
+
+	label_close(label);
+
+	test_bd_destroy(bd);
+}
+
+
+PCUT_TEST(gpt_part) {
+	label_t *label;
+	label_bd_t lbd;
+	label_info_t linfo;
+	label_part_t *part;
+	label_part_spec_t pspec;
+	label_part_info_t pinfo;
+	label_ptype_t ptype;
+	test_bd_t *bd = NULL;
+	int rc;
+
+	rc = test_bd_create(test_block_size, test_nblocks, &bd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	lbd.ops = &label_test_ops;
+	lbd.arg = (void *)bd;
+
+	rc = label_create(&lbd, lt_gpt, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* There should be no partitions */
+	part = label_part_first(label);
+	PCUT_ASSERT_NULL(part);
+
+	rc = label_suggest_ptype(label, lpc_ext4, &ptype);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	memset(&pspec, 0, sizeof(pspec));
+	pspec.index = 1;
+	pspec.block0 = linfo.ablock0;
+	pspec.nblocks = linfo.anblocks;
+	pspec.hdr_blocks = 0;
+	pspec.pkind = lpk_primary;
+	pspec.ptype = ptype;
+
+	rc = label_part_create(label, &pspec, &part);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	label_part_get_info(part, &pinfo);
+	PCUT_ASSERT_INT_EQUALS(1, pinfo.index);
+	PCUT_ASSERT_INT_EQUALS(lpk_primary, pinfo.pkind);
+	PCUT_ASSERT_INT_EQUALS(linfo.ablock0, pinfo.block0);
+	PCUT_ASSERT_INT_EQUALS(linfo.anblocks, pinfo.nblocks);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = label_get_info(label, &linfo);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(lt_gpt, linfo.ltype);
+	PCUT_ASSERT_INT_EQUALS(lf_can_create_pri | lf_ptype_uuid |
+	    lf_can_delete_part, linfo.flags);
+
+	part = label_part_first(label);
+	PCUT_ASSERT_NOT_NULL(part);
+	PCUT_ASSERT_NULL(label_part_next(part));
+
+	label_part_get_info(part, &pinfo);
+	PCUT_ASSERT_INT_EQUALS(1, pinfo.index);
+	PCUT_ASSERT_INT_EQUALS(lpk_primary, pinfo.pkind);
+	PCUT_ASSERT_INT_EQUALS(linfo.ablock0, pinfo.block0);
+	PCUT_ASSERT_INT_EQUALS(linfo.anblocks, pinfo.nblocks);
+
+	/* Destroy the partition */
+	rc = label_part_destroy(part);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Close and reopen */
+	label_close(label);
+
+	rc = label_open(&lbd, &label);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* There should be no partitions */
+	part = label_part_first(label);
+	PCUT_ASSERT_NULL(part);
+
+	label_close(label);
+
+	test_bd_destroy(bd);
+}
+
+PCUT_EXPORT(label);
Index: uspace/lib/label/test/main.c
===================================================================
--- uspace/lib/label/test/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/label/test/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <pcut/pcut.h>
+
+PCUT_INIT
+
+PCUT_IMPORT(label);
+
+PCUT_MAIN()
Index: uspace/lib/math/arch/amd64/src/cos.S
===================================================================
--- uspace/lib/math/arch/amd64/src/cos.S	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/math/arch/amd64/src/cos.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -68,5 +68,5 @@
 		jnz reduce
 	
-	fstpl %st(1)
+	fstp %st(1)
 	fcos
 	
Index: uspace/lib/math/arch/amd64/src/sin.S
===================================================================
--- uspace/lib/math/arch/amd64/src/sin.S	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/math/arch/amd64/src/sin.S	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -68,5 +68,5 @@
 		jnz reduce
 	
-	fstpl %st(1)
+	fstp %st(1)
 	fsin
 	
Index: uspace/lib/nettl/src/amap.c
===================================================================
--- uspace/lib/nettl/src/amap.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/nettl/src/amap.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -59,4 +59,20 @@
 #include <stdlib.h>
 
+/** Convert association map flags to port range flags.
+ *
+ * @param flags Association map flags
+ * @return Port range flags
+ */
+static portrng_flags_t aflags_to_pflags(amap_flags_t flags)
+{
+	portrng_flags_t pflags;
+
+	pflags = 0;
+	if ((flags & af_allow_system) != 0)
+		pflags |= pf_allow_system;
+
+	return pflags;
+}
+
 /** Create association map.
  *
@@ -97,4 +113,8 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_destroy()");
+
+	assert(list_empty(&map->repla));
+	assert(list_empty(&map->laddr));
+	assert(list_empty(&map->llink));
 	free(map);
 }
@@ -374,5 +394,5 @@
 	mepp = *epp;
 
-	rc = portrng_alloc(repla->portrng, epp->local.port, arg, flags,
+	rc = portrng_alloc(repla->portrng, epp->local.port, arg, aflags_to_pflags(flags),
 	    &mepp.local.port);
 	if (rc != EOK) {
@@ -418,5 +438,5 @@
 	mepp = *epp;
 
-	rc = portrng_alloc(laddr->portrng, epp->local.port, arg, flags,
+	rc = portrng_alloc(laddr->portrng, epp->local.port, arg, aflags_to_pflags(flags),
 	    &mepp.local.port);
 	if (rc != EOK) {
@@ -462,5 +482,5 @@
 	mepp = *epp;
 
-	rc = portrng_alloc(llink->portrng, epp->local.port, arg, flags,
+	rc = portrng_alloc(llink->portrng, epp->local.port, arg, aflags_to_pflags(flags),
 	    &mepp.local.port);
 	if (rc != EOK) {
@@ -494,5 +514,5 @@
 	mepp = *epp;
 
-	rc = portrng_alloc(map->unspec, epp->local.port, arg, flags,
+	rc = portrng_alloc(map->unspec, epp->local.port, arg, aflags_to_pflags(flags),
 	    &mepp.local.port);
 	if (rc != EOK) {
Index: uspace/lib/nettl/src/portrng.c
===================================================================
--- uspace/lib/nettl/src/portrng.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/nettl/src/portrng.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -182,15 +182,19 @@
 void portrng_free_port(portrng_t *pr, uint16_t pnum)
 {
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port(%u)", pnum);
 	log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port() - begin");
 	list_foreach(pr->used, lprng, portrng_port_t, port) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port - check port %u", port->pn);
 		if (port->pn == pnum) {
+			log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port - OK");
 			list_remove(&port->lprng);
 			free(port);
+			log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port() - end");
 			return;
 		}
 	}
 
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port - FAIL");
 	assert(false);
-	log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port() - end");
 }
 
@@ -209,3 +213,2 @@
  * @}
  */
-
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/nic/src/nic_driver.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -249,7 +249,7 @@
 	
 	/* Connect to the parent's driver. */
-	parent_sess = ddf_dev_parent_sess_create(dev);
+	parent_sess = ddf_dev_parent_sess_get(dev);
 	if (parent_sess == NULL)
-		return EPARTY;
+		return EIO;
 	
 	return hw_res_get_list_parsed(parent_sess, resources, 0);
Index: uspace/lib/nic/src/nic_rx_control.c
===================================================================
--- uspace/lib/nic/src/nic_rx_control.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/nic/src/nic_rx_control.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,4 @@
 #include <assert.h>
 #include <stdlib.h>
-#include <stdbool.h>
 #include <errno.h>
 #include <mem.h>
Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -55,4 +55,5 @@
 SOURCES = \
 	source/ctype.c \
+	source/dlfcn.c \
 	source/errno.c \
 	source/fcntl.c \
@@ -102,5 +103,5 @@
 	sed 's/.*/posix_& &/' <$(COLLISIONS_LIST) >$@
 
-$(COLLISIONS_LIST):
+$(COLLISIONS_LIST): include/posix/*.h include/posix/*/*.h
 	find ./include/posix -name '*.h' -exec \
 		sed -n -e '/^#/d' -e 's/__POSIX_DEF__/\n&/gp' {} \; | \
Index: uspace/lib/posix/include/posix/dlfcn.h
===================================================================
--- uspace/lib/posix/include/posix/dlfcn.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/posix/include/posix/dlfcn.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 Vojtech Horky
+ * 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 libposix
+ * @{
+ */
+
+#ifndef POSIX_DLFCN_H_
+#define POSIX_DLFCN_H_
+
+#ifndef __POSIX_DEF__
+#define __POSIX_DEF__(x) x
+#endif
+
+#define RTLD_LAZY 1
+#define RTLD_NOW 2
+#define RTLD_GLOBAL 32
+#define RTLD_LOCAL 0
+
+
+extern void *__POSIX_DEF__(dlopen)(const char *, int);
+extern void *__POSIX_DEF__(dlsym)(void *, const char *);
+extern int __POSIX_DEF__(dlclose)(void *);
+extern char *__POSIX_DEF__(dlerror)(void);
+
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/posix/include/posix/stdbool.h
===================================================================
--- uspace/lib/posix/include/posix/stdbool.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/posix/include/posix/stdbool.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Vojtech Horky
+ * 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 libposix
+ * @{
+ */
+/** @file
+ */
+
+#ifndef POSIX_BOOL_H_
+#define POSIX_BOOL_H_
+
+#define bool _Bool
+#define false  0
+#define true   1
+#define __bool_true_false_are_defined 1
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/posix/include/posix/stdint.h
===================================================================
--- uspace/lib/posix/include/posix/stdint.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/include/posix/stdint.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -102,6 +102,4 @@
 #define UINTMAX_MAX UINT64_MAX
 
-#include "libc/sys/types.h"
-
 /*
  * Fast* and least* integer types.
Index: uspace/lib/posix/include/posix/strings.h
===================================================================
--- uspace/lib/posix/include/posix/strings.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/include/posix/strings.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,5 +42,5 @@
 
 
-#include <libarch/types.h>
+#include <types/common.h>
 
 /* Search Functions */
Index: uspace/lib/posix/include/posix/sys/time.h
===================================================================
--- uspace/lib/posix/include/posix/sys/time.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/posix/include/posix/sys/time.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Vojtech Horky
+ * 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 libposix
+ * @{
+ */
+
+#ifndef POSIX_SYS_TIME_H_
+#define POSIX_SYS_TIME_H_
+
+#ifndef __POSIX_DEF__
+#define __POSIX_DEF__(x) x
+#endif
+
+#include "libc/sys/time.h"
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/posix/include/posix/sys/types.h
===================================================================
--- uspace/lib/posix/include/posix/sys/types.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/include/posix/sys/types.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,6 +41,7 @@
 #endif
 
-#include "libc/sys/types.h"
+#include "libc/offset.h"
 #include "libc/sys/time.h"
+#include "libc/types/common.h"
 
 typedef unsigned int __POSIX_DEF__(ino_t);
Index: uspace/lib/posix/include/posix/unistd.h
===================================================================
--- uspace/lib/posix/include/posix/unistd.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/include/posix/unistd.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -57,4 +57,7 @@
 /* Environment */
 extern char **__POSIX_DEF__(environ);
+
+/* Sleeping */
+extern unsigned int __POSIX_DEF__(sleep)(unsigned int);
 
 /* Login Information */
Index: uspace/lib/posix/source/dlfcn.c
===================================================================
--- uspace/lib/posix/source/dlfcn.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/lib/posix/source/dlfcn.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017 Vojtech Horky
+ * 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 libposix
+ * @{
+ */
+
+#define LIBPOSIX_INTERNAL
+#define __POSIX_DEF__(x) posix_##x
+
+#include "internal/common.h"
+#include "posix/dlfcn.h"
+
+#include "libc/dlfcn.h"
+
+void *posix_dlopen(const char *filename, int flags)
+{
+	if (flags != 0) {
+		fprintf(stderr, "dlopen() not implemented with non-zero flags (%s:%d), something will NOT work.\n", __FILE__, __LINE__);
+	}
+	
+	return dlopen(filename, 0);
+}
+
+void *posix_dlsym(void *handle, const char *symbol)
+{
+	return dlsym(handle, symbol);
+}
+
+int posix_dlclose(void *handle)
+{
+	not_implemented();
+	return 0;
+}
+
+char *posix_dlerror(void)
+{
+	not_implemented();
+	return (char *)"dlerror()";
+}
+
+/** @}
+ */
Index: uspace/lib/posix/source/internal/common.h
===================================================================
--- uspace/lib/posix/source/internal/common.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/source/internal/common.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,5 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/types.h>
+#include <offset.h>
 #include <vfs/vfs.h>
 
Index: uspace/lib/posix/source/stdio.c
===================================================================
--- uspace/lib/posix/source/stdio.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/source/stdio.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -49,5 +49,4 @@
 #include "libc/stdio.h"
 #include "libc/io/printf_core.h"
-#include "libc/stdbool.h"
 #include "libc/str.h"
 #include "libc/malloc.h"
Index: uspace/lib/posix/source/stdlib.c
===================================================================
--- uspace/lib/posix/source/stdlib.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/source/stdlib.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -47,5 +47,5 @@
 #include "posix/unistd.h"
 
-#include "libc/sort.h"
+#include "libc/qsort.h"
 #include "libc/str.h"
 #include "libc/vfs/vfs.h"
@@ -136,27 +136,4 @@
 
 /**
- * Private helper function that serves as a compare function for qsort().
- *
- * @param elem1 First element to compare.
- * @param elem2 Second element to compare.
- * @param compare Comparison function without userdata parameter.
- * @return Relative ordering of the elements.
- */
-static int sort_compare_wrapper(void *elem1, void *elem2, void *userdata)
-{
-	int (*compare)(const void *, const void *) = userdata;
-	int ret = compare(elem1, elem2);
-	
-	/* Native qsort internals expect this. */
-	if (ret < 0) {
-		return -1;
-	} else if (ret > 0) {
-		return 1;
-	} else {
-		return 0;
-	}
-}
-
-/**
  * Array sorting utilizing the quicksort algorithm.
  *
@@ -169,6 +146,5 @@
     int (*compare)(const void *, const void *))
 {
-	/* Implemented in libc with one extra argument. */
-	qsort(array, count, size, sort_compare_wrapper, compare);
+	qsort(array, count, size, compare);
 }
 
Index: uspace/lib/posix/source/time.c
===================================================================
--- uspace/lib/posix/source/time.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/source/time.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,10 +45,9 @@
 #include "posix/assert.h"
 
+#include "libc/fibril_synch.h"
 #include "libc/malloc.h"
 #include "libc/task.h"
 #include "libc/stats.h"
-#include "libc/stdbool.h"
 #include "libc/stddef.h"
-#include "libc/thread.h"
 #include "libc/sys/time.h"
 
@@ -315,8 +314,8 @@
 			// TODO: interruptible sleep
 			if (rqtp->tv_sec != 0) {
-				thread_sleep(rqtp->tv_sec);
+				fibril_sleep(rqtp->tv_sec);
 			}
 			if (rqtp->tv_nsec != 0) {
-				thread_usleep(rqtp->tv_nsec / 1000);
+				fibril_usleep(rqtp->tv_nsec / 1000);
 			}
 			return 0;
Index: uspace/lib/posix/source/unistd.c
===================================================================
--- uspace/lib/posix/source/unistd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/posix/source/unistd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,4 +45,5 @@
 
 #include "libc/task.h"
+#include "libc/thread.h"
 #include "libc/stats.h"
 #include "libc/malloc.h"
@@ -56,4 +57,19 @@
 char **posix_environ = NULL;
 char *posix_optarg;
+
+/**
+ * Sleep for the specified number of seconds.
+ *
+ * Note that POSIX allows this call to be interrupted and then the return
+ * value represents remaining seconds for the sleep. HelenOS does not offer
+ * such functionality and thus always the whole sleep is taken.
+ *
+ * @param seconds Number of seconds to sleep.
+ * @return Always 0 on HelenOS.
+ */
+unsigned int posix_sleep(unsigned int seconds)
+{
+	return thread_sleep(seconds);
+}
 
 /**
Index: uspace/lib/softrend/filter.h
===================================================================
--- uspace/lib/softrend/filter.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/softrend/filter.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,5 +37,4 @@
 #define SOFTREND_FILTER_H_
 
-#include <stdbool.h>
 #include <io/pixelmap.h>
 
Index: uspace/lib/softrend/rectangle.h
===================================================================
--- uspace/lib/softrend/rectangle.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/softrend/rectangle.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 
 #include <stdbool.h>
+#include <types/common.h>
 
 extern bool rectangle_intersect(
Index: uspace/lib/usb/include/usb/usb.h
===================================================================
--- uspace/lib/usb/include/usb/usb.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/usb/include/usb/usb.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,7 +35,8 @@
 #define LIBUSB_USB_H_
 
+#include <byteorder.h>
 #include <stdbool.h>
 #include <stdint.h>
-#include <byteorder.h>
+#include <types/common.h>
 
 /** Convert 16bit value from native (host) endianness to USB endianness. */
Index: uspace/lib/usb/src/usb.c
===================================================================
--- uspace/lib/usb/src/usb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/usb/src/usb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -74,5 +74,5 @@
 const char *usb_str_transfer_type(usb_transfer_type_t t)
 {
-	if (t >= ARRAY_SIZE(str_transfer_type)) {
+	if ((size_t)t >= ARRAY_SIZE(str_transfer_type)) {
 		return "invalid";
 	}
@@ -87,5 +87,5 @@
 const char *usb_str_transfer_type_short(usb_transfer_type_t t)
 {
-	if (t >= ARRAY_SIZE(str_transfer_type_short)) {
+	if ((size_t)t >= ARRAY_SIZE(str_transfer_type_short)) {
 		return "invl";
 	}
Index: uspace/lib/usbdev/src/devdrv.c
===================================================================
--- uspace/lib/usbdev/src/devdrv.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/usbdev/src/devdrv.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -53,5 +53,5 @@
 
 /** USB device structure. */
-typedef struct usb_device {
+struct usb_device {
 	/** Connection to device on USB bus */
 	usb_dev_session_t *bus_session;
@@ -95,5 +95,5 @@
 	 */
 	void *driver_data;
-} usb_device_t;
+};
 
 /** Count number of pipes the driver expects.
@@ -489,10 +489,8 @@
 	int iface_no = -1;
 
-	async_sess_t *sess = devman_parent_device_connect(
-	    ddf_dev_get_handle(ddf_dev), IPC_FLAG_BLOCKING);
+	async_sess_t *sess = ddf_dev_parent_sess_get(ddf_dev);
 	if (sess == NULL)
 		return ENOMEM;
 	const int ret = usb_device_get_info(sess, &h, &iface_no);
-	async_hangup(sess);
 	if (ret != EOK)
 		return ret;
Index: uspace/lib/usbhost/include/usb/host/ddf_helpers.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -88,5 +88,5 @@
 hcd_t *dev_to_hcd(ddf_dev_t *dev);
 
-int hcd_ddf_enable_interrupts(ddf_dev_t *device);
+int hcd_ddf_enable_interrupt(ddf_dev_t *device, int);
 int hcd_ddf_get_registers(ddf_dev_t *device, hw_res_list_parsed_t *hw_res);
 int hcd_ddf_setup_interrupts(ddf_dev_t *device,
Index: uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,4 @@
 
 #include <assert.h>
-#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
Index: uspace/lib/usbhost/src/ddf_helpers.c
===================================================================
--- uspace/lib/usbhost/src/ddf_helpers.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/lib/usbhost/src/ddf_helpers.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -47,5 +47,4 @@
 #include <ddf/interrupt.h>
 #include <device/hw_res_parsed.h>
-#include <devman.h>
 #include <errno.h>
 #include <fibril_synch.h>
@@ -607,34 +606,29 @@
 }
 
-//TODO: Move this to generic ddf?
-/** Call the parent driver with a request to enable interrupts
+//TODO: Cache parent session in HCD
+/** Call the parent driver with a request to enable interrupt
  *
  * @param[in] device Device asking for interrupts
+ * @param[in] inum Interrupt number
  * @return Error code.
  */
-int hcd_ddf_enable_interrupts(ddf_dev_t *device)
-{
-	assert(device);
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(ddf_dev_get_handle(device),
-	    IPC_FLAG_BLOCKING);
-	const bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-
-	return enabled ? EOK : EIO;
-}
-
-//TODO: Move this to generic ddf?
+int hcd_ddf_enable_interrupt(ddf_dev_t *device, int inum)
+{
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
+	if (parent_sess == NULL)
+		return EIO;
+
+	return hw_res_enable_interrupt(parent_sess, inum);
+}
+
+//TODO: Cache parent session in HCD
 int hcd_ddf_get_registers(ddf_dev_t *device, hw_res_list_parsed_t *hw_res)
 {
-	assert(device);
-	assert(hw_res);
-
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(ddf_dev_get_handle(device),
-	    IPC_FLAG_BLOCKING);
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
+	if (parent_sess == NULL)
+		return EIO;
+
 	hw_res_list_parsed_init(hw_res);
 	const int ret = hw_res_get_list_parsed(parent_sess, hw_res, 0);
-	async_hangup(parent_sess);
 	if (ret != EOK)
 		hw_res_list_parsed_clean(hw_res);
@@ -663,5 +657,6 @@
  * @param[in] gen_irq_code IRQ code generator.
  *
- * @return EOK on success or negative error code
+ * @return IRQ capability handle on success.
+ * @return Negative error code.
  */
 int hcd_ddf_setup_interrupts(ddf_dev_t *device,
@@ -687,22 +682,22 @@
 
 	/* Register handler to avoid interrupt lockup */
-	int ret = register_interrupt_handler(device, irq, handler, &irq_code);
+	const int irq_cap = register_interrupt_handler(device, irq, handler,
+	    &irq_code);
 	irq_code_clean(&irq_code);
-	if (ret != EOK) {
+	if (irq_cap < 0) {
 		usb_log_error("Failed to register interrupt handler: %s.\n",
-		    str_error(ret));
-		return ret;
+		    str_error(irq_cap));
+		return irq_cap;
 	}
 
 	/* Enable interrupts */
-	ret = hcd_ddf_enable_interrupts(device);
+	int ret = hcd_ddf_enable_interrupt(device, irq);
 	if (ret != EOK) {
 		usb_log_error("Failed to enable interrupts: %s.\n",
 		    str_error(ret));
-		unregister_interrupt_handler(device, irq);
+		unregister_interrupt_handler(device, irq_cap);
 		return ret;
 	}
-	assert(irq > 0);
-	return irq;
+	return irq_cap;
 }
 
@@ -796,6 +791,8 @@
 	interrupt_handler_t *irq_handler =
 	    driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler;
-	const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler, driver->irq_code_gen);
-	if (!(irq < 0)) {
+	const int irq_cap = hcd_ddf_setup_interrupts(device, &hw_res,
+	    irq_handler, driver->irq_code_gen);
+	bool irqs_enabled = !(irq_cap < 0);
+	if (irqs_enabled) {
 		usb_log_debug("Hw interrupts enabled.\n");
 	}
@@ -812,5 +809,5 @@
 	/* Start hw driver */
 	if (driver->start)
-		ret = driver->start(hcd, !(irq < 0));
+		ret = driver->start(hcd, irqs_enabled);
 	if (ret != EOK) {
 		usb_log_error("Failed to start HCD: %s.\n", str_error(ret));
@@ -819,5 +816,5 @@
 
 	/* Need working irq replacement to setup root hub */
-	if ((irq < 0) && hcd->ops.status_hook) {
+	if (!irqs_enabled && hcd->ops.status_hook) {
 		hcd->polling_fibril = fibril_create(interrupt_polling, hcd);
 		if (hcd->polling_fibril == 0) {
@@ -828,5 +825,5 @@
 		fibril_add_ready(hcd->polling_fibril);
 		usb_log_warning("Failed to enable interrupts: %s."
-		    " Falling back to polling.\n", str_error(irq));
+		    " Falling back to polling.\n", str_error(irq_cap));
 	}
 
@@ -854,5 +851,5 @@
 		driver->stop(hcd);
 err_irq:
-	unregister_interrupt_handler(device, irq);
+	unregister_interrupt_handler(device, irq_cap);
 	if (driver->fini)
 		driver->fini(hcd);
Index: uspace/srv/bd/file_bd/file_bd.c
===================================================================
--- uspace/srv/bd/file_bd/file_bd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/bd/file_bd/file_bd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -47,5 +47,4 @@
 #include <stddef.h>
 #include <stdint.h>
-#include <sys/typefmt.h>
 #include <errno.h>
 #include <stdbool.h>
Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/bd/vbd/disk.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,6 @@
 #include <errno.h>
 #include <io/log.h>
+#include <label/empty.h>
+#include <label/label.h>
 #include <loc.h>
 #include <stdio.h>
@@ -75,4 +77,10 @@
 static vbd_part_id_t vbds_part_id = 1;
 
+static int vbds_label_get_bsize(void *, size_t *);
+static int vbds_label_get_nblocks(void *, aoff64_t *);
+static int vbds_label_read(void *, aoff64_t, size_t, void *);
+static int vbds_label_write(void *, aoff64_t, size_t, const void *);
+
+/** Block device operations provided by VBD */
 static bd_ops_t vbds_bd_ops = {
 	.open = vbds_bd_open,
@@ -83,4 +91,12 @@
 	.get_block_size = vbds_bd_get_block_size,
 	.get_num_blocks = vbds_bd_get_num_blocks
+};
+
+/** Provide disk access to liblabel */
+static label_bd_ops_t vbds_label_bd_ops = {
+	.get_bsize = vbds_label_get_bsize,
+	.get_nblocks = vbds_label_get_nblocks,
+	.read = vbds_label_read,
+	.write = vbds_label_write
 };
 
@@ -450,4 +466,5 @@
 {
 	label_t *label = NULL;
+	label_bd_t lbd;
 	vbds_disk_t *disk = NULL;
 	bool block_inited = false;
@@ -467,4 +484,7 @@
 		return ENOMEM;
 
+	/* Must be set before calling label_open */
+	disk->svc_id = sid;
+
 	rc = loc_service_get_name(sid, &disk->svc_name);
 	if (rc != EOK) {
@@ -501,5 +521,8 @@
 	block_inited = true;
 
-	rc = label_open(sid, &label);
+	lbd.ops = &vbds_label_bd_ops;
+	lbd.arg = (void *) disk;
+
+	rc = label_open(&lbd, &label);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to open label in disk %s.",
@@ -509,5 +532,4 @@
 	}
 
-	disk->svc_id = sid;
 	disk->label = label;
 	disk->block_size = block_size;
@@ -648,4 +670,5 @@
 {
 	label_t *label;
+	label_bd_t lbd;
 	label_info_t linfo;
 	vbds_disk_t *disk;
@@ -683,5 +706,8 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_create(%zu) - label_create", sid);
 
-	rc = label_create(sid, ltype, &label);
+	lbd.ops = &vbds_label_bd_ops;
+	lbd.arg = (void *) disk;
+
+	rc = label_create(&lbd, ltype, &label);
 	if (rc != EOK)
 		goto error;
@@ -695,5 +721,8 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_create(%zu) - failure", sid);
 	if (disk->label == NULL) {
-		rc2 = label_open(sid, &label);
+		lbd.ops = &vbds_label_bd_ops;
+		lbd.arg = (void *) disk;
+
+		rc2 = label_open(&lbd, &label);
 		if (rc2 != EOK) {
 			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to open label in disk %s.",
@@ -713,4 +742,5 @@
 	vbds_disk_t *disk;
 	label_t *label;
+	label_bd_t lbd;
 	int rc;
 
@@ -735,5 +765,8 @@
 	disk->label = NULL;
 
-	rc = label_open(disk->svc_id, &label);
+	lbd.ops = &vbds_label_bd_ops;
+	lbd.arg = (void *) disk;
+
+	rc = label_open(&lbd, &label);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to open label in disk %s.",
@@ -811,4 +844,10 @@
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating partition.");
+		goto error;
+	}
+
+	rc = label_part_empty(lpart);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error emptying partition.");
 		goto error;
 	}
@@ -1179,4 +1218,32 @@
 }
 
+/** Get block size wrapper for liblabel */
+static int vbds_label_get_bsize(void *arg, size_t *bsize)
+{
+	vbds_disk_t *disk = (vbds_disk_t *)arg;
+	return block_get_bsize(disk->svc_id, bsize);
+}
+
+/** Get number of blocks wrapper for liblabel */
+static int vbds_label_get_nblocks(void *arg, aoff64_t *nblocks)
+{
+	vbds_disk_t *disk = (vbds_disk_t *)arg;
+	return block_get_nblocks(disk->svc_id, nblocks);
+}
+
+/** Read blocks wrapper for liblabel */
+static int vbds_label_read(void *arg, aoff64_t ba, size_t cnt, void *buf)
+{
+	vbds_disk_t *disk = (vbds_disk_t *)arg;
+	return block_read_direct(disk->svc_id, ba, cnt, buf);
+}
+
+/** Write blocks wrapper for liblabel */
+static int vbds_label_write(void *arg, aoff64_t ba, size_t cnt, const void *data)
+{
+	vbds_disk_t *disk = (vbds_disk_t *)arg;
+	return block_write_direct(disk->svc_id, ba, cnt, data);
+}
+
 /** @}
  */
Index: uspace/srv/bd/vbd/types/vbd.h
===================================================================
--- uspace/srv/bd/vbd/types/vbd.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/bd/vbd/types/vbd.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,5 @@
 #include <atomic.h>
 #include <bd_srv.h>
-#include <label.h>
+#include <label/label.h>
 #include <loc.h>
 #include <stdbool.h>
Index: uspace/srv/bd/vbd/vbd.c
===================================================================
--- uspace/srv/bd/vbd/vbd.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/bd/vbd/vbd.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,4 +39,5 @@
 #include <ipc/services.h>
 #include <ipc/vbd.h>
+#include <label/label.h>
 #include <loc.h>
 #include <macros.h>
Index: uspace/srv/clipboard/clipboard.c
===================================================================
--- uspace/srv/clipboard/clipboard.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/clipboard/clipboard.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -27,13 +27,14 @@
  */
 
+#include <async.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <ipc/services.h>
+#include <ipc/clipboard.h>
+#include <loc.h>
+#include <malloc.h>
 #include <stdio.h>
 #include <stdbool.h>
-#include <async.h>
-#include <ns.h>
-#include <ipc/services.h>
-#include <ipc/clipboard.h>
-#include <malloc.h>
-#include <fibril_synch.h>
-#include <errno.h>
+#include <task.h>
 
 #define NAME  "clipboard"
@@ -43,4 +44,5 @@
 static clipboard_tag_t clip_tag = CLIPBOARD_TAG_NONE;
 static FIBRIL_MUTEX_INITIALIZE(clip_mtx);
+static service_id_t svc_id;
 
 static void clip_put_data(ipc_callid_t rid, ipc_call_t *request)
@@ -179,10 +181,20 @@
 int main(int argc, char *argv[])
 {
+	int rc;
+	
 	printf("%s: HelenOS clipboard service\n", NAME);
-	
 	async_set_fallback_port_handler(clip_connection, NULL);
-	int rc = service_register(SERVICE_CLIPBOARD);
-	if (rc != EOK)
+	
+	rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		printf("%s: Failed registering server. (%d)\n", NAME, rc);
 		return rc;
+	}
+	
+	rc = loc_service_register(SERVICE_NAME_CLIPBOARD, &svc_id);
+	if (rc != EOK) {
+		printf("%s: Failed registering service. (%d)\n", NAME, rc);
+		return rc;
+	}
 	
 	printf("%s: Accepting connections\n", NAME);
Index: uspace/srv/fs/cdfs/cdfs_ops.c
===================================================================
--- uspace/srv/fs/cdfs/cdfs_ops.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/cdfs/cdfs_ops.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -52,4 +52,6 @@
 #include <byteorder.h>
 #include <macros.h>
+#include <unaligned.h>
+
 #include "cdfs.h"
 #include "cdfs_endian.h"
@@ -115,4 +117,5 @@
 } cdfs_dir_flag_t;
 
+/** Directory record */
 typedef struct {
 	uint8_t length;
@@ -132,4 +135,22 @@
 } __attribute__((packed)) cdfs_dir_t;
 
+/** Directory record for the root directory */
+typedef struct {
+	uint8_t length;
+	uint8_t ea_length;
+	
+	uint32_t_lb lba;
+	uint32_t_lb size;
+	
+	cdfs_timestamp_t timestamp;
+	uint8_t flags;
+	uint8_t unit_size;
+	uint8_t gap_size;
+	uint16_t_lb sequence_nr;
+	
+	uint8_t name_length;
+	uint8_t name[1];
+} __attribute__((packed)) cdfs_root_dir_t;
+
 typedef struct {
 	uint8_t flags; /* reserved in primary */
@@ -153,5 +174,5 @@
 	uint32_t opt_path_table_msb;
 	
-	cdfs_dir_t root_dir;
+	cdfs_root_dir_t root_dir;
 	uint8_t pad0;
 	
@@ -458,5 +479,6 @@
 		size_t i;
 		for (i = 0; i < dsize / sizeof(uint16_t); i++) {
-			buf[i] = uint16_t_be2host(((uint16_t *)data)[i]);
+			buf[i] = uint16_t_be2host(
+			    ((unaligned_uint16_t *)data)[i]);
 		}
 		
Index: uspace/srv/fs/exfat/exfat_dentry.c
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/exfat/exfat_dentry.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -90,5 +90,5 @@
 void exfat_dentry_get_name(const exfat_name_dentry_t *name, size_t size, uint16_t *dst, size_t *offset)
 {
-	size_t i = 0; 
+	size_t i = 0;
 	while (i < EXFAT_NAME_PART_LEN && *offset < size) {
 		dst[*offset] = uint16_t_le2host(name->name[i]);
@@ -97,4 +97,15 @@
 	}
 	dst[*offset] = '\0';
+}
+
+void exfat_dentry_get_vollabel(const exfat_vollabel_dentry_t *vollabel,
+    size_t size, uint16_t *dst)
+{
+	size_t i = 0;
+	while (i < EXFAT_VOLLABEL_LEN && i < vollabel->size && i < size) {
+		dst[i] = uint16_t_le2host(vollabel->label[i]);
+		i++;
+	}
+	dst[i] = '\0';
 }
 
@@ -130,14 +141,4 @@
 }
 
-size_t exfat_utf16_length(const uint16_t *wstr)
-{
-	size_t len = 0;
-	
-	while (*wstr++ != 0)
-		len++;
-	
-	return len;
-}
-
 /**
  * @}
Index: uspace/srv/fs/exfat/exfat_dentry.h
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/exfat/exfat_dentry.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -34,4 +34,5 @@
 #define EXFAT_EXFAT_DENTRY_H_
 
+#include <stddef.h>
 #include <stdint.h>
 #include <stdbool.h>
@@ -39,4 +40,5 @@
 #define EXFAT_FILENAME_LEN	255
 #define EXFAT_NAME_PART_LEN	15
+#define EXFAT_VOLLABEL_LEN	11
 
 #define EXFAT_TYPE_UNUSED	0x00
@@ -155,5 +157,6 @@
 extern void exfat_dentry_get_name(const exfat_name_dentry_t *, size_t,
     uint16_t *, size_t *);
-
+extern void exfat_dentry_get_vollabel(const exfat_vollabel_dentry_t *, size_t,
+    uint16_t *);
 
 extern bool exfat_valid_char(wchar_t);
Index: uspace/srv/fs/exfat/exfat_directory.c
===================================================================
--- uspace/srv/fs/exfat/exfat_directory.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/exfat/exfat_directory.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -260,4 +260,32 @@
 }
 
+int exfat_directory_read_vollabel(exfat_directory_t *di, char *label,
+    size_t size)
+{
+	uint16_t wlabel[EXFAT_VOLLABEL_LEN + 1];
+	exfat_dentry_t *d = NULL;
+	int rc;
+	aoff64_t start_pos = 0;
+
+	start_pos = di->pos;
+
+	rc = exfat_directory_seek(di, 0);
+	if (rc != EOK)
+		return rc;
+
+	rc = exfat_directory_find(di, EXFAT_DENTRY_VOLLABEL, &d);
+	if (rc != EOK)
+		return rc;
+
+	exfat_dentry_get_vollabel(&d->vollabel, EXFAT_VOLLABEL_LEN, wlabel);
+
+	rc = utf16_to_str(label, size, wlabel);
+	if (rc != EOK)
+		return rc;
+
+	exfat_directory_seek(di, start_pos);
+	return EOK;
+}
+
 static uint16_t exfat_directory_set_checksum(const uint8_t *bytes, size_t count)
 {
@@ -371,5 +399,5 @@
 	ds.stream.valid_data_size = 0;
 	ds.stream.data_size = 0;
-	ds.stream.name_size = exfat_utf16_length(wname);
+	ds.stream.name_size = utf16_wsize(wname);
 	ds.stream.hash = host2uint16_t_le(exfat_name_hash(wname, uctable, 
 	    uctable_chars));
Index: uspace/srv/fs/exfat/exfat_directory.h
===================================================================
--- uspace/srv/fs/exfat/exfat_directory.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/exfat/exfat_directory.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -71,8 +71,10 @@
 extern int exfat_directory_read_file(exfat_directory_t *, char *, size_t,
     exfat_file_dentry_t *, exfat_stream_dentry_t *);
+extern int exfat_directory_read_vollabel(exfat_directory_t *, char *, size_t);
 extern int exfat_directory_sync_file(exfat_directory_t *, exfat_file_dentry_t *,
     exfat_stream_dentry_t *);
 extern int exfat_directory_write_file(exfat_directory_t *, const char *);
 extern int exfat_directory_erase_file(exfat_directory_t *, aoff64_t);
+
 
 extern int exfat_directory_expand(exfat_directory_t *);
Index: uspace/srv/fs/exfat/exfat_ops.c
===================================================================
--- uspace/srv/fs/exfat/exfat_ops.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/exfat/exfat_ops.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -595,4 +595,7 @@
 int exfat_node_put(fs_node_t *fn)
 {
+	if (fn == NULL)
+		return EOK;
+
 	exfat_node_t *nodep = EXFAT_NODE(fn);
 	bool destroy = false;
@@ -932,5 +935,5 @@
 int exfat_free_block_count(service_id_t service_id, uint64_t *count)
 {
-	fs_node_t *node;
+	fs_node_t *node = NULL;
 	exfat_node_t *bmap_node;
 	exfat_bs_t *bs;
@@ -945,5 +948,4 @@
 
 	bs = block_bb_get(service_id);
-	node = NULL;
 	rc = exfat_bitmap_get(&node, service_id);
 	if (rc != EOK)
@@ -1013,4 +1015,218 @@
 };
 
+static int exfat_fs_open(service_id_t service_id, enum cache_mode cmode,
+    fs_node_t **rrfn, exfat_idx_t **rridxp, vfs_fs_probe_info_t *info)
+{
+	int rc;
+	exfat_node_t *rootp = NULL, *bitmapp = NULL, *uctablep = NULL;
+	exfat_bs_t *bs;
+
+	/* initialize libblock */
+	rc = block_init(service_id, BS_SIZE);
+	if (rc != EOK)
+		return rc;
+
+	/* prepare the boot block */
+	rc = block_bb_read(service_id, BS_BLOCK);
+	if (rc != EOK) {
+		block_fini(service_id);
+		return rc;
+	}
+
+	/* get the buffer with the boot sector */
+	bs = block_bb_get(service_id);
+
+	/* Do some simple sanity checks on the file system. */
+	rc = exfat_sanity_check(bs);
+	if (rc != EOK) {
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		return rc;
+	}
+
+	/* Initialize the block cache */
+	rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
+	if (rc != EOK) {
+		block_fini(service_id);
+		return rc;
+	}
+
+	rc = exfat_idx_init_by_service_id(service_id);
+	if (rc != EOK) {
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		return rc;
+	}
+
+	/* Initialize the root node. */
+	rc = exfat_node_get_new_by_pos(&rootp, service_id, EXFAT_ROOT_PAR, 
+	    EXFAT_ROOT_POS);
+	if (rc!=EOK) {
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOMEM;
+	}
+	assert(rootp->idx->index == EXFAT_ROOT_IDX);
+
+	rootp->type = EXFAT_DIRECTORY;
+	rootp->firstc = ROOT_FC(bs);
+	rootp->fragmented = true;
+	rootp->refcnt = 1;
+	rootp->lnkcnt = 0;	/* FS root is not linked */
+
+	uint32_t clusters;
+	rc = exfat_clusters_get(&clusters, bs, service_id, rootp->firstc);
+	if (rc != EOK) {
+		free(rootp);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOTSUP;
+	}
+	rootp->size = BPS(bs) * SPC(bs) * clusters;
+	fibril_mutex_unlock(&rootp->idx->lock);
+
+	/* Open root directory and looking for Bitmap and UC-Table */
+	exfat_directory_t di;
+	exfat_dentry_t *de;
+	rc = exfat_directory_open(rootp, &di);
+	if (rc != EOK) {
+		free(rootp);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOTSUP;
+	}
+
+	/* Initialize the bitmap node. */
+	rc = exfat_directory_find(&di, EXFAT_DENTRY_BITMAP, &de);
+	if (rc != EOK) {
+		free(rootp);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOTSUP;
+	}
+
+	rc = exfat_node_get_new_by_pos(&bitmapp, service_id, rootp->firstc, 
+	    di.pos);
+	if (rc != EOK) {
+		free(rootp);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOMEM;
+	}
+	assert(bitmapp->idx->index == EXFAT_BITMAP_IDX);
+	fibril_mutex_unlock(&bitmapp->idx->lock);
+
+	bitmapp->type = EXFAT_BITMAP;
+	bitmapp->firstc = uint32_t_le2host(de->bitmap.firstc);
+	bitmapp->fragmented = true;
+	bitmapp->idx->parent_fragmented = true;
+	bitmapp->refcnt = 1;
+	bitmapp->lnkcnt = 0;
+	bitmapp->size = uint64_t_le2host(de->bitmap.size);
+
+	/* Initialize the uctable node. */
+	rc = exfat_directory_seek(&di, 0);
+	if (rc != EOK) {
+		free(rootp);
+		free(bitmapp);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOTSUP;
+	}
+
+	rc = exfat_directory_find(&di, EXFAT_DENTRY_UCTABLE, &de);
+	if (rc != EOK) {
+		free(rootp);
+		free(bitmapp);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOTSUP;
+	}
+
+	rc = exfat_node_get_new_by_pos(&uctablep, service_id, rootp->firstc, 
+	    di.pos);
+	if (rc != EOK) {
+		free(rootp);
+		free(bitmapp);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOMEM;
+	}
+	assert(uctablep->idx->index == EXFAT_UCTABLE_IDX);
+	fibril_mutex_unlock(&uctablep->idx->lock);
+
+	uctablep->type = EXFAT_UCTABLE;
+	uctablep->firstc = uint32_t_le2host(de->uctable.firstc);
+	uctablep->fragmented = true;
+	uctablep->idx->parent_fragmented = true;
+	uctablep->refcnt = 1;
+	uctablep->lnkcnt = 0;
+	uctablep->size = uint64_t_le2host(de->uctable.size);
+
+	if (info != NULL) {
+		/* Read volume label. */
+		rc = exfat_directory_read_vollabel(&di, info->label,
+		    FS_LABEL_MAXLEN + 1);
+		if (rc != EOK) {
+			free(rootp);
+			free(bitmapp);
+			free(uctablep);
+			(void) block_cache_fini(service_id);
+			block_fini(service_id);
+			exfat_idx_fini_by_service_id(service_id);
+    		    return ENOTSUP;
+		}
+	}
+
+	rc = exfat_directory_close(&di);
+	if (rc != EOK) {
+		free(rootp);
+		free(bitmapp);
+		free(uctablep);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		exfat_idx_fini_by_service_id(service_id);
+		return ENOMEM;
+	}
+
+	/* exfat_fsinfo(bs, service_id); */
+
+	*rrfn = FS_NODE(rootp);
+	*rridxp = rootp->idx;
+
+	if (info != NULL) {
+//		str_cpy(info->label, FS_LABEL_MAXLEN + 1, label);
+	}
+
+	return EOK;
+}
+
+static void exfat_fs_close(service_id_t service_id, fs_node_t *rfn)
+{
+	/*
+	 * Put the root node and force it to the FAT free node list.
+	 */
+	(void) exfat_node_put(rfn);
+	(void) exfat_node_put(rfn);
+
+	/*
+	 * 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) exfat_node_fini_by_service_id(service_id);
+	exfat_idx_fini_by_service_id(service_id);
+	(void) block_cache_fini(service_id);
+	block_fini(service_id);
+}
+
 
 /*
@@ -1054,27 +1270,13 @@
 {
 	int rc;
-	exfat_bs_t *bs;
-
-	/* initialize libblock */
-	rc = block_init(service_id, BS_SIZE);
-	if (rc != EOK)
-		return rc;
-
-	/* prepare the boot block */
-	rc = block_bb_read(service_id, BS_BLOCK);
-	if (rc != EOK) {
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* get the buffer with the boot sector */
-	bs = block_bb_get(service_id);
-
-	/* Do some simple sanity checks on the file system. */
-	rc = exfat_sanity_check(bs);
-
-	(void) block_cache_fini(service_id);
-	block_fini(service_id);
-	return rc;
+	exfat_idx_t *ridxp;
+	fs_node_t *rfn;
+
+	rc = exfat_fs_open(service_id, CACHE_MODE_WT, &rfn, &ridxp, info);
+	if (rc != EOK)
+		return rc;
+
+	exfat_fs_close(service_id, rfn);
+	return EOK;
 }
 
@@ -1084,7 +1286,7 @@
 {
 	int rc;
-	exfat_node_t *rootp = NULL, *bitmapp = NULL, *uctablep = NULL;
 	enum cache_mode cmode;
-	exfat_bs_t *bs;
+	exfat_idx_t *ridxp;
+	fs_node_t *rfn;
 
 	/* Check for option enabling write through. */
@@ -1094,170 +1296,11 @@
 		cmode = CACHE_MODE_WB;
 
-	/* initialize libblock */
-	rc = block_init(service_id, BS_SIZE);
-	if (rc != EOK)
-		return rc;
-
-	/* prepare the boot block */
-	rc = block_bb_read(service_id, BS_BLOCK);
-	if (rc != EOK) {
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* get the buffer with the boot sector */
-	bs = block_bb_get(service_id);
-
-	/* Do some simple sanity checks on the file system. */
-	rc = exfat_sanity_check(bs);
-	if (rc != EOK) {
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* Initialize the block cache */
-	rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
-	if (rc != EOK) {
-		block_fini(service_id);
-		return rc;
-	}
-
-	rc = exfat_idx_init_by_service_id(service_id);
-	if (rc != EOK) {
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* Initialize the root node. */
-	rc = exfat_node_get_new_by_pos(&rootp, service_id, EXFAT_ROOT_PAR, 
-	    EXFAT_ROOT_POS);
-	if (rc!=EOK) {
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-	assert(rootp->idx->index == EXFAT_ROOT_IDX);
-
-	rootp->type = EXFAT_DIRECTORY;
-	rootp->firstc = ROOT_FC(bs);
-	rootp->fragmented = true;
-	rootp->refcnt = 1;
-	rootp->lnkcnt = 0;	/* FS root is not linked */
-
-	uint32_t clusters;
-	rc = exfat_clusters_get(&clusters, bs, service_id, rootp->firstc);
-	if (rc != EOK) {
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-	rootp->size = BPS(bs) * SPC(bs) * clusters;
-	fibril_mutex_unlock(&rootp->idx->lock);
-
-	/* Open root directory and looking for Bitmap and UC-Table */
-	exfat_directory_t di;
-	exfat_dentry_t *de;
-	rc = exfat_directory_open(rootp, &di);
-	if (rc != EOK) {
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-
-	/* Initialize the bitmap node. */
-	rc = exfat_directory_find(&di, EXFAT_DENTRY_BITMAP, &de);
-	if (rc != EOK) {
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-
-	rc = exfat_node_get_new_by_pos(&bitmapp, service_id, rootp->firstc, 
-	    di.pos);
-	if (rc != EOK) {
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-	assert(bitmapp->idx->index == EXFAT_BITMAP_IDX);
-	fibril_mutex_unlock(&bitmapp->idx->lock);
-
-	bitmapp->type = EXFAT_BITMAP;
-	bitmapp->firstc = uint32_t_le2host(de->bitmap.firstc);
-	bitmapp->fragmented = true;
-	bitmapp->idx->parent_fragmented = true;
-	bitmapp->refcnt = 1;
-	bitmapp->lnkcnt = 0;
-	bitmapp->size = uint64_t_le2host(de->bitmap.size);
-
-	/* Initialize the uctable node. */
-	rc = exfat_directory_seek(&di, 0);
-	if (rc != EOK) {
-		free(rootp);
-		free(bitmapp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-
-	rc = exfat_directory_find(&di, EXFAT_DENTRY_UCTABLE, &de);
-	if (rc != EOK) {
-		free(rootp);
-		free(bitmapp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-
-	rc = exfat_node_get_new_by_pos(&uctablep, service_id, rootp->firstc, 
-	    di.pos);
-	if (rc != EOK) {
-		free(rootp);
-		free(bitmapp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-	assert(uctablep->idx->index == EXFAT_UCTABLE_IDX);
-	fibril_mutex_unlock(&uctablep->idx->lock);
-
-	uctablep->type = EXFAT_UCTABLE;
-	uctablep->firstc = uint32_t_le2host(de->uctable.firstc);
-	uctablep->fragmented = true;
-	uctablep->idx->parent_fragmented = true;
-	uctablep->refcnt = 1;
-	uctablep->lnkcnt = 0;
-	uctablep->size = uint64_t_le2host(de->uctable.size);
-
-	rc = exfat_directory_close(&di);
-	if (rc != EOK) {
-		free(rootp);
-		free(bitmapp);
-		free(uctablep);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-
-	/* exfat_fsinfo(bs, service_id); */
-
-	*index = rootp->idx->index;
-	*size = rootp->size;
-	
+	rc = exfat_fs_open(service_id, cmode, &rfn, &ridxp, NULL);
+	if (rc != EOK)
+		return rc;
+
+	*index = ridxp->index;
+	*size = EXFAT_NODE(rfn)->size;
+
 	return EOK;
 }
@@ -1265,38 +1308,12 @@
 static int exfat_unmounted(service_id_t service_id)
 {
-	fs_node_t *fn;
-	exfat_node_t *nodep;
-	int rc;
-
-	rc = exfat_root_get(&fn, service_id);
-	if (rc != EOK)
-		return rc;
-	nodep = EXFAT_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) exfat_node_put(fn);
-		return EBUSY;
-	}
-
-	/*
-	 * Put the root node and force it to the FAT free node list.
-	 */
-	(void) exfat_node_put(fn);
-	(void) exfat_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) exfat_node_fini_by_service_id(service_id);
-	exfat_idx_fini_by_service_id(service_id);
-	(void) block_cache_fini(service_id);
-	block_fini(service_id);
-
+	fs_node_t *rfn;
+	int rc;
+
+	rc = exfat_root_get(&rfn, service_id);
+	if (rc != EOK)
+		return rc;
+
+	exfat_fs_close(service_id, rfn);
 	return EOK;
 }
@@ -1363,5 +1380,5 @@
 			return ENOTSUP;
 		}
-			
+
 		aoff64_t spos = pos;
 		char name[EXFAT_FILENAME_LEN + 1];
Index: uspace/srv/fs/fat/fat.h
===================================================================
--- uspace/srv/fs/fat/fat.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/fat/fat.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -136,5 +136,5 @@
 			/** Signature. */
 			uint16_t	signature;
-		} fat32 __attribute__ ((packed));
+		} __attribute__ ((packed)) fat32;
 	};
 } __attribute__ ((packed)) fat_bs_t;
Index: uspace/srv/fs/fat/fat_dentry.c
===================================================================
--- uspace/srv/fs/fat/fat_dentry.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/fat/fat_dentry.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -180,4 +180,33 @@
 }
 
+void fat_dentry_vollabel_get(const fat_dentry_t *d, char *buf)
+{
+	unsigned int i;
+	
+	for (i = 0; i < FAT_NAME_LEN; i++) {
+		if (d->name[i] == FAT_PAD)
+			break;
+		
+		if (d->name[i] == FAT_DENTRY_E5_ESC)
+			*buf++ = 0xe5;
+		else
+			*buf++ = d->name[i];
+	}
+	
+	for (i = 0; i < FAT_EXT_LEN; i++) {
+		if (d->ext[i] == FAT_PAD) {
+			*buf = '\0';
+			return;
+		}
+		
+		if (d->ext[i] == FAT_DENTRY_E5_ESC)
+			*buf++ = 0xe5;
+		else
+			*buf++ = d->ext[i];
+	}
+	
+	*buf = '\0';
+}
+
 fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *d)
 {
@@ -191,5 +220,5 @@
 	if (d->attr & FAT_ATTR_VOLLABEL) {
 		/* volume label entry */
-		return FAT_DENTRY_SKIP;
+		return FAT_DENTRY_VOLLABEL;
 	}
 	if (d->name[0] == FAT_DENTRY_ERASED) {
@@ -398,14 +427,4 @@
 }
 
-size_t utf16_length(const uint16_t *wstr)
-{
-	size_t len = 0;
-	
-	while (*wstr++ != 0)
-		len++;
-	
-	return len;
-}
-
 /**
  * @}
Index: uspace/srv/fs/fat/fat_dentry.h
===================================================================
--- uspace/srv/fs/fat/fat_dentry.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/fat/fat_dentry.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,7 +35,9 @@
 #define FAT_FAT_DENTRY_H_
 
+#include <ctype.h>
 #include <stdint.h>
 #include <stdbool.h>
-#include <sys/types.h>
+#include <stddef.h>
+#include <unaligned.h>
 
 #define IS_D_CHAR(ch) (isalnum(ch) || ch == '_')
@@ -44,4 +46,5 @@
 #define FAT_NAME_LEN		8
 #define FAT_EXT_LEN		3
+#define FAT_VOLLABEL_LEN	11
 
 #define FAT_NAME_DOT		".       "
@@ -97,5 +100,6 @@
 	FAT_DENTRY_FREE,
 	FAT_DENTRY_VALID,
-	FAT_DENTRY_LFN
+	FAT_DENTRY_LFN,
+	FAT_DENTRY_VOLLABEL
 } fat_dentry_clsf_t;
 
@@ -137,4 +141,5 @@
 extern void fat_dentry_name_get(const fat_dentry_t *, char *);
 extern void fat_dentry_name_set(fat_dentry_t *, const char *);
+extern void fat_dentry_vollabel_get(const fat_dentry_t *, char *);
 extern fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *);
 extern uint8_t fat_dentry_chksum(uint8_t *);
@@ -147,5 +152,4 @@
 
 extern void str_to_ascii(char *, const char *, size_t, uint8_t);
-extern size_t utf16_length(const uint16_t *);
 
 extern bool fat_valid_name(const char *);
Index: uspace/srv/fs/fat/fat_directory.c
===================================================================
--- uspace/srv/fs/fat/fat_directory.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/fat/fat_directory.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -223,7 +223,8 @@
 			*de = d;
 			return EOK;
-		default:
 		case FAT_DENTRY_SKIP:
 		case FAT_DENTRY_FREE:
+		case FAT_DENTRY_VOLLABEL:
+		default:
 			long_entry_count = 0;
 			long_entry = false;
@@ -252,5 +253,5 @@
 	while (!flag && fat_directory_prev(di) == EOK) {
 		if (fat_directory_get(di, &d) == EOK &&
-		    fat_classify_dentry(d) == FAT_DENTRY_LFN &&			
+		    fat_classify_dentry(d) == FAT_DENTRY_LFN &&	
 		    checksum == FAT_LFN_CHKSUM(d)) {
 			if (FAT_IS_LFN(d))
@@ -300,5 +301,5 @@
 			return rc;
 		
-		lfn_size = utf16_length(wname);
+		lfn_size = utf16_wsize(wname);
 		long_entry_count = lfn_size / FAT_LFN_ENTRY_SIZE;
 		if (lfn_size % FAT_LFN_ENTRY_SIZE)
@@ -473,4 +474,5 @@
 			case FAT_DENTRY_LFN:
 			case FAT_DENTRY_SKIP:
+			case FAT_DENTRY_VOLLABEL:
 			default:
 				found = 0;
@@ -523,10 +525,39 @@
 		case FAT_DENTRY_LFN:
 		case FAT_DENTRY_SKIP:
+		case FAT_DENTRY_VOLLABEL:
 		case FAT_DENTRY_FREE:
 			break;
 		}
-	} while (fat_directory_next(di) == EOK);	
+	} while (fat_directory_next(di) == EOK);
 
 	return false;
+}
+
+/** Find volume label entry in a directory.
+ *
+ * @return EOK on success, ENOENT if not found, EIO on I/O error
+ */
+int fat_directory_vollabel_get(fat_directory_t *di, char *label)
+{
+	fat_dentry_t *d;
+	int rc;
+
+	fat_directory_seek(di, 0);
+	do {
+		rc = fat_directory_get(di, &d);
+		if (rc != EOK)
+			return EIO;
+
+		switch (fat_classify_dentry(d)) {
+		case FAT_DENTRY_VOLLABEL:
+			fat_dentry_vollabel_get(d, label);
+			return EOK;
+		default:
+			break;
+		}
+	} while (fat_directory_next(di) == EOK);
+
+	/* Not found */
+	return ENOENT;
 }
 
Index: uspace/srv/fs/fat/fat_directory.h
===================================================================
--- uspace/srv/fs/fat/fat_directory.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/fat/fat_directory.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -72,4 +72,5 @@
     const char *);
 extern int fat_directory_expand(fat_directory_t *);
+extern int fat_directory_vollabel_get(fat_directory_t *, char *);
 
 #endif
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -785,4 +785,5 @@
 			case FAT_DENTRY_SKIP:
 			case FAT_DENTRY_FREE:
+			case FAT_DENTRY_VOLLABEL:
 				continue;
 			case FAT_DENTRY_LAST:
@@ -909,9 +910,6 @@
 };
 
-/*
- * FAT VFS_OUT operations.
- */
-
-static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
+static int fat_fs_open(service_id_t service_id, enum cache_mode cmode,
+    fs_node_t **rrfn, fat_idx_t **rridxp)
 {
 	fat_bs_t *bs;
@@ -939,5 +937,5 @@
 
 	/* Initialize the block cache */
-	rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, CACHE_MODE_WB);
+	rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
 	if (rc != EOK) {
 		block_fini(service_id);
@@ -947,9 +945,133 @@
 	/* Do some simple sanity checks on the file system. */
 	rc = fat_sanity_check(bs, service_id);
-
+	if (rc != EOK) {
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		return rc;
+	}
+
+	rc = fat_idx_init_by_service_id(service_id);
+	if (rc != EOK) {
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		return rc;
+	}
+
+	/* Initialize the root node. */
+	fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
+	if (!rfn) {
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		fat_idx_fini_by_service_id(service_id);
+		return ENOMEM;
+	}
+
+	fs_node_initialize(rfn);
+	fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
+	if (!rootp) {
+		free(rfn);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		fat_idx_fini_by_service_id(service_id);
+		return ENOMEM;
+	}
+	fat_node_initialize(rootp);
+
+	fat_idx_t *ridxp = fat_idx_get_by_pos(service_id, FAT_CLST_ROOTPAR, 0);
+	if (!ridxp) {
+		free(rfn);
+		free(rootp);
+		(void) block_cache_fini(service_id);
+		block_fini(service_id);
+		fat_idx_fini_by_service_id(service_id);
+		return ENOMEM;
+	}
+	assert(ridxp->index == 0);
+	/* ridxp->lock held */
+
+	rootp->type = FAT_DIRECTORY;
+	rootp->firstc = FAT_ROOT_CLST(bs);
+	rootp->refcnt = 1;
+	rootp->lnkcnt = 0;	/* FS root is not linked */
+
+	if (FAT_IS_FAT32(bs)) {
+		uint32_t clusters;
+		rc = fat_clusters_get(&clusters, bs, service_id, rootp->firstc);
+		if (rc != EOK) {
+			fibril_mutex_unlock(&ridxp->lock);
+			free(rfn);
+			free(rootp);
+			(void) block_cache_fini(service_id);
+			block_fini(service_id);
+			fat_idx_fini_by_service_id(service_id);
+			return ENOTSUP;
+		}
+		rootp->size = BPS(bs) * SPC(bs) * clusters;
+	} else
+		rootp->size = RDE(bs) * sizeof(fat_dentry_t);
+
+	rootp->idx = ridxp;
+	ridxp->nodep = rootp;
+	rootp->bp = rfn;
+	rfn->data = rootp;
+
+	fibril_mutex_unlock(&ridxp->lock);
+
+	*rrfn = rfn;
+	*rridxp = ridxp;
+
+	return EOK;
+}
+
+static void fat_fs_close(service_id_t service_id, fs_node_t *rfn)
+{
+	free(rfn->data);
+	free(rfn);
 	(void) block_cache_fini(service_id);
 	block_fini(service_id);
-
-	return rc;
+	fat_idx_fini_by_service_id(service_id);
+}
+
+/*
+ * FAT VFS_OUT operations.
+ */
+
+static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
+{
+	fat_idx_t *ridxp;
+	fs_node_t *rfn;
+	fat_node_t *nodep;
+	fat_directory_t di;
+	char label[FAT_VOLLABEL_LEN + 1];
+	int rc;
+
+	rc = fat_fs_open(service_id, CACHE_MODE_WT, &rfn, &ridxp);
+	if (rc != EOK)
+		return rc;
+
+	nodep = FAT_NODE(rfn);
+
+	rc = fat_directory_open(nodep, &di);
+	if (rc != EOK) {
+		fat_fs_close(service_id, rfn);
+		return rc;
+	}
+
+	rc = fat_directory_vollabel_get(&di, label);
+	if (rc != EOK) {
+		if (rc != ENOENT) {
+			fat_fs_close(service_id, rfn);
+			return rc;
+		}
+
+		label[0] = '\0';
+	}
+
+	str_cpy(info->label, FS_LABEL_MAXLEN + 1, label);
+
+	fat_directory_close(&di);
+	fat_fs_close(service_id, rfn);
+
+	return EOK;
 }
 
@@ -959,6 +1081,7 @@
 {
 	enum cache_mode cmode = CACHE_MODE_WB;
-	fat_bs_t *bs;
 	fat_instance_t *instance;
+	fat_idx_t *ridxp;
+	fs_node_t *rfn;
 	int rc;
 
@@ -978,6 +1101,5 @@
 	}
 
-	/* initialize libblock */
-	rc = block_init(service_id, BS_SIZE);
+	rc = fat_fs_open(service_id, cmode, &rfn, &ridxp);
 	if (rc != EOK) {
 		free(instance);
@@ -985,124 +1107,18 @@
 	}
 
-	/* prepare the boot block */
-	rc = block_bb_read(service_id, BS_BLOCK);
-	if (rc != EOK) {
-		free(instance);
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* get the buffer with the boot sector */
-	bs = block_bb_get(service_id);
-	
-	if (BPS(bs) != BS_SIZE) {
-		free(instance);
-		block_fini(service_id);
-		return ENOTSUP;
-	}
-
-	/* Initialize the block cache */
-	rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
-	if (rc != EOK) {
-		free(instance);
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* Do some simple sanity checks on the file system. */
-	rc = fat_sanity_check(bs, service_id);
-	if (rc != EOK) {
-		free(instance);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		return rc;
-	}
-
-	rc = fat_idx_init_by_service_id(service_id);
-	if (rc != EOK) {
-		free(instance);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* Initialize the root node. */
-	fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
-	if (!rfn) {
-		free(instance);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		fat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-
-	fs_node_initialize(rfn);
-	fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
-	if (!rootp) {
-		free(instance);
-		free(rfn);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		fat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-	fat_node_initialize(rootp);
-
-	fat_idx_t *ridxp = fat_idx_get_by_pos(service_id, FAT_CLST_ROOTPAR, 0);
-	if (!ridxp) {
-		free(instance);
-		free(rfn);
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		fat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-	assert(ridxp->index == 0);
-	/* ridxp->lock held */
-
-	rootp->type = FAT_DIRECTORY;
-	rootp->firstc = FAT_ROOT_CLST(bs);
-	rootp->refcnt = 1;
-	rootp->lnkcnt = 0;	/* FS root is not linked */
-
-	if (FAT_IS_FAT32(bs)) {
-		uint32_t clusters;
-		rc = fat_clusters_get(&clusters, bs, service_id, rootp->firstc);
-		if (rc != EOK) {
-			fibril_mutex_unlock(&ridxp->lock);
-			free(instance);
-			free(rfn);
-			free(rootp);
-			(void) block_cache_fini(service_id);
-			block_fini(service_id);
-			fat_idx_fini_by_service_id(service_id);
-			return ENOTSUP;
-		}
-		rootp->size = BPS(bs) * SPC(bs) * clusters;
-	} else
-		rootp->size = RDE(bs) * sizeof(fat_dentry_t);
+	fibril_mutex_lock(&ridxp->lock);
 
 	rc = fs_instance_create(service_id, instance);
 	if (rc != EOK) {
 		fibril_mutex_unlock(&ridxp->lock);
+		fat_fs_close(service_id, rfn);
 		free(instance);
-		free(rfn);
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		fat_idx_fini_by_service_id(service_id);
-		return rc;
-	}
-
-	rootp->idx = ridxp;
-	ridxp->nodep = rootp;
-	rootp->bp = rfn;
-	rfn->data = rootp;
+		return rc;
+	}
 
 	fibril_mutex_unlock(&ridxp->lock);
 
 	*index = ridxp->index;
-	*size = rootp->size;
+	*size = FAT_NODE(rfn)->size;
 
 	return EOK;
@@ -1174,5 +1190,4 @@
 	 */
 	(void) fat_node_put(fn);
-	(void) fat_node_put(fn);
 
 	/*
@@ -1182,7 +1197,5 @@
 	 */
 	(void) fat_node_fini_by_service_id(service_id);
-	fat_idx_fini_by_service_id(service_id);
-	(void) block_cache_fini(service_id);
-	block_fini(service_id);
+	fat_fs_close(service_id, fn);
 
 	void *data;
Index: uspace/srv/fs/udf/udf_osta.c
===================================================================
--- uspace/srv/fs/udf/udf_osta.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/fs/udf/udf_osta.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -51,20 +51,4 @@
 #include "udf_osta.h"
 #include "udf_cksum.h"
-
-/** Calculate length of UTF-16 string
- *
- * FIXME: This is wrong! UTF-16 is not a fixed-width encoding,
- *        it is a variable-width encoding (mind the surrogate
- *        pairs).
- *
- */
-static size_t utf16_length(uint16_t *string) {
-	size_t len = 0;
-	
-	while (*string++ != 0)
-		len++;
-	
-	return len;
-}
 
 /** Illegal UNIX characters are NULL and slash.
@@ -296,5 +280,5 @@
 		ucode_chars =
 		    udf_uncompress_unicode(len, (uint8_t *) id, raw_name, MAX_BUF);
-		ucode_chars = min(ucode_chars, utf16_length(raw_name));
+		ucode_chars = min(ucode_chars, utf16_wsize(raw_name));
 		nice_uchars =
 		    udf_translate_name(unix_name, raw_name, ucode_chars);
Index: uspace/srv/hid/input/ctl/kbdev.c
===================================================================
--- uspace/srv/hid/input/ctl/kbdev.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hid/input/ctl/kbdev.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -45,5 +45,4 @@
 #include <stdlib.h>
 #include <vfs/vfs_sess.h>
-#include <sys/typefmt.h>
 #include "../gsp.h"
 #include "../input.h"
Index: uspace/srv/hid/input/port/adb.c
===================================================================
--- uspace/srv/hid/input/port/adb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hid/input/port/adb.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -62,7 +62,7 @@
 	kbd_dev = kdev;
 	
-	const char *dev = "adb/kbd";
+	const char *dev = "devices/\\hw\\adb\\kbd";
 	service_id_t service_id;
-	int rc = loc_service_get_id(dev, &service_id, 0);
+	int rc = loc_service_get_id(dev, &service_id, IPC_FLAG_BLOCKING);
 	if (rc != EOK)
 		return rc;
Index: uspace/srv/hid/input/port/adb_mouse.c
===================================================================
--- uspace/srv/hid/input/port/adb_mouse.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hid/input/port/adb_mouse.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -75,10 +75,10 @@
 static int adb_port_init(mouse_dev_t *mdev)
 {
-	const char *dev = "adb/mouse";
+	const char *dev = "devices/\\hw\\adb\\mouse";
 	
 	mouse_dev = mdev;
 	
 	service_id_t service_id;
-	int rc = loc_service_get_id(dev, &service_id, 0);
+	int rc = loc_service_get_id(dev, &service_id, IPC_FLAG_BLOCKING);
 	if (rc != EOK)
 		return rc;
Index: uspace/srv/hid/input/port/msim.c
===================================================================
--- uspace/srv/hid/input/port/msim.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hid/input/port/msim.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -97,6 +97,5 @@
 	msim_ranges[0].base = paddr;
 	msim_cmds[0].addr = (void *) paddr;
-	async_irq_subscribe(inr, device_assign_devno(), msim_irq_handler, NULL,
-	    &msim_kbd);
+	async_irq_subscribe(inr, msim_irq_handler, NULL, &msim_kbd);
 	
 	return 0;
Index: uspace/srv/hid/input/proto/mousedev.c
===================================================================
--- uspace/srv/hid/input/proto/mousedev.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hid/input/proto/mousedev.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,4 @@
 #include <ipc/mouseev.h>
 #include <loc.h>
-#include <sys/typefmt.h>
 #include "../mouse.h"
 #include "../mouse_port.h"
Index: uspace/srv/hid/output/proto/vt100.c
===================================================================
--- uspace/srv/hid/output/proto/vt100.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hid/output/proto/vt100.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,4 +36,5 @@
 #include <malloc.h>
 #include <io/color.h>
+#include <types/common.h>
 #include "vt100.h"
 
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -137,6 +137,5 @@
 	    (void *) ts->paddr, inr);
 
-	async_irq_subscribe(inr, device_assign_devno(), s3c24xx_ts_irq_handler,
-	    NULL, &ts_irq_code);
+	async_irq_subscribe(inr, s3c24xx_ts_irq_handler, NULL, &ts_irq_code);
 
 	s3c24xx_ts_wait_for_int_mode(ts, updn_down);
Index: pace/srv/hw/bus/cuda_adb/Makefile
===================================================================
--- uspace/srv/hw/bus/cuda_adb/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#
-# 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 = ../../../..
-BINARY = cuda_adb
-
-SOURCES = \
-	cuda_adb.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/srv/hw/bus/cuda_adb/cuda_adb.c
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,528 +1,0 @@
-/*
- * 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 <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <ddi.h>
-#include <libarch/ddi.h>
-#include <loc.h>
-#include <sysinfo.h>
-#include <errno.h>
-#include <ipc/adb.h>
-#include <assert.h>
-#include "cuda_adb.h"
-
-#define NAME  "cuda_adb"
-
-static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
-static int cuda_init(void);
-static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg);
-
-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_pio_range_t cuda_ranges[] = {
-	{
-		.base = 0,
-		.size = sizeof(cuda_t)
-	}
-};
-
-static irq_cmd_t cuda_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = NULL,
-		.dstarg = 1
-	},
-	{
-		.cmd = CMD_AND,
-		.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_ranges) / sizeof(irq_pio_range_t),
-	cuda_ranges,
-	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[])
-{
-	service_id_t service_id;
-	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_sess = NULL;
-		adb_dev[i].service_id = 0;
-	}
-
-	async_set_fallback_port_handler(cuda_connection, NULL);
-	rc = loc_server_register(NAME);
-	if (rc < 0) {
-		printf(NAME ": Unable to register server.\n");
-		return rc;
-	}
-
-	rc = loc_service_register("adb/kbd", &service_id);
-	if (rc != EOK) {
-		printf(NAME ": Unable to register service %s.\n", "adb/kdb");
-		return rc;
-	}
-
-	adb_dev[2].service_id = service_id;
-	adb_dev[8].service_id = service_id;
-
-	rc = loc_service_register("adb/mouse", &service_id);
-	if (rc != EOK) {
-		printf(NAME ": Unable to register servise %s.\n", "adb/mouse");
-		return rc;
-	}
-
-	adb_dev[9].service_id = service_id;
-
-	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, void *arg)
-{
-	ipc_callid_t callid;
-	ipc_call_t call;
-	sysarg_t method;
-	service_id_t dsid;
-	int dev_addr, i;
-
-	/* Get the device handle. */
-	dsid = IPC_GET_ARG2(*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].service_id == dsid)
-			dev_addr = i;
-	}
-
-	if (dev_addr < 0) {
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-
-	/* Answer the IPC_M_CONNECT_ME_TO call. */
-	async_answer_0(iid, EOK);
-
-	while (true) {
-		callid = async_get_call(&call);
-		method = IPC_GET_IMETHOD(call);
-		
-		if (!method) {
-			/* The other side has hung up. */
-			async_answer_0(callid, EOK);
-			return;
-		}
-		
-		async_sess_t *sess =
-		    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
-		if (sess != NULL) {
-			if (adb_dev[dev_addr].client_sess == NULL) {
-				adb_dev[dev_addr].client_sess = sess;
-				
-				/*
-				 * A hack so that we send the data to the session
-				 * regardless of which address the device is on.
-				 */
-				for (i = 0; i < ADB_MAX_ADDR; ++i) {
-					if (adb_dev[i].service_id == dsid)
-						adb_dev[i].client_sess = sess;
-				}
-				
-				async_answer_0(callid, EOK);
-			} else
-				async_answer_0(callid, ELIMIT);
-		} else
-			async_answer_0(callid, EINVAL);
-	}
-}
-
-
-static int cuda_init(void)
-{
-	if (sysinfo_get_value("cuda.address.physical", &(instance->cuda_physical)) != EOK)
-		return -1;
-	
-	void *vaddr;
-	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.ranges[0].base = (uintptr_t) instance->cuda_physical;
-	cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_physical)->ifr;
-	async_irq_subscribe(10, device_assign_devno(), cuda_irq_handler, NULL,
-	    &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, void *arg)
-{
-	uint8_t rbuf[CUDA_RCV_BUF_SIZE];
-	size_t len;
-	bool handle;
-
-	handle = false;
-	len = 0;
-
-	fibril_mutex_lock(&instance->dev_lock);
-
-	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;
-	}
-	
-	/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
-	pio_write_8(&instance->cuda->ifr, SR_INT);
-
-	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 = pio_read_8(&dev->b);
-	
-	if ((b & TREQ) != 0) {
-		printf("cuda_irq_listen: no TREQ?!\n");
-		return;
-	}
-	
-	pio_write_8(&dev->b, b & ~TIP);
-	instance->xstate = cx_receive;
-}
-
-/** Interrupt in receive state.
- *
- * Receive next byte of packet.
- */
-static void cuda_irq_receive(void)
-{
-	uint8_t data = pio_read_8(&dev->sr);
-	if (instance->bidx < CUDA_RCV_BUF_SIZE)
-		instance->rcv_buf[instance->bidx++] = data;
-	
-	uint8_t 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 b = pio_read_8(&dev->b);
-	
-	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_sess == NULL)
-		return;
-
-	async_exch_t *exch =
-	    async_exchange_begin(adb_dev[dev_addr].client_sess);
-	async_msg_1(exch, ADB_REG_NOTIF, reg_val);
-	async_exchange_end(exch);
-}
-
-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: pace/srv/hw/bus/cuda_adb/cuda_adb.h
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,126 +1,0 @@
-/*
- * 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 <stddef.h>
-#include <stdint.h>
-#include <async.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 {
-	service_id_t service_id;
-	async_sess_t *client_sess;
-} adb_dev_t;
-
-typedef struct {
-	cuda_t *cuda;
-	uintptr_t cuda_physical;
-
-	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/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -193,6 +193,5 @@
 	    (void *) uart->paddr, inr);
 
-	async_irq_subscribe(inr, device_assign_devno(), s3c24xx_uart_irq_handler,
-	    NULL, &uart_irq_code);
+	async_irq_subscribe(inr, s3c24xx_uart_irq_handler, NULL, &uart_irq_code);
 
 	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
Index: uspace/srv/hw/irc/apic/apic.c
===================================================================
--- uspace/srv/hw/irc/apic/apic.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hw/irc/apic/apic.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,6 @@
  */
 
-#include <ipc/services.h>
 #include <ipc/irc.h>
-#include <ns.h>
+#include <loc.h>
 #include <sysinfo.h>
 #include <as.h>
@@ -185,4 +184,8 @@
 			async_answer_0(callid, apic_enable_irq(IPC_GET_ARG1(call)));
 			break;
+		case IRC_DISABLE_INTERRUPT:
+			/* XXX TODO */
+			async_answer_0(callid, EOK);
+			break;
 		case IRC_CLEAR_INTERRUPT:
 			/* Noop */
@@ -202,4 +205,6 @@
 {
 	sysarg_t apic;
+	category_id_t irc_cat;
+	service_id_t svc_id;
 	
 	if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) {
@@ -216,5 +221,30 @@
 	
 	async_set_fallback_port_handler(apic_connection, NULL);
-	service_register(SERVICE_IRC);
+	
+	rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		printf("%s: Failed registering server. (%d)\n", NAME, rc);
+		return false;
+	}
+	
+	rc = loc_service_register("irc/" NAME, &svc_id);
+	if (rc != EOK) {
+		printf("%s: Failed registering service. (%d)\n", NAME, rc);
+		return false;
+	}
+	
+	rc = loc_category_get_id("irc", &irc_cat, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Failed resolving category 'iplink' (%d).\n", NAME,
+		    rc);
+		return false;
+	}
+	
+	rc = loc_service_add_to_cat(svc_id, irc_cat);
+	if (rc != EOK) {
+		printf("%s: Failed adding service to category (%d).\n", NAME,
+		    rc);
+		return false;
+	}
 	
 	return true;
Index: uspace/srv/hw/irc/i8259/i8259.c
===================================================================
--- uspace/srv/hw/irc/i8259/i8259.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hw/irc/i8259/i8259.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,7 +36,6 @@
  */
 
-#include <ipc/services.h>
 #include <ipc/irc.h>
-#include <ns.h>
+#include <loc.h>
 #include <sysinfo.h>
 #include <as.h>
@@ -47,5 +46,4 @@
 #include <async.h>
 #include <stdio.h>
-#include <ipc/loc.h>
 
 #define NAME  "i8259"
@@ -120,4 +118,8 @@
 			async_answer_0(callid, pic_enable_irq(IPC_GET_ARG1(call)));
 			break;
+		case IRC_DISABLE_INTERRUPT:
+			/* XXX TODO */
+			async_answer_0(callid, EOK);
+			break;
 		case IRC_CLEAR_INTERRUPT:
 			/* Noop */
@@ -137,4 +139,7 @@
 {
 	sysarg_t i8259;
+	category_id_t irc_cat;
+	service_id_t svc_id;
+	int rc;
 	
 	if ((sysinfo_get_value("i8259", &i8259) != EOK) || (!i8259)) {
@@ -152,5 +157,30 @@
 	
 	async_set_fallback_port_handler(i8259_connection, NULL);
-	service_register(SERVICE_IRC);
+
+	rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		printf("%s: Failed registering server. (%d)\n", NAME, rc);
+		return false;
+	}
+
+	rc = loc_service_register("irc/" NAME, &svc_id);
+	if (rc != EOK) {
+		printf("%s: Failed registering service. (%d)\n", NAME, rc);
+		return false;
+	}
+
+	rc = loc_category_get_id("irc", &irc_cat, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Failed resolving category 'iplink' (%d).\n", NAME,
+		    rc);
+		return false;
+	}
+
+	rc = loc_service_add_to_cat(svc_id, irc_cat);
+	if (rc != EOK) {
+		printf("%s: Failed adding service to category (%d).\n", NAME,
+		    rc);
+		return false;
+	}
 	
 	return true;
Index: pace/srv/hw/irc/icp-ic/Makefile
===================================================================
--- uspace/srv/hw/irc/icp-ic/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#
-# Copyright (c) 2014 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 = ../../../..
-BINARY = icp-ic
-
-SOURCES = \
-	icp-ic.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/srv/hw/irc/icp-ic/icp-ic.c
===================================================================
--- uspace/srv/hw/irc/icp-ic/icp-ic.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,189 +1,0 @@
-/*
- * Copyright (c) 2014 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 icp-ic
- * @{
- */
-
-/**
- * @file icp-ic.c
- * @brief IntegratorCP interrupt controller driver.
- */
-
-#include <async.h>
-#include <bitops.h>
-#include <ddi.h>
-#include <errno.h>
-#include <io/log.h>
-#include <ipc/services.h>
-#include <ipc/irc.h>
-#include <ns.h>
-#include <sysinfo.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <str.h>
-
-#include "icp-ic_hw.h"
-
-#define NAME  "icp-ic"
-
-enum {
-	icp_pic_base = 0x14000000,
-	icpic_max_irq = 32
-};
-
-static icpic_regs_t *icpic_regs;
-
-static int icpic_enable_irq(sysarg_t irq)
-{
-	if (irq > icpic_max_irq)
-		return EINVAL;
-
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Enable IRQ %d", irq);
-
-	pio_write_32(&icpic_regs->irq_enableset, BIT_V(uint32_t, irq));
-	return EOK;
-}
-
-/** Handle one connection to i8259.
- *
- * @param iid   Hash of the request that opened the connection.
- * @param icall Call data of the request that opened the connection.
- * @param arg	Local argument.
- */
-static void icpic_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	ipc_callid_t callid;
-	ipc_call_t call;
-
-	/*
-	 * Answer the first IPC_M_CONNECT_ME_TO call.
-	 */
-	async_answer_0(iid, EOK);
-
-	while (true) {
-		callid = async_get_call(&call);
-
-		if (!IPC_GET_IMETHOD(call)) {
-			/* The other side has hung up. */
-			async_answer_0(callid, EOK);
-			return;
-		}
-
-		switch (IPC_GET_IMETHOD(call)) {
-		case IRC_ENABLE_INTERRUPT:
-			async_answer_0(callid,
-			    icpic_enable_irq(IPC_GET_ARG1(call)));
-			break;
-		case IRC_CLEAR_INTERRUPT:
-			/* Noop */
-			async_answer_0(callid, EOK);
-			break;
-		default:
-			async_answer_0(callid, EINVAL);
-			break;
-		}
-	}
-}
-
-static int icpic_init(void)
-{
-	char *platform = NULL;
-	char *pstr = NULL;
-	size_t platform_size;
-	void *regs;
-	int rc;
-
-	platform = sysinfo_get_data("platform", &platform_size);
-	if (platform == NULL) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting platform type.");
-		rc = ENOENT;
-		goto error;
-	}
-
-	pstr = str_ndup(platform, platform_size);
-	if (pstr == NULL) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory.");
-		rc = ENOMEM;
-		goto error;
-	}
-
-	if (str_cmp(pstr, "integratorcp") != 0) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Platform '%s' is not 'integratorcp'.",
-
-		    pstr);
-		rc = ENOENT;
-		goto error;
-	}
-
-	rc = pio_enable((void *)icp_pic_base, sizeof(icpic_regs_t), &regs);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error enabling PIO");
-		goto error;
-	}
-
-	icpic_regs = (icpic_regs_t *)regs;
-
-	async_set_fallback_port_handler(icpic_connection, NULL);
-	service_register(SERVICE_IRC);
-
-	free(platform);
-	free(pstr);
-	return EOK;
-error:
-	free(platform);
-	free(pstr);
-	return rc;
-}
-
-int main(int argc, char **argv)
-{
-	int rc;
-
-	printf("%s: HelenOS IntegratorCP interrupt controller driver\n", NAME);
-
-	rc = log_init(NAME);
-	if (rc != EOK) {
-		printf(NAME ": Error connecting logging service.");
-		return 1;
-	}
-
-	if (icpic_init() != EOK)
-		return -1;
-
-	log_msg(LOG_DEFAULT, LVL_NOTE, "%s: Accepting connections\n", NAME);
-	task_retval(0);
-	async_manager();
-
-	/* Not reached */
-	return 0;
-}
-
-/**
- * @}
- */
Index: pace/srv/hw/irc/icp-ic/icp-ic_hw.h
===================================================================
--- uspace/srv/hw/irc/icp-ic/icp-ic_hw.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * Copyright (c) 2014 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 pl050
- * @{
- */
-/** @file ARM PrimeCell PS2 Keyboard/Mouse Interface (PL050) registers
- */
-
-#ifndef ICP_IC_HW_H
-#define ICP_IC_HW_H
-
-#include <ddi.h>
-
-typedef struct {
-	ioport32_t irq_status;
-	ioport32_t irq_rawstat;
-	ioport32_t irq_enableset;
-	ioport32_t irq_enableclr;
-	ioport32_t int_softset;
-	ioport32_t int_softclr;
-	ioport32_t fiq_status;
-	ioport32_t fiq_rawstat;
-	ioport32_t fiq_enableset;
-	ioport32_t fiq_enableclr;
-} icpic_regs_t;
-
-#endif
-
-/** @}
- */
Index: uspace/srv/hw/irc/obio/obio.c
===================================================================
--- uspace/srv/hw/irc/obio/obio.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/hw/irc/obio/obio.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -42,10 +42,10 @@
  */
 
-#include <ipc/services.h>
 #include <ipc/irc.h>
-#include <ns.h>
+#include <loc.h>
 #include <as.h>
 #include <ddi.h>
 #include <align.h>
+#include <inttypes.h>
 #include <stdbool.h>
 #include <errno.h>
@@ -54,9 +54,8 @@
 #include <async.h>
 #include <stdio.h>
-#include <ipc/loc.h>
 
 #define NAME "obio"
 
-#define OBIO_SIZE	0x1898	
+#define OBIO_SIZE	0x1898
 
 #define OBIO_IMR_BASE	0x200
@@ -97,4 +96,8 @@
 			async_answer_0(callid, EOK);
 			break;
+		case IRC_DISABLE_INTERRUPT:
+			/* XXX TODO */
+			async_answer_0(callid, EOK);
+			break;
 		case IRC_CLEAR_INTERRUPT:
 			inr = IPC_GET_ARG1(call);
@@ -115,4 +118,8 @@
 static bool obio_init(void)
 {
+	category_id_t irc_cat;
+	service_id_t svc_id;
+	int rc;
+	
 	base_phys = (uintptr_t) 0x1fe00000000ULL;
 	
@@ -127,8 +134,33 @@
 	}
 	
-	printf("%s: OBIO registers with base at %lx\n", NAME, base_phys);
+	printf("%s: OBIO registers with base at 0x%" PRIun "\n", NAME, base_phys);
 	
 	async_set_fallback_port_handler(obio_connection, NULL);
-	service_register(SERVICE_IRC);
+	
+	rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		printf("%s: Failed registering server. (%d)\n", NAME, rc);
+		return false;
+	}
+	
+	rc = loc_service_register("irc/" NAME, &svc_id);
+	if (rc != EOK) {
+		printf("%s: Failed registering service. (%d)\n", NAME, rc);
+		return false;
+	}
+	
+	rc = loc_category_get_id("irc", &irc_cat, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Failed resolving category 'iplink' (%d).\n", NAME,
+		    rc);
+		return false;
+	}
+	
+	rc = loc_service_add_to_cat(svc_id, irc_cat);
+	if (rc != EOK) {
+		printf("%s: Failed adding service to category (%d).\n", NAME,
+		    rc);
+		return false;
+	}
 	
 	return true;
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/locsrv/locsrv.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -1359,4 +1359,7 @@
 	categ_dir_add_cat(&cdir, cat);
 
+	cat = category_new("irc");
+	categ_dir_add_cat(&cdir, cat);
+
 	cat = category_new("visualizer");
 	categ_dir_add_cat(&cdir, cat);
Index: uspace/srv/net/dhcp/transport.c
===================================================================
--- uspace/srv/net/dhcp/transport.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/dhcp/transport.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -153,4 +153,10 @@
 	}
 
+	rc = udp_assoc_set_nolocal(assoc);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
 	dt->udp = udp;
 	dt->assoc = assoc;
Index: uspace/srv/net/dnsrsrv/dns_msg.c
===================================================================
--- uspace/srv/net/dnsrsrv/dns_msg.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/dnsrsrv/dns_msg.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -77,5 +77,5 @@
 		return ENOMEM;
 
-	str_cpy((*dstr) + s1, nsize - s1, suff);
+	str_cpy(nstr + s1, nsize - s1, suff);
 
 	*dstr = nstr;
@@ -195,12 +195,4 @@
 			break;
 
-		if (!first) {
-			rc = dns_dstr_ext(&name, ".");
-			if (rc != EOK) {
-				rc = ENOMEM;
-				goto error;
-			}
-		}
-
 		if ((lsize & 0xc0) == 0xc0) {
 			/* Pointer */
@@ -233,5 +225,6 @@
 			 * the message continues
 			 */
-			*eoff = eptr;
+			if (*eoff == 0)
+				*eoff = eptr;
 
 			bp = pdu->data + ptr;
@@ -243,4 +236,12 @@
 			rc = EINVAL;
 			goto error;
+		}
+
+		if (!first) {
+			rc = dns_dstr_ext(&name, ".");
+			if (rc != EOK) {
+				rc = ENOMEM;
+				goto error;
+			}
 		}
 
@@ -413,5 +414,5 @@
 	rc = dns_name_decode(pdu, boff, &rr->name, &name_eoff);
 	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "Error decoding name");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_rr_decode: error decoding name");
 		free(rr);
 		return ENOMEM;
@@ -421,4 +422,5 @@
 		free(rr->name);
 		free(rr);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_rr_decode: error name_off");
 		return EINVAL;
 	}
@@ -430,4 +432,5 @@
 		free(rr->name);
 		free(rr);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_rr_decode: error bsz");
 		return EINVAL;
 	}
@@ -445,4 +448,7 @@
 	bsz -= sizeof(uint32_t);
 
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "dns_rr_decode: rtype=0x%x, rclass=0x%x, ttl=0x%x",
+	    rr->rtype, rr->rclass, rr->ttl );
+
 	rdlength = dns_uint16_t_decode(bp, bsz);
 	bp += sizeof(uint16_t);
@@ -452,12 +458,15 @@
 		free(rr->name);
 		free(rr);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_rr_decode: Error rdlength %zu > bsz %zu", rdlength, bsz);
 		return EINVAL;
 	}
 
 	rr->rdata_size = rdlength;
-	rr->rdata = calloc(1, sizeof(rdlength));
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "dns_rr_decode: rdlength=%zu", rdlength);
+	rr->rdata = calloc(1, rdlength);
 	if (rr->rdata == NULL) {
 		free(rr->name);
 		free(rr);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_rr_decode: Error memory");
 		return ENOMEM;
 	}
@@ -470,4 +479,5 @@
 	*eoff = bp - pdu->data;
 	*retrr = rr;
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "dns_rr_decode: done");
 	return EOK;
 }
@@ -586,5 +596,5 @@
 	memcpy(msg->pdu.data, data, size);
 	msg->pdu.size = size;
-	log_msg(LOG_DEFAULT, LVL_NOTE, "dns_message_decode: pdu->data = %p, "
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "dns_message_decode: pdu->data = %p, "
 	    "pdu->size=%zu", msg->pdu.data, msg->pdu.size);
 
@@ -605,4 +615,6 @@
 
 	qd_count = uint16_t_be2host(hdr->qd_count);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "qd_count=%zu", qd_count);
+
 
 	for (i = 0; i < qd_count; i++) {
@@ -618,4 +630,5 @@
 
 	an_count = uint16_t_be2host(hdr->an_count);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "an_count=%zu", an_count);
 
 	for (i = 0; i < an_count; i++) {
Index: uspace/srv/net/dnsrsrv/query.c
===================================================================
--- uspace/srv/net/dnsrsrv/query.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/dnsrsrv/query.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -90,4 +90,5 @@
 	list_append(&question->msg, &msg->question);
 	
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_name_query: send DNS request");
 	dns_message_t *amsg;
 	int rc = dns_request(msg, &amsg);
Index: uspace/srv/net/dnsrsrv/transport.c
===================================================================
--- uspace/srv/net/dnsrsrv/transport.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/dnsrsrv/transport.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -183,4 +183,5 @@
 	void *req_data;
 	size_t req_size;
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_request: Encode dns message");
 	int rc = dns_message_encode(req, &req_data, &req_size);
 	if (rc != EOK)
@@ -194,8 +195,11 @@
 
 	while (ntry < REQ_RETRY_MAX) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_request: Send DNS message");
 		rc = udp_assoc_send_msg(transport_assoc, &ep, req_data,
 		    req_size);
-		if (rc != EOK)
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Error %d sending message", rc);
 			goto error;
+		}
 
 		treq = treq_create(req);
Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -111,5 +111,5 @@
 	}
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "inet_iplink_recv: link_id=%zu", packet.link_id);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv: link_id=%zu", packet.link_id);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()");
 	rc = inet_recv_packet(&packet);
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -450,5 +450,5 @@
 	ipc_call_t answer;
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "inet_ev_recv: iplink=%zu",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_ev_recv: iplink=%zu",
 	    dgram->iplink);
 
Index: uspace/srv/net/tcp/Makefile
===================================================================
--- uspace/srv/net/tcp/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -37,6 +37,7 @@
 BINARY = tcp
 
-SOURCES = \
+SOURCES_COMMON = \
 	conn.c \
+	inet.c \
 	iqueue.c \
 	ncsim.c \
@@ -44,10 +45,25 @@
 	rqueue.c \
 	segment.c \
-	service.c \
 	seq_no.c \
-	tcp.c \
 	test.c \
 	tqueue.c \
 	ucall.c
 
+SOURCES = \
+	$(SOURCES_COMMON) \
+	service.c \
+	tcp.c
+
+TEST_SOURCES = \
+	$(SOURCES_COMMON) \
+	test/conn.c \
+	test/iqueue.c \
+	test/main.c \
+	test/pdu.c \
+	test/rqueue.c \
+	test/segment.c \
+	test/seq_no.c \
+	test/tqueue.c \
+	test/ucall.c
+
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/net/tcp/conn.c
===================================================================
--- uspace/srv/net/tcp/conn.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/conn.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -44,5 +44,8 @@
 #include <stdlib.h>
 #include "conn.h"
+#include "inet.h"
 #include "iqueue.h"
+#include "pdu.h"
+#include "rqueue.h"
 #include "segment.h"
 #include "seq_no.h"
@@ -57,12 +60,26 @@
 #define TIME_WAIT_TIMEOUT	(2*MAX_SEGMENT_LIFETIME)
 
+/** List of all allocated connections */
 static LIST_INITIALIZE(conn_list);
 /** Taken after tcp_conn_t lock */
 static FIBRIL_MUTEX_INITIALIZE(conn_list_lock);
+/** Connection association map */
 static amap_t *amap;
-
-static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg);
-static void tcp_conn_tw_timer_set(tcp_conn_t *conn);
-static void tcp_conn_tw_timer_clear(tcp_conn_t *conn);
+/** Taken after tcp_conn_t lock */
+static FIBRIL_MUTEX_INITIALIZE(amap_lock);
+
+/** Internal loopback configuration */
+tcp_lb_t tcp_conn_lb = tcp_lb_none;
+
+static void tcp_conn_seg_process(tcp_conn_t *, tcp_segment_t *);
+static void tcp_conn_tw_timer_set(tcp_conn_t *);
+static void tcp_conn_tw_timer_clear(tcp_conn_t *);
+static void tcp_transmit_segment(inet_ep2_t *, tcp_segment_t *);
+static void tcp_conn_trim_seg_to_wnd(tcp_conn_t *, tcp_segment_t *);
+static void tcp_reply_rst(inet_ep2_t *, tcp_segment_t *);
+
+static tcp_tqueue_cb_t tcp_conn_tqueue_cb = {
+	.transmit_seg = tcp_transmit_segment
+};
 
 /** Initialize connections. */
@@ -78,4 +95,13 @@
 
 	return EOK;
+}
+
+/** Finalize connections. */
+void tcp_conns_fini(void)
+{
+	assert(list_empty(&conn_list));
+
+	amap_destroy(amap);
+	amap = NULL;
 }
 
@@ -130,6 +156,8 @@
 
 	/* Initialize retransmission queue */
-	if (tcp_tqueue_init(&conn->retransmit, conn) != EOK)
+	if (tcp_tqueue_init(&conn->retransmit, conn, &tcp_conn_tqueue_cb)
+	    != EOK) {
 		goto error;
+	}
 
 	tqueue_inited = true;
@@ -147,4 +175,8 @@
 	if (epp != NULL)
 		conn->ident = *epp;
+
+	fibril_mutex_lock(&conn_list_lock);
+	list_append(&conn->link, &conn_list);
+	fibril_mutex_unlock(&conn_list_lock);
 
 	return conn;
@@ -181,5 +213,11 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_free(%p)", conn->name, conn);
+
+	assert(conn->mapped == false);
 	tcp_tqueue_fini(&conn->retransmit);
+
+	fibril_mutex_lock(&conn_list_lock);
+	list_remove(&conn->link);
+	fibril_mutex_unlock(&conn_list_lock);
 
 	if (conn->rcv_buf != NULL)
@@ -271,5 +309,5 @@
 
 	tcp_conn_addref(conn);
-	fibril_mutex_lock(&conn_list_lock);
+	fibril_mutex_lock(&amap_lock);
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_add: conn=%p", conn);
@@ -278,11 +316,11 @@
 	if (rc != EOK) {
 		tcp_conn_delref(conn);
-		fibril_mutex_unlock(&conn_list_lock);
+		fibril_mutex_unlock(&amap_lock);
 		return rc;
 	}
 
 	conn->ident = aepp;
-	list_append(&conn->link, &conn_list);
-	fibril_mutex_unlock(&conn_list_lock);
+	conn->mapped = true;
+	fibril_mutex_unlock(&amap_lock);
 
 	return EOK;
@@ -293,10 +331,13 @@
  * Remove connection from the connection map.
  */
-void tcp_conn_remove(tcp_conn_t *conn)
-{
-	fibril_mutex_lock(&conn_list_lock);
+static void tcp_conn_remove(tcp_conn_t *conn)
+{
+	if (!conn->mapped)
+		return;
+
+	fibril_mutex_lock(&amap_lock);
 	amap_remove(amap, &conn->ident);
-	list_remove(&conn->link);
-	fibril_mutex_unlock(&conn_list_lock);
+	conn->mapped = false;
+	fibril_mutex_unlock(&amap_lock);
 	tcp_conn_delref(conn);
 }
@@ -335,4 +376,6 @@
 void tcp_conn_sync(tcp_conn_t *conn)
 {
+	assert(fibril_mutex_is_locked(&conn->lock));
+
 	/* XXX select ISS */
 	conn->iss = 1;
@@ -388,10 +431,10 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref(%p)", epp);
 
-	fibril_mutex_lock(&conn_list_lock);
+	fibril_mutex_lock(&amap_lock);
 
 	rc = amap_find_match(amap, epp, &arg);
 	if (rc != EOK) {
 		assert(rc == ENOENT);
-		fibril_mutex_unlock(&conn_list_lock);
+		fibril_mutex_unlock(&amap_lock);
 		return NULL;
 	}
@@ -400,5 +443,5 @@
 	tcp_conn_addref(conn);
 
-	fibril_mutex_unlock(&conn_list_lock);
+	fibril_mutex_unlock(&amap_lock);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref: got conn=%p",
 	    conn);
@@ -412,5 +455,11 @@
 void tcp_conn_reset(tcp_conn_t *conn)
 {
+	assert(fibril_mutex_is_locked(&conn->lock));
+
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_reset()", conn->name);
+
+	if (conn->cstate == st_closed)
+		return;
+
 	conn->reset = true;
 	tcp_conn_state_set(conn, st_closed);
@@ -865,5 +914,10 @@
 		return cp_done;
 
-	/* TODO */
+	if (conn->fin_is_acked) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN acked -> Time-Wait",
+		    conn->name);
+		tcp_conn_state_set(conn, st_time_wait);
+	}
+
 	return cp_continue;
 }
@@ -1062,9 +1116,9 @@
 		log_msg(LOG_DEFAULT, LVL_DEBUG, " - FIN found in segment.");
 
+		conn->rcv_nxt++;
+		conn->rcv_wnd--;
+
 		/* Send ACK */
 		tcp_tqueue_ctrl_seg(conn, CTL_ACK);
-
-		conn->rcv_nxt++;
-		conn->rcv_wnd--;
 
 		/* Change connection state */
@@ -1211,5 +1265,5 @@
 
 		/* Need to remove and re-insert connection with new identity */
-		fibril_mutex_lock(&conn_list_lock);
+		fibril_mutex_lock(&amap_lock);
 
 		if (inet_addr_is_any(&conn->ident.remote.addr))
@@ -1227,5 +1281,5 @@
 			assert(rc == ENOMEM);
 			log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory.");
-			fibril_mutex_unlock(&conn_list_lock);
+			fibril_mutex_unlock(&amap_lock);
 			tcp_conn_unlock(conn);
 			return;
@@ -1233,5 +1287,5 @@
 
 		amap_remove(amap, &oldepp);
-		fibril_mutex_unlock(&conn_list_lock);
+		fibril_mutex_unlock(&amap_lock);
 
 		conn->name = (char *) "a";
@@ -1322,5 +1376,5 @@
  * @param seg		Segment
  */
-void tcp_conn_trim_seg_to_wnd(tcp_conn_t *conn, tcp_segment_t *seg)
+static void tcp_conn_trim_seg_to_wnd(tcp_conn_t *conn, tcp_segment_t *seg)
 {
 	uint32_t left, right;
@@ -1346,4 +1400,61 @@
 }
 
+/** Transmit segment over network.
+ *
+ * @param epp Endpoint pair with source and destination information
+ * @param seg Segment (ownership retained by caller)
+ */
+static void tcp_transmit_segment(inet_ep2_t *epp, tcp_segment_t *seg)
+{
+	tcp_pdu_t *pdu;
+	tcp_segment_t *dseg;
+	inet_ep2_t rident;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
+	    "tcp_transmit_segment(l:(%u),f:(%u), %p)",
+	    epp->local.port, epp->remote.port, seg);
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
+	    seg->seq, seg->wnd);
+
+	tcp_segment_dump(seg);
+
+	if (tcp_conn_lb == tcp_lb_segment) {
+		/* Loop back segment */
+//		tcp_ncsim_bounce_seg(sp, seg);
+
+		/* Reverse the identification */
+		tcp_ep2_flipped(epp, &rident);
+
+		/* Insert segment back into rqueue */
+		dseg = tcp_segment_dup(seg);
+		tcp_rqueue_insert_seg(&rident, dseg);
+		return;
+	}
+
+	if (tcp_pdu_encode(epp, seg, &pdu) != EOK) {
+		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
+		return;
+	}
+
+	if (tcp_conn_lb == tcp_lb_pdu) {
+		/* Loop back PDU */
+		if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) {
+			log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
+			tcp_pdu_delete(pdu);
+			return;
+		}
+
+		tcp_pdu_delete(pdu);
+
+		/* Insert decoded segment into rqueue */
+		tcp_rqueue_insert_seg(&rident, dseg);
+		return;
+	}
+
+	tcp_transmit_pdu(pdu);
+	tcp_pdu_delete(pdu);
+}
+
 /** Compute flipped endpoint pair for response.
  *
@@ -1364,5 +1475,5 @@
  * @param seg		Incoming segment
  */
-void tcp_reply_rst(inet_ep2_t *epp, tcp_segment_t *seg)
+static void tcp_reply_rst(inet_ep2_t *epp, tcp_segment_t *seg)
 {
 	tcp_segment_t *rseg;
Index: uspace/srv/net/tcp/conn.h
===================================================================
--- uspace/srv/net/tcp/conn.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/conn.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,12 +41,11 @@
 
 extern int tcp_conns_init(void);
+extern void tcp_conns_fini(void);
 extern tcp_conn_t *tcp_conn_new(inet_ep2_t *);
 extern void tcp_conn_delete(tcp_conn_t *);
 extern int tcp_conn_add(tcp_conn_t *);
-extern void tcp_conn_remove(tcp_conn_t *);
 extern void tcp_conn_reset(tcp_conn_t *conn);
 extern void tcp_conn_sync(tcp_conn_t *);
 extern void tcp_conn_fin_sent(tcp_conn_t *);
-extern void tcp_conn_ack_of_fin_rcvd(tcp_conn_t *);
 extern tcp_conn_t *tcp_conn_find_ref(inet_ep2_t *);
 extern void tcp_conn_addref(tcp_conn_t *);
@@ -57,8 +56,8 @@
 extern void tcp_conn_segment_arrived(tcp_conn_t *, inet_ep2_t *,
     tcp_segment_t *);
-extern void tcp_conn_trim_seg_to_wnd(tcp_conn_t *, tcp_segment_t *);
 extern void tcp_unexpected_segment(inet_ep2_t *, tcp_segment_t *);
 extern void tcp_ep2_flipped(inet_ep2_t *, inet_ep2_t *);
-extern void tcp_reply_rst(inet_ep2_t *, tcp_segment_t *);
+
+extern tcp_lb_t tcp_conn_lb;
 
 #endif
Index: uspace/srv/net/tcp/inet.c
===================================================================
--- uspace/srv/net/tcp/inet.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/inet.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2015 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 tcp
+ * @{
+ */
+
+/**
+ * @file TCP inet interfacing
+ */
+
+#include <bitops.h>
+#include <byteorder.h>
+#include <errno.h>
+#include <inet/inet.h>
+#include <mem.h>
+#include <io/log.h>
+#include <stdlib.h>
+
+#include "inet.h"
+#include "pdu.h"
+#include "rqueue.h"
+#include "std.h"
+
+#define NAME       "tcp"
+
+static int tcp_inet_ev_recv(inet_dgram_t *dgram);
+static void tcp_received_pdu(tcp_pdu_t *pdu);
+
+static inet_ev_ops_t tcp_inet_ev_ops = {
+	.recv = tcp_inet_ev_recv
+};
+
+/** Received datagram callback */
+static int tcp_inet_ev_recv(inet_dgram_t *dgram)
+{
+	uint8_t *pdu_raw;
+	size_t pdu_raw_size;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv()");
+
+	pdu_raw = dgram->data;
+	pdu_raw_size = dgram->size;
+
+	/* Split into header and payload. */
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv() - split header/payload");
+
+	tcp_pdu_t *pdu;
+	size_t hdr_size;
+	tcp_header_t *hdr;
+	uint32_t data_offset;
+
+	if (pdu_raw_size < sizeof(tcp_header_t)) {
+		log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < sizeof(tcp_header_t) = %zu",
+		    pdu_raw_size, sizeof(tcp_header_t));
+		return EINVAL;
+	}
+
+	hdr = (tcp_header_t *)pdu_raw;
+	data_offset = BIT_RANGE_EXTRACT(uint32_t, DF_DATA_OFFSET_h, DF_DATA_OFFSET_l,
+	    uint16_t_be2host(hdr->doff_flags));
+
+	hdr_size = sizeof(uint32_t) * data_offset;
+
+	if (pdu_raw_size < hdr_size) {
+		log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu",
+		    pdu_raw_size, hdr_size);
+		return EINVAL;
+	}
+
+	if (hdr_size < sizeof(tcp_header_t)) {
+		log_msg(LOG_DEFAULT, LVL_WARN, "hdr_size = %zu < sizeof(tcp_header_t) = %zu",
+		    hdr_size, sizeof(tcp_header_t));		return EINVAL;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "pdu_raw_size=%zu, hdr_size=%zu",
+	    pdu_raw_size, hdr_size);
+	pdu = tcp_pdu_create(pdu_raw, hdr_size, pdu_raw + hdr_size,
+	    pdu_raw_size - hdr_size);
+	if (pdu == NULL) {
+		log_msg(LOG_DEFAULT, LVL_WARN, "Failed creating PDU. Dropped.");
+		return ENOMEM;
+	}
+
+	pdu->src = dgram->src;
+	pdu->dest = dgram->dest;
+
+	tcp_received_pdu(pdu);
+	tcp_pdu_delete(pdu);
+
+	return EOK;
+}
+
+/** Transmit PDU over network layer. */
+void tcp_transmit_pdu(tcp_pdu_t *pdu)
+{
+	int rc;
+	uint8_t *pdu_raw;
+	size_t pdu_raw_size;
+	inet_dgram_t dgram;
+
+	pdu_raw_size = pdu->header_size + pdu->text_size;
+	pdu_raw = malloc(pdu_raw_size);
+	if (pdu_raw == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU. Out of memory.");
+		return;
+	}
+
+	memcpy(pdu_raw, pdu->header, pdu->header_size);
+	memcpy(pdu_raw + pdu->header_size, pdu->text,
+	    pdu->text_size);
+
+	dgram.iplink = 0;
+	dgram.src = pdu->src;
+	dgram.dest = pdu->dest;
+	dgram.tos = 0;
+	dgram.data = pdu_raw;
+	dgram.size = pdu_raw_size;
+
+	rc = inet_send(&dgram, INET_TTL_MAX, 0);
+	if (rc != EOK)
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU.");
+
+	free(pdu_raw);
+}
+
+/** Process received PDU. */
+static void tcp_received_pdu(tcp_pdu_t *pdu)
+{
+	tcp_segment_t *dseg;
+	inet_ep2_t rident;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_received_pdu()");
+
+	if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) {
+		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. PDU dropped.");
+		return;
+	}
+
+	/* Insert decoded segment into rqueue */
+	tcp_rqueue_insert_seg(&rident, dseg);
+}
+
+/** Initialize TCP inet interface. */
+int tcp_inet_init(void)
+{
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_init()");
+
+	rc = inet_init(IP_PROTO_TCP, &tcp_inet_ev_ops);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting to internet service.");
+		return ENOENT;
+	}
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/net/tcp/inet.h
===================================================================
--- uspace/srv/net/tcp/inet.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/inet.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 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 tcp
+ * @{
+ */
+/** @file TCP inet interfacing
+ */
+
+#ifndef TCP_INET_H
+#define TCP_INET_H
+
+#include "tcp_type.h"
+
+extern int tcp_inet_init(void);
+extern void tcp_transmit_pdu(tcp_pdu_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/tcp/iqueue.c
===================================================================
--- uspace/srv/net/tcp/iqueue.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/iqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -84,6 +84,8 @@
 		    tcp_iqueue_entry_t, link);
 
-		if (seq_no_seg_cmp(iqueue->conn, iqe->seg, qe->seg) >= 0)
+		if (seq_no_seg_cmp(iqueue->conn, iqe->seg, qe->seg) < 0)
 			break;
+
+		link = list_next(link, &iqueue->list);
 	}
 
@@ -92,4 +94,36 @@
 	else
 		list_append(&iqe->link, &iqueue->list);
+}
+
+/** Remove segment from incoming queue.
+ *
+ * @param iqueue	Incoming queue
+ * @param seg		Segment
+ */
+void tcp_iqueue_remove_seg(tcp_iqueue_t *iqueue, tcp_segment_t *seg)
+{
+	tcp_iqueue_entry_t *qe;
+	link_t *link;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "tcp_iqueue_remove_seg()");
+
+	link = list_first(&iqueue->list);
+	while (link != NULL) {
+			log_msg(LOG_DEFAULT, LVL_NOTE, "tcp_iqueue_remove_seg() - next");
+		qe = list_get_instance(link,
+		    tcp_iqueue_entry_t, link);
+
+		if (qe->seg == seg) {
+			log_msg(LOG_DEFAULT, LVL_NOTE, "tcp_iqueue_remove_seg() - found, DONE");
+			list_remove(&qe->link);
+			free(qe);
+			return;
+		}
+
+		link = list_next(link, &iqueue->list);
+	}
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "tcp_iqueue_remove_seg() - not found");
+	assert(false);
 }
 
Index: uspace/srv/net/tcp/iqueue.h
===================================================================
--- uspace/srv/net/tcp/iqueue.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/iqueue.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,4 +40,5 @@
 extern void tcp_iqueue_init(tcp_iqueue_t *, tcp_conn_t *);
 extern void tcp_iqueue_insert_seg(tcp_iqueue_t *, tcp_segment_t *);
+extern void tcp_iqueue_remove_seg(tcp_iqueue_t *, tcp_segment_t *);
 extern int tcp_iqueue_get_ready_seg(tcp_iqueue_t *, tcp_segment_t **);
 
Index: uspace/srv/net/tcp/ncsim.c
===================================================================
--- uspace/srv/net/tcp/ncsim.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/ncsim.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -73,8 +73,10 @@
 	tcp_squeue_entry_t *sqe;
 	tcp_squeue_entry_t *old_qe;
+	inet_ep2_t rident;
 	link_t *link;
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ncsim_bounce_seg()");
-	tcp_rqueue_bounce_seg(epp, seg);
+	tcp_ep2_flipped(epp, &rident);
+	tcp_rqueue_insert_seg(&rident, seg);
 	return;
 
@@ -125,4 +127,5 @@
 	link_t *link;
 	tcp_squeue_entry_t *sqe;
+	inet_ep2_t rident;
 	int rc;
 
@@ -148,5 +151,6 @@
 
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "NCSim - End Sleep");
-		tcp_rqueue_bounce_seg(&sqe->epp, sqe->seg);
+		tcp_ep2_flipped(&sqe->epp, &rident);
+		tcp_rqueue_insert_seg(&rident, sqe->seg);
 		free(sqe);
 	}
Index: uspace/srv/net/tcp/rqueue.c
===================================================================
--- uspace/srv/net/tcp/rqueue.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/rqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,8 +38,9 @@
 #include <errno.h>
 #include <io/log.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <fibril.h>
+#include <fibril_synch.h>
 #include "conn.h"
-#include "pdu.h"
 #include "rqueue.h"
 #include "segment.h"
@@ -47,59 +48,32 @@
 #include "ucall.h"
 
-/** Transcode bounced segments.
- *
- * If defined, segments bounced via the internal debugging loopback will
- * be encoded to a PDU and the decoded. Otherwise they will be bounced back
- * directly without passing the encoder-decoder.
- */
-#define BOUNCE_TRANSCODE
-
 static prodcons_t rqueue;
+static bool fibril_active;
+static fibril_mutex_t lock;
+static fibril_condvar_t cv;
+static tcp_rqueue_cb_t *rqueue_cb;
 
 /** Initialize segment receive queue. */
-void tcp_rqueue_init(void)
+void tcp_rqueue_init(tcp_rqueue_cb_t *rcb)
 {
 	prodcons_initialize(&rqueue);
+	fibril_mutex_initialize(&lock);
+	fibril_condvar_initialize(&cv);
+	fibril_active = false;
+	rqueue_cb = rcb;
 }
 
-/** Bounce segment directy into receive queue without constructing the PDU.
- *
- * This is for testing purposes only.
- *
- * @param sp	Endpoint pair, oriented for transmission
- * @param seg	Segment
- */
-void tcp_rqueue_bounce_seg(inet_ep2_t *epp, tcp_segment_t *seg)
+/** Finalize segment receive queue. */
+void tcp_rqueue_fini(void)
 {
-	inet_ep2_t rident;
+	inet_ep2_t epp;
 
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_rqueue_bounce_seg()");
+	inet_ep2_init(&epp);
+	tcp_rqueue_insert_seg(&epp, NULL);
 
-#ifdef BOUNCE_TRANSCODE
-	tcp_pdu_t *pdu;
-	tcp_segment_t *dseg;
-
-	if (tcp_pdu_encode(epp, seg, &pdu) != EOK) {
-		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
-		return;
-	}
-
-	if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) {
-		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
-		return;
-	}
-
-	tcp_pdu_delete(pdu);
-
-	/** Insert decoded segment into rqueue */
-	tcp_rqueue_insert_seg(&rident, dseg);
-	tcp_segment_delete(seg);
-#else
-	/* Reverse the identification */
-	tcp_ep2_flipped(epp, &rident);
-
-	/* Insert segment back into rqueue */
-	tcp_rqueue_insert_seg(&rident, seg);
-#endif
+	fibril_mutex_lock(&lock);
+	while (fibril_active)
+		fibril_condvar_wait(&cv, &lock);
+	fibril_mutex_unlock(&lock);
 }
 
@@ -107,12 +81,14 @@
  *
  * @param epp	Endpoint pair, oriented for reception
- * @param seg	Segment
+ * @param seg	Segment (ownership transferred to rqueue)
  */
 void tcp_rqueue_insert_seg(inet_ep2_t *epp, tcp_segment_t *seg)
 {
 	tcp_rqueue_entry_t *rqe;
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_rqueue_insert_seg()");
 
-	tcp_segment_dump(seg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "tcp_rqueue_insert_seg()");
+
+	if (seg != NULL)
+		tcp_segment_dump(seg);
 
 	rqe = calloc(1, sizeof(tcp_rqueue_entry_t));
@@ -140,9 +116,21 @@
 		rqe = list_get_instance(link, tcp_rqueue_entry_t, link);
 
-		tcp_as_segment_arrived(&rqe->epp, rqe->seg);
+		if (rqe->seg == NULL) {
+			free(rqe);
+			break;
+		}
+
+		rqueue_cb->seg_received(&rqe->epp, rqe->seg);
 		free(rqe);
 	}
 
-	/* Not reached */
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "tcp_rqueue_fibril() exiting");
+
+	/* Finished */
+	fibril_mutex_lock(&lock);
+	fibril_active = false;
+	fibril_mutex_unlock(&lock);
+	fibril_condvar_broadcast(&cv);
+
 	return 0;
 }
@@ -162,4 +150,5 @@
 
 	fibril_add_ready(fid);
+	fibril_active = true;
 }
 
Index: uspace/srv/net/tcp/rqueue.h
===================================================================
--- uspace/srv/net/tcp/rqueue.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/rqueue.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -39,9 +39,8 @@
 #include "tcp_type.h"
 
-extern void tcp_rqueue_init(void);
-extern void tcp_rqueue_bounce_seg(inet_ep2_t *, tcp_segment_t *);
+extern void tcp_rqueue_init(tcp_rqueue_cb_t *);
+extern void tcp_rqueue_fibril_start(void);
+extern void tcp_rqueue_fini(void);
 extern void tcp_rqueue_insert_seg(inet_ep2_t *, tcp_segment_t *);
-extern void tcp_rqueue_handler(void *);
-extern void tcp_rqueue_fibril_start(void);
 
 
Index: uspace/srv/net/tcp/segment.c
===================================================================
--- uspace/srv/net/tcp/segment.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/segment.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,5 +43,5 @@
 
 /** Alocate new segment structure. */
-tcp_segment_t *tcp_segment_new(void)
+static tcp_segment_t *tcp_segment_new(void)
 {
 	return calloc(1, sizeof(tcp_segment_t));
Index: uspace/srv/net/tcp/segment.h
===================================================================
--- uspace/srv/net/tcp/segment.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/segment.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,5 +40,4 @@
 #include "tcp_type.h"
 
-extern tcp_segment_t *tcp_segment_new(void);
 extern void tcp_segment_delete(tcp_segment_t *);
 extern tcp_segment_t *tcp_segment_dup(tcp_segment_t *);
Index: uspace/srv/net/tcp/seq_no.c
===================================================================
--- uspace/srv/net/tcp/seq_no.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/seq_no.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -134,5 +134,12 @@
 }
 
-/** Determine whether segment is fully acked */
+/** Determine whether segment is fully acked.
+ *
+ * @param conn Connection
+ * @param seg  Segment
+ * @param ack  Last received ACK (i.e. SND.UNA)
+ *
+ * @return @c true if segment is fully acked, @c false otherwise
+ */
 bool seq_no_segment_acked(tcp_conn_t *conn, tcp_segment_t *seg, uint32_t ack)
 {
@@ -141,5 +148,9 @@
 }
 
-/** Determine whether initial SYN is acked */
+/** Determine whether initial SYN is acked.
+ *
+ * @param conn Connection
+ * @return @c true if initial SYN is acked, @c false otherwise
+ */
 bool seq_no_syn_acked(tcp_conn_t *conn)
 {
@@ -147,14 +158,30 @@
 }
 
-/** Determine whether segment overlaps the receive window */
+/** Determine whether segment overlaps the receive window.
+ *
+ * @param conn Connection
+ * @param seg  Segment
+ * @return @c true if segment overlaps the receive window, @c false otherwise
+ */
 bool seq_no_segment_acceptable(tcp_conn_t *conn, tcp_segment_t *seg)
 {
 	bool b_in, e_in;
-
+	bool wb_in, we_in;
+
+	/* Beginning of segment is inside window */
 	b_in = seq_no_le_lt(conn->rcv_nxt, seg->seq, conn->rcv_nxt
 	    + conn->rcv_wnd);
 
+	/* End of segment is inside window */
 	e_in = seq_no_le_lt(conn->rcv_nxt, seg->seq + seg->len - 1,
 	    conn->rcv_nxt + conn->rcv_wnd);
+
+	/* Beginning of window is inside segment */
+	wb_in = seq_no_le_lt(seg->seq, conn->rcv_nxt,
+	    seg->seq + seg->len);
+
+	/* End of window is inside segment */
+	we_in = seq_no_le_lt(seg->seq, conn->rcv_nxt + conn->rcv_wnd - 1,
+	    seg->seq + seg->len);
 
 	if (seg->len == 0 && conn->rcv_wnd == 0) {
@@ -165,9 +192,13 @@
 		return false;
 	} else {
-		return b_in || e_in;
-	}
-}
-
-/** Determine size that control bits occupy in sequence space. */
+		return b_in || e_in || wb_in || we_in;
+	}
+}
+
+/** Determine size that control bits occupy in sequence space.
+ *
+ * @param ctrl Control bits combination
+ * @return Number of sequence space units occupied
+ */
 uint32_t seq_no_control_len(tcp_control_t ctrl)
 {
@@ -183,5 +214,11 @@
 }
 
-/** Calculate the amount of trim needed to fit segment in receive window. */
+/** Calculate the amount of trim needed to fit segment in receive window.
+ *
+ * @param conn  Connection
+ * @param seg   Segment
+ * @param left  Place to store number of units to trim at the beginning
+ * @param right Place to store number of units to trim at the end
+ */
 void seq_no_seg_trim_calc(tcp_conn_t *conn, tcp_segment_t *seg,
     uint32_t *left, uint32_t *right)
Index: uspace/srv/net/tcp/service.c
===================================================================
--- uspace/srv/net/tcp/service.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/service.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -705,4 +705,7 @@
 			log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_impl() - EAGAIN");
 			return EAGAIN;
+		case TCP_ECLOSING:
+			*nrecv = 0;
+			return EOK;
 		default:
 			log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_impl() - trc=%d", rc);
Index: uspace/srv/net/tcp/tcp.c
===================================================================
--- uspace/srv/net/tcp/tcp.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/tcp.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,141 +36,22 @@
 
 #include <async.h>
-#include <bitops.h>
-#include <byteorder.h>
 #include <errno.h>
-#include <inet/inet.h>
 #include <io/log.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <task.h>
 
 #include "conn.h"
+#include "inet.h"
 #include "ncsim.h"
-#include "pdu.h"
 #include "rqueue.h"
 #include "service.h"
-#include "std.h"
-#include "tcp.h"
 #include "test.h"
+#include "ucall.h"
 
 #define NAME       "tcp"
 
-static int tcp_inet_ev_recv(inet_dgram_t *dgram);
-static void tcp_received_pdu(tcp_pdu_t *pdu);
-
-static inet_ev_ops_t tcp_inet_ev_ops = {
-	.recv = tcp_inet_ev_recv
+static tcp_rqueue_cb_t tcp_rqueue_cb = {
+	.seg_received = tcp_as_segment_arrived
 };
-
-/** Received datagram callback */
-static int tcp_inet_ev_recv(inet_dgram_t *dgram)
-{
-	uint8_t *pdu_raw;
-	size_t pdu_raw_size;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv()");
-
-	pdu_raw = dgram->data;
-	pdu_raw_size = dgram->size;
-
-	/* Split into header and payload. */
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv() - split header/payload");
-
-	tcp_pdu_t *pdu;
-	size_t hdr_size;
-	tcp_header_t *hdr;
-	uint32_t data_offset;
-
-	if (pdu_raw_size < sizeof(tcp_header_t)) {
-		log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < sizeof(tcp_header_t) = %zu",
-		    pdu_raw_size, sizeof(tcp_header_t));
-		return EINVAL;
-	}
-
-	hdr = (tcp_header_t *)pdu_raw;
-	data_offset = BIT_RANGE_EXTRACT(uint32_t, DF_DATA_OFFSET_h, DF_DATA_OFFSET_l,
-	    uint16_t_be2host(hdr->doff_flags));
-
-	hdr_size = sizeof(uint32_t) * data_offset;
-
-	if (pdu_raw_size < hdr_size) {
-		log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu",
-		    pdu_raw_size, hdr_size);
-		return EINVAL;
-	}
-
-	if (hdr_size < sizeof(tcp_header_t)) {
-		log_msg(LOG_DEFAULT, LVL_WARN, "hdr_size = %zu < sizeof(tcp_header_t) = %zu",
-		    hdr_size, sizeof(tcp_header_t));		return EINVAL;
-	}
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "pdu_raw_size=%zu, hdr_size=%zu",
-	    pdu_raw_size, hdr_size);
-	pdu = tcp_pdu_create(pdu_raw, hdr_size, pdu_raw + hdr_size,
-	    pdu_raw_size - hdr_size);
-	if (pdu == NULL) {
-		log_msg(LOG_DEFAULT, LVL_WARN, "Failed creating PDU. Dropped.");
-		return ENOMEM;
-	}
-
-	pdu->src = dgram->src;
-	pdu->dest = dgram->dest;
-
-	tcp_received_pdu(pdu);
-	tcp_pdu_delete(pdu);
-
-	return EOK;
-}
-
-/** Transmit PDU over network layer. */
-void tcp_transmit_pdu(tcp_pdu_t *pdu)
-{
-	int rc;
-	uint8_t *pdu_raw;
-	size_t pdu_raw_size;
-	inet_dgram_t dgram;
-
-	pdu_raw_size = pdu->header_size + pdu->text_size;
-	pdu_raw = malloc(pdu_raw_size);
-	if (pdu_raw == NULL) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU. Out of memory.");
-		return;
-	}
-
-	memcpy(pdu_raw, pdu->header, pdu->header_size);
-	memcpy(pdu_raw + pdu->header_size, pdu->text,
-	    pdu->text_size);
-
-	dgram.iplink = 0;
-	dgram.src = pdu->src;
-	dgram.dest = pdu->dest;
-	dgram.tos = 0;
-	dgram.data = pdu_raw;
-	dgram.size = pdu_raw_size;
-
-	rc = inet_send(&dgram, INET_TTL_MAX, 0);
-	if (rc != EOK)
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU.");
-
-	free(pdu_raw);
-}
-
-/** Process received PDU. */
-static void tcp_received_pdu(tcp_pdu_t *pdu)
-{
-	tcp_segment_t *dseg;
-	inet_ep2_t rident;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_received_pdu()");
-
-	if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) {
-		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. PDU dropped.");
-		return;
-	}
-
-	/* Insert decoded segment into rqueue */
-	tcp_rqueue_insert_seg(&rident, dseg);
-}
 
 static int tcp_init(void)
@@ -187,5 +68,5 @@
 	}
 
-	tcp_rqueue_init();
+	tcp_rqueue_init(&tcp_rqueue_cb);
 	tcp_rqueue_fibril_start();
 
@@ -195,9 +76,7 @@
 	if (0) tcp_test();
 
-	rc = inet_init(IP_PROTO_TCP, &tcp_inet_ev_ops);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting to internet service.");
+	rc = tcp_inet_init();
+	if (rc != EOK)
 		return ENOENT;
-	}
 
 	rc = tcp_service_init();
Index: pace/srv/net/tcp/tcp.h
===================================================================
--- uspace/srv/net/tcp/tcp.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2011 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 tcp
- * @{
- */
-/** @file TCP (Transmission Control Protocol) network module
- */
-
-#ifndef TCP_H
-#define TCP_H
-
-#include <async.h>
-#include "tcp_type.h"
-
-extern void tcp_transmit_pdu(tcp_pdu_t *);
-
-#endif
-
-/** @}
- */
Index: uspace/srv/net/tcp/tcp_type.h
===================================================================
--- uspace/srv/net/tcp/tcp_type.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/tcp_type.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -126,13 +126,4 @@
 } tcp_iqueue_t;
 
-/** Retransmission queue */
-typedef struct {
-	struct tcp_conn *conn;
-	list_t list;
-
-	/** Retransmission timer */
-	fibril_timer_t *timer;
-} tcp_tqueue_t;
-
 /** Active or passive connection */
 typedef enum {
@@ -156,4 +147,83 @@
 	void (*recv_data)(tcp_conn_t *, void *);
 } tcp_cb_t;
+
+/** Data returned by Status user call */
+typedef struct {
+	/** Connection state */
+	tcp_cstate_t cstate;
+} tcp_conn_status_t;
+
+typedef struct {
+	/** SYN, FIN */
+	tcp_control_t ctrl;
+
+	/** Segment sequence number */
+	uint32_t seq;
+	/** Segment acknowledgement number */
+	uint32_t ack;
+	/** Segment length in sequence space */
+	uint32_t len;
+	/** Segment window */
+	uint32_t wnd;
+	/** Segment urgent pointer */
+	uint32_t up;
+
+	/** Segment data, may be moved when trimming segment */
+	void *data;
+	/** Segment data, original pointer used to free data */
+	void *dfptr;
+} tcp_segment_t;
+
+/** Receive queue entry */
+typedef struct {
+	link_t link;
+	inet_ep2_t epp;
+	tcp_segment_t *seg;
+} tcp_rqueue_entry_t;
+
+/** Receive queue callbacks */
+typedef struct {
+	/** Segment received */
+	void (*seg_received)(inet_ep2_t *, tcp_segment_t *);
+} tcp_rqueue_cb_t;
+
+/** NCSim queue entry */
+typedef struct {
+	link_t link;
+	suseconds_t delay;
+	inet_ep2_t epp;
+	tcp_segment_t *seg;
+} tcp_squeue_entry_t;
+
+/** Incoming queue entry */
+typedef struct {
+	link_t link;
+	tcp_segment_t *seg;
+} tcp_iqueue_entry_t;
+
+/** Retransmission queue entry */
+typedef struct {
+	link_t link;
+	tcp_conn_t *conn;
+	tcp_segment_t *seg;
+} tcp_tqueue_entry_t;
+
+/** Retransmission queue callbacks */
+typedef struct {
+	/** Segment received */
+	void (*transmit_seg)(inet_ep2_t *, tcp_segment_t *);
+} tcp_tqueue_cb_t;
+
+/** Retransmission queue */
+typedef struct {
+	struct tcp_conn *conn;
+	list_t list;
+
+	/** Retransmission timer */
+	fibril_timer_t *timer;
+
+	/** Callbacks */
+	tcp_tqueue_cb_t *cb;
+} tcp_tqueue_t;
 
 /** Connection */
@@ -169,4 +239,6 @@
 	/** Connection identification (local and remote endpoint) */
 	inet_ep2_t ident;
+	/** Connection is in association map */
+	bool mapped;
 
 	/** Active or passive connection */
@@ -246,59 +318,4 @@
 };
 
-/** Data returned by Status user call */
-typedef struct {
-	/** Connection state */
-	tcp_cstate_t cstate;
-} tcp_conn_status_t;
-
-typedef struct {
-	/** SYN, FIN */
-	tcp_control_t ctrl;
-
-	/** Segment sequence number */
-	uint32_t seq;
-	/** Segment acknowledgement number */
-	uint32_t ack;
-	/** Segment length in sequence space */
-	uint32_t len;
-	/** Segment window */
-	uint32_t wnd;
-	/** Segment urgent pointer */
-	uint32_t up;
-
-	/** Segment data, may be moved when trimming segment */
-	void *data;
-	/** Segment data, original pointer used to free data */
-	void *dfptr;
-} tcp_segment_t;
-
-/** Receive queue entry */
-typedef struct {
-	link_t link;
-	inet_ep2_t epp;
-	tcp_segment_t *seg;
-} tcp_rqueue_entry_t;
-
-/** NCSim queue entry */
-typedef struct {
-	link_t link;
-	suseconds_t delay;
-	inet_ep2_t epp;
-	tcp_segment_t *seg;
-} tcp_squeue_entry_t;
-
-/** Incoming queue entry */
-typedef struct {
-	link_t link;
-	tcp_segment_t *seg;
-} tcp_iqueue_entry_t;
-
-/** Retransmission queue entry */
-typedef struct {
-	link_t link;
-	tcp_conn_t *conn;
-	tcp_segment_t *seg;
-} tcp_tqueue_entry_t;
-
 /** Continuation of processing.
  *
@@ -354,5 +371,5 @@
 /** TCP client */
 typedef struct tcp_client {
-	/** Client callbac session */
+	/** Client callback session */
 	async_sess_t *sess;
 	/** Client's connections */
@@ -362,4 +379,14 @@
 } tcp_client_t;
 
+/** Internal loopback type */
+typedef enum {
+	/** No loopback */
+	tcp_lb_none,
+	/** Segment loopback */
+	tcp_lb_segment,
+	/** PDU loopback */
+	tcp_lb_pdu
+} tcp_lb_t;
+
 #endif
 
Index: uspace/srv/net/tcp/test/conn.c
===================================================================
--- uspace/srv/net/tcp/test/conn.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/conn.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <errno.h>
+#include <inet/endpoint.h>
+#include <io/log.h>
+#include <pcut/pcut.h>
+
+#include "../conn.h"
+#include "../rqueue.h"
+#include "../ucall.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(conn);
+
+static tcp_rqueue_cb_t test_rqueue_cb = {
+	.seg_received = tcp_as_segment_arrived
+};
+
+PCUT_TEST_BEFORE
+{
+	int rc;
+
+	/* We will be calling functions that perform logging */
+	rc = log_init("test-tcp");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = tcp_conns_init();
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	tcp_rqueue_init(&test_rqueue_cb);
+	tcp_rqueue_fibril_start();
+
+	/* Enable internal loopback */
+	tcp_conn_lb = tcp_lb_segment;
+}
+
+PCUT_TEST_AFTER
+{
+	tcp_rqueue_fini();
+	tcp_conns_fini();
+}
+
+/** Test creating and deleting connection */
+PCUT_TEST(new_delete)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	tcp_conn_lock(conn);
+	tcp_conn_reset(conn);
+	tcp_conn_unlock(conn);
+	tcp_conn_delete(conn);
+}
+
+/** Test adding, finding and deleting a connection */
+PCUT_TEST(add_find_delete)
+{
+	tcp_conn_t *conn, *cfound;
+	inet_ep2_t epp;
+	int rc;
+
+	inet_ep2_init(&epp);
+
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	rc = tcp_conn_add(conn);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Find the connection */
+	cfound = tcp_conn_find_ref(&conn->ident);
+	PCUT_ASSERT_EQUALS(conn, cfound);
+	tcp_conn_delref(cfound);
+
+	/* We should have been assigned a port address, should not match */
+	cfound = tcp_conn_find_ref(&epp);
+	PCUT_ASSERT_EQUALS(NULL, cfound);
+
+	tcp_conn_lock(conn);
+	tcp_conn_reset(conn);
+	tcp_conn_unlock(conn);
+	tcp_conn_delete(conn);
+}
+
+/** Test trying to connect to endpoint that sends RST back */
+PCUT_TEST(connect_rst)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	int rc;
+
+	inet_ep2_init(&epp);
+	inet_addr(&epp.local.addr, 127, 0, 0, 1);
+	inet_addr(&epp.remote.addr, 127, 0, 0, 1);
+	epp.remote.port = inet_port_user_lo;
+
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	rc = tcp_conn_add(conn);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(st_listen, conn->cstate);
+
+	tcp_conn_lock(conn);
+	tcp_conn_sync(conn);
+	PCUT_ASSERT_INT_EQUALS(st_syn_sent, conn->cstate);
+
+	while (conn->cstate == st_syn_sent)
+                fibril_condvar_wait(&conn->cstate_cv, &conn->lock);
+
+	PCUT_ASSERT_INT_EQUALS(st_closed, conn->cstate);
+
+	tcp_conn_unlock(conn);
+	tcp_conn_delete(conn);
+}
+
+/** Test establishing a connection */
+PCUT_TEST(conn_establish)
+{
+	tcp_conn_t *cconn, *sconn;
+	inet_ep2_t cepp, sepp;
+	int rc;
+
+	/* Client EPP */
+	inet_ep2_init(&cepp);
+	inet_addr(&cepp.local.addr, 127, 0, 0, 1);
+	inet_addr(&cepp.remote.addr, 127, 0, 0, 1);
+	cepp.remote.port = inet_port_user_lo;
+
+	/* Server EPP */
+	inet_ep2_init(&sepp);
+	inet_addr(&sepp.local.addr, 127, 0, 0, 1);
+	sepp.local.port = inet_port_user_lo;
+
+	/* Client side of the connection */
+	cconn = tcp_conn_new(&cepp);
+	PCUT_ASSERT_NOT_NULL(cconn);
+
+	rc = tcp_conn_add(cconn);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(st_listen, cconn->cstate);
+	PCUT_ASSERT_FALSE(tcp_conn_got_syn(cconn));
+
+	/* Server side of the connection */
+	sconn = tcp_conn_new(&sepp);
+	PCUT_ASSERT_NOT_NULL(sconn);
+
+	rc = tcp_conn_add(sconn);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_INT_EQUALS(st_listen, sconn->cstate);
+	PCUT_ASSERT_FALSE(tcp_conn_got_syn(sconn));
+
+	/* Start establishing the connection */
+
+	tcp_conn_lock(cconn);
+	tcp_conn_sync(cconn);
+	PCUT_ASSERT_INT_EQUALS(st_syn_sent, cconn->cstate);
+	PCUT_ASSERT_FALSE(tcp_conn_got_syn(cconn));
+
+	/* Wait for client-side state to transition */
+	while (cconn->cstate == st_syn_sent)
+                fibril_condvar_wait(&cconn->cstate_cv, &cconn->lock);
+
+	PCUT_ASSERT_INT_EQUALS(st_established, cconn->cstate);
+	PCUT_ASSERT_TRUE(tcp_conn_got_syn(cconn));
+	tcp_conn_unlock(cconn);
+
+	/* Wait for server-side state to transition */
+	tcp_conn_lock(sconn);
+	while (sconn->cstate == st_listen || sconn->cstate == st_syn_received)
+                fibril_condvar_wait(&sconn->cstate_cv, &sconn->lock);
+
+	PCUT_ASSERT_INT_EQUALS(st_established, sconn->cstate);
+	PCUT_ASSERT_TRUE(tcp_conn_got_syn(sconn));
+
+	/* Verify counters */
+	PCUT_ASSERT_EQUALS(cconn->iss + 1, cconn->snd_nxt);
+	PCUT_ASSERT_EQUALS(cconn->iss + 1, cconn->snd_una);
+	PCUT_ASSERT_EQUALS(sconn->iss + 1, sconn->snd_nxt);
+	PCUT_ASSERT_EQUALS(sconn->iss + 1, sconn->snd_una);
+
+	tcp_conn_unlock(sconn);
+
+	tcp_conn_lock(cconn);
+	tcp_conn_reset(cconn);
+	tcp_conn_unlock(cconn);
+	tcp_conn_delete(cconn);
+
+	tcp_conn_lock(sconn);
+	tcp_conn_reset(sconn);
+	tcp_conn_unlock(sconn);
+	tcp_conn_delete(sconn);
+}
+
+PCUT_TEST(ep2_flipped)
+{
+	inet_ep2_t a, fa;
+
+	inet_addr(&a.local.addr, 1, 2, 3, 4);
+	a.local.port = 1234;
+	inet_addr(&a.remote.addr, 5, 6, 7, 8);
+	a.remote.port = 5678;
+
+	tcp_ep2_flipped(&a, &fa);
+
+	PCUT_ASSERT_INT_EQUALS(a.local.port, fa.remote.port);
+	PCUT_ASSERT_INT_EQUALS(a.remote.port, fa.local.port);
+
+	PCUT_ASSERT_TRUE(inet_addr_compare(&a.local.addr, &fa.remote.addr));
+	PCUT_ASSERT_TRUE(inet_addr_compare(&a.remote.addr, &fa.local.addr));
+}
+
+PCUT_EXPORT(conn);
Index: uspace/srv/net/tcp/test/iqueue.c
===================================================================
--- uspace/srv/net/tcp/test/iqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/iqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <inet/endpoint.h>
+#include <pcut/pcut.h>
+
+#include "../conn.h"
+#include "../iqueue.h"
+#include "../segment.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(iqueue);
+
+/** Test empty queue */
+PCUT_TEST(empty_queue)
+{
+	tcp_conn_t *conn;
+	tcp_iqueue_t iqueue;
+	inet_ep2_t epp;
+	tcp_segment_t *rseg;
+	int rc;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	conn->rcv_nxt = 10;
+	conn->rcv_wnd = 20;
+
+	tcp_iqueue_init(&iqueue, conn);
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+
+	tcp_conn_delete(conn);
+}
+
+/** Test iqeue with one segment */
+PCUT_TEST(one_segment)
+{
+	tcp_conn_t *conn;
+	tcp_iqueue_t iqueue;
+	inet_ep2_t epp;
+	tcp_segment_t *rseg;
+	tcp_segment_t *seg;
+	void *data;
+	size_t dsize;
+	int rc;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	conn->rcv_nxt = 10;
+	conn->rcv_wnd = 20;
+
+	dsize = 15;
+	data = calloc(dsize, 1);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	seg = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	tcp_iqueue_init(&iqueue, conn);
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+
+	seg->seq = 10;
+	tcp_iqueue_insert_seg(&iqueue, seg);
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	seg->seq = 15;
+	tcp_iqueue_insert_seg(&iqueue, seg);
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+	tcp_iqueue_remove_seg(&iqueue, seg);
+
+	tcp_segment_delete(seg);
+	free(data);
+	tcp_conn_delete(conn);
+}
+
+/** Test iqeue with two segments */
+PCUT_TEST(two_segments)
+{
+	tcp_conn_t *conn;
+	tcp_iqueue_t iqueue;
+	inet_ep2_t epp;
+	tcp_segment_t *rseg;
+	tcp_segment_t *seg1, *seg2;
+	void *data;
+	size_t dsize;
+	int rc;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	conn->rcv_nxt = 10;
+	conn->rcv_wnd = 20;
+
+	dsize = 15;
+	data = calloc(dsize, 1);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	seg1 = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg1);
+	seg2 = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg2);
+
+	tcp_iqueue_init(&iqueue, conn);
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+
+	/* Test reception in ascending order */
+	seg1->seq = 5;
+	tcp_iqueue_insert_seg(&iqueue, seg1);
+	seg2->seq = 10;
+	tcp_iqueue_insert_seg(&iqueue, seg2);
+
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_TRUE(rseg == seg1);
+
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_TRUE(rseg == seg2);
+
+	/* Test reception in descending order */
+	seg1->seq = 10;
+	tcp_iqueue_insert_seg(&iqueue, seg1);
+	seg2->seq = 5;
+	tcp_iqueue_insert_seg(&iqueue, seg2);
+
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_EQUALS(seg2, rseg);
+
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_EQUALS(seg1, rseg);
+
+	rc = tcp_iqueue_get_ready_seg(&iqueue, &rseg);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+
+	tcp_segment_delete(seg1);
+	tcp_segment_delete(seg2);
+	free(data);
+	tcp_conn_delete(conn);
+}
+
+
+PCUT_EXPORT(iqueue);
Index: uspace/srv/net/tcp/test/main.c
===================================================================
--- uspace/srv/net/tcp/test/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/main.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017 Jiri Svobda
+ * 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 <mem.h>
+#include <pcut/pcut.h>
+
+#include "main.h"
+#include "../segment.h"
+#include "../tcp_type.h"
+
+/** Verify that two segments have the same content */
+void test_seg_same(tcp_segment_t *a, tcp_segment_t *b)
+{
+	PCUT_ASSERT_INT_EQUALS(a->ctrl, b->ctrl);
+	PCUT_ASSERT_INT_EQUALS(a->seq, b->seq);
+	PCUT_ASSERT_INT_EQUALS(a->ack, b->ack);
+	PCUT_ASSERT_INT_EQUALS(a->len, b->len);
+	PCUT_ASSERT_INT_EQUALS(a->wnd, b->wnd);
+	PCUT_ASSERT_INT_EQUALS(a->up, b->up);
+	PCUT_ASSERT_INT_EQUALS(tcp_segment_text_size(a),
+	    tcp_segment_text_size(b));
+	if (tcp_segment_text_size(a) != 0)
+		PCUT_ASSERT_NOT_NULL(a->data);
+	if (tcp_segment_text_size(b) != 0)
+		PCUT_ASSERT_NOT_NULL(b->data);
+	if (tcp_segment_text_size(a) != 0) {
+		PCUT_ASSERT_INT_EQUALS(0, memcmp(a->data, b->data,
+		    tcp_segment_text_size(a)));
+	}
+}
+
+PCUT_INIT
+
+PCUT_IMPORT(conn);
+PCUT_IMPORT(iqueue);
+PCUT_IMPORT(pdu);
+PCUT_IMPORT(rqueue);
+PCUT_IMPORT(segment);
+PCUT_IMPORT(seq_no);
+PCUT_IMPORT(tqueue);
+PCUT_IMPORT(ucall);
+
+PCUT_MAIN()
Index: uspace/srv/net/tcp/test/main.h
===================================================================
--- uspace/srv/net/tcp/test/main.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/main.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 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 tcp
+ * @{
+ */
+/** @file
+ */
+
+#ifndef TEST_MAIN_H
+#define TEST_MAIN_H
+
+#include "../tcp_type.h"
+
+extern void test_seg_same(tcp_segment_t *, tcp_segment_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/tcp/test/pdu.c
===================================================================
--- uspace/srv/net/tcp/test/pdu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/pdu.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <errno.h>
+#include <inet/endpoint.h>
+#include <mem.h>
+#include <pcut/pcut.h>
+#include <stdlib.h>
+
+#include "main.h"
+#include "../pdu.h"
+#include "../segment.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(pdu);
+
+/** Test encode/decode round trip for control PDU */
+PCUT_TEST(encdec_syn)
+{
+	tcp_segment_t *seg, *dseg;
+	tcp_pdu_t *pdu;
+	inet_ep2_t epp, depp;
+	int rc;
+
+	inet_ep2_init(&epp);
+	inet_addr(&epp.local.addr, 1, 2, 3, 4);
+	inet_addr(&epp.remote.addr, 5, 6, 7, 8);
+
+	seg = tcp_segment_make_ctrl(CTL_SYN);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	seg->seq = 20;
+	seg->ack = 19;
+	seg->wnd = 18;
+	seg->up = 17;
+
+	rc = tcp_pdu_encode(&epp, seg, &pdu);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	rc = tcp_pdu_decode(pdu, &depp, &dseg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	test_seg_same(seg, dseg);
+	tcp_segment_delete(seg);
+}
+
+/** Test encode/decode round trip for data PDU */
+PCUT_TEST(encdec_data)
+{
+	tcp_segment_t *seg, *dseg;
+	tcp_pdu_t *pdu;
+	inet_ep2_t epp, depp;
+	uint8_t *data;
+	size_t i, dsize;
+	int rc;
+
+	inet_ep2_init(&epp);
+	inet_addr(&epp.local.addr, 1, 2, 3, 4);
+	inet_addr(&epp.remote.addr, 5, 6, 7, 8);
+
+	dsize = 15;
+	data = malloc(dsize);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	for (i = 0; i < dsize; i++)
+		data[i] = (uint8_t) i;
+
+	seg = tcp_segment_make_data(CTL_SYN, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	seg->seq = 20;
+	seg->ack = 19;
+	seg->wnd = 18;
+	seg->up = 17;
+
+	rc = tcp_pdu_encode(&epp, seg, &pdu);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	rc = tcp_pdu_decode(pdu, &depp, &dseg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	test_seg_same(seg, dseg);
+	tcp_segment_delete(seg);
+	free(data);
+}
+
+PCUT_EXPORT(pdu);
Index: uspace/srv/net/tcp/test/rqueue.c
===================================================================
--- uspace/srv/net/tcp/test/rqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/rqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <adt/prodcons.h>
+#include <inet/endpoint.h>
+#include <io/log.h>
+#include <pcut/pcut.h>
+
+#include "../rqueue.h"
+#include "../segment.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(rqueue);
+
+enum {
+	test_seg_max = 10
+};
+
+static void test_seg_received(inet_ep2_t *, tcp_segment_t *);
+
+static tcp_rqueue_cb_t rcb = {
+	.seg_received = test_seg_received
+};
+
+static int seg_cnt;
+static tcp_segment_t *recv_seg[test_seg_max];
+
+static void test_seg_received(inet_ep2_t *epp, tcp_segment_t *seg)
+{
+	recv_seg[seg_cnt++] = seg;
+}
+
+PCUT_TEST_BEFORE
+{
+	int rc;
+
+	/* We will be calling functions that perform logging */
+	rc = log_init("test-tcp");
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+}
+
+/** Test empty queue */
+PCUT_TEST(init_fini)
+{
+	tcp_rqueue_init(&rcb);
+	tcp_rqueue_fibril_start();
+	tcp_rqueue_fini();
+}
+
+/** Test one segment */
+PCUT_TEST(one_segment)
+{
+	tcp_segment_t *seg;
+	inet_ep2_t epp;
+
+	tcp_rqueue_init(&rcb);
+	seg_cnt = 0;
+
+	seg = tcp_segment_make_ctrl(CTL_SYN);
+	PCUT_ASSERT_NOT_NULL(seg);
+	inet_ep2_init(&epp);
+
+	tcp_rqueue_insert_seg(&epp, seg);
+	tcp_rqueue_fibril_start();
+	tcp_rqueue_fini();
+
+	PCUT_ASSERT_INT_EQUALS(1, seg_cnt);
+	PCUT_ASSERT_EQUALS(seg, recv_seg[0]);
+
+	tcp_segment_delete(seg);
+}
+
+/** Test multiple segments */
+PCUT_TEST(multiple_segments)
+{
+	tcp_segment_t *seg[test_seg_max];
+	inet_ep2_t epp;
+	int i;
+
+	tcp_rqueue_init(&rcb);
+	seg_cnt = 0;
+
+    	inet_ep2_init(&epp);
+
+	tcp_rqueue_fibril_start();
+
+	for (i = 0; i < test_seg_max; i++) {
+		seg[i] = tcp_segment_make_ctrl(CTL_ACK);
+		PCUT_ASSERT_NOT_NULL(seg[i]);
+		tcp_rqueue_insert_seg(&epp, seg[i]);
+	}
+
+	tcp_rqueue_fini();
+
+	PCUT_ASSERT_INT_EQUALS(test_seg_max, seg_cnt);
+	for (i = 0; i < test_seg_max; i++) {
+		PCUT_ASSERT_EQUALS(seg[i], recv_seg[i]);
+		tcp_segment_delete(seg[i]);
+	}
+
+}
+
+PCUT_EXPORT(rqueue);
Index: uspace/srv/net/tcp/test/segment.c
===================================================================
--- uspace/srv/net/tcp/test/segment.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/segment.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <pcut/pcut.h>
+
+#include "main.h"
+#include "../segment.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(segment);
+
+/** Test create/destroy control segment */
+PCUT_TEST(ctrl_seg_mkdel)
+{
+	tcp_segment_t *seg;
+
+	seg = tcp_segment_make_ctrl(CTL_SYN);
+	PCUT_ASSERT_NOT_NULL(seg);
+	tcp_segment_delete(seg);
+}
+
+/** Test create/destroy data segment */
+PCUT_TEST(data_seg_mkdel)
+{
+	tcp_segment_t *seg;
+	uint8_t *data;
+	size_t i, dsize;
+
+	dsize = 15;
+	data = malloc(dsize);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	for (i = 0; i < dsize; i++)
+		data[i] = (uint8_t) i;
+
+	seg = tcp_segment_make_data(CTL_SYN, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	tcp_segment_delete(seg);
+	free(data);
+}
+
+/** Test create/duplicate/destroy control segment */
+PCUT_TEST(ctrl_seg_dup)
+{
+	tcp_segment_t *seg, *dup;
+
+	seg = tcp_segment_make_ctrl(CTL_SYN);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	seg->seq = 20;
+	seg->ack = 19;
+	seg->wnd = 18;
+	seg->up = 17;
+
+	dup = tcp_segment_dup(seg);
+	test_seg_same(seg, dup);
+
+	tcp_segment_delete(seg);
+	tcp_segment_delete(dup);
+}
+
+/** Test create/duplicate/destroy data segment */
+PCUT_TEST(data_seg_dup)
+{
+	tcp_segment_t *seg, *dup;
+	uint8_t *data;
+	size_t i, dsize;
+
+	dsize = 15;
+	data = malloc(dsize);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	for (i = 0; i < dsize; i++)
+		data[i] = (uint8_t) i;
+
+	seg = tcp_segment_make_data(CTL_SYN, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	seg->seq = 20;
+	seg->ack = 19;
+	seg->wnd = 18;
+	seg->up = 17;
+
+	dup = tcp_segment_dup(seg);
+	test_seg_same(seg, dup);
+
+	tcp_segment_delete(seg);
+	tcp_segment_delete(dup);
+	free(data);
+}
+
+/** Test reset segment for segment with ACK not set */
+PCUT_TEST(noack_seg_rst)
+{
+	tcp_segment_t *seg, *rst;
+
+	seg = tcp_segment_make_ctrl(CTL_SYN);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	seg->seq = 20;
+	seg->ack = 19;
+	seg->wnd = 18;
+	seg->up = 17;
+
+	rst = tcp_segment_make_rst(seg);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	tcp_segment_delete(seg);
+	tcp_segment_delete(rst);
+}
+
+/** Test reset segment for segment with ACK set */
+PCUT_TEST(ack_seg_rst)
+{
+	tcp_segment_t *seg, *rst;
+
+	seg = tcp_segment_make_ctrl(CTL_SYN | CTL_ACK);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	seg->seq = 20;
+	seg->ack = 19;
+	seg->wnd = 18;
+	seg->up = 17;
+
+	rst = tcp_segment_make_rst(seg);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	tcp_segment_delete(seg);
+	tcp_segment_delete(rst);
+}
+
+/** Test copying out data segment text */
+PCUT_TEST(data_seg_text)
+{
+	tcp_segment_t *seg;
+	uint8_t *data;
+	uint8_t *cdata;
+	size_t i, dsize;
+
+	dsize = 15;
+	data = malloc(dsize);
+	PCUT_ASSERT_NOT_NULL(data);
+	cdata = malloc(dsize);
+	PCUT_ASSERT_NOT_NULL(cdata);
+
+	for (i = 0; i < dsize; i++)
+		data[i] = (uint8_t) i;
+
+	seg = tcp_segment_make_data(CTL_SYN, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	PCUT_ASSERT_INT_EQUALS(dsize, tcp_segment_text_size(seg));
+	tcp_segment_text_copy(seg, cdata, dsize);
+
+	for (i = 0; i < dsize; i++)
+		PCUT_ASSERT_INT_EQUALS(data[i], cdata[i]);
+
+	tcp_segment_delete(seg);
+	free(data);
+	free(cdata);
+}
+
+/** Test trimming data segment text */
+PCUT_TEST(data_seg_trim)
+{
+	tcp_segment_t *seg;
+	uint8_t *data;
+	uint8_t *cdata;
+	size_t i, dsize;
+
+	dsize = 15;
+	data = malloc(dsize);
+	PCUT_ASSERT_NOT_NULL(data);
+	cdata = malloc(dsize);
+	PCUT_ASSERT_NOT_NULL(cdata);
+
+	for (i = 0; i < dsize; i++)
+		data[i] = (uint8_t) i;
+
+	seg = tcp_segment_make_data(CTL_SYN | CTL_FIN, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	PCUT_ASSERT_INT_EQUALS(dsize, tcp_segment_text_size(seg));
+	tcp_segment_text_copy(seg, cdata, dsize);
+
+	for (i = 0; i < dsize; i++)
+		PCUT_ASSERT_INT_EQUALS(data[i], cdata[i]);
+
+	PCUT_ASSERT_INT_EQUALS(CTL_SYN | CTL_FIN, seg->ctrl);
+
+	tcp_segment_trim(seg, 1, 0);
+	PCUT_ASSERT_INT_EQUALS(CTL_FIN, seg->ctrl);
+	PCUT_ASSERT_INT_EQUALS(dsize, tcp_segment_text_size(seg));
+
+	tcp_segment_trim(seg, 0, 1);
+	PCUT_ASSERT_INT_EQUALS(0, seg->ctrl);
+	PCUT_ASSERT_INT_EQUALS(dsize, tcp_segment_text_size(seg));
+
+	tcp_segment_trim(seg, 1, 0);
+	PCUT_ASSERT_INT_EQUALS(0, seg->ctrl);
+	PCUT_ASSERT_INT_EQUALS(dsize - 1, tcp_segment_text_size(seg));
+
+	tcp_segment_text_copy(seg, cdata, dsize - 1);
+	for (i = 0; i < dsize - 1; i++)
+		PCUT_ASSERT_INT_EQUALS(data[i + 1], cdata[i]);
+
+	tcp_segment_trim(seg, 0, 1);
+	PCUT_ASSERT_INT_EQUALS(0, seg->ctrl);
+	PCUT_ASSERT_INT_EQUALS(dsize - 2, tcp_segment_text_size(seg));
+
+	tcp_segment_text_copy(seg, cdata, dsize - 2);
+	for (i = 0; i < dsize - 2; i++)
+		PCUT_ASSERT_INT_EQUALS(data[i + 1], cdata[i]);
+
+	tcp_segment_delete(seg);
+	free(data);
+	free(cdata);
+}
+
+PCUT_EXPORT(segment);
Index: uspace/srv/net/tcp/test/seq_no.c
===================================================================
--- uspace/srv/net/tcp/test/seq_no.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/seq_no.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <errno.h>
+#include <inet/endpoint.h>
+#include <pcut/pcut.h>
+
+#include "../conn.h"
+#include "../segment.h"
+#include "../seq_no.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(seq_no);
+
+/** Test seq_no_ack_acceptable() */
+PCUT_TEST(ack_acceptable)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	/* ACK is acceptable iff SND.UNA < SEG.ACK <= SND.NXT */
+
+	conn->snd_una = 10;
+	conn->snd_nxt = 30;
+
+	PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 9));
+	PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 10));
+	PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 11));
+	PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 29));
+	PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 30));
+	PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 31));
+
+	/* We also test whether seq_no_lt_le() wraps around properly */
+
+	conn->snd_una = 30;
+	conn->snd_nxt = 10;
+
+	PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 29));
+	PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 30));
+	PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 31));
+	PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 9));
+	PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 10));
+	PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 11));
+
+	tcp_conn_delete(conn);
+}
+
+/** Test seq_no_ack_duplicate() */
+PCUT_TEST(ack_duplicate)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	/* ACK is duplicate iff SEG.ACK <= SND.UNA */
+
+	conn->snd_una = 10;
+
+	PCUT_ASSERT_TRUE(seq_no_ack_duplicate(conn, 9));
+	PCUT_ASSERT_TRUE(seq_no_ack_duplicate(conn, 10));
+	PCUT_ASSERT_FALSE(seq_no_ack_duplicate(conn, 11));
+
+	conn->snd_una = (uint32_t) -10;
+
+	PCUT_ASSERT_TRUE(seq_no_ack_duplicate(conn, (uint32_t) -11));
+	PCUT_ASSERT_TRUE(seq_no_ack_duplicate(conn, (uint32_t) -10));
+	PCUT_ASSERT_FALSE(seq_no_ack_duplicate(conn, (uint32_t) -9));
+
+	tcp_conn_delete(conn);
+}
+
+/** Test seq_no_in_rcv_wnd() */
+PCUT_TEST(in_rcv_wnd)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	/* In receive window iff RCV.WND <= SEG.SEQ <= SND.UNA */
+
+	conn->rcv_nxt = 10;
+	conn->rcv_wnd = 20;
+
+	PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 9));
+	PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 10));
+	PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 11));
+	PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 29));
+	PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 30));
+	PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 31));
+
+	/* We also test whether seq_no_le_lt() wraps around properly */
+
+	conn->rcv_nxt = 20;
+	conn->rcv_wnd = (uint32_t) -10;
+
+	PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn,19));
+	PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 20));
+	PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 21));
+	PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 9));
+	PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 10));
+	PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 11));
+
+	tcp_conn_delete(conn);
+}
+
+/** Test seq_no_new_wnd_update() */
+PCUT_TEST(new_wnd_update)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	tcp_segment_t *seg;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	/*
+	 * Segment must be acceptable. Segment has new window update iff
+	 * either SND.WL1 < SEG.SEQ or
+	 * (SND.WL1 = SEG.SEQ and SND.WL2 <= SEG.ACK)
+	 */
+
+	conn->rcv_nxt = 10;
+	conn->rcv_wnd = 20;
+	conn->snd_una = 30;
+	conn->snd_wnd = 40;
+	conn->snd_wl1 = 15;
+	conn->snd_wl2 = 60;
+
+	seg = tcp_segment_make_ctrl(CTL_ACK);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	seg->seq = 14;
+	seg->ack = 80;
+	PCUT_ASSERT_FALSE(seq_no_new_wnd_update(conn, seg));
+
+	seg->seq = 15;
+	seg->ack = 59;
+	PCUT_ASSERT_FALSE(seq_no_new_wnd_update(conn, seg));
+
+	seg->seq = 15;
+	seg->ack = 60;
+	PCUT_ASSERT_TRUE(seq_no_new_wnd_update(conn, seg));
+
+	seg->seq = 16;
+	seg->ack = 50;
+	PCUT_ASSERT_TRUE(seq_no_new_wnd_update(conn, seg));
+
+	tcp_segment_delete(seg);
+	tcp_conn_delete(conn);
+}
+
+/** Test seq_no_segment_acked() */
+PCUT_TEST(segment_acked)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	tcp_segment_t *seg;
+	uint8_t *data;
+	size_t dsize;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	dsize = 15;
+	data = calloc(dsize, 1);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	seg = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	/* Segment is acked iff SEG.SEQ + SEG.LEN <= SND.UNA */
+
+	seg->seq = 10;
+	PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
+
+	PCUT_ASSERT_FALSE(seq_no_segment_acked(conn, seg, 24));
+	PCUT_ASSERT_TRUE(seq_no_segment_acked(conn, seg, 25));
+
+	tcp_segment_delete(seg);
+	tcp_conn_delete(conn);
+	free(data);
+}
+
+/** Test seq_no_syn_acked() */
+PCUT_TEST(syn_acked)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	conn->iss = 1;
+	conn->snd_una = 1;
+	conn->snd_nxt = 2;
+
+	PCUT_ASSERT_FALSE(seq_no_syn_acked(conn));
+
+	conn->snd_una = 2;
+	PCUT_ASSERT_TRUE(seq_no_syn_acked(conn));
+
+	tcp_conn_delete(conn);
+}
+
+/** Test seq_no_segment_ready() */
+PCUT_TEST(segment_ready)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	tcp_segment_t *seg;
+	uint8_t *data;
+	size_t dsize;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	dsize = 15;
+	data = calloc(dsize, 1);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	seg = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	/* Segment must be acceptable. Ready iff intersects RCV.NXT */
+
+	conn->rcv_nxt = 30;
+	conn->rcv_wnd = 20;
+
+	PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
+
+	seg->seq = 16;
+	PCUT_ASSERT_TRUE(seq_no_segment_ready(conn, seg));
+
+	seg->seq = 17;
+	PCUT_ASSERT_TRUE(seq_no_segment_ready(conn, seg));
+
+	seg->seq = 29;
+	PCUT_ASSERT_TRUE(seq_no_segment_ready(conn, seg));
+
+	seg->seq = 30;
+	PCUT_ASSERT_TRUE(seq_no_segment_ready(conn, seg));
+
+	seg->seq = 31;
+	PCUT_ASSERT_FALSE(seq_no_segment_ready(conn, seg));
+
+	tcp_segment_delete(seg);
+	tcp_conn_delete(conn);
+	free(data);
+}
+
+/** Test seq_no_segment_acceptable() */
+PCUT_TEST(segment_acceptable)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	tcp_segment_t *seg;
+	uint8_t *data;
+	size_t dsize;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	dsize = 15;
+	data = calloc(dsize, 1);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	seg = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	/* Segment acceptable iff overlaps receive window */
+
+	/* Segment shorter than receive window */
+	conn->rcv_nxt = 30;
+	conn->rcv_wnd = 20;
+
+	PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
+
+	seg->seq = 10;
+	PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
+
+	seg->seq = 15;
+	PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
+
+	seg->seq = 16;
+	PCUT_ASSERT_TRUE(seq_no_segment_acceptable(conn, seg));
+
+	seg->seq = 49;
+	PCUT_ASSERT_TRUE(seq_no_segment_acceptable(conn, seg));
+
+	seg->seq = 50;
+	PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
+
+	/* Segment longer than receive window */
+	conn->rcv_nxt = 30;
+	conn->rcv_wnd = 10;
+
+	PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
+
+	seg->seq = 10;
+	PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
+
+	seg->seq = 15;
+	PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
+
+	seg->seq = 16;
+	PCUT_ASSERT_TRUE(seq_no_segment_acceptable(conn, seg));
+
+	seg->seq = 39;
+	PCUT_ASSERT_TRUE(seq_no_segment_acceptable(conn, seg));
+
+	seg->seq = 40;
+	PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
+
+	tcp_segment_delete(seg);
+	tcp_conn_delete(conn);
+	free(data);
+}
+
+/** Test seq_no_seg_trim_calc() */
+PCUT_TEST(seg_trim_calc)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	tcp_segment_t *seg;
+	uint8_t *data;
+	size_t dsize;
+	uint32_t ltrim, rtrim;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	dsize = 15;
+	data = calloc(dsize, 1);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	seg = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg);
+
+	/* Segment must be acceptable, amount of trim needed */
+
+	/* Segment shorter than receive window */
+	conn->rcv_nxt = 30;
+	conn->rcv_wnd = 20;
+
+	PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
+
+	seg->seq = 16;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(14, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 17;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(13, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 29;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(1, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 30;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(0, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 31;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(0, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 35;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(0, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 36;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(0, ltrim);
+	PCUT_ASSERT_INT_EQUALS(1, rtrim);
+
+	seg->seq = 37;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(0, ltrim);
+	PCUT_ASSERT_INT_EQUALS(2, rtrim);
+
+	seg->seq = 48;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(0, ltrim);
+	PCUT_ASSERT_INT_EQUALS(13, rtrim);
+
+	seg->seq = 49;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(0, ltrim);
+	PCUT_ASSERT_INT_EQUALS(14, rtrim);
+
+	/* Segment longer than receive window */
+	conn->rcv_nxt = 30;
+	conn->rcv_wnd = 10;
+
+	PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
+
+	seg->seq = 16;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(14, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 17;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(13, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 24;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(6, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 25;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(5, ltrim);
+	PCUT_ASSERT_INT_EQUALS(0, rtrim);
+
+	seg->seq = 26;
+	seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
+	PCUT_ASSERT_INT_EQUALS(4, ltrim);
+	PCUT_ASSERT_INT_EQUALS(1, rtrim);
+
+	tcp_segment_delete(seg);
+	tcp_conn_delete(conn);
+	free(data);
+}
+
+/** Test seq_no_seg_cmp() */
+PCUT_TEST(seg_cmp)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	tcp_segment_t *seg1, *seg2;
+	uint8_t *data;
+	size_t dsize;
+
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	dsize = 15;
+	data = calloc(dsize, 1);
+	PCUT_ASSERT_NOT_NULL(data);
+
+	seg1 = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg1);
+	seg2 = tcp_segment_make_data(0, data, dsize);
+	PCUT_ASSERT_NOT_NULL(seg2);
+
+	/* Both segments must be acceptable */
+
+	conn->rcv_nxt = 10;
+	conn->rcv_wnd = 20;
+
+	PCUT_ASSERT_INT_EQUALS(dsize, seg1->len);
+	PCUT_ASSERT_INT_EQUALS(dsize, seg2->len);
+
+	seg1->seq = 5;
+	seg2->seq = 6;
+	PCUT_ASSERT_INT_EQUALS(-1, seq_no_seg_cmp(conn, seg1, seg2));
+
+	seg1->seq = 6;
+	seg2->seq = 6;
+	PCUT_ASSERT_INT_EQUALS(0, seq_no_seg_cmp(conn, seg1, seg2));
+
+	seg1->seq = 6;
+	seg2->seq = 5;
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_seg_cmp(conn, seg1, seg2));
+
+	tcp_segment_delete(seg1);
+	tcp_segment_delete(seg2);
+	tcp_conn_delete(conn);
+	free(data);
+}
+
+/** Test seq_no_control_len() */
+PCUT_TEST(control_len)
+{
+	PCUT_ASSERT_INT_EQUALS(0, seq_no_control_len(0));
+	PCUT_ASSERT_INT_EQUALS(0, seq_no_control_len(CTL_ACK));
+	PCUT_ASSERT_INT_EQUALS(0, seq_no_control_len(CTL_RST));
+	PCUT_ASSERT_INT_EQUALS(0, seq_no_control_len(CTL_ACK | CTL_RST));
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_SYN));
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_FIN));
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_SYN | CTL_ACK));
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_FIN | CTL_ACK));
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_SYN | CTL_RST));
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_FIN | CTL_RST));
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_SYN | CTL_ACK |
+	    CTL_RST));
+	PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_FIN | CTL_ACK |
+	    CTL_RST));
+	PCUT_ASSERT_INT_EQUALS(2, seq_no_control_len(CTL_SYN | CTL_FIN));
+	PCUT_ASSERT_INT_EQUALS(2, seq_no_control_len(CTL_SYN | CTL_FIN |
+	    CTL_ACK));
+	PCUT_ASSERT_INT_EQUALS(2, seq_no_control_len(CTL_SYN | CTL_FIN |
+	    CTL_RST));
+	PCUT_ASSERT_INT_EQUALS(2, seq_no_control_len(CTL_SYN | CTL_FIN |
+	    CTL_ACK | CTL_RST));
+}
+
+PCUT_EXPORT(seq_no);
Index: uspace/srv/net/tcp/test/tqueue.c
===================================================================
--- uspace/srv/net/tcp/test/tqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/tqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+//#include <inet/endpoint.h>
+#include <io/log.h>
+#include <pcut/pcut.h>
+
+#include "../conn.h"
+#include "../tqueue.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(tqueue);
+
+enum {
+	test_seg_max = 10
+};
+
+static int seg_cnt;
+static tcp_segment_t *trans_seg[test_seg_max];
+
+static void tqueue_test_transmit_seg(inet_ep2_t *, tcp_segment_t *);
+
+static tcp_tqueue_cb_t tqueue_test_cb = {
+	.transmit_seg = tqueue_test_transmit_seg
+};
+
+PCUT_TEST_BEFORE
+{
+	int rc;
+
+	/* We will be calling functions that perform logging */
+	rc = log_init("test-tcp");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = tcp_conns_init();
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+}
+
+PCUT_TEST_AFTER
+{
+	tcp_conns_fini();
+}
+
+
+/** Test  */
+PCUT_TEST(init_fini)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+
+	/* XXX tqueue can only be created via tcp_conn_new */
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	/* Redirect segment transmission */
+	conn->retransmit.cb = &tqueue_test_cb;
+	seg_cnt = 0;
+
+	tcp_conn_lock(conn);
+	tcp_conn_reset(conn);
+	tcp_conn_unlock(conn);
+	tcp_conn_delete(conn);
+	PCUT_ASSERT_EQUALS(0, seg_cnt);
+}
+
+/** Test sending control segment and tearing down a non-empty queue */
+PCUT_TEST(ctrl_seg_teardown)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+
+	/* XXX tqueue can only be created via tcp_conn_new */
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	conn->snd_nxt = 10;
+
+	/* Redirect segment transmission */
+	conn->retransmit.cb = &tqueue_test_cb;
+	seg_cnt = 0;
+
+	tcp_conn_lock(conn);
+	tcp_tqueue_ctrl_seg(conn, CTL_SYN);
+	tcp_conn_reset(conn);
+	tcp_conn_unlock(conn);
+	PCUT_ASSERT_EQUALS(11, conn->snd_nxt);
+
+	tcp_conn_delete(conn);
+	PCUT_ASSERT_EQUALS(1, seg_cnt);
+	PCUT_ASSERT_EQUALS(CTL_SYN, trans_seg[0]->ctrl);
+	PCUT_ASSERT_EQUALS(10, trans_seg[0]->seq);
+}
+
+/** Test sending data and FIN */
+PCUT_TEST(new_data_fin)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	int i;
+
+	/* XXX tqueue can only be created via tcp_conn_new */
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	conn->cstate = st_established;
+	conn->snd_una = 10;
+	conn->snd_nxt = 10;
+	conn->snd_wnd = 1024;
+	conn->snd_buf_used = 20;
+	conn->snd_buf_fin = true;
+	for (i = 0; i < 20; i++)
+		conn->snd_buf[i] = i;
+
+	/* Redirect segment transmission */
+	conn->retransmit.cb = &tqueue_test_cb;
+	seg_cnt = 0;
+
+	tcp_conn_lock(conn);
+	tcp_tqueue_new_data(conn);
+	tcp_conn_reset(conn);
+	tcp_conn_unlock(conn);
+	PCUT_ASSERT_EQUALS(31, conn->snd_nxt);
+	PCUT_ASSERT_EQUALS(0, conn->snd_buf_used);
+	PCUT_ASSERT_FALSE(conn->snd_buf_fin);
+
+	tcp_conn_delete(conn);
+	PCUT_ASSERT_EQUALS(1, seg_cnt);
+	PCUT_ASSERT_EQUALS(CTL_FIN | CTL_ACK, trans_seg[0]->ctrl);
+	PCUT_ASSERT_EQUALS(10, trans_seg[0]->seq);
+}
+
+/** Test sending data when send window is smaller */
+PCUT_TEST(new_data_small_win)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	int i;
+
+	/* XXX tqueue can only be created via tcp_conn_new */
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	conn->cstate = st_established;
+	conn->snd_una = 10;
+	conn->snd_nxt = 10;
+	conn->snd_wnd = 5;
+	conn->snd_buf_used = 30;
+	conn->snd_buf_fin = false;
+	for (i = 0; i < 30; i++)
+		conn->snd_buf[i] = i;
+
+	/* Redirect segment transmission */
+	conn->retransmit.cb = &tqueue_test_cb;
+	seg_cnt = 0;
+
+	tcp_conn_lock(conn);
+	tcp_tqueue_new_data(conn);
+	tcp_conn_reset(conn);
+	tcp_conn_unlock(conn);
+
+	PCUT_ASSERT_EQUALS(15, conn->snd_nxt);
+	PCUT_ASSERT_EQUALS(25, conn->snd_buf_used);
+	PCUT_ASSERT_FALSE(conn->snd_buf_fin);
+	for (i = 0; i < 25; i++)
+		PCUT_ASSERT_INT_EQUALS(5 + i, conn->snd_buf[i]);
+
+	tcp_conn_delete(conn);
+	PCUT_ASSERT_EQUALS(1, seg_cnt);
+	PCUT_ASSERT_EQUALS(CTL_ACK, trans_seg[0]->ctrl);
+	PCUT_ASSERT_EQUALS(10, trans_seg[0]->seq);
+}
+
+/** Test flushing tqueue due to receiving an ACK */
+PCUT_TEST(ack_received)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	int i;
+
+	/* XXX tqueue can only be created via tcp_conn_new */
+	inet_ep2_init(&epp);
+	conn = tcp_conn_new(&epp);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	conn->cstate = st_established;
+	conn->snd_una = 10;
+	conn->snd_nxt = 10;
+	conn->snd_wnd = 1024;
+
+	/* Redirect segment transmission */
+	conn->retransmit.cb = &tqueue_test_cb;
+	seg_cnt = 0;
+
+	tcp_conn_lock(conn);
+
+	/* Queue first data segment */
+	conn->snd_buf_used = 10;
+	conn->snd_buf_fin = false;
+	for (i = 0; i < 10; i++)
+		conn->snd_buf[i] = i;
+	tcp_tqueue_new_data(conn);
+
+	PCUT_ASSERT_EQUALS(20, conn->snd_nxt);
+
+	/* Queue second data segment */
+	conn->snd_buf_used = 20;
+	conn->snd_buf_fin = false;
+	for (i = 0; i < 20; i++)
+		conn->snd_buf[i] = i;
+	tcp_tqueue_new_data(conn);
+
+	PCUT_ASSERT_EQUALS(40, conn->snd_nxt);
+
+	PCUT_ASSERT_INT_EQUALS(2, list_count(&conn->retransmit.list));
+
+	/* One of the two segments is acked */
+	conn->snd_una = 20;
+	tcp_tqueue_ack_received(conn);
+
+	PCUT_ASSERT_INT_EQUALS(1, list_count(&conn->retransmit.list));
+
+	tcp_conn_reset(conn);
+	tcp_conn_unlock(conn);
+	tcp_conn_delete(conn);
+}
+
+static void tqueue_test_transmit_seg(inet_ep2_t *epp, tcp_segment_t *seg)
+{
+	trans_seg[seg_cnt++] = seg;
+}
+
+PCUT_EXPORT(tqueue);
Index: uspace/srv/net/tcp/test/ucall.c
===================================================================
--- uspace/srv/net/tcp/test/ucall.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
+++ uspace/srv/net/tcp/test/ucall.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include <errno.h>
+#include <inet/endpoint.h>
+#include <io/log.h>
+#include <pcut/pcut.h>
+
+#include "../conn.h"
+#include "../rqueue.h"
+#include "../ucall.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(ucall);
+
+static void test_cstate_change(tcp_conn_t *, void *, tcp_cstate_t);
+static void test_conns_establish(tcp_conn_t **, tcp_conn_t **);
+static void test_conns_tear_down(tcp_conn_t *, tcp_conn_t *);
+
+static tcp_rqueue_cb_t test_rqueue_cb = {
+	.seg_received = tcp_as_segment_arrived
+};
+
+static tcp_cb_t test_conn_cb = {
+	.cstate_change = test_cstate_change
+};
+
+static tcp_conn_status_t cconn_status;
+static tcp_conn_status_t sconn_status;
+
+static FIBRIL_MUTEX_INITIALIZE(cst_lock);
+static FIBRIL_CONDVAR_INITIALIZE(cst_cv);
+
+PCUT_TEST_BEFORE
+{
+	int rc;
+
+	/* We will be calling functions that perform logging */
+	rc = log_init("test-tcp");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = tcp_conns_init();
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	tcp_rqueue_init(&test_rqueue_cb);
+	tcp_rqueue_fibril_start();
+
+	/* Enable internal loopback */
+	tcp_conn_lb = tcp_lb_segment;
+}
+
+PCUT_TEST_AFTER
+{
+	tcp_rqueue_fini();
+	tcp_conns_fini();
+}
+
+/** Test creating a listening passive connection and then deleting it. */
+PCUT_TEST(listen_delete)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	tcp_error_t trc;
+	tcp_conn_status_t cstatus;
+
+	inet_ep2_init(&epp);
+	inet_addr(&epp.local.addr, 127, 0, 0, 1);
+	epp.local.port = inet_port_user_lo;
+
+	conn = NULL;
+	trc = tcp_uc_open(&epp, ap_passive, tcp_open_nonblock, &conn);
+	PCUT_ASSERT_INT_EQUALS(TCP_EOK, trc);
+	PCUT_ASSERT_NOT_NULL(conn);
+
+	tcp_uc_status(conn, &cstatus);
+	PCUT_ASSERT_INT_EQUALS(st_listen, cstatus.cstate);
+
+	trc = tcp_uc_close(conn);
+	PCUT_ASSERT_INT_EQUALS(TCP_EOK, trc);
+	tcp_uc_delete(conn);
+}
+
+/** Test trying to connect to endpoint that sends RST back */
+PCUT_TEST(connect_rst)
+{
+	tcp_conn_t *conn;
+	inet_ep2_t epp;
+	tcp_error_t trc;
+
+	inet_ep2_init(&epp);
+	inet_addr(&epp.local.addr, 127, 0, 0, 1);
+	inet_addr(&epp.remote.addr, 127, 0, 0, 1);
+	epp.remote.port = inet_port_user_lo;
+
+	conn = NULL;
+	trc = tcp_uc_open(&epp, ap_active, 0, &conn);
+	PCUT_ASSERT_INT_EQUALS(TCP_ERESET, trc);
+	PCUT_ASSERT_NULL(conn);
+}
+
+/** Test establishing a connection */
+PCUT_TEST(conn_establish)
+{
+	tcp_conn_t *cconn, *sconn;
+
+	test_conns_establish(&cconn, &sconn);
+	test_conns_tear_down(cconn, sconn);
+}
+
+/** Test establishing and then closing down a connection first on one side,
+ * then on_the other. */
+PCUT_TEST(conn_est_close_seq)
+{
+	tcp_conn_t *cconn, *sconn;
+	tcp_error_t trc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: establish");
+	/* Establish */
+	test_conns_establish(&cconn, &sconn);
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: close cconn");
+	/* Close client side */
+	trc = tcp_uc_close(cconn);
+	PCUT_ASSERT_INT_EQUALS(TCP_EOK, trc);
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: wait cconn = fin-wait-2");
+	/* Wait for cconn to go to Fin-Wait-2 */
+	fibril_mutex_lock(&cst_lock);
+	tcp_uc_status(cconn, &cconn_status);
+	while (cconn_status.cstate != st_fin_wait_2)
+		fibril_condvar_wait(&cst_cv, &cst_lock);
+	fibril_mutex_unlock(&cst_lock);
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: wait sconn = close-wait");
+	/* Wait for sconn to go to Close-Wait */
+	fibril_mutex_lock(&cst_lock);
+	tcp_uc_status(sconn, &sconn_status);
+	while (sconn_status.cstate != st_close_wait)
+		fibril_condvar_wait(&cst_cv, &cst_lock);
+	fibril_mutex_unlock(&cst_lock);
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: close sconn");
+	/* Close server side */
+	trc = tcp_uc_close(sconn);
+	PCUT_ASSERT_INT_EQUALS(TCP_EOK, trc);
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: wait cconn = time-wait");
+	/* Wait for cconn to go to Time-Wait */
+	fibril_mutex_lock(&cst_lock);
+	tcp_uc_status(cconn, &cconn_status);
+	while (cconn_status.cstate != st_time_wait)
+		fibril_condvar_wait(&cst_cv, &cst_lock);
+	fibril_mutex_unlock(&cst_lock);
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: wait sconn = closed");
+	/* Wait for sconn to go to Closed */
+	fibril_mutex_lock(&cst_lock);
+	tcp_uc_status(sconn, &sconn_status);
+	while (sconn_status.cstate != st_closed) {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: sconn.status == %d", sconn_status.cstate);
+		fibril_condvar_wait(&cst_cv, &cst_lock);
+	}
+	fibril_mutex_unlock(&cst_lock);
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "conn_est_close_seq: tear down");
+	/* Tear down */
+	test_conns_tear_down(cconn, sconn);
+}
+
+/** Test establishing and then simultaneously closing down a connection. */
+PCUT_TEST(conn_est_close_simult)
+{
+	tcp_conn_t *cconn, *sconn;
+	tcp_error_t trc;
+
+	/* Establish */
+	test_conns_establish(&cconn, &sconn);
+
+	/* Close both sides simultaneously */
+	trc = tcp_uc_close(cconn);
+	PCUT_ASSERT_INT_EQUALS(TCP_EOK, trc);
+	trc = tcp_uc_close(sconn);
+	PCUT_ASSERT_INT_EQUALS(TCP_EOK, trc);
+
+	/* Wait for cconn to go to Time-Wait */
+	fibril_mutex_lock(&cst_lock);
+	tcp_uc_status(cconn, &cconn_status);
+	while (cconn_status.cstate != st_time_wait)
+		fibril_condvar_wait(&cst_cv, &cst_lock);
+	fibril_mutex_unlock(&cst_lock);
+
+	/*
+	 * Wait for sconn to go to Closed or Time-Wait. The connection
+	 * goes to Closed if we managed to call tcp_uc_close() before
+	 * sconn received FIN. Otherwise it goes to Time-Wait.
+	 *
+	 * XXX We may want to add delay to the loopback here to be
+	 * absolutely sure that we go to Closing -> Time-Wait.
+	 */
+	fibril_mutex_lock(&cst_lock);
+	tcp_uc_status(sconn, &sconn_status);
+	while (sconn_status.cstate != st_time_wait &&
+	    sconn_status.cstate != st_closed)
+		fibril_condvar_wait(&cst_cv, &cst_lock);
+	fibril_mutex_unlock(&cst_lock);
+
+	/* Tear down */
+	test_conns_tear_down(cconn, sconn);
+}
+
+static void test_cstate_change(tcp_conn_t *conn, void *arg,
+    tcp_cstate_t old_state)
+{
+	tcp_conn_status_t *status = (tcp_conn_status_t *)arg;
+
+	fibril_mutex_lock(&cst_lock);
+	tcp_uc_status(conn, status);
+	fibril_mutex_unlock(&cst_lock);
+	fibril_condvar_broadcast(&cst_cv);
+}
+
+/** Establish client-server connection */
+static void test_conns_establish(tcp_conn_t **rcconn, tcp_conn_t **rsconn)
+{
+	tcp_conn_t *cconn, *sconn;
+	inet_ep2_t cepp, sepp;
+	tcp_conn_status_t cstatus;
+	tcp_error_t trc;
+
+	/* Client EPP */
+	inet_ep2_init(&cepp);
+	inet_addr(&cepp.local.addr, 127, 0, 0, 1);
+	inet_addr(&cepp.remote.addr, 127, 0, 0, 1);
+	cepp.remote.port = inet_port_user_lo;
+
+	/* Server EPP */
+	inet_ep2_init(&sepp);
+	inet_addr(&sepp.local.addr, 127, 0, 0, 1);
+	sepp.local.port = inet_port_user_lo;
+
+	/* Server side of the connection */
+	sconn = NULL;
+	trc = tcp_uc_open(&sepp, ap_passive, tcp_open_nonblock, &sconn);
+	PCUT_ASSERT_INT_EQUALS(TCP_EOK, trc);
+	PCUT_ASSERT_NOT_NULL(sconn);
+
+	tcp_uc_set_cb(sconn, &test_conn_cb, &sconn_status);
+	PCUT_ASSERT_EQUALS(&sconn_status, tcp_uc_get_userptr(sconn));
+
+	tcp_uc_status(sconn, &cstatus);
+	PCUT_ASSERT_INT_EQUALS(st_listen, cstatus.cstate);
+
+	/* Client side of the connection */
+
+	cconn = NULL;
+	trc = tcp_uc_open(&cepp, ap_active, 0, &cconn);
+	PCUT_ASSERT_INT_EQUALS(TCP_EOK, trc);
+	PCUT_ASSERT_NOT_NULL(cconn);
+
+	tcp_uc_set_cb(cconn, &test_conn_cb, &cconn_status);
+	PCUT_ASSERT_EQUALS(&cconn_status, tcp_uc_get_userptr(cconn));
+
+	/* The client side of the connection should be established by now */
+
+	tcp_uc_status(cconn, &cstatus);
+	PCUT_ASSERT_INT_EQUALS(st_established, cstatus.cstate);
+
+	/* Need to wait for server side */
+
+	fibril_mutex_lock(&cst_lock);
+	tcp_uc_status(sconn, &sconn_status);
+	while (sconn_status.cstate != st_established)
+		fibril_condvar_wait(&cst_cv, &cst_lock);
+	fibril_mutex_unlock(&cst_lock);
+
+	*rcconn = cconn;
+	*rsconn = sconn;
+}
+
+/* Tear down client-server connection. */
+static void test_conns_tear_down(tcp_conn_t *cconn, tcp_conn_t *sconn)
+{
+	tcp_uc_abort(cconn);
+	tcp_uc_delete(cconn);
+
+	tcp_uc_abort(sconn);
+	tcp_uc_delete(sconn);
+}
+
+PCUT_EXPORT(ucall);
Index: uspace/srv/net/tcp/tqueue.c
===================================================================
--- uspace/srv/net/tcp/tqueue.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/tqueue.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -43,24 +43,30 @@
 #include <mem.h>
 #include <stdlib.h>
+
 #include "conn.h"
+#include "inet.h"
 #include "ncsim.h"
-#include "pdu.h"
 #include "rqueue.h"
 #include "segment.h"
 #include "seq_no.h"
 #include "tqueue.h"
-#include "tcp.h"
 #include "tcp_type.h"
 
 #define RETRANSMIT_TIMEOUT	(2*1000*1000)
 
-static void retransmit_timeout_func(void *arg);
-static void tcp_tqueue_timer_set(tcp_conn_t *conn);
-static void tcp_tqueue_timer_clear(tcp_conn_t *conn);
-
-int tcp_tqueue_init(tcp_tqueue_t *tqueue, tcp_conn_t *conn)
+static void retransmit_timeout_func(void *);
+static void tcp_tqueue_timer_set(tcp_conn_t *);
+static void tcp_tqueue_timer_clear(tcp_conn_t *);
+static void tcp_tqueue_seg(tcp_conn_t *, tcp_segment_t *);
+static void tcp_conn_transmit_segment(tcp_conn_t *, tcp_segment_t *);
+static void tcp_prepare_transmit_segment(tcp_conn_t *, tcp_segment_t *);
+static void tcp_tqueue_send_immed(tcp_conn_t *, tcp_segment_t *);
+
+int tcp_tqueue_init(tcp_tqueue_t *tqueue, tcp_conn_t *conn,
+    tcp_tqueue_cb_t *cb)
 {
 	tqueue->conn = conn;
 	tqueue->timer = fibril_timer_create(&conn->lock);
+	tqueue->cb = cb;
 	if (tqueue->timer == NULL)
 		return ENOMEM;
@@ -78,8 +84,20 @@
 void tcp_tqueue_fini(tcp_tqueue_t *tqueue)
 {
+	link_t *link;
+	tcp_tqueue_entry_t *tqe;
+
 	if (tqueue->timer != NULL) {
 		fibril_timer_destroy(tqueue->timer);
 		tqueue->timer = NULL;
 	}
+
+	while (!list_empty(&tqueue->list)) {
+		link = list_first(&tqueue->list);
+		tqe = list_get_instance(link, tcp_tqueue_entry_t, link);
+		list_remove(link);
+
+		tcp_segment_delete(tqe->seg);
+		free(tqe);
+	}
 }
 
@@ -87,4 +105,6 @@
 {
 	tcp_segment_t *seg;
+
+	assert(fibril_mutex_is_locked(&conn->lock));
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_tqueue_ctrl_seg(%p, %u)", conn, ctrl);
@@ -95,8 +115,10 @@
 }
 
-void tcp_tqueue_seg(tcp_conn_t *conn, tcp_segment_t *seg)
+static void tcp_tqueue_seg(tcp_conn_t *conn, tcp_segment_t *seg)
 {
 	tcp_segment_t *rt_seg;
 	tcp_tqueue_entry_t *tqe;
+
+	assert(fibril_mutex_is_locked(&conn->lock));
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_tqueue_seg(%p, %p)", conn->name, conn,
@@ -135,5 +157,5 @@
 }
 
-void tcp_prepare_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
+static void tcp_prepare_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
 {
 	/*
@@ -267,5 +289,5 @@
 }
 
-void tcp_conn_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
+static void tcp_conn_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_transmit_segment(%p, %p)",
@@ -279,12 +301,12 @@
 		seg->ack = 0;
 
-	tcp_transmit_segment(&conn->ident, seg);
-}
-
-void tcp_transmit_segment(inet_ep2_t *epp, tcp_segment_t *seg)
+	tcp_tqueue_send_immed(conn, seg);
+}
+
+void tcp_tqueue_send_immed(tcp_conn_t *conn, tcp_segment_t *seg)
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG,
-	    "tcp_transmit_segment(l:(%u),f:(%u), %p)",
-	    epp->local.port, epp->remote.port, seg);
+	    "tcp_tqueue_send_immed(l:(%u),f:(%u), %p)",
+	    conn->ident.local.port, conn->ident.remote.port, seg);
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
@@ -292,20 +314,6 @@
 
 	tcp_segment_dump(seg);
-/*
-	tcp_pdu_prepare(conn, seg, &data, &len);
-	tcp_pdu_transmit(data, len);
-*/
-//	tcp_rqueue_bounce_seg(sp, seg);
-//	tcp_ncsim_bounce_seg(sp, seg);
-
-	tcp_pdu_t *pdu;
-
-	if (tcp_pdu_encode(epp, seg, &pdu) != EOK) {
-		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
-		return;
-	}
-
-	tcp_transmit_pdu(pdu);
-	tcp_pdu_delete(pdu);
+
+	conn->retransmit.cb->transmit_seg(&conn->ident, seg);
 }
 
@@ -362,4 +370,6 @@
 static void tcp_tqueue_timer_set(tcp_conn_t *conn)
 {
+	assert(fibril_mutex_is_locked(&conn->lock));
+
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "### %s: tcp_tqueue_timer_set() begin", conn->name);
 
@@ -377,4 +387,6 @@
 static void tcp_tqueue_timer_clear(tcp_conn_t *conn)
 {
+	assert(fibril_mutex_is_locked(&conn->lock));
+
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "### %s: tcp_tqueue_timer_clear() begin", conn->name);
 
Index: uspace/srv/net/tcp/tqueue.h
===================================================================
--- uspace/srv/net/tcp/tqueue.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/tqueue.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,16 +40,11 @@
 #include "tcp_type.h"
 
-extern int tcp_tqueue_init(tcp_tqueue_t *, tcp_conn_t *);
+extern int tcp_tqueue_init(tcp_tqueue_t *, tcp_conn_t *,
+    tcp_tqueue_cb_t *);
 extern void tcp_tqueue_clear(tcp_tqueue_t *);
 extern void tcp_tqueue_fini(tcp_tqueue_t *);
 extern void tcp_tqueue_ctrl_seg(tcp_conn_t *, tcp_control_t);
-extern void tcp_tqueue_seg(tcp_conn_t *, tcp_segment_t *);
 extern void tcp_tqueue_new_data(tcp_conn_t *);
 extern void tcp_tqueue_ack_received(tcp_conn_t *);
-extern void tcp_prepare_transmit_segment(tcp_conn_t *, tcp_segment_t *);
-extern void tcp_conn_transmit_segment(tcp_conn_t *, tcp_segment_t *);
-extern void tcp_transmit_segment(inet_ep2_t *, tcp_segment_t *);
-extern void tcp_header_setup(tcp_conn_t *, tcp_segment_t *, tcp_header_t *);
-extern void tcp_phdr_setup(tcp_conn_t *, tcp_segment_t *, tcp_phdr_t *);
 
 #endif
Index: uspace/srv/net/tcp/ucall.c
===================================================================
--- uspace/srv/net/tcp/ucall.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/tcp/ucall.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -108,4 +108,5 @@
 		assert(nconn->cstate == st_closed);
 		tcp_conn_unlock(nconn);
+		tcp_conn_delete(nconn);
 		return TCP_ERESET;
 	}
@@ -280,4 +281,8 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_abort()");
+
+	tcp_conn_lock(conn);
+	tcp_conn_reset(conn);
+	tcp_conn_unlock(conn);
 }
 
Index: uspace/srv/net/udp/assoc.c
===================================================================
--- uspace/srv/net/udp/assoc.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/udp/assoc.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,4 +40,5 @@
 #include <fibril_synch.h>
 #include <inet/endpoint.h>
+#include <inet/inet.h>
 #include <io/log.h>
 #include <nettl/amap.h>
@@ -261,7 +262,20 @@
 		return EINVAL;
 
+	/* This association has no local address set. Need to determine one. */
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send - check no local addr");
+	if (inet_addr_is_any(&epp.local.addr) && !assoc->nolocal) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Determine local address.");
+		rc = inet_get_srcaddr(&epp.remote.addr, 0, &epp.local.addr);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Cannot determine "
+			    "local address.");
+			return EINVAL;
+		}
+	}
+
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send - check version");
 
-	if (epp.remote.addr.version != epp.local.addr.version)
+	if (!inet_addr_is_any(&epp.local.addr) &&
+	    epp.remote.addr.version != epp.local.addr.version)
 		return EINVAL;
 
Index: uspace/srv/net/udp/service.c
===================================================================
--- uspace/srv/net/udp/service.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/udp/service.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -270,4 +270,28 @@
 }
 
+/** Set association sending messages with no local address.
+ *
+ * Handle client request to set nolocal flag (with parameters unmarshalled).
+ *
+ * @param client   UDP client
+ * @param assoc_id Association ID
+ * @return EOK on success, ENOENT if no such association is found
+ */
+static int udp_assoc_set_nolocal_impl(udp_client_t *client, sysarg_t assoc_id)
+{
+	udp_cassoc_t *cassoc;
+	int rc;
+
+	rc = udp_cassoc_get(client, assoc_id, &cassoc);
+	if (rc != EOK) {
+		assert(rc == ENOENT);
+		return ENOENT;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Setting nolocal to true");
+	cassoc->assoc->nolocal = true;
+	return EOK;
+}
+
 /** Send message via association.
  *
@@ -391,4 +415,25 @@
 	assoc_id = IPC_GET_ARG1(*icall);
 	rc = udp_assoc_destroy_impl(client, assoc_id);
+	async_answer_0(iid, rc);
+}
+
+/** Set association with no local address.
+ *
+ * Handle client request to set no local address flag.
+ *
+ * @param client   UDP client
+ * @param iid      Async request ID
+ * @param icall    Async request data
+ */
+static void udp_assoc_set_nolocal_srv(udp_client_t *client, ipc_callid_t iid,
+    ipc_call_t *icall)
+{
+	sysarg_t assoc_id;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "udp_assoc_set_nolocal_srv()");
+
+	assoc_id = IPC_GET_ARG1(*icall);
+	rc = udp_assoc_set_nolocal_impl(client, assoc_id);
 	async_answer_0(iid, rc);
 }
@@ -662,4 +707,7 @@
 			udp_assoc_destroy_srv(&client, callid, &call);
 			break;
+		case UDP_ASSOC_SET_NOLOCAL:
+			udp_assoc_set_nolocal_srv(&client, callid, &call);
+			break;
 		case UDP_ASSOC_SEND_MSG:
 			udp_assoc_send_msg_srv(&client, callid, &call);
Index: uspace/srv/net/udp/udp_inet.c
===================================================================
--- uspace/srv/net/udp/udp_inet.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/udp/udp_inet.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -35,11 +35,7 @@
  */
 
-#include <bitops.h>
-#include <byteorder.h>
 #include <errno.h>
 #include <inet/inet.h>
 #include <io/log.h>
-#include <stdio.h>
-#include <task.h>
 
 #include "assoc.h"
Index: uspace/srv/net/udp/udp_type.h
===================================================================
--- uspace/srv/net/udp/udp_type.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/net/udp/udp_type.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,4 +41,5 @@
 #include <inet/endpoint.h>
 #include <ipc/loc.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <inet/addr.h>
@@ -119,4 +120,6 @@
 	/** Receive queue CV. Broadcast when new datagram is inserted */
 	fibril_condvar_t rcv_queue_cv;
+	/** Allow sending messages with no local address */
+	bool nolocal;
 
 	udp_assoc_cb_t *cb;
Index: uspace/srv/ns/clonable.c
===================================================================
--- uspace/srv/ns/clonable.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/ns/clonable.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,5 +31,5 @@
  */
 
-#include <ipc/ipc.h>
+#include <async.h>
 #include <ipc/services.h>
 #include <adt/list.h>
@@ -81,5 +81,5 @@
 		/* There was no pending connection request. */
 		printf("%s: Unexpected clonable server.\n", NAME);
-		ipc_answer_0(callid, EBUSY);
+		async_answer_0(callid, EBUSY);
 		return;
 	}
@@ -91,11 +91,17 @@
 	assert(csr->service == SERVICE_LOADER);
 	
-	ipc_answer_0(callid, EOK);
+	async_answer_0(callid, EOK);
 	
-	ipc_forward_fast(csr->callid, phone, csr->iface, csr->arg3, 0,
+	async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (sess == NULL)
+		async_answer_0(callid, EIO);
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_forward_fast(csr->callid, exch, csr->iface, csr->arg3, 0,
 	    IPC_FF_NONE);
+	async_exchange_end(exch);
 	
 	free(csr);
-	ipc_hangup(phone);
+	async_hangup(sess);
 }
 
@@ -117,5 +123,5 @@
 	cs_req_t *csr = malloc(sizeof(cs_req_t));
 	if (csr == NULL) {
-		ipc_answer_0(callid, ENOMEM);
+		async_answer_0(callid, ENOMEM);
 		return;
 	}
@@ -126,5 +132,5 @@
 	if (rc < 0) {
 		free(csr);
-		ipc_answer_0(callid, rc);
+		async_answer_0(callid, rc);
 		return;
 	}
Index: uspace/srv/ns/ns.c
===================================================================
--- uspace/srv/ns/ns.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/ns/ns.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -36,5 +36,6 @@
  */
 
-#include <ipc/ipc.h>
+#include <abi/ipc/methods.h>
+#include <async.h>
 #include <ipc/ns.h>
 #include <ipc/services.h>
@@ -47,4 +48,82 @@
 #include "clonable.h"
 #include "task.h"
+
+static void ns_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	ipc_call_t call;
+	ipc_callid_t callid;
+	iface_t iface;
+	service_t service;
+
+	iface = IPC_GET_ARG1(*icall);
+	service = IPC_GET_ARG2(*icall);
+	if (service != 0) {
+		/*
+		 * Client requests to be connected to a service.
+		 */
+		if (service_clonable(service)) {
+			connect_to_clonable(service, iface, icall, iid);
+		} else {
+			connect_to_service(service, iface, icall, iid);
+		}
+		return;
+	}
+	
+	async_answer_0(iid, EOK);
+
+	while (true) {
+		process_pending_conn();
+		
+		callid = async_get_call(&call);
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
+		task_id_t id;
+		sysarg_t retval;
+		
+		service_t service;
+		sysarg_t phone;
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case NS_REGISTER:
+			service = IPC_GET_ARG1(call);
+			phone = IPC_GET_ARG5(call);
+			
+			/*
+			 * Server requests service registration.
+			 */
+			if (service_clonable(service)) {
+				register_clonable(service, phone, &call, callid);
+				continue;
+			} else {
+				retval = register_service(service, phone, &call);
+			}
+			
+			break;
+		case NS_PING:
+			retval = EOK;
+			break;
+		case NS_TASK_WAIT:
+			id = (task_id_t)
+			    MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			wait_for_task(id, &call, callid);
+			continue;
+		case NS_ID_INTRO:
+			retval = ns_task_id_intro(&call);
+			break;
+		case NS_RETVAL:
+			retval = ns_task_retval(&call);
+			break;
+		default:
+			printf("ns: method not supported\n");
+			retval = ENOTSUP;
+			break;
+		}
+		
+		async_answer_0(callid, retval);
+	}
+
+	(void) ns_task_disconnect(&call);
+}
 
 int main(int argc, char **argv)
@@ -64,74 +143,8 @@
 		return rc;
 	
+	async_set_fallback_port_handler(ns_connection, NULL);
+	
 	printf("%s: Accepting connections\n", NAME);
-	
-	while (true) {
-		process_pending_conn();
-		
-		ipc_call_t call;
-		ipc_callid_t callid = ipc_wait_for_call(&call);
-		
-		task_id_t id;
-		sysarg_t retval;
-		
-		iface_t iface;
-		service_t service;
-		sysarg_t phone;
-		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			retval = ns_task_disconnect(&call);
-			break;
-		case IPC_M_CONNECT_TO_ME:
-			service = IPC_GET_ARG2(call);
-			phone = IPC_GET_ARG5(call);
-			
-			/*
-			 * Server requests service registration.
-			 */
-			if (service_clonable(service)) {
-				register_clonable(service, phone, &call, callid);
-				continue;
-			} else
-				retval = register_service(service, phone, &call);
-			
-			break;
-		case IPC_M_CONNECT_ME_TO:
-			iface = IPC_GET_ARG1(call);
-			service = IPC_GET_ARG2(call);
-			
-			/*
-			 * Client requests to be connected to a service.
-			 */
-			if (service_clonable(service)) {
-				connect_to_clonable(service, iface, &call, callid);
-				continue;
-			} else {
-				connect_to_service(service, iface, &call, callid);
-				continue;
-			}
-			break;
-		case NS_PING:
-			retval = EOK;
-			break;
-		case NS_TASK_WAIT:
-			id = (task_id_t)
-			    MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
-			wait_for_task(id, &call, callid);
-			continue;
-		case NS_ID_INTRO:
-			retval = ns_task_id_intro(&call);
-			break;
-		case NS_RETVAL:
-			retval = ns_task_retval(&call);
-			break;
-		default:
-			retval = ENOENT;
-			break;
-		}
-		
-		if (!(callid & IPC_CALLID_NOTIFICATION))
-			ipc_answer_0(callid, retval);
-	}
+	async_manager();
 	
 	/* Not reached */
Index: uspace/srv/ns/service.c
===================================================================
--- uspace/srv/ns/service.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/ns/service.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -31,7 +31,7 @@
  */
 
-#include <ipc/ipc.h>
 #include <adt/hash_table.h>
 #include <assert.h>
+#include <async.h>
 #include <errno.h>
 #include <stdio.h>
@@ -47,9 +47,6 @@
 	service_t service;
 	
-	/** Phone registered with the interface */
-	sysarg_t phone;
-	
-	/** Incoming phone hash */
-	sysarg_t in_phone_hash;
+	/** Session to the service */
+	async_sess_t *sess;
 } hashed_service_t;
 
@@ -121,6 +118,8 @@
 		
 		hashed_service_t *hashed_service = hash_table_get_inst(link, hashed_service_t, link);
-		(void) ipc_forward_fast(pending->callid, hashed_service->phone,
-		    pending->iface, pending->arg3, 0, IPC_FF_NONE);
+		async_exch_t *exch = async_exchange_begin(hashed_service->sess);
+		async_forward_fast(pending->callid, exch, pending->iface,
+		    pending->arg3, 0, IPC_FF_NONE);
+		async_exchange_end(exch);
 		
 		list_remove(&pending->link);
@@ -151,9 +150,9 @@
 	
 	hashed_service->service = service;
-	hashed_service->phone = phone;
-	hashed_service->in_phone_hash = call->in_phone_hash;
+	hashed_service->sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (hashed_service->sess == NULL)
+		return EIO;
 	
 	hash_table_insert(&service_hash_table, &hashed_service->link);
-	
 	return EOK;
 }
@@ -202,11 +201,11 @@
 	
 	hashed_service_t *hashed_service = hash_table_get_inst(link, hashed_service_t, link);
-	(void) ipc_forward_fast(callid, hashed_service->phone, iface, arg3,
-	    0, IPC_FF_NONE);
+	async_exch_t *exch = async_exchange_begin(hashed_service->sess);
+	async_forward_fast(callid, exch, iface, arg3, 0, IPC_FF_NONE);
+	async_exchange_end(exch);
 	return;
 	
 out:
-	if (!(callid & IPC_CALLID_NOTIFICATION))
-		ipc_answer_0(callid, retval);
+	async_answer_0(callid, retval);
 }
 
Index: uspace/srv/ns/task.c
===================================================================
--- uspace/srv/ns/task.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/ns/task.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -32,6 +32,6 @@
  */
 
-#include <ipc/ipc.h>
 #include <adt/hash_table.h>
+#include <async.h>
 #include <stdbool.h>
 #include <errno.h>
@@ -182,10 +182,7 @@
 			continue;
 		
-		if (!(pr->callid & IPC_CALLID_NOTIFICATION)) {
-			texit = ht->have_rval ? TASK_EXIT_NORMAL :
-			    TASK_EXIT_UNEXPECTED;
-			ipc_answer_2(pr->callid, EOK, texit,
-			    ht->retval);
-		}
+		texit = ht->have_rval ? TASK_EXIT_NORMAL :
+		    TASK_EXIT_UNEXPECTED;
+		async_answer_2(pr->callid, EOK, texit, ht->retval);
 		
 		list_remove(&pr->link);
@@ -203,5 +200,5 @@
 	if (ht == NULL) {
 		/* No such task exists. */
-		ipc_answer_0(callid, ENOENT);
+		async_answer_0(callid, ENOENT);
 		return;
 	}
@@ -210,5 +207,5 @@
 		task_exit_t texit = ht->have_rval ? TASK_EXIT_NORMAL :
 		    TASK_EXIT_UNEXPECTED;
-		ipc_answer_2(callid, EOK, texit, ht->retval);
+		async_answer_2(callid, EOK, texit, ht->retval);
 		return;
 	}
@@ -218,6 +215,5 @@
 	    (pending_wait_t *) malloc(sizeof(pending_wait_t));
 	if (!pr) {
-		if (!(callid & IPC_CALLID_NOTIFICATION))
-			ipc_answer_0(callid, ENOMEM);
+		async_answer_0(callid, ENOMEM);
 		return;
 	}
@@ -282,4 +278,24 @@
 int ns_task_retval(ipc_call_t *call)
 {
+	task_id_t id = call->in_task_id;
+	
+	ht_link_t *link = hash_table_find(&task_hash_table, &id);
+	hashed_task_t *ht = (link != NULL) ?
+	    hash_table_get_inst(link, hashed_task_t, link) : NULL;
+	
+	if ((ht == NULL) || (ht->finished))
+		return EINVAL;
+	
+	ht->finished = true;
+	ht->have_rval = true;
+	ht->retval = IPC_GET_ARG1(*call);
+	
+	process_pending_wait();
+	
+	return EOK;
+}
+
+int ns_task_disconnect(ipc_call_t *call)
+{
 	task_id_t id;
 	int rc = get_id_by_phone(call->in_phone_hash, &id);
@@ -287,27 +303,4 @@
 		return rc;
 	
-	ht_link_t *link = hash_table_find(&task_hash_table, &id);
-	hashed_task_t *ht = (link != NULL) ?
-	    hash_table_get_inst(link, hashed_task_t, link) : NULL;
-	
-	if ((ht == NULL) || (ht->finished))
-		return EINVAL;
-	
-	ht->finished = true;
-	ht->have_rval = true;
-	ht->retval = IPC_GET_ARG1(*call);
-	
-	process_pending_wait();
-	
-	return EOK;
-}
-
-int ns_task_disconnect(ipc_call_t *call)
-{
-	task_id_t id;
-	int rc = get_id_by_phone(call->in_phone_hash, &id);
-	if (rc != EOK)
-		return rc;
-	
 	/* Delete from phone-to-id map. */
 	hash_table_remove(&phone_to_id, &call->in_phone_hash);
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/taskmon/taskmon.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,5 +38,4 @@
 #include <async.h>
 #include <ipc/services.h>
-#include <sys/typefmt.h>
 #include <task.h>
 #include <ipc/corecfg.h>
Index: uspace/srv/volsrv/Makefile
===================================================================
--- uspace/srv/volsrv/Makefile	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/volsrv/Makefile	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -29,6 +29,11 @@
 USPACE_PREFIX = ../..
 
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a
-EXTRA_CFLAGS = -I $(LIBBLOCK_PREFIX)
+LIBS = \
+	$(LIBLABEL_PREFIX)/liblabel.a \
+	$(LIBBLOCK_PREFIX)/libblock.a
+
+EXTRA_CFLAGS = \
+	-I$(LIBLABEL_PREFIX)/include \
+	-I$(LIBBLOCK_PREFIX)
 
 BINARY = volsrv
Index: uspace/srv/volsrv/empty.c
===================================================================
--- uspace/srv/volsrv/empty.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/volsrv/empty.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -38,4 +38,5 @@
 #include <errno.h>
 #include <io/log.h>
+#include <label/empty.h>
 #include <loc.h>
 #include <stdlib.h>
@@ -43,70 +44,21 @@
 #include "empty.h"
 
-/*
- * The partition will be considered empty if at least a minimum number of
- * bytes *and* blocks (whichever is larger) at the beginning and end of
- * the partition is zero.
- */
-enum {
-	min_empty_bytes = 16384,
-	/*
-	 * First block in ISO 9660 that cannot be empty is the first
-	 * volume descriptor at LBA 16
-	 */
-	min_empty_blocks = 17
+static int empty_get_bsize(void *, size_t *);
+static int empty_get_nblocks(void *, aoff64_t *);
+static int empty_read(void *, aoff64_t, size_t, void *);
+static int empty_write(void *, aoff64_t, size_t, const void *);
+
+/** Provide disk access to liblabel */
+static label_bd_ops_t empty_bd_ops = {
+	.get_bsize = empty_get_bsize,
+	.get_nblocks = empty_get_nblocks,
+	.read = empty_read,
+	.write = empty_write
 };
-
-static bool mem_is_zero(void *buf, size_t size)
-{
-	uint8_t *bp;
-	size_t i;
-
-	bp = (uint8_t *)buf;
-	for (i = 0; i < size; i++) {
-		if (bp[i] != 0)
-			return false;
-	}
-
-	return true;
-}
-
-/** Calculate number of blocks to check.
- *
- * Will store to @a *ncb the number of blocks that should be checked
- * at the beginning and end of device each.
- *
- * @param nblocks Total number of blocks on block device
- * @param block_size Block size
- * @param ncb Place to store number of blocks to check.
- */
-static void calc_num_check_blocks(aoff64_t nblocks, size_t block_size,
-    aoff64_t *ncb)
-{
-	aoff64_t n;
-
-	/* Check first 16 kiB / 16 blocks, whichever is more */
-	n = (min_empty_bytes + block_size - 1) / block_size;
-	if (n < min_empty_blocks)
-		n = min_empty_blocks;
-	/*
-	 * Limit to half of the device so we do not process the same blocks
-	 * twice
-	 */
-	if (n > (nblocks + 1) / 2)
-		n = (nblocks + 1) / 2;
-
-	*ncb = n;
-}
 
 int volsrv_part_is_empty(service_id_t sid, bool *rempty)
 {
 	int rc;
-	bool block_inited = false;
-	void *buf = NULL;
-	aoff64_t nblocks;
-	aoff64_t n;
-	aoff64_t i;
-	size_t block_size;
-	bool empty;
+	label_bd_t lbd;
 
 	rc = block_init(sid, 2048);
@@ -114,77 +66,13 @@
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
 		    "block device service %zu", sid);
-		rc = EIO;
-		goto error;
+		return EIO;
 	}
 
-	block_inited = true;
+	lbd.ops = &empty_bd_ops;
+	lbd.arg = (void *)&sid;
 
-	rc = block_get_bsize(sid, &block_size);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
-		    "block size.");
-		rc = EIO;
-		goto error;
-	}
+	rc = label_bd_is_empty(&lbd, rempty);
 
-	rc = block_get_nblocks(sid, &nblocks);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
-		    "number of blocks.");
-		rc = EIO;
-		goto error;
-	}
-
-	calc_num_check_blocks(nblocks, block_size, &n);
-
-	buf = calloc(block_size, 1);
-	if (buf == NULL) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
-		rc = ENOMEM;
-		goto error;
-	}
-
-	empty = true;
-
-	for (i = 0; i < n; i++) {
-		rc = block_read_direct(sid, i, 1, buf);
-		if (rc != EOK) {
-			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
-			    "reading blocks.");
-			rc = EIO;
-			goto error;
-		}
-
-		if (!mem_is_zero(buf, block_size)) {
-			empty = false;
-			goto done;
-		}
-	}
-
-	for (i = 0; i < n; i++) {
-		rc = block_read_direct(sid, nblocks - n + i, 1, buf);
-		if (rc != EOK) {
-			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
-			    "reading blocks.");
-			rc = EIO;
-			goto error;
-		}
-
-		if (!mem_is_zero(buf, block_size)) {
-			empty = false;
-			goto done;
-		}
-	}
-
-done:
 	block_fini(sid);
-	free(buf);
-	*rempty = empty;
-	return EOK;
-error:
-	if (block_inited)
-		block_fini(sid);
-	if (buf != NULL)
-		free(buf);
 	return rc;
 }
@@ -193,10 +81,5 @@
 {
 	int rc;
-	bool block_inited = false;
-	void *buf = NULL;
-	aoff64_t nblocks;
-	aoff64_t n;
-	aoff64_t i;
-	size_t block_size;
+	label_bd_t lbd;
 
 	rc = block_init(sid, 2048);
@@ -204,64 +87,42 @@
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
 		    "block device service %zu", sid);
-		rc = EIO;
-		goto error;
+		return EIO;
 	}
 
-	block_inited = true;
+	lbd.ops = &empty_bd_ops;
+	lbd.arg = (void *)&sid;
 
-	rc = block_get_bsize(sid, &block_size);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
-		    "block size.");
-		rc = EIO;
-		goto error;
-	}
-
-	rc = block_get_nblocks(sid, &nblocks);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
-		    "number of blocks.");
-		rc = EIO;
-		goto error;
-	}
-
-	calc_num_check_blocks(nblocks, block_size, &n);
-
-	buf = calloc(block_size, 1);
-	if (buf == NULL) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
-		rc = ENOMEM;
-		goto error;
-	}
-
-	for (i = 0; i < n; i++) {
-		rc = block_write_direct(sid, i, 1, buf);
-		if (rc != EOK) {
-			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
-			    "reading blocks.");
-			rc = EIO;
-			goto error;
-		}
-	}
-
-	for (i = 0; i < n; i++) {
-		rc = block_write_direct(sid, nblocks - n + i, 1, buf);
-		if (rc != EOK) {
-			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
-			    "reading blocks.");
-			rc = EIO;
-			goto error;
-		}
-	}
+	rc = label_bd_empty(&lbd);
 
 	block_fini(sid);
-	free(buf);
-	return EOK;
-error:
-	if (block_inited)
-		block_fini(sid);
-	if (buf != NULL)
-		free(buf);
 	return rc;
+}
+
+/** Get block size wrapper for liblabel */
+static int empty_get_bsize(void *arg, size_t *bsize)
+{
+	service_id_t svc_id = *(service_id_t *)arg;
+	return block_get_bsize(svc_id, bsize);
+}
+
+/** Get number of blocks wrapper for liblabel */
+static int empty_get_nblocks(void *arg, aoff64_t *nblocks)
+{
+	service_id_t svc_id = *(service_id_t *)arg;
+	return block_get_nblocks(svc_id, nblocks);
+}
+
+/** Read blocks wrapper for liblabel */
+static int empty_read(void *arg, aoff64_t ba, size_t cnt, void *buf)
+{
+	service_id_t svc_id = *(service_id_t *)arg;
+	return block_read_direct(svc_id, ba, cnt, buf);
+}
+
+/** Write blocks wrapper for liblabel */
+static int empty_write(void *arg, aoff64_t ba, size_t cnt, const void *data)
+{
+	service_id_t svc_id = *(service_id_t *)arg;
+	return block_write_direct(svc_id, ba, cnt, data);
 }
 
Index: uspace/srv/volsrv/mkfs.c
===================================================================
--- uspace/srv/volsrv/mkfs.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/volsrv/mkfs.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -40,4 +40,5 @@
 #include <stdarg.h>
 #include <stdlib.h>
+#include <str.h>
 #include <str_error.h>
 #include <task.h>
@@ -101,5 +102,5 @@
 
 
-int volsrv_part_mkfs(service_id_t sid, vol_fstype_t fstype)
+int volsrv_part_mkfs(service_id_t sid, vol_fstype_t fstype, const char *label)
 {
 	const char *cmd;
@@ -131,9 +132,29 @@
 		return rc;
 
-	rc = cmd_runl(cmd, cmd, svc_name, NULL);
+	if (str_size(label) > 0)
+		rc = cmd_runl(cmd, cmd, "--label", label, svc_name, NULL);
+	else
+		rc = cmd_runl(cmd, cmd, svc_name, NULL);
+
 	free(svc_name);
 	return rc;
 }
 
+void volsrv_part_get_lsupp(vol_fstype_t fstype, vol_label_supp_t *vlsupp)
+{
+	vlsupp->supported = false;
+
+	switch (fstype) {
+	case fs_exfat:
+	case fs_fat:
+		vlsupp->supported = true;
+		break;
+	case fs_minix:
+	case fs_ext4:
+	case fs_cdfs:
+		break;
+	}
+}
+
 /** @}
  */
Index: uspace/srv/volsrv/mkfs.h
===================================================================
--- uspace/srv/volsrv/mkfs.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/volsrv/mkfs.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -41,5 +41,6 @@
 #include <types/vol.h>
 
-extern int volsrv_part_mkfs(service_id_t, vol_fstype_t);
+extern int volsrv_part_mkfs(service_id_t, vol_fstype_t, const char *);
+extern void volsrv_part_get_lsupp(vol_fstype_t, vol_label_supp_t *);
 
 #endif
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/volsrv/part.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -143,10 +143,67 @@
 }
 
-static int vol_part_add_locked(service_id_t sid)
-{
-	vol_part_t *part;
+static int vol_part_probe(vol_part_t *part)
+{
 	bool empty;
 	vfs_fs_probe_info_t info;
 	struct fsname_type *fst;
+	char *label;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Probe partition %s", part->svc_name);
+
+	assert(fibril_mutex_is_locked(&vol_parts_lock));
+
+	fst = &fstab[0];
+	while (fst->name != NULL) {
+		rc = vfs_fsprobe(fst->name, part->svc_id, &info);
+		if (rc == EOK)
+			break;
+		++fst;
+	}
+
+	if (fst->name != NULL) {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Found %s, label '%s'",
+		    fst->name, info.label);
+		label = str_dup(info.label);
+		if (label == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		part->pcnt = vpc_fs;
+		part->fstype = fst->fstype;
+		part->label = label;
+	} else {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Partition does not contain "
+		    "a recognized file system.");
+
+		rc = volsrv_part_is_empty(part->svc_id, &empty);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed determining if "
+			    "partition is empty.");
+			rc = EIO;
+			goto error;
+		}
+
+		label = str_dup("");
+		if (label == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		part->pcnt = empty ? vpc_empty : vpc_unknown;
+		part->label = label;
+	}
+
+	return EOK;
+
+error:
+	return rc;
+}
+
+static int vol_part_add_locked(service_id_t sid)
+{
+	vol_part_t *part;
 	int rc;
 
@@ -171,32 +228,7 @@
 	}
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Probe partition %s", part->svc_name);
-
-	fst = &fstab[0];
-	while (fst->name != NULL) {
-		rc = vfs_fsprobe(fst->name, sid, &info);
-		if (rc == EOK)
-			break;
-		++fst;
-	}
-
-	if (fst->name != NULL) {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Found %s, label '%s'",
-		    fst->name, info.label);
-		part->pcnt = vpc_fs;
-		part->fstype = fst->fstype;
-	} else {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Partition does not contain "
-		    "a recognized file system.");
-
-		rc = volsrv_part_is_empty(sid, &empty);
-		if (rc != EOK) {
-			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed determining if "
-			    "partition is empty.");
-			goto error;
-		}
-
-		part->pcnt = empty ? vpc_empty : vpc_unknown;
-	}
+	rc = vol_part_probe(part);
+	if (rc != EOK)
+		goto error;
 
 	list_append(&part->lparts, &vol_parts);
@@ -305,5 +337,6 @@
 }
 
-int vol_part_mkfs_part(vol_part_t *part, vol_fstype_t fstype)
+int vol_part_mkfs_part(vol_part_t *part, vol_fstype_t fstype,
+    const char *label)
 {
 	int rc;
@@ -311,13 +344,26 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_mkfs_part()");
 
-	rc = volsrv_part_mkfs(part->svc_id, fstype);
+	fibril_mutex_lock(&vol_parts_lock);
+
+	rc = volsrv_part_mkfs(part->svc_id, fstype, label);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_mkfs_part() - failed %d",
 		    rc);
+		fibril_mutex_unlock(&vol_parts_lock);
 		return rc;
 	}
 
-	part->pcnt = vpc_fs;
-	part->fstype = fstype;
+	/*
+	 * Re-probe the partition to update information. This is needed since
+	 * the FS can make conversions of the volume label (e.g. make it
+	 * uppercase).
+	 */
+	rc = vol_part_probe(part);
+	if (rc != EOK) {
+		fibril_mutex_unlock(&vol_parts_lock);
+		return rc;
+	}
+
+	fibril_mutex_unlock(&vol_parts_lock);
 	return EOK;
 }
@@ -327,4 +373,5 @@
 	pinfo->pcnt = part->pcnt;
 	pinfo->fstype = part->fstype;
+	str_cpy(pinfo->label, sizeof(pinfo->label), part->label);
 	return EOK;
 }
Index: uspace/srv/volsrv/part.h
===================================================================
--- uspace/srv/volsrv/part.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/volsrv/part.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -49,5 +49,5 @@
 extern int vol_part_find_by_id(service_id_t, vol_part_t **);
 extern int vol_part_empty_part(vol_part_t *);
-extern int vol_part_mkfs_part(vol_part_t *, vol_fstype_t);
+extern int vol_part_mkfs_part(vol_part_t *, vol_fstype_t, const char *);
 extern int vol_part_get_info(vol_part_t *, vol_part_info_t *);
 
Index: uspace/srv/volsrv/types/part.h
===================================================================
--- uspace/srv/volsrv/types/part.h	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/volsrv/types/part.h	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -52,4 +52,6 @@
 	/** Filesystem type */
 	vol_fstype_t fstype;
+	/** Volume label */
+	char *label;
 } vol_part_t;
 
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision dbf32b10e7146a1f953c4eda94c63b8ac246f0ba)
+++ uspace/srv/volsrv/volsrv.c	(revision 95c675b4aa3fea7b424b73892a90b052c673cfd3)
@@ -46,4 +46,5 @@
 #include <types/vol.h>
 
+#include "mkfs.h"
 #include "part.h"
 
@@ -131,5 +132,4 @@
 	async_answer_0(iid, EOK);
 }
-
 
 static void vol_part_info_srv(ipc_callid_t iid, ipc_call_t *icall)
@@ -204,4 +204,42 @@
 }
 
+static void vol_part_get_lsupp_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	vol_fstype_t fstype;
+	vol_label_supp_t vlsupp;
+	int rc;
+
+	fstype = IPC_GET_ARG1(*icall);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_get_lsupp_srv(%u)",
+	    fstype);
+
+	volsrv_part_get_lsupp(fstype, &vlsupp);
+
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_read_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(vol_label_supp_t)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	rc = async_data_read_finalize(callid, &vlsupp,
+	    min(size, sizeof(vlsupp)));
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	async_answer_0(iid, EOK);
+}
+
+
 static void vol_part_mkfs_srv(ipc_callid_t iid, ipc_call_t *icall)
 {
@@ -209,4 +247,5 @@
 	vol_part_t *part;
 	vol_fstype_t fstype;
+	char *label;
 	int rc;
 
@@ -214,19 +253,29 @@
 	fstype = IPC_GET_ARG2(*icall);
 
+	rc = async_data_write_accept((void **)&label, true, 0, VOL_LABEL_MAXLEN,
+	    0, NULL);
+	if (rc != EOK) {
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	printf("vol_part_mkfs_srv: label=%p\n", label);
+	if (label!=NULL) printf("vol_part_mkfs_srv: label='%s'\n", label);
+
 	rc = vol_part_find_by_id(sid, &part);
 	if (rc != EOK) {
+		free(label);
 		async_answer_0(iid, ENOENT);
 		return;
 	}
 
-	rc = vol_part_mkfs_part(part, fstype);
-	if (rc != EOK) {
-		async_answer_0(iid, rc);
-		return;
-	}
-
-	part->pcnt = vpc_fs;
-	part->fstype = fstype;
-
+	rc = vol_part_mkfs_part(part, fstype, label);
+	if (rc != EOK) {
+		free(label);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	free(label);
 	async_answer_0(iid, EOK);
 }
@@ -263,4 +312,7 @@
 			vol_part_empty_srv(callid, &call);
 			break;
+		case VOL_PART_LSUPP:
+			vol_part_get_lsupp_srv(callid, &call);
+			break;
 		case VOL_PART_MKFS:
 			vol_part_mkfs_srv(callid, &call);
